Grasshopper

algorithmic modeling for Rhino

mesh edge topology: how does it work? how is that sorted when offseting a mesh?

Hi to everybody,

I am creating a solid mesh with c# just offseting topside and bottomside a central mesh.

When I am doing this the vertex and face list index remain consistent with the original central surface, but this is not happening with the edge mesh list!

In fact when I want to create mesh faces (the side mesh faces to close the boundaries surfaces) I can see (and I have tested/x2 checked within GH), that the corrispondent top edge and bottom edge of a determinated face are not coincident.

How can I assign a consistent index list to the top and bottom mesh edge list?

How the edge topology is assigned?

I post here the code, FYI, even I do not think that can help to find the problem.

And 2 screenshot to show you the problem.

            double thickness = new double();
            if (!DA.GetData(0, ref thickness)) return;
            
            Mesh baseMesh = new Mesh();
            if (!DA.GetData(1, ref baseMesh)) return;

            List<Plane> localCSPlanes = new List<Plane>();
            if (!DA.GetDataList<Plane> (2, localCSPlanes)) return;

            List<Mesh> solidMesh = new List<Mesh>();
            List<Point3d> meshFaceCenterPlus = new List<Point3d>();
            List<Point3d> meshFaceCenterMinus = new List<Point3d>();
            List<Plane> localCSPlanesPlus = new List<Plane>();
            List<Plane> localCSPlanesMinus = new List<Plane>();
            List<Line> edgeMeshPlusLine = new List<Line>();
            List<Line> edgeMeshMinusLine = new List<Line>();

            Mesh offsetPlus = baseMesh.Offset(0.5*thickness, false);
            Mesh offsetMinus = baseMesh.Offset(-0.5 * thickness, false);

            Mesh recMesh = new Mesh();

            solidMesh.Add(offsetPlus);
            solidMesh.Add(offsetMinus);
            
            //This for-cycle creates a index-consistent list of plus-offset mesh face center points and local coordinate system mesh planes.
            int nFcsPl = offsetPlus.Faces.Count;
            int nEdg = offsetPlus.TopologyEdges.Count;

            for (int i = 0; i <= nFcsPl - 1; i++)
            {
                meshFaceCenterPlus.Add(new Point3d(offsetPlus.Faces.GetFaceCenter(i)));
                localCSPlanesPlus.Add(new Plane(offsetPlus.Faces.GetFaceCenter(i), localCSPlanes[i].XAxis, localCSPlanes[i].YAxis));
            }
          
            //This for-cycle creates a index-consistent list of minus-offset mesh face center points and local coordinate system mesh planes.
            int nFcsMn = offsetMinus.Faces.Count;
            int nEdgMn = offsetMinus.TopologyEdges.Count;

            for (int i = 0; i <= nFcsMn - 1; i++)
            {
                meshFaceCenterMinus.Add(new Point3d(offsetMinus.Faces.GetFaceCenter(i)));
                localCSPlanesMinus.Add(new Plane(offsetMinus.Faces.GetFaceCenter(i), localCSPlanes[i].XAxis, localCSPlanes[i].YAxis));               
            }

            for (int i = 0; i <= nEdg - 1; i++)
            {

                Line lineRecPlus = offsetPlus.TopologyEdges.EdgeLine(i);
                edgeMeshPlusLine.Add(lineRecPlus);

                Point3d recPointA = lineRecPlus.From;
                recMesh.Vertices.Add(recPointA);

                Point3d recPointB = lineRecPlus.To;
                recMesh.Vertices.Add(recPointB);

                Line lineRecMinus = offsetMinus.TopologyEdges.EdgeLine(i);
                edgeMeshMinusLine.Add(lineRecMinus);

                Point3d recPointC = lineRecMinus.To;
                recMesh.Vertices.Add(recPointC);

                Point3d recPointD = lineRecMinus.From;
                recMesh.Vertices.Add(recPointD);

                recMesh.Faces.AddFace(0 + 4 * i, 1 + 4 * i, 2 + 4 * i, 3 + 4 * i);
           

NOTE: I know how to create a solid from a single mesh surface, but this is not what I want now, because I have to sort (for further purpose) the solid mesh in top, bottom and side faces.

Thanks a lot for your help!

cheers,

matteo

Views: 4661

Attachments:

Replies to This Discussion

Hi to everybody,

I am making progress as you can see from the code below, but I got now that:

the vertex Topology of the edges doen't match with the original vertex Topology.

In fact in GH the side mesh faces are not modeled properly as you can see from the screenshot below.

Is this true or am I comminting some mistakes in the code?

Point3d[] vertexPlus = new Point3d[nVrtBase];
            vertexPlus = offsetPlus.Vertices.ToPoint3dArray();

            Point3d[] vertexMinus = new Point3d[nVrtBase];
            vertexMinus = offsetMinus.Vertices.ToPoint3dArray();

            int nEdgCntMesh = baseMesh.TopologyEdges.Count;

            for (int i = 0; i <= nEdgCntMesh - 1; i++)
            {
                Line rec = new Line();
                rec = baseMesh.TopologyEdges.EdgeLine(i);
                centerMeshEdge.Add(rec);

            }

            for (int i = 0; i <=nEdgCntMesh- 1; i++)
            {
                IndexPair recTopologyEdges = new IndexPair();
                recTopologyEdges = baseMesh.TopologyEdges.GetTopologyVertices(i);

                num1.Add(recTopologyEdges.I);
                num2.Add(recTopologyEdges.J);

                //int a = recTopologyEdges.I;
                //int b = recTopologyEdges.J;

                Point3d one = new Point3d(vertexPlus[recTopologyEdges.I]);
                sideFaceMesh.Vertices.Add(one);

                Point3d two = new Point3d(vertexPlus[recTopologyEdges.J]);
                sideFaceMesh.Vertices.Add(two);

                Point3d three = new Point3d(vertexMinus[recTopologyEdges.J]);
                sideFaceMesh.Vertices.Add(three);

                Point3d four = new Point3d(vertexMinus[recTopologyEdges.I]);
                sideFaceMesh.Vertices.Add(four);
                
                sideFaceMesh.Faces.AddFace(0 + 4 * i, 1 + 4 * i, 2 + 4 * i, 3 + 4 * i);            
            }

thanks for your replies

matteo

Attachments:

Hi to everybody,

I have solved it! :) i have created the solid mesh.

but still remain the question (it seems strange to me) of inconsistency between face vertex topology and edge vertex topology. Why is that? It seems an unecessary complication!

thanks for the answer

Matteo

Hi Matteo,

I just came across the same issue. When simulating moving/changing mesh shapes in Kangaroo:

Though The Vertex and Face Lists remain the same, The Mesh Edge List seem to jitter the indeces.

In both, Weaverbird's and GH's Mesh edge component this appears.

Do you (or anyone else) know more about how these commends sort the mesh edges? Maybe they sort them by the coordinates of their center points or something????

Okay, here's a little work-around:

It retrieves mesh edges of a given mesh due to the mesh edge order of a given Guide mesh

Sorry.. here:

Attachments:

Hi Benjamin,

Because with the standard face-vertex mesh data structure the edges are not stored explicitly, this issue of edge ordering will often cause issues, especially if you do things like welding vertices.

This was one of the motivations for the development of Plankton (http://www.grasshopper3d.com/group/plankton)

This uses the edges as the primary connectivity information, so their order is preserved.

So for instance, when using a mesh in Kangaroo, you could input the vertices to the Geometry input and reconstruct the mesh from the OutputGeometry with the same connectivity and edge ordering (also - soon I'll add the possibility to use a PlanktonMesh directly through Kangaroo's geometry input/output).

Also - Weaverbird's wbEdges component has the "face order" option.

If you set this to true, then I think edge ordering should remain consistent.

It will. It will also stay constant across Welds.

Hi Giulio,

I am writing some basic mesh analysis functions which rely on consistent edge list order. I just came across the same issue as described above when using "mesh.TopologyEdges" within a Python component. Does your "wbEdges" component use the standard RhinoCommon mesh class for extracting the edges, or, is there some deeper wizardry going on?

Thanks,
Anders

Weaverbird is written so that understands an edge to be there the first time it sees it appearing in a face definition. This means that it does not have the same order as Rhino, but the order is stable across rotation, scaling, etc.

There is an ongoing discussion in McNeel, how to improve RhinoCommon's mesh edges to be more robustly ordered. I do not think that it will take very long before that will start to be distributed - yet, I do not exactly know when it will happen.

What sort of "basic mesh analysis function" where you trying to write? Is there something I can help with?

Thanks,

Giulio
--
Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com

Thanks Guilio, that explains the behaviour I was seeing. It sounds really great with the push for an improved mesh class in RhinoCommon. I was simply comparing topologically identical meshes by edge length difference (before/after unrolling with the Kangaroo unroller). I'll stick to weaverbird for now :)

Hi Daniel,

but somehow in Plankton I noticed the same issue, which was the reason I made that little work-around.
Using your C# component from the PlanktonDemo0.2.0.gh to retrieve four points around an edge (the lower one in the file), it also rearranged the indeces.
When I was playing around I figured it sorts them the same way as the WB Mesh Edge component does.

Though I didn't use the actual Construct - Deconstruct Plankton Mesh components to retrieve these edges. Could that be the issue?

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service