CSG with BufferGeometry (three >= r125)

As part of my project enable3d, I maintain a CGS version that works with BufferGeometries.

It uses Geometry, DirectGeometry, Face3 and the old BufferGeometry().fromGeometry under the hood. But it works great!

You can install it from npm and use it in any three.js (>=0.125.2) project.

// for now, install the latest dev version
npm install @enable3d/three-graphics@0.22.0-dev.1
import { CSG } from '@enable3d/three-graphics/jsm/csg'

const meshC = CSG.intersect(meshA, meshB)
const meshD = CSG.subtract(meshA, meshB)
const meshE = CSG.union(meshA, meshB)

scene.add(meshC, meshD, meshE)

To see it in action, check out the threejs-ammojs-webpack-example.

12 Likes

Hi Yannick,

Does this work with custom made geometries (irregular geometries) with thousands of vertices of both meshes ?

Looks great !

Thanks :slight_smile:

I don’t know if there is a limit. But in this post, I have subtracted two boxes from Suzanne and it works great!

1 Like

There isn’t a built in limit, but CSG operations are slow when both geometries are high poly… you can work around this by using a lower poly intermediate object…

Instead of having complex object A subtracting from complex object B, instead make a single box “C” and subtract C from B, and subtract A from the result of that, then merge the results back together.

Then if you need to make adjustments, you only need to repeat the last step, and that goes quicker. Here’s some screenshots of embossing text on some complex geometries:

4 Likes

There are various acceleration structures that can be used beyond the BSP tree to optimize CSG, but they each have their own caveats and bring along their own set of tradeoffs, but with clever structuring of the operations you can work around the slow NxN2 operations.

2 Likes

This is great.
Is there an online in-browser example?
Can the Boolean operations perform per-frame? Ie: animateable?

http://vectorslave.com/csg/demos/CSGDemo.html

http://vectorslave.com/csg/demos/CSGShinyDemo.html

and a more complex experiment:

http://vectorslave.com/csg/v2/index.html

1 Like

Whoops… to be clear… this isn’t OP’s library… this is my library that OPs was forked from, and I have recently updated for latest threejs. The functionality may vary so caveat emptor. :slight_smile: You can check it out here: GitHub - manthrax/THREE-CSGMesh: Conversion of a CSG library for use with modern THREE.js

3 Likes

Wow.
Some unexpectedly yet seriously performant things going on there.

Definetely following this, as it’s right up my ally.
Thanks for sharing!

2 Likes

Doesn’t work for subtracting Mesh with ShapeGeometry.

Hi,can you add a new feature that maybe allow us to apply another material to the intersection parts?

Hi, can you please elaborate in formula terms,
" instead make a single box “C” and subtract C from B, and subtract A from the result of that" = (B-C) - A
“then merge the results back together” - which results to merge together to get B-A ?
Thanks.

if we have 2 objects, each 1000 triangles…
subtracting them from each other is like… ~(1000 * 1000) operations, which is too slow.

If we make a 3rd object that is the bounding box of B… (12 triangles)
we get the intersection of box and A (1000*12) operations
we subtract B from this intersection (1000 * size of intersection) operations
then merge the geometries with brute force geometry merge (1000 + size of intersection) operations.

Here’s a picture:

I’m having a hard time articulating it, but we’re making the csg operation simpler, by chopping out just the area affected by the operation, doing the operation on that simpler piece… then combining the results back together.

So… in that picture… there is a gold base… and white text geometry…

and a box set to the size of the text.

the little slab in the middle is that box subtracted from the gold base…

then the text is subtracted from that little slab…

and then the result is merged back in with the base… yielding the final object in the upper right.

this turns out to be faster than subtracting the text from the base directly.

2 Likes

Let’s draw it:

7 Likes

Yes. You nailed it.

3 Likes

I think it does if you prepare your shapegeometry correctly, by merging vertices, making the mesh watertight.

I believe if does allow you to apply another material to the intersection. It creates material groups, so you if you set .material = [ material1, material2 ] you may get material2 on the intersection.