speps / LibTessDotNet

C# port of the famous GLU Tessellator - prebuilt binaries now available in "releases" tab
https://www.nuget.org/packages/LibTessDotNet
Other
313 stars 59 forks source link

Robustness and collinear points compatibility #17

Closed electroremy closed 6 years ago

electroremy commented 6 years ago

Hi,

I’m very interested in your LibTessDotNet project :-)

Indeed, polygon triangulation is still a “hot topic” in 2018!

I have a VB.NET project that use Clipper and Poly2Tri to make 2.5D pieces for NC milling machines and 3D printers.

Clipper works fine.

But, as you said, Poly2Tri does not support polygons from Clipper, more specifically vertices with same coordinates or coincident points.

As I reported here (https://github.com/greenm01/poly2tri/issues/110), the problem is that you can’t transform any possible 2D shape in polygon tree structure without coincident points. It’s not possible, so poly2tri cannot be used if your software needs to deal with any possible 2D shape.

Here is an example of 2.5D piece:

http://electroremy.free.fr/GitHub/3D_OK.jpg

The blue horizontal surfaces are clipper polygon tree structure (that is to say, polygon with holes, and inside holes, possibly others polygons with holes).

The yellow vertical surfaces are just “walls” that connect the horizontal surfaces together.

I need polygon triangulation to get all blue horizontal surface triangles.

The yellow vertical triangles (walls) are easy to generate, I just need to create two triangles for each polygon or hole edge.

There is another important thing to understanding here: the “T-junction problem”

The “T-junction problem” is described here: https://blackflux.wordpress.com/2014/02/23/meshing-in-voxel-engines-part-1/

To solve the “T-junction problem”, I have to add some collinear points on the polygons after Clipper processing.

Look at the previous image, in which my program adds all collinear points needed.

Now look at the difference in the next picture, without collinear points; you can see the “T-junction problem” on the bright yellow triangle edge:

http://electroremy.free.fr/GitHub/3D_NOK.jpg

So I need triangulation that:

About numerical robustness, the greatest idea of Clipper is to use integer values. That is to say fixed point arithmetic instead of floating point arithmetic.

Floating point arithmetic is a bad idea when you deals with geometry. Because in floating point arithmetic, the precision is depending on the value, so each time you translate an object, there are rounding errors. So in floating point arithmetic, each time you translate an object you get deformation!

Indeed, in fixed point arithmetic, you get the same precision regardless of object position.

That is to say, fixed point arithmetic XY plane is a regular grid plane, but if you use floating point XY coordinates, your XY plane is a strange and insane “variable pitch” grid. So we should never use floating points to deals with geometric problems.

Also I think the best idea is to get a fixed point arithmetic triangulation process, with 64 bits integer values like in Clipper. These code can also be directly integrated in clipper, with also a code to add collinear instead of re-creating the whole polygon tree structure.

Edit : the most recent Clipper update is here : https://sourceforge.net/p/polyclipping/code/HEAD/tree/

Thanks!

PS : I'm french, sorry for bad english :-)

speps commented 6 years ago

I'm French too so speak French if you prefer.

However, I don't really understand the issue you want me to take a look at. Is it only that you'd like to use fixed point arithmetic instead of floating point?

If that's what you're asked, I would first suggest to try your geometry through LibTessDotNet and see if there's any issues before making assumptions on wether or not you're going to hit precision issues. More so because you can use double in LibTessDotNet as well and probably completely forget about precision issues. I would also add that my code is based on decades old code that's been very robust in regards to precision so far as it handles comparison very well.

Anyway, feel free to switch to French to explain what you want :)

electroremy commented 6 years ago

Hi,

I think we should continue in English, because there are not a lot of people dealing with these kinds of problems, and so English allows everybody to both contribute and use the project.

I’m working on my app since 2010. It’s quite a long (!) and fortunately I found clipper that is both:

But for the triangulation problem I still have issues. I’ve made a high number of tests, and the best solution is Poly2Tri but Poly2Tri can’t handle 100% of clipper polygons. In fact, as I explained before, Poly2Tri can’t handle 100% of possible 2D shape, it’s a major issue.

So I found your project, and also I’ve read your discuss between you and Pro100AlexHell. Before trying your project or the Pro100AlexHell fork, I had to know:

Also I’ve a lot of “degenerated” polygon sets to tests my software, it will be useful. But I fear that degenerated case for Poly2Tri are not the same for your software. If it’s true, I had to make again hundred and hundred hours of testing.

I use triangulation just for two things in my app:

Indeed, I don’t need triangulation for 2D viewing and NC milling, those are the main functions in my app.

If there are little errors in triangulation:

So if a robust and 100% fail-safe triangulation is impossible, I’m searching for a triangulation algorithm that work in most cases, and can give a “degenerated but nice” triangle mesh instead of crashing in particular cases. I’m sure that video games engines and CAD professional software work in this way.

I try to modify Poly2Tri to catch “EdgeEvent” problem and so modify polygons but it’s very difficult. Poly2Tri can’t handle ANY coincident edge, so in several cases you have to cut a polygon into 2, 3 or more little polygons and there is always a case that fails…

When I talk to you about integers VS. floats, it’s not an issue but an idea. I just think it’s possibly easier to get rid of triangulation issues with integers but I’m not sure.

In 1997 I’ve created a CAD software (CiDess), to draw PCB. It’s still available and update (http://cidess.free.fr/index-fr.html); in CiDess I’ve use integer coordinate values because with floats I’ve get rounding errors when moving parts. So I still think that floating point arithmetic is not a good idea for geometric computing.

Unfortunately today CPUs support only integer and floating number, they don’t support fixed point arithmetic. So when dealing with integers you must use scaling and a lot of double <—> integer conversion. Only specials DSPs support fixed point arithmetic.

Thanks

speps commented 6 years ago

Please try the library and see if it works. My philosophy is "try before you buy". Download the project, run the TessBed project and open a .txt file that contains your polygon points (one point per line, extra line to have multiple polygons), see the TessBed/Data folder for examples.

This library IS robust, it's based on libtess which was part of SGI GLU library, more than 18 years ago. If you look at TessBed/UnitTests.cs, you'll find plenty of tests that have degenerate cases that are handled correctly by my library. Running TessBed, you'll also find polygons that intersect in many places and even one that I generated with Clipper some time ago and was crashing Poly2Tri but works with mine.

I do agree that fixed point arithmetic is better for geometry and it could be possible to actually use an arbitrary precision library in LibTessDotNet as I've already done the work to handle float or double.

Just to reiterate my point, please use the library in your software directly, replace Poly2Tri and see where it goes. So many times I've seen projects where people don't make progress because they spend time discussing instead of doing :)

KellanHiggins commented 6 years ago

Just have to chime in here. This is a great library and other than zero area triangles (which I submitted a pull request and fixed) it has been nothing but great!

electroremy commented 6 years ago

Hi,

I've made some tests with LibTessDotNet and compare the results between Poly2Tri.

In my app, LibTessDotNet and Poly2Tri have the same speed.

If you want both quality and robustness, you can use Poly2Tri, and if it trows an exeption, then use LibTessDotNet

You can look at the following screenshots to get the difference between Poly2Tri and LibTessDotNet :

Sample "BetC" : LibTessDotNet : http://electroremy.free.fr/GitHub/BetC_LibTess.jpg Poly2Tri : http://electroremy.free.fr/GitHub/BetC_P2T.jpg

Sample "ImageDeLaMort" : LibTessDotNet : http://electroremy.free.fr/GitHub/ImageDeLaMort_LibTess.jpg Poly2Tri : http://electroremy.free.fr/GitHub/ImageDeLaMort_P2T.jpg

Sample "T-Junction" : LibTessDotNet : http://electroremy.free.fr/GitHub/T-Junction_LibTess.jpg Poly2Tri : http://electroremy.free.fr/GitHub/T-Junction_P2T.jpg

Sample "TEST_COLINEAR4" : LibTessDotNet : http://electroremy.free.fr/GitHub/TEST_COLINEAR4_LibTess.jpg Poly2Tri : FAIL (EdgeEvent) !

Sample "TEST_COLINEAR5" : LibTessDotNet : http://electroremy.free.fr/GitHub/TEST_COLINEAR5_LibTess.jpg Poly2Tri : http://electroremy.free.fr/GitHub/TEST_COLINEAR5_P2T.jpg

Sample "TEST_COLINEAR6" : LibTessDotNet : http://electroremy.free.fr/GitHub/TEST_COLINEAR6_LibTess.jpg Poly2Tri : FAIL (EdgeEvent) !

Sample "TEST_COLINEAR7" : LibTessDotNet : http://electroremy.free.fr/GitHub/TEST_COLINEAR7_LibTess.jpg Poly2Tri : FAIL (EdgeEvent) !

Sample "_8bits_OK" : LibTessDotNet : http://electroremy.free.fr/GitHub/_8bits_OK_LibTess.jpg Poly2Tri : http://electroremy.free.fr/GitHub/_8bits_OK_P2T.jpg

Sample "____EXGM" : LibTessDotNet : http://electroremy.free.fr/GitHub/________EXGM_LibTess.jpg Poly2Tri : http://electroremy.free.fr/GitHub/________EXGM_P2T.jpg

Sample "____EXG" : LibTessDotNet : http://electroremy.free.fr/GitHub/________EXG_LibTess.jpg Poly2Tri : http://electroremy.free.fr/GitHub/________EXG_P2T.jpg

Sample "____EX" : LibTessDotNet : http://electroremy.free.fr/GitHub/________EX_LibTess.jpg Poly2Tri : http://electroremy.free.fr/GitHub/________EX_P2T.jpg

Thanks

speps commented 6 years ago

I do agree that LibTessDotNet doesn't produce perfect looking meshes in respect to triangle sizes. However, for most applications, and actually for applications that it wasn't designed for it's sometimes better. For example, when used with OpenGL, it's not great that it produces long thin triangles but for your use case, I would have thought that you didn't care too much about that.

Regarding the colinear points getting removed, do you have a minimal example that would show the removal that you've seen? You can run TessBed and use the Open button to open a .txt file that contains polygons (the format is the same as the example .dat files). If you attach this file, I can have a look at why it's removing points. I'm not sure if it's a bug or a feature but either way it seems fixable.

Really awesome looking application by the way, it's very similar to what @KellanHiggins is doing but you're actually making a physical object from it from what I could see :)

electroremy commented 6 years ago

Hi,

It’s strange because LibTessDotNet does not remove all collinear points…

The sample “T-Junction” has collinear points and both Poly2Tri and LibTessDotNet are OK

But in the “TEST_COLINEAR5” LibTessDotNet remove 4 collinear points

“ImageDeLaMort” and “_8bits_OK” are OK with Poly2Tri but there are a lot of errors with LibTessDotNet

Indeed, collinear points into polygons are often considered as useless or errors. Unfortunately, collinear points cause robustness problems and crash some algorithms!

Thus, clipper removes collinear points!

I need to add collinear points to solve the “T-junction” problem that is a 3D problem and not a 2D problem. But a lot of software made 3D parts as an assembly of 2D shapes. When you deal with arbitrary 3D shape you should already have a triangle mesh or a point cloud to triangulate, that is a problem completely different.

Indeed, my 3D objects (or rather my 2.5D objects) are a stack of 2D layers connected together with walls. Each 2D layer is a polygon tree structure (polygon with holes with islands with holes…)

When you deal with a 3D or 2.5D triangle mesh, you get “T-junction” problem that does not exist with a single 2D polygon tree structure.

To solve the “T-junction” it’s necessary to add some collinear points. You can see more explanation and samples here: https://blackflux.wordpress.com/2014/02/23/meshing-in-voxel-engines-part-1/

To get an optimal result, I continue to use Poly2Tri, and when Poly2Tri fails, I use LibTessDotNet as “second chance” triangulation to handle “nasty” polygons. In this way I’ve got both robustness and quality. Better: I can put an option so the user of my software can choose between “Poly2Tri only,” “LibTessDotNet only” and “Poly2Tri / LibTessDotNet 2nd chance.”

Fortunately, the LibTessDotNet artifacts and T-junction problems are very tiny, so it’s OK for 3D viewing and it’s OK for 3D printers software that have built-in corrections.

I think I could check if LibTessDotNet returns “flat” triangle (3 vertex collinear) so I can delete those triangles?

I notice that LibTessDotNet use Z coordinate (that are useless in 2D) and also a “data” object. I think I should remove Z and Data to save memory and increase a little bit speed?

Thanks.

speps commented 6 years ago

Okay, I think I understand what you mean for the T-junction issue. I really don't think it removes the points. It would be really good if you could provide test data to reproduce the problem you mention for TEST_COLINEAR5 and when it has a lot of errors. I'm sure it could be solved and might be due to precision as you mentioned before. If it's a precision I can look into arbitrary precision libraries or fixed precision and I think it might be possible to integrate into the library (with a performance impact of course).

Regarding the degenerate triangles, that feature is already here, just set NoEmptyPolygons = true on the Tess instance you create.

electroremy commented 6 years ago

Hi

I use NoEmptyPolygons = true

I made some tests with DAT files generation :

DAT.zip

Into the zip you will find :

There are 3 sample :

I think it's possibly a precision issue rather than a colinear problem

Thanks

electroremy commented 6 years ago

Thus, I notice that you've just uploaded a new release, but I don't understand changes :-P

Thanks

electroremy commented 6 years ago

Hi,

Here is my VB.NET code to use LibTessDotNet :

Private Sub TriangulariserPoly(c As PolyNode)
    Dim c2 As Clipper.PolyNode
    Dim c3 As Clipper.PolyNode
    Dim p1 As Clipper.IntPoint
    Dim p2 As Clipper.IntPoint
    Dim i As Integer
    Dim polyg As List(Of IntPoint)

    Dim Tess As LibTessDotNet.Tess
    Dim TessV() As LibTessDotNet.ContourVertex
    Dim TessTri0 As Integer
    Dim TessTri1 As Integer
    Dim TessTri2 As Integer

    'POLY
    Tess = New LibTessDotNet.Tess
    Tess.NoEmptyPolygons = True
    polyg = Clipper.CleanPolygon(c.Contour)
    Call RestoreColinears(polyg, ListCol)
    TessV = New LibTessDotNet.ContourVertex(polyg.Count - 1) {}
    For i = 0 To polyg.Count - 1
        p1 = polyg.Item(i)
        If i = 0 OrElse p2.X <> p1.X OrElse p2.Y <> p1.Y Then
            TessV(i).Position = New LibTessDotNet.Vec3()
            TessV(i).Position.X = p1.X
            TessV(i).Position.Y = p1.Y
            TessV(i).Position.Z = 0
        End If
        p2 = p1
    Next i
    Tess.AddContour(TessV)

    'POLY'S HOLES:
    For Each c2 In c.Childs
        polyg = Clipper.CleanPolygon(c2.Contour)
        Call RestoreColinears(polyg, ListCol)
        TessV = New LibTessDotNet.ContourVertex(polyg.Count - 1) {}
        For i = 0 To polyg.Count - 1
            p1 = polyg.Item(i)
            If i = 0 OrElse p2.X <> p1.X OrElse p2.Y <> p1.Y Then
                TessV(i).Position = New LibTessDotNet.Vec3()
                TessV(i).Position.X = p1.X
                TessV(i).Position.Y = p1.Y
                TessV(i).Position.Z = 0
            End If
            p2 = p1
        Next i
        Tess.AddContour(TessV)
    Next

    'TRIANGULATION
    Tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3)

    'GET TRIANGLES
    For i = 0 To Tess.ElementCount - 1
        TessTri0 = Tess.Elements(i * 3)
        TessTri1 = Tess.Elements(i * 3 + 1)
        TessTri2 = Tess.Elements(i * 3 + 2)
        If Not (TessTri0 = -1 OrElse TessTri1 = -1 OrElse TessTri2 = -1) Then
            Call EcrireTriangle(Tess.Vertices(TessTri0).Position.X, Tess.Vertices(TessTri0).Position.Y, Tess.Vertices(TessTri1).Position.X, Tess.Vertices(TessTri1).Position.Y, Tess.Vertices(TessTri2).Position.X, Tess.Vertices(TessTri2).Position.Y)
        End If
    Next

    'ISLANDS (POLYS INTO POLY'S HOLES) :
    For Each c2 In c.Childs
        For Each c3 In c2.Childs
            call TriangulariserPoly(c3)
        Next
    Next
End Sub

Thanks

speps commented 6 years ago

Thanks for the data, I'll have a look and try to see if it's fixable.

The new release yesterday was only for fixing a bug I introduced which made the callback be null and crash code in TessBed.

electroremy commented 6 years ago

Hi,

Another important thing : I use the "single" version of LibTessDotNet, not the "Double"

Indeed, Poly2Tri works with single, so I would first compare P2T with the single version of LibTess

If you open .DAT files, you can see that it's only Integer "big" values (as it comes from clipper output)

I can give you .DAT files for all samples if you want.

Thanks

electroremy commented 6 years ago

Hi,

I made a test with LibTessDotNet.Double

The results are the same

Thanks

speps commented 6 years ago

If you pull latest master and run TessBed, you should now be able to load a folder of .dat files. I did that with the files from your DAT.zip file.

However, I couldn't see any errors in any of the models. Could you have a look yourself and point me to one that shows problems? Thanks.

electroremy commented 6 years ago

Indeed, the errors are "3D" errors and not 2D errors. That is to say, each polygon triangulation is OK but a polygon "layer" does not match perfectly the others polygon "layer".

The .jpg screenshots of the opened STL files with VisCamView let you see the difference between Poly2Tri and LibTessDotNet.

I get the last version but I can't load a whole folder.

Thanks

speps commented 6 years ago

Sorry but the screenshots aren't clear enough for me :) Could you circle or put some text and arrows to show me what I should be paying attention to in the screenshots?

From your code above, I think you should only keep the triangulation output from LibTessDotNet. What I mean here is you keep the triangles and use the indices (TessTri0, TessTri1, TessTri2 in your code) to index into your original vertices (the ones you give to the library, from polyg). If you do as your code above, you're converting from integer to float and lose precision. However, you only need the triangles so just keep the triangles, not the vertices and your final output should be perfect as it's the same coordinates without the loss of precision.

EDIT: to make it easier for you, you could also set Data on each ContourVertex to get the original value you had from polyg

Let me know if that didn't make any sort of sense :)

electroremy commented 6 years ago

Hi,

Unfortunatelly, errors are little artefacts so there are difficult to see / I should make special "zoom" screenshots for you

Your idea is very great ! Indeed, I just need to pick the point indexes of triangles instead of coordinates !

Thus I can use data object if there a no relationship between polygon points order and triangle indexes. As you see I first add external polygon's points in the right order, thus each hole points in the right order (clipper generate clockwise / counterclockwise data for external polygons and holes)

But something is strange : I need to convert integer to float because STL files are made with single values... And in a STL file, dimenssions must be in mm so I have to scale my data and use floats.

.... so ...P2T rounding is better than LibTess rounding ???

...or rounding is different from one polygon layer to other ???

It's a good question I will try this !

Thanks

electroremy commented 6 years ago

Hello,

I've just try your idea and the result is ... the same :-D :-/

It's both bad and good news : there is no rounding problem, but a problem

I wonder if the problem would be "extra flat triangles" (with an angle close to 0° but not null) ; because LibTessDotNet generate a lot of "flat triangles" and P2T no too much.

Here is two "zoom" screenshots, you can see the difference between P2T and LibTess

LibTess : imagedelamort_detail_libtess

P2T : imagedelamort_detail_p2t

NB : in the picture there are flat triangle that you can't see (quality part check is right, there is no missing triangles in P2T picture, and no so much missing triangle in LibTess picture)

Thanks

electroremy commented 6 years ago

This is another king of LibTess error : "unmatching edges" (in yellow) is produced when 2 points of a poly and 1 point of a hole are on a single triangle edge :

_8bits_ok_libtess_errors

_8bits_ok_libtess_errors_detail

_8bits_ok_libtess_errors_detailsuper

Thanks

speps commented 6 years ago

You should try setting NoEmptyPolygons to true on the Tess instance, that removes those degenerate triangles (zero area ones).

electroremy commented 6 years ago

Hi,

I've already done it

... Tess = New LibTessDotNet.Tess Tess.NoEmptyPolygons = True ...

I think that the "extra flat" triangle don't have null but very small area

Thus, a very flat but very long triangle could have a "not so small" area

Thanks.

electroremy commented 6 years ago

Also your LibTessDotNet works fine, and the errors I found are both rare and only little artefacts :-)

But as mathematicians, we prefer no errors :-)

electroremy commented 6 years ago

I think a "errorless" code is not robust...

It's like if we can't have both quality and robustness

Most of P2T problems come from "FlipScan" algorithm. It's the FlipScan function that give quality mesh and avoid extra flat triangles.

electroremy commented 6 years ago

For my app, the best way to deals with triangulation is to use P2T, and when P2T fails, switch to LibTessDotNet.

...it is not as bad as it looks :-)

electroremy commented 6 years ago

Hi

I’ve made others tests…

I decided to not remove zero area and flat triangles. It’s very interesting; with LibTessDotNet:

On the two next pictures you can see the result with no removing flat triangles, and an explanation on the third picture.

_8bits_ok_libtess_errors2

imagedelamort_libtess_errors2

libtess_vs_p2t

Thanks!

KellanHiggins commented 6 years ago

I was having issues with zero area triangles on my project and added a test to remove them. I think it is just a byproduct of the LibTessDotNet, since it loves to make reaaaaaaaaaally long and skinny tris.

electroremy commented 6 years ago

Hi

If you dont' want zero area triangles you should:

For single values, use 1.0E-44 as epsilon (safer than zero)

Thanks

speps commented 6 years ago

That's already what LibTessDotNet does though:

                if (NoEmptyPolygons)
                {
                    var area = MeshUtils.FaceArea(f);
                    if (Math.Abs(area) < Real.Epsilon)
                    {
                        continue;
                    }
                }

With Real.Epsilon being 1.401298E-45F (from C# Single.Epsilon).

speps commented 6 years ago

Looking at your diagram, I'll have a look at how it's handled and see if it can be fixed. I wonder if it's the sweeping direction that messes it up.

speps commented 6 years ago

I ran a simple test using a similar configuration as your example diagram.

Using tjunction.txt, I got this:

2018-03-27 17_42_02-libtessdotnet - tessbed

As you can see at the bottom of the screenshot, it produces 2 triangles. I intentionally used very big coordinates for those points. Again, I would love to have an example that reproduces the issue you're talking about, a simple case like I just did :)

EDIT: note this is with 4 points, triangulating ABDC as you said.

electroremy commented 6 years ago

Hi

My diagram is not an example

My diagram is just a little part of the picture below:

imagedelamort_detail_libtess

Here, BDC is the yellow edge

Thanks

speps commented 6 years ago

What I tried here is a reasonable reproduceable case, the only way to have that BDC triangle is to actually add that edge as a contour. If you only give 4 points, 1 contour to LibTessDotNet like I did, you do not end up with a triangle in BDC at all.

I just made a new release, as before it shows empty triangles, but now in pink (try with issue6-L), it also includes the "Folder" button in the toolbar (in the sub menu on the right): https://github.com/speps/LibTessDotNet/releases/tag/v1.0.68

I tried all files starting with ImageDeLaMort (name of the image from your screenshot) and none of them showed any pink edges so it doesn't result in empty triangles (I didn't have the "No empty" button checked).

From this, I do not understand what data you're giving to LibTessDotNet, is it different from those .dat files you sent me? In your screenshot, are there really multiple points along the yellow edge? I would guess the problem you're pointing at on the yellow edge is that the number of points doesn't match what's on the vertical edge, right?

I'm really interested in helping you figure out what's wrong :)

electroremy commented 6 years ago

Thank you very much !

I can make more accurate tests between P2T and LibTess

I hope I can give you a precise case on a single DAT file

Thanks

electroremy commented 6 years ago

Hi

Here is more details:

ZIP file with .DAT file of the polygon, and also 3D STL files:

Files.zip

Poly2Tri OK:

poly2tri_ok

LibTess artefact:

libtess_nok_detail

libtess_nok_location

libtess_nok_tessbed

The error is more complex than the diagram... I think that kind of case are difficult to handle

Thanks

electroremy commented 6 years ago

Hi

Here is another kind of error (common edge with hole):

Files: DAT3.zip

Poly2Tri OK:

poly2tri_ok

LibTess artefact:

libtess_nok_location

libtess_nok_detail

libtess_nok_tessbed

Thanks

speps commented 6 years ago

Regarding that last one, I added a zoom feature to TessBed (not in master yet) and it shows like this.

2018-03-28 17_51_06-libtessdotnet - tessbed

I don't see anything wrong here, can you explain what is the problem? It's very thin triangles I agree but it's valid triangles.

I'll have a look at the other one.

speps commented 6 years ago

For the other one, it's actually exactly the same, very thin triangles.

2018-03-28 17_59_38-libtessdotnet - tessbed

I don't know why your program removes those triangles but they are totally valid from a mesh perspective. Again, very thin, but valid :)

Do you do any post processing after triangulation to remove those triangles?

EDIT: I just noticed in one of your screenshots, those triangles are visible but the edge is painted yellow. How does the detection that makes them yellow work?

electroremy commented 6 years ago

Hi

Your zoom feature is a very good idea, thank you very much !!!

My program does not remove triangles if I do not check the "zero triangle remove" option.

The screen shots are not made with my program, but with VisCAM View software.

VisCAM View is a famous software to check the quality of STL files, but I don't know how it works...

Please mind the "T-junction problem" that is not a 2D but a 3D problem, in an STL file, you should not have "vertex on edge" but edges connected together only at edge. It's the raison why I must preserve or add colinear points.

Here is VisCam View software, you can open the STL files with it : https://drive.google.com/open?id=18aLRkoV0l_IV_PgYbUYDcUczWg2eJDJW

Also in some case my program can't add all colinear points ; but you can compare Poly2Tri STL file between LibTessDotNet STL file to see the difference. As my program give to P2T and to LibTess the same polygon data, it's the best way to understand what appends

In VisCamView:

I don't understand why P2T and LibTess produce different STL result as the process before and after is the same ; P2T triangle mesh is better quality than LibTess but LibTess seems to bo OK also, just with a lot of long and flat triangle.

Thanks

speps commented 6 years ago

I used VisCAM and it does the same issue:

2018-03-29 16_38_20-viscam view 5 2 - model 1_ imagedelamort_libtess - facet part

I also tried with MeshLab which seemed recommended for doing that kind of check. Here is the result when trying to show non manifold edges:

2018-03-29 16_40_24-meshlab 2016 12 - project_2 2018-03-29 16_40_33-microsoft edge

With those display options:

2018-03-29 16_42_58-meshlab 2016 12 - project_2

So I think it's a VisCAM issue rather than a mesh issue.

To download MeshLab if you want to check for yourself: http://www.meshlab.net/

electroremy commented 6 years ago

Thank you very much!!!

What a waste of time! It’s difficult to find out the cause of a problem when you use a software chain. Indeed VisCamView may have a precision issue.

I will check again all my samples with meshlab.

Unfortunately VisCamView is one of the few software that handles colored STL files, a feature that is very useful to me for debugging. In a “color” STL file, for each triangle two unused “attribute” bytes are used to set RGB color as explained here: https://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL

I wonder if some of my very complicated error checks and correction algorithms in my program are still necessary.

Our exchange will be very useful for the Unity, 3D printing and NC milling community.

We can consider that LibTessDotNet is THE library to use for triangulation. For those who want good quality, it’s simple to use Poly2Tri with a try…catch statement, and to use LibTessDotNet when Poly2Tri fails on a polygon.

Thanks

electroremy commented 6 years ago

Geometrical computing is difficult because to debug a program, we need a viewing tool that is both fail-safe and relevant. When we have bugs both on program and viewing tool, it’s a nightmare to find out what’s wrong.

Also the “zoom feature” in TessBed will be useful for everybody, we can both check quality of input and quality of triangulation.

I just have an idea: in the TessBed Window it will be interesting to have a textBox that indicates number of vertices in the current view. It’s a good way to be sure that there are no two or more points too close to be distinguished.

For example, if I see 5 points when the textbox indicates 6 points, which means I need to zoom again to find out a “hidden” point and probably a “hidden” triangle.

Thanks

speps commented 6 years ago

Unfortunately VisCamView is one of the few software that handles colored STL files, a feature that is very useful to me for debugging. In a “color” STL file

MeshLab does support that already :)

I'll try to submit the zoom feature in TessBed soon. For now, I'll close this issue. Feel free to re-open if needed.