Closed jahting closed 8 years ago
Hmm, how's it performance wise compared to the current code? If this is a full replacement, I'm tempted to have it as a library outside the lib (used in examples folder) and reduce the code in core even more...
From the past issues you can see that the problems with current implementation start with holes, which are needed for fonts also (e.g. "$", "%", "&").
For polygons without holes the current implementation is quite fast. While it has a worse worst case running time, for all practical cases (fonts or polygons up to at least 500 vertices) it seems to be faster than PnlTri.js . So I guess I should integrate the old core triangulation (which is quite small) for polygons without holes into PnlTri.js too.
For polygons with holes a big advantage of PnlTri.js is that it makes no assumption on winding order, a big problem with the current implementation. Even with using PnlTri.js the extrusion algorithm still relies on winding order (ref. "opQR" in: http://jsfiddle.net/MnV2R/2/) but that might be resolved.
Using my old Laptop (Core 2 Duo T7200, 2 GHz) with Firefox 30.0:
I like the numbers! :)
Do you mind doing a PR with the pnltri.min.js
in examples/js
and with the relevant examples updated?
:+1:
Triangulation is only used internally by ExtrudeGeometry, ShapeGeometry and TextGeometry and not called explicitly in any example. So changing any example would just require the following glue code:
THREE.Shape.Utils.triangulateShape = function ( contour, holes ) {
var pnlTriangulator = new PNLTRI.Triangulator();
return pnlTriangulator.triangulate_polygon( [ contour ].concat(holes) );
}
... a rather nasty method :-( .
So instead of changing any existing example I would suggest, that I make a copy of webgl_geometry_text.html
-> webgl_geometry_text2.html
and add this glue code as an additional example.
Well, that seems like a good first step. Does the triangulator needs to be instanced all the time, or could it be like this?
THREE.Shape.Utils.triangulateShape = ( function () {
var pnlTriangulator = new PNLTRI.Triangulator();
return function ( contour, holes ) {
return pnlTriangulator.triangulate_polygon( [ contour ].concat(holes) );
};
} )();
@jahting do you think changing the way we do triangulation as suggested in this issue https://github.com/mrdoob/three.js/issues/4745 would be more better since you're working in this area too?
@zz85 yes I agree with your idea in #4745. As you can see from my example #4950 the API of the present triangulation and my new one is quite small - just an Array of vertex lists (polygons and holes), which are just Arrays of objects with at least the attributes x and y. The resulting triangles are presented as Array of triangles, which are triples of indexes into the original vertex list (faces). This API is not sufficient for triangulations which allow the creation of additional Steiner points, which at present seems not necessary. So it is easy to separate the triangulation and write adapters for other libraries.
Are there any intentions to replace THREE.triangulateShape
with pnltri in the future?
I think it'll happen eventually. It's a matter of being able to fit it in the ~100kb gzip budget :)
I'm still working on improving performance and functionality and reducing size. It would help if someone knows how to change the output of the closure compiler so it can be used as input to the closure compiler again (for including the compiled version of pnltri in three.js).
@jahting
Sorry if I ask something already answered...
Anyway, thanks for this superb job
@tonnot
I hope I could answer your questions and that pnltri.js is still useful for you.
@mrdoob FYI in case you're still considering a better triangulation algorithm. I wrote https://github.com/mapbox/earcut, ultimately the fastest and smallest (2.3k gzipped) JS triangulation library. It's very robust and scales well with shape complexity. Check it out!
@mourner #5959 : - )
Three.js at present includes a Shape/Text triangulation which was easy to implement but also needed several add-ons, eg. to decide between contours and holes and to remove those holes, and it had quite some issues concerning:
It seems to work correctly by now but is quite slow if there are many vertices or holes.
Instead of trying to improve the present code further, I created a new project PnlTri.js: Polygon Near-Linear Triangulation in JavaScript
I also created a branch for Three.js with PnlTri, replacing the present mechanism. So interested users of Three.js can test their data against it. More test data would be welcome.
The main drawback might be that this algorithm often produces rather long, slim triangles. I'm thinking about a post-processing step to improve on this in the future. There is still some room to refactor PnlTri and reduce the code surrounding triangulation in Three.js. The next major step for PnlTri will be to allow polygons with intersections which would also increase robustness further.
@mrdoob: Is it small enough for integration into Three.js, or should it be left for people to combine them on their own ?