Sorting edge-endpooints around plane in order to unify mesh edges direction in C#

Hi everybody,

as the title says, I got stuck unifying the direction of the meshedges for a meshface.


I am extracting a meshface, getting the edges, comparing the angle between a line from startpoint to facecenter(lineA) and a line from endpoint to facecenter(lineB).
grafik

private void RunScript(Mesh mesh, ref object Lines)
  {
    if(mesh == null)return;

    var lines = new List<Line>();

    var MTE = mesh.TopologyEdges;

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


      //make a plane for the actual face for compare points to flip edge if necesarry
      Vector3d normal = mesh.FaceNormals[i];
      Point3d center = mesh.Faces.GetFaceCenter(i);
      Plane plane = new Plane(center, normal);

      var edgeIndices = MTE.GetEdgesForFace(i);// get all the edges for the face

      for (int j = 0; j < edgeIndices.Length; j++)
      {

        Line line = MTE.EdgeLine(edgeIndices[j]);//get the actual edge
        double angle1 = Vector3d.VectorAngle(plane.XAxis, line.From - center, plane);
        double angle2 = Vector3d.VectorAngle(plane.XAxis, line.To - center, plane);

        if (angle1 > angle2)
          line.Flip();

        lines.Add(line);

      }
    }


    Lines = lines;


  }

I am not sure if this is a proper way. Can this work?

Any hint is really appreciated.

Have a nice Eastern !

Thanks everybody!

File:20210405_UnifiyMeshEdges.gh (5.7 KB)

You can simply take mesh face vertices. And check if edge vertex order is following mesh face vertex order. If not flip line.

If your collection is MTV (it should) there’s a R Method for that:

This Sort is handy for things the likes:

Thank´s again @Petras_Vestartas,
while I was searching methods to accomplish it the way you proposed I stumbled over this one:
MeshTopologyEdgeList.GetEdgesForFace (Int32,Boolean [ ]) , which returns an array of the orientation of the edge.

1 Like

Hi @PeterFotiadis ,

thanks for the input. I am not sure if we are talking about the same thing. Probably we do and I just don’t understand.
Anyways I found that handy function MeshTopologyEdgeList.GetEdgesForFace Method (Int32,Boolean[]). Not sure if it is avaliable in R5? Seems so.
Regards!

If you want sorted vertices in order, say, to measure angles (like in a classic truss out of a Mesh [clash detection etc]) then we are talking about the same thing (implicitly - so to speak).

And yes every thing with some real-life AEC usage/purpose for mesh connectivity is available in R5.

BTW: Only for simple cases the mesh.UnifyNormals() has some rational purpose. As a challenge do the following: voxelize a blob (getting boxes and then meshes) and try to append them to an “envelope” mesh. Then try to play games with normals.

Lamentably it’s not for real life usage. Just as playing around.
Trying to get some cardboard together:

After getting the EF connectivity and after computing the mesh face normals … do the connections where their plane Z is the face/face dihedral. But this type of connectors yields a highly unstable thingy > better think something related with the nodes (vertices).

Spend a couple of minutes on that: get the outline of the solution … er … for some other planet (like Zorg).

Finish it by doing this, that (and the other thing).

Mesh_JoinWithStripes_V1.gh (19.0 KB)

1 Like

hey Peter,

thanks for the file. Always nice to see how the profis cut the mustard.

in the meantime I came up with this one:

  private void RunScript(Mesh mesh, double heigth, double width, ref object Tiles)
  {
    if(mesh == null)return;

    var MTE = mesh.TopologyEdges;

    var plines = new List<Curve>();
    var circles = new List<Circle>();

    var disks = new List<PolyCurve>();

    for (int i = 0; i < mesh.Faces.Count; i++)
    {
      //List for the polyline segments
      var outline = new List<Curve>();
      //get normal
      Vector3d normal = mesh.FaceNormals[i];

      //get edgeIndices for actual face
      bool[] sameOrientation;
      var edgeIndices = MTE.GetEdgesForFace(i, out sameOrientation);

      for (int j = 0; j < edgeIndices.Length; j++)
      {
        //if it is a naked edge,continue
        if(MTE.GetConnectedFaces(edgeIndices[j]).Length == 1)
        {
          outline.Add(MTE.EdgeLine(edgeIndices[j]).ToNurbsCurve());
          continue;
        }

        //if the edge is in not ccw->reverse
        Line line = MTE.EdgeLine(edgeIndices[j]);
        if (sameOrientation[j] == false)
          line.Flip();

        //get the correct vector
        Vector3d cross = Vector3d.CrossProduct(normal, line.Direction);
        cross.Unitize();
        //make the rectangle
        outline.Add(MakeSlotOnLine(line, cross, heigth, width).ToNurbsCurve());
      }
      var joinedOutline = Curve.JoinCurves(outline);
      plines.Add(joinedOutline[0]);
    }


    Tiles = plines;

  }

  // <Custom additional code> 


  public Polyline MakeSlotOnLine(Line line, Vector3d direction, double heigth, double width)
  {
    var pts = new List<Point3d>();
    pts.Add(line.From);

    Point3d pt1 = line.PointAtLength((line.Length / 2) - width);
    pts.Add(pt1);

    var pt2 = pt1 + direction * heigth;
    pts.Add(pt2);


    Point3d pt3 = line.PointAtLength((line.Length / 2) + width);
    var pt4 = pt3 + direction * heigth;
    pts.Add(pt4);
    pts.Add(pt3);

    pts.Add(line.To);

    return new Polyline(pts);
  }

which gives the outline of the tile with slot:

BTW: The only way to do some rigid cardboard thingy is this (Note: vertex normals indexing IS NOT the same as MTV indexing):

So do the module (as a collection), do the layout (unrolled pieces as one piece), get some UHU and do the thing … or better reset to reality and forget all that.

The other way is to create torsion free beams (you’ll need K2 for that) and do standalone triangle modules from plywood … but why bother with things like these?

BTW: Challenge for the brave: Make the attached 30++ times faster (you don’t need sorting for that type of stuff … but … you do need some clevel Method [and/or a thread safe // approach] in order to cut the mustard properly).

Mesh_JoinWithStripes_V1A.gh (36.1 KB)

BTW: My best gurus working on that mustard puzzle: hope dies last.

If you’re making the connectors and need to distinguish the in/out directions to get edge normals, the boolean overload here can also be helpful:
https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Collections_MeshTopologyEdgeList_GetConnectedFaces_1.htm

Thanks @DanielPiker ,
I found that method after asking as mentioned in a previous post.

Hey @PeterFotiadis,
thanks a lot!

That image looks interesting,I may try this once I start cutting the tiles.

To the code:
I got the gist, I think. You don’t need to look at the edges since you create the vectors over the vertices which always are in correct order. Nice!
As always a lot of stuff to learn from the meshhating meshlord.

Mentioning thread safe I imagine you are referring to parallel loops, which I never did and would be nice to do. Unfortunately the next 2 weekends are reserved for my fishing license, hopefully I find some GH/C# time in between and I can get my hands dirty with the challenge.

Here’s some indicative pics on that rigid flimsy envelope thingy (DO NOT attempt to unroll using the Unroller > do it the “änalytic” way [we need the top piece to stay always “at the center” of the combo]).

Spot the diff in layouts when the bottom reinforcement (rather a must) triangles are added. That way you may(?) can do a 2-5 meter long envelope with some(?) hope(?) to stay in one(?) piece (but why bother with such stupid things?).

BTW: On serious matters: read this several times:

http://www.albahari.com/threading/

BTW: Beat the Chinese fellas who do boats inside bottles: get lot’s of Vodka (and cigars) and assemble the attached (Note: layout pieces indexing is the Mesh faces indexing). You’ll need 667.78 UHU sticks.

FlimsyThatMaybeIsRigid_Demo1.3dm (1.3 MB)

Hi Peter,

as always, thanks for the input!
I tried some stupid and ugly things with paper and glue in the last days.


Then I made some changes, thats how it looks now with your mesh:
I also kept developing the connector version:

I hope this week I can get my hands dirty again.I’ll keep you up to date.

1 Like

ResetNowForEver: forget ugly/stupid/pointless things and do the right/proper thing (when finished don’t apply at Zaha [but you can try SOM]):

  1. Use some blob and get a tri Mesh out of it.
  2. Do a classic Mero KK (mono or double layered) truss + member(s) clash checks [cones, sleeves, bolts, tubes, cats, dogs etc etc].
  3. Then compute (clash + level of freedom + …) and design (up to nut and bolt level) a suitable planar glazing (no frames) envelope for the thing.

Hi Peter,

as always thanks for the input!

I like your challenges. I would like to start this one, once I finish the cardboard shell.Probably in a 14-30 days, being realistic.

I really don’t like(I think I could actually say I hate it) Zaha and most organic architecture. I like geometrical challenges and I imagine being in the ZHA code team is really interesting.
By the way, this are the practices I know I would love to work for (just the german selection):

  • Seele group
  • Knippers Helbig
  • Bollinger Grohmann
  • Schlaich Bergermann+ Partner
  • probably several that I forgot

Excellent news > walk that walk and become the next Mies.

BTW: For nuts and bolts I mean something [a variation on the planar glazing theme using a tensegrity truss] like this (you’ll need a proper solid thingy [NOT Rhino]):