Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intersecting differences of triangular prisms flips faces #537

Open
rpavlik opened this issue Dec 23, 2019 · 6 comments
Open

Intersecting differences of triangular prisms flips faces #537

rpavlik opened this issue Dec 23, 2019 · 6 comments

Comments

@rpavlik
Copy link
Contributor

rpavlik commented Dec 23, 2019

System information

SolveSpace version: 3.0~64c0f62b

Operating system: Debian Buster

Expected behavior

I have essentially a rectangular prism that I wanted to cut two triangular grooves in, one "vertically" and one "horizontally" (same height, and intersecting - making vise jaws). So, one 2d sketch + extrude for positive solid, one 2d sketch and extrude as difference for one groove, then perpindicular 2d sketch and extrude as difference for other groove. It should look normal.

Actual behavior

Several of the faces are red, indicating they are back-faces. (The solver didn't fail - it thinks it succeeded.) It actually looks like I'm seeing thru missing faces, when I went and redrew it...

difference-fail

image

image

Forcing to trimesh does fix it (despite the lack of a solver fail message), but I would have guessed that this was a fairly easy geometry to handle - nothing curved :)

image

Additional information

open jaw-covers.slvs - the other is my reference linked in. (I'm not sure how to, or if I can, "re-seat" the origin of sketches to be able to simplify this one without redrawing)

jaw-.zip

OK, decided to not be lazy and re-draw a simpler test case.

Peek 2019-12-23 10-06

and with workaround:

image

example2.zip

Update: exporting to STL or "show naked edges" without doing the workaround pops up this nice and half-scary message:

image

and the exported STL is missing the same faces that are missing in the app. As loaded into PrusaSlicer with (left) and without (right) the workaround:

image

@ghost
Copy link

ghost commented Dec 23, 2019

As a workaround, just lower one of triangular to 0.001 mm

pic.1

@ruevs
Copy link
Member

ruevs commented Dec 23, 2019

This may not be a NURBS failure, but rather a failure in triangulating the "surfaces" (planes). It fails here:
https://github.com/solvespace/solvespace/blob/master/src/srf/triangulate.cpp#L353
with

couldn't find an ear! fail

Obviously the single point in the center - the "tip" of the pyramid where the two prisms intersect is the problem. Four of the edges going to it are missing. If I switch the last group to union they decrease to two.

But maybe it is a NURBS problem and the long edge (that the two missing edges should have been pieces of) was not cut in half by the surface intersections.

One more thing to debug :-)

@ruevs
Copy link
Member

ruevs commented Aug 5, 2020

@phkahler since you tinkered with the triangulation code recently maybe you can shed some light on what happens here?
Attached is the simplest case (that I could come up with at the time) that reproduces the problem.
Prisms_EarFail.zip

@phkahler
Copy link
Member

phkahler commented Aug 5, 2020

@ruevs I really believe this is a NURBS issue. My understanding (which may be wrong, I'd like to find the exact source lines for thsi) is that each 3D group creates NURBS surfaces. If a group is forced to triangle mesh, or if the one before it already was a triangle mesh, then the boolean is done on the prior and new triangle meshes. If it's not necessary to create a triangle mesh, none is created - except at whatever group needs to be displayed, that one is triangulated after the boolean in order to have triangles to hand to OpenGL. So everything is NURBS by default unless forced not to be, or for display. The fact that the above works when forced to triangle mesh suggests the issue is in the NURBS boolean operation combining the last group with the previous groups SShell. In other words, both groups can be triangulated properly and combined which requires both NURBS shells to be correct, but the NURBS boolean fails and then triangulation fails after that.

I suspect this is a failure in one of thtree places:

  1. It could fail to properly assemble a polygon.
  2. It's an issue with what the code calls a "choosing point" where more than 2 edges meet within the same surface.
  3. It's a failure to classify an edge as "inside" or "outside" of a shell. (possibly due to 2 above)

Your reduced test case is really nice because it does not contain coincident surfaces which would offer a 4th place the error could be coming from.

Since these are planar surfaces with all straight edges I'm going to say probably not a failure to assemble polygon (that prints an error anyway doesn't it?).

I have not read and understood every aspect of the boolean code or even splitting edges against shells, but there is one case that I am curious about how it's handled which is also present here. There is a distinction between curves and edges. And I don't just mean PieceWiseLinear approximations (PWLs). A curve can be split into more then one section as a result of a boolean. Imagine a line ----------------------- gets cut by another solid which results in ------- ----------- The original curve is preserved and there are 2 different PWL edges (is that the right term as opposed to segments?). The thing I wonder is this: When the curve (straight line) is being split against another shell, that is done one surface at a time. When the curve is split by one surface one side of the surface should be discarded and the other kept (which one depends on the boolean operation). The thing with this case is that one side needs to be kept and the other piece will be partially kept beyond the other surface intersection. In other words, splitting at a surface only has enough information to split a curve in 2 pieces but this case requires information from 2 surface intersections to classify 3 sections of the curve. I know the process involves finding all the cut points along the curve prior to classifying the edges, so in this case the middle edge should get discarded. Maybe I just explained it to myself. ;-)

That's all I've got for now. Hope it helps someone to understand and maybe find a bug.

@phkahler
Copy link
Member

phkahler commented Sep 8, 2020

Here is possibly a 2D sketch that fails to fill the contour. Possibly a simple example of what's failing here.
It broke when constraining the bottom of the V to the origin which produces similar planar geometry. Either way now we have another simple sketch that fails contour filling.

537_2D.zip

EDIT: Sorry, it declares that sketch self-intersecting so probably doesn't even try to fill it. I can still see how triangulation may fail though.

@ruevs
Copy link
Member

ruevs commented Sep 22, 2023

Between 1b8e1de and b399d9a this model (#537 (comment)) has improved slightly (also attached here #594 (comment))

Before

NastyPrismsRPavlikLike

After

NastyPrismsRPavlikLike_After1410

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants