Introducing TriRemesh - high quality triangular and hexagonal remeshing and shrink wrapping

I struggle with remeshing this big and “ugly” Delaunay mesh - perhaps it is too ugly? Are there some rules of thumb one should follow at the moment?

Although I think I did a correct job with providing polyline segments as Features input I cant receive consistent results.

Is there a way to force some edges as welded or unwelded? What I expected to be continuous unwelded edge breaks into pieces in places that are not that different from each other. This broken white line was fully unwelded in my previous tests, where mesh input was just slightly different.

Probably you don’t need my test file to answer those questions, but I attach it just in case.
Sorry that it is big, but hey, it’s a real-life scenario :wink:

Triremesh - big mesh.gh (1.4 MB)

Have you tired Unweld with 10 degrees?

Hi @Czaja

I think the issue here is related to the gaps between the vertices of the input mesh and the input feature curves.

When the ‘Sharp’ option is set to True, the remeshing detects ‘creased’ edges where the angle between the normals of the adjacent faces is above a threshold and keeps them as features.

Low quality input triangulations might have relatively large angles between faces in places you don’t really want to be features though, like the region between the curves near the right of your second image.
You might also have parts which you do want to be features, yet which have quite small angles between faces, like the middle of the top ridge in that image.
So automatic detection of features from this sort of input won’t always work.

When ‘Sharp’ is set to False though, it does not do this automated feature detection based on face angles, and feature edges are only those close within a tolerance to the curves in the ‘Features’ input. I’ll look at ways of adding more control over this tolerance. It can get a bit tricky though if the gaps between the vertices you want to snap to the features are bigger than the lengths of the short edges.

Where is the input coming from?
I’m wondering if there might be a way to get the exact curves you want to input as features(or do your initial meshing so the gaps are smaller) to get around this tolerance issue.

@Holo
Thanks, for the suggestion. That may work, but may also bring some unwanted results and I consider it more as a „post-process” solution. As I know exactly where I need unwelded edges I would rather like to point them out before remeshing. Also, I can imagine a scenario where I want some parts to be unwelded on the completely flat mesh so unwelding by angle would not work there.

Hi, @DanielPiker

Eh, those gaps, I will investigate how it could happen that they are there.

Input mesh is created by me… I have a couple millions of XYZ points as a representation of the terrain. Depends on the quality of the scan, point clouds can be noisy and also some not-important terrain features bring unwanted data.

I tried to interpolate some areas of the river bank and useless points in areas which I don’t mind to be flatter than in the reality.

After that, I used all points to create Delaunay mesh and then tried to triremesh it featuring some polylines (this should eventually help me to split the mesh into pieces, excluding the bottom of the water canal, canal banks, etc. But have good continuity between all parts).

I don’t like those very thin and sharp triangles I receive from Delaunay mesh and I imagine they might bring some problems. Maybe I should try different 3D meshing algorithms to start with?

Then try the add crease command in V7, it’s called just _Crease

You can try my TerrainMesh plugin if you like, but if you use points as input it should give about the same result as it is a delaunay mesher.

You can also try to reduceMesh the result a bit to get rid of small edges etc. (Reducemesh to 90% so you only remove 10% can be worth a go)

Just a little update with the last Rhino 7 Service Release Candidate - the issue with input of points as features is now fixed
image

Also, for the Geometry input, as well as Breps and Meshes, it will now accept direct input of SubDs, polylines, and planar NURBS curves.
Furthermore, MultiPipe also now accepts meshes as input, and will pipe the edges, or if the mesh has ngons (such as the Dual D output of TriRemesh) it will pipe the ngon boundaries.

14 Likes

Thanks for adding the point feature input, i was hoping for that, looks like it also works on edges of a mesh too…

@DanielPiker I’m not sure if this has been asked yet, but I am having a bit of trouble with the ngon mesh structure. When I decompose the mesh to do some kind of other operations (maybe some relaxation with kangaroo) then rebuild the mesh, I will get a triangulated mesh. Is there an easy way to understand the face groups that make up the original ngon mesh? In the end I would like the mesh edges of the ngon when I rebuild the mesh.

Thanks!

Hi @porterfield.aaron

The dual output uses the standard Rhino Ngon class, where they are stored as groupings of triangles.

You can get the ngon boundaries as polylines using the FaceBoundaries component, and if you want just the edges you can explode and remove duplicates.

Mesh ngons are preserved by Kangaroo if passed through the ‘Show’ component.

If you want other topological data about the ngons you can access it from these classes
https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_Collections_MeshNgonList.htm
https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_MeshNgon.htm

Does that help?

2 Likes

For user interface I did quite some work to make NGons usable from rhinocommon to grasshopper components, including polygon extraction to conversion back to ngon data structure, adjacency of vertex, edge and faces that are currently missing in standard Rhinocommon methods. For sure you can code them up, but there are some parts that will take some time to figure it out due to mapping between triangles and triangles groups. So you can use super nice Daniel Piker Remesh algorithm in combination with this tool-set.

To answer your question about converting polygons to mesh data structure without triangulation you can simply use NGon components - a) fromPolylines (equivalent to FaceBoundaries component) and b) toPolylines.

1 Like

Just to clarify - that conversion also happens automatically without additional components.
The D output is already a Rhino Ngon mesh, and passing this to the standard Face Boundaries component gives you the polygons which are the boundaries of each Ngon.

1 Like

Hi Daniel,

Thanks so much for the quick reply. I think in my case, I will need to do some operations to the mesh, and will need to decompose and rebuild it. I think the best option for me will be to have a list of face indices per ngon. I will take a look at the ngon class to see if I can figure that out.

Cheers!

Hi Petras,

Quick question. Will your “fromPolylines” component preserve the topology of the original ngon mesh?

Yes, there are two typical triangulation methods by right click fromPolylines: a) star triangulation b) ear-clipping. It is the same NGon Rhino mesh, and the topology comes from polygon adjacency. If you have more specific question post a file.

If you already have an ngon mesh (which the dual output is), you don’t need to go via polylines.

Also, each of the ngons in this dual output is triangulated radially (to better preserve smooth shapes), so if you use a different triangulation, the face groupings will be different.


ngons_example.gh (12.3 KB)

Thanks Daniel, this is exactly what I was looking for!

Hi Petras,

I just tried some of the tools in you Ngon plugin and was able to do exactly what I was wanting. Extract certain ngons from the mesh while preserving the topology.

Daniel just showed I could have done this with a couple lines of code, but I appreciate the extensive plugin and tools since I am not much of a coder.

Cheers!

Also, showing how the ngon list matches the FaceBoundaries output
ngons_example2.gh (18.9 KB)

Yup that was a point, to have a grasshopper interface since these C# methods start to pile up once you have a bigger definition. For example, a simple case of computing mesh face normal, you need to get an average of all faces cross-products, taking one center or one normal might be not enough for some geometry methods. Then the last part of what Daniel shows where you take mesh vertices and ngon indices from C# and convert to one polyline is the same method in one component - toPolylines. FaceBoundaries of standard mesh is the same as toPolylines, but in the beginning I started the plug-in this component did not behave in the same way and only gave triangle outlines.

In addition, there is an NGonsCore.dll that helps to deal with these triangular to polygon and vice versa mappings for .NET coding.

For taking out one polygonal mesh face, this also works with “fewer” components while preserving original mesh topology:

As most often, there are multiple ways to do a similar thing.