Closed tonyskansf closed 2 years ago
Thanks for the detailed report - I'll look into it.
I did some digging and noticed this with the mesh created from the SCNBox
geometry:
The polygons share vertices; however, in some cases, these (visually same) vertices have different values in their x, y, or z position
coordinate. Although those values vary, they visually represent the same vertex.
For example: Both vertices were created from the Mesh.init
and from whatever data was in the geometry SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
.
// A shared vertex between two polygons.
let vertexA = Vector(-0.10000000149, 0.10000000149, -0.10000000149)
let vertexB = Vector(-0.10000000149, 0.099999986589, -0.10000001639099999)
vertexA == vertexB
would return false
.vertexA.isEqual(to: vertexB)
would return false
.vertexA.isEqual(to: vertexB, withPrecision: 1e-7)
would return true
.Also: There is a shared edge LineSegment
in the highlighted triangles but treated as non-equal due to the difference in start
and end
.
(It seems like this is the reason why polygons.areWatertight
would return false
for this geometry even though the mesh is watertight as every edge is attached to at least two polygons.)
Not sure if it helps anything, but I thought it might have something to do with how polygons/vertices are compared during the subtraction algorithm (?).
I'd like to look into this more too, so if you have any idea where the problem might root from, I'm more than happy to help debug this.
@tonyskansf AFAICT the issue is with the actual vertices produced by SceneKit. If I reduce the precision
value in Utilities.quantize()
down to 1e-7
it solves the problem, but that's not really a good solution as it breaks other models with fine details.
I'm not really sure what to do about it. I could add a special case to produce clean data for SCNBox
, but that wouldn't solve the general problem. Maybe I need to add some code to clean up vertex data generally.
Hmm, it seems like reducing epsilon
to 1e-7
also solves the problem, and is a slightly less terrible solution. I'm still not very happy with simply tweaking magic numbers as a solution though, since there are presumably other cases which this would either break or fail to solve.
Just as you said, reducing the numbers might help in this specific case, but is breaking other cases. I still have two input meshes that are watertight but the resulting mesh after subtract
is not even though there is no reason not to be. Not sure however how to proceed further with the issue.
@tonyskansf this should be fixed in 0.5.19. I've added some additional logic to makeWatertight()
that merges vertices that are close but not exactly equal, such as those in the SCN primitives.
Hi, I'm getting weird results from multiple
subtract
operations between two nodes created from theSCNBox
geometry—there are always some polygons from the RHS mesh remaining in the resulting mesh after the subtraction. This, however, does not happen when Euclid'sMesh.cube
is used.I believe the below example should explain what's happening. The example is simplified. I'm facing the same issue with custom nodes created from custom
SCNGeometry
.Example: The loop simulates a real-time node movement (position changes) and subtraction.
Unexpected results:
Works fine with Euclid's
Mesh.cube
: