# Boolean operations with three-bvh-csg ```js import { Brush, Evaluator, ADDITION, SUBTRACTION, INTERSECTION, DIFFERENCE } from 'three-bvh-csg'; ``` (already mapped in the import map of template.html) ## Rules - CSG operands are `Brush` objects (a `Mesh` subclass): `new Brush(geometry, material)`. - Place the brush (`position`, `rotation`, `scale`), then call `brush.updateMatrixWorld()`; the evaluator works on world matrices. - `const ev = new Evaluator(); ev.useGroups = false;` - then the result is one mesh that takes the material you assign (`result.material = mat`). - `ev.evaluate(a, b, OP)` returns a NEW Brush. Add the result to the scene, not the operands. - Chain operations by reusing the result: `part = ev.evaluate(part, nextTool, SUBTRACTION)`. - Curved cuts need enough segments: `new THREE.CylinderGeometry(r, r, h, 48)`. - Make the cutting tool slightly longer than the solid (cube size 2 -> cylinder height 2.2). Exactly coplanar faces produce artifacts. - Results have no smooth normals across the cut; call `result.geometry.computeVertexNormals()` only if the shading looks wrong (flat shading is usually fine for CAD-like parts). ## Operations | Constant | Result | |---|---| | `ADDITION` | union of a and b | | `SUBTRACTION` | a minus b (holes, pockets) | | `INTERSECTION` | volume shared by a and b | | `DIFFERENCE` | symmetric difference (a xor b) | ## Example: cube with a through-hole ```js const mat = new THREE.MeshStandardMaterial({ color: 0x4488ff, metalness: 0.2, roughness: 0.5 }); const cube = new Brush(new THREE.BoxGeometry(2, 2, 2), mat); const hole = new Brush(new THREE.CylinderGeometry(0.5, 0.5, 2.2, 48), mat); hole.rotation.x = Math.PI / 2; // cylinder axis along z cube.updateMatrixWorld(); hole.updateMatrixWorld(); const ev = new Evaluator(); ev.useGroups = false; const part = ev.evaluate(cube, hole, SUBTRACTION); part.material = mat; scene.add(part); ```