1.9 KiB
1.9 KiB
Boolean operations with three-bvh-csg
import { Brush, Evaluator, ADDITION, SUBTRACTION, INTERSECTION, DIFFERENCE } from 'three-bvh-csg';
(already mapped in the import map of template.html)
Rules
- CSG operands are
Brushobjects (aMeshsubclass):new Brush(geometry, material). - Place the brush (
position,rotation,scale), then callbrush.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
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);