Open bsupnik opened 6 years ago
One random thought: if the algorithm sweeps mono regions from left to right, is this an artifact of not closing off the end of the sweep properly when there are multiple right-side edges?
I've seen the algorithm to generate bunch of zero area triangles before, but not missing a triangle. I think you are right that the problem is due to monotone triangulation.
I did not write the triangulation code, it is based on the GLU tessellator, I once understood it really well, but a lot of that is forgotten.
I try to find some time in coming week to see if I can figure out what is causing it. I'm super short on time, so if you have the patience to step through the case in debugger that'd be great help.
@memononen Thanks - if I find any more details (or specific or confirmed details), I'll be sure to post them here. I've had experience with sweep-line algorithms before but I haven't taken the time to pull this one apart yet.
This isn't at the top of my Q because the colinear triangle does generate an (I guess?) mesh that is manifold and thus doesn't break OpenGL's mesh cracking rules, but it's a case that would be nice to fix because our input data is all axis-aligned, and the next stage for the triangulation algorithm is another algorithm that doesn't cope with degeneracies well. If I spot something I'll let you know.
The incremental delaunay pass that was added recently removes the degenerates quite well. But does not solve the specific case you found.
I've found the source of the colinear triangle (or at least, the code path that causes it). The very beginning of tessMessTessellateMonoRegion is producing the colinear triangle in its very first triangulation step.
The algorithm works by blocking off sub-regions of the monotone polygon and fan-triangulating them. In the first iteration the top right side is "lo" and the top is "up". No triangles are built because the algorithm never 'ears off' lo and up; lo is walked backward to the bottom right side.
On pass 2 "Lo's" org forms the beginning of a colinear vertical section, hitting the EdgeSign <= 0 case (our edge sign is exactly 0). We form a triangle from lo->Lnext->Dst to lo->org.
Since we have explicitly allowed for this edge sign to be 0, this step seems weird to me...it explicitly allows us to build a colinear triangle.
I did experiment with making the Edgesign tests < 0 and > 0 and it does seem to fix my case - the algorithm walks "lo" past the colinear vertices on the right side and starts fanning from the upper left corner.
Does that EdgeSign <= 0 case happen to be this one: https://github.com/memononen/libtess2/commit/955761f46fcec73c91c5dbf2547b6f88afb5d3fc
I wish I had documented the fix better. It's not that long ago and I cannot remember all my reasoning. I think there was mismatch between the assert and the code. It has taken me days to swap in those comparisons and equalities a few times in the past :)
No, fortunately (maybe?) that's a different code site.
Hi,
I'm not sure if this is a bug or design limitation, but: the tesselator appears to create a colinear triangle (e.g. a triangle where all 3 vertices are colinear) if the input is a single contour with colinear vertices on a vertical right side.
Here's my test program.
The output is:
gives us
where each triangle is non-colinear.