Mesh becomes very angular after substracting with

2019-03-22 08:47发布

I experience a problem when substracting a mesh from an other mesh using ThreeCSG. My main mesh is a ring and the mesh to substract is a diamond. Before the process to scene looks like this: Mesh fine. But after substracting the meshes the ring becomes angular: Mesh Broken. I do apply the same material / shading as before. Here is the code I use:

var ring_bsp = new ThreeBSP(ring);
var stone_bsp = new ThreeBSP(stone);
var substract_bsp = ring_bsp.subtract( stone_bsp );
var result = substract_bsp.toMesh( ringMaterial );

result.geometry.computeVertexNormals();

result.material.needsUpdate = true;
result.geometry.buffersNeedUpdate = true;
result.geometry.uvsNeedUpdate = true;

result.scale.x = result.scale.y = result.scale.z = 19;

scene.remove(ring);
scene.add(result);

Update one: If I remove "result.geometry.computeVertexNormals();" the result looks even worst: link.

Update two: I created a jsfiddle with a minimal case

Update three: After looking some more into the problem and Wilts last update, I saw that after I use ThreeBSP the vertexes are messed up. You can see this very well in this fiddle.

Update four: The problem seems to be within the "fromGeometry / toGeometry" functions as I get the same broken mesh if I don't do any substraction at all.

1条回答
迷人小祖宗
2楼-- · 2019-03-22 09:35

It looks like (some of) your vertex normals get lost during translation (translating your geometry to CSG and translating back to Three.js). You should check out the source code to see where this goes wrong.

UPDATE 1:

I looked into the source code of ThreeCSG.js it seems there is a bug on line 48.

It should be:

vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs );

The index for the vertexNormals should be 1 instead of 2. Maybe that bug causes the wrong export result.

UPDATE 2:

Try updating the vertexNormals of the geometry before you convert to CSG:

var geometry = ring.geometry;
geometry.computeFaceNormals();
geometry.computeVertexNormals();

Note. You need to call computeNormals() first for the correct result.

UPDATE 3:

In the conversion of faces from Three.js geometries to CSG geometries the ThreeBSP.Polygon.prototype.classifySide method checks wheter the vertex of the adjacent face is in the front, in the back or coplanar to the current face. If the point is coplanar the CSG face will be defined as a Face with four vertex points. Because of this process some of your THREE.Face3 get converted to a 4 point CSG face. When later translating it back to a THREE.Face3 the Face vertexNormals become different from their initial values.

The vertex is classified FRONT, BACK or COPLANAR using an EPSILON value to compare the vertex normal with the face normal. If the difference is too small the Vertex is considered coplanar. By increasing the EPSILON value in your ThreeBSP library you can control the precision. If you set EPSILON to 10 your triangles will never be considered coplanar and the conversion result will be correct.

So at line 5 of your ThreeBSP library set:

EPSILON = 10,
查看更多
登录 后发表回答