Very small gaps after csg operation between faces of the meshes

this.uiManager.uploadedBrushes = this.uiManager.uploadedBrushes.map((brush, index) => {
            if (!doesIntersect(brush)) return brush;
    
            const originalState = originalStates[index];
            const result = this.evaluator.evaluate(brush, cuttingBrush, SUBTRACTION);
            result.userData = { ...originalState.userData };

            result.geometry = mergeVertices(result.geometry, 1e-4)
            // result.geometry.computeVertexNormals();
    
            const normals = result.geometry.attributes.normal;
            const faceCount = result.geometry.index ?
                result.geometry.index.count / 3 :
                result.geometry.attributes.position.count / 3;
    
            const faceKeys = new Array(faceCount);
            const materialsMap = new Map();
            const finalMaterials = [];
    
            for (let faceIndex = 0; faceIndex < faceCount; faceIndex++) {
                const faceNormal = new THREE.Vector3();
                for (let i = 0; i < 3; i++) {
                    const vertexIndex = result.geometry.index ?
                        result.geometry.index.array[faceIndex * 3 + i] :
                        faceIndex * 3 + i;
                    faceNormal.add(new THREE.Vector3(
                        normals.array[vertexIndex * 3],
                        normals.array[vertexIndex * 3 + 1],
                        normals.array[vertexIndex * 3 + 2]
                    ));
                }
                faceNormal.normalize();
    
                let keyFound = null;
                for (const [normalKey, materialInfo] of originalState.faceNormals) {
                    const originalNormal = new THREE.Vector3().fromArray(normalKey.split(',').map(Number));
                    originalNormal.normalize();
                    if (faceNormal.dot(originalNormal) > 0.9999) {
                        keyFound = normalKey;
                        break;
                    }
                }
                if (!keyFound) {
                    keyFound = faceNormal.toArray().join(',');
                }
                faceKeys[faceIndex] = keyFound;
    
                if (!materialsMap.has(keyFound)) {
                    let materialInfo = originalState.faceNormals.get(keyFound);
                    if (!materialInfo) {
                        materialInfo = {
                            materialIndex: 0,
                            material: Array.isArray(brush.material) ?
                                brush.material[0].clone() :
                                brush.material.clone()
                        };
                    }
                    const newIndex = finalMaterials.length;
                    materialsMap.set(keyFound, newIndex);
                    finalMaterials.push(materialInfo.material);
                }
            }
    
            result.geometry.clearGroups();
    
            let groupStartFace = 0;
            let currentKey = faceKeys[0];
            for (let faceIndex = 1; faceIndex < faceCount; faceIndex++) {
                if (faceKeys[faceIndex] !== currentKey) {
                    const materialIndex = materialsMap.get(currentKey);
                    result.geometry.addGroup(groupStartFace * 3, (faceIndex - groupStartFace) * 3, materialIndex);
                    groupStartFace = faceIndex;
                    currentKey = faceKeys[faceIndex];
                }
            }
            {
                const materialIndex = materialsMap.get(currentKey);
                result.geometry.addGroup(groupStartFace * 3, (faceCount - groupStartFace) * 3, materialIndex);
            }
    
            result.material = finalMaterials;
            result.material.forEach(mat => {
                mat.side = THREE.DoubleSide;
                mat.needsUpdate = true;
            });
            
            this.scene.remove(brush);
            this.scene.add(result);
            return result;
        });

there are small gaps between faces of the mesh if you load the model in blender or 3d viewing software.

please help me solve this

You might be able to run mergeVertices or remove duplicate verts in blender, to get a more stable input to the CSG.

https://threejs.org/docs/#examples/en/utils/BufferGeometryUtils.mergeVertices

run mergeVertices doesnt work at all even if i increase tolerance i found a similar issue can you check this ?

Can you make a codepen or jsfiddle showing the issue?

1 Like

I will try to set it up

1 Like

Hi i am having some trouble setting it up, can you suggest some other way for me to showcase ?
As per Three-bvh-csg issue with r148 - #12 by gkjohnson

i tried removing all the mesh doubleside and cutting geometry double side property but still i see the issue.

https://gkjohnson.github.io/three-bvh-csg/examples/bundle/geometry.html

Can you use that sample and put your models in perhaps?

i didnt had time to create the io page, honestly forgot how to.

here is the link for the model house and the door i try to place 3d-demo-data/models/stanford-bunny at main · KaustubhJha-TUL-UpperFunnel/3d-demo-data · GitHub

The samples code is here:

geometry.html and geometry.js

what version of three are you using? I can no longer replicate the problem with the latest versions…

three@0.173.0
three-mesh-bvh@0.9.0
three-bvh-csg@0.0.16

the problem I had before was using double sided materials (workaround was setting material.side = 0 before operations) with the outdated versions:

three@0.148.0
three-mesh-bvh@0.5.24
three-bvh-csg@v0.0.2

I’d suggest setting up a live example with your setup, here’s a starting point…

1 Like

hi this is my code pen link, place the doors on a wall couple of times and then you will be able to see it in high 3d render of this

@manthrax and @Lawrence3DPK please also help

here is the sample image

this is rendering in shapespark software for now. but you can see in high quality blender output also

Hi everyone this is solved, this was the issue in the shapespark software i will post a link to this

thanks everyone for your precious time.

1 Like

Nice! Glad you figured it out.

1 Like

if you can help me with the csg operation geometry forming, it would be a even better, the tolerance is too low for mergeVertices to work

mergevertices tolerance isn’t working?

tolerance is working properly but none of the values from 0.001 to 0.00001 fit my use case, i would have to binary search a perfect value to general solution but it’s still too tedious. I want to stick to a generic solution. Thanks!

The problem might be that…

With real meshes… the hard surface normals and/or uvs force those vertices to become unique even tho their positions are close.

Once those planes are islands, there isn’t any constraint against creating t-junctions between neighboring faces… (which cause those cracks).

You can take the initial mesh…

delete its normal attribute:
geometry.deleteAttribute(‘normal’);

delete its uv attribute:
geometry.deleteAttribute(‘uv’);

Then merge its vertices with a small threshold.

Then call geometry.computeVertexNormals()

and then do csg on that…

Then get the csg result…

call geometry.computeVertexNormals()

Then use:
three.js docs

To get back the hard edges…

or smth…

but idk. :smiley: