algorithmic modeling for Rhino
I'm converting Tetgen program 3D Voronoi diagrams faces to meshes in Python/Rhinocommon. However, unlike the Rhino Polyline Through Points command that automatically sorts the points to always give a single non-overlapping closed loop, Rhinocommon only seems to have a generic Polyline structure that fails to sort the points, so my unordered input points are giving self-overlapping curves that can't then be converted to mesh faces.
Must I use Python to sort the points around their center using math? Or does Rhinocommon have a trick or two to do this for me? Each group of points are coplanar, albeit at various 3D angles.
I'm disappointed in Rhinocommon today since I can't use Rhino power commands now that I sadly realize the Tetgen tetrahedral mesh generator binary is not offering ordered points, just a list of lines I have to extract endpoints from and cull duplicates.
Just a "clockwise" sorting function would do.
The Grasshopper Polyline component also fails to sort the points so I can't use node-in-code for that. I must use several components, to fit a circle then sort points along curve, which is a lot of Grasshopper binding I may wish to avoid.
Tags:
You have the overload sort() in the polyline object of RhinoCommon. You may need to use some argument on this method, for example you can find out the sequence of indexes by using the ClosestIndex method of the Point3dList object. This can not be done automatically and always, because the user may not want to have ordered points.
Hi Nik
the Rhino _CurveThroughPoints performs some sorting, but it does not guarantee that there will be no self-intersections. See this example.
You can use the SortAndCullPointList method of Point3d (still with the problem above) but you will run into this.
If you need a robust solution, Rhino WIP has a Mesh.CreateFromTessellation() method, which can be easily accessed in Python. This can be used for this, and is even able to add missing points in case self-intersection would be unavoidable. This is an example of a script for Rhino WIP:
import rhinoscriptsyntax as rsimport scriptcontext as sc import Rhino.Geometry as rg
def make_tessellation(pts):
if pts and len(pts) >= 3:
fr, pl = rg.Plane.FitPlaneToPoints(pts)
if pl:
pts = rs.coerce3dpointlist(pts)
mesh = rg.Mesh.CreateFromTessellation(pts, None, pl, True)
id = sc.doc.Objects.Add(mesh)
sc.doc.Views.Redraw()
return id
pts = rs.GetPoints()
make_tessellation(pts)
I hope this helps,
Giulio
--
Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com
Another option that I can this of, would be to use the Delaunay triangulator in Grasshopper.
Every option has its advantages and disadvantages, and probably depends from what you would rather be doing in detail.
Thanks guys, for confirming the dilemma. I only found Python for the 2D case so was in over my head.
It seems Tetgen is giving the edges of each Voronoi face in proper loop order after all but just that the directions of each edge is necessary arbitrary so all I needed to do was some bookkeeping as I removed duplicate endpoints looping through the lines, filling up a list with the unique points, then check if the very first point was indeed an orphan or part of the chain of existing points, and then flip the first two points if if wasn't an orphan, to expose the real start point.
There is a possible solution via Rhinocommon, though I've lost attachment to this thread.
http://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_...
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
© 2024 Created by Scott Davidson. Powered by