jcode/skills/threejs-csg/csg.md

43 lines
1.9 KiB
Markdown

# 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);
```