Find unwelded mesh edges

Thanks Peter, I have R6 but no C knowledge. I get to this point very often where I know it should be possible somehow, if I only understood how to code.

I realized in the meantime that the weld command in Rhino shows which edges are unwelded….

Thanks again!

You are a wise man. Stay away from Dark Side matters and be a happy bunny.

In the mean time your def is ready (after removing a ton of internal stuff from one of my conn C#'s) it does 4 conn 2 dim trees [out of 9] and the weld/unweld clustering thingy [by index]. The disjoint job is included as well (should I add a quad> tri check/conversion?). However extensive tests for the validity of your input ARE NOT included: avoid feeding the thing with bananas.

But since I never work with meshes (other than in tensile membrane cases) I don’t have properly bad meshes : can you provide some for the BETA testing? (better safe than sorry). Some freaky/ugly/unspeakable meshes could be handy as well (in The Name of Science).


Awesome @PeterFotiadis, but first I need a MESH UnweldEdge with lines or points as an input, similar to this approach

Then, of course, verify the unwelded edge with another c#, thanks

What means unweldEdge?? You mean … er … on purpose making an edge (by index) an unwelded one? (adding possibly vertices to faces sharing that edge since unweld means that the faces MUST have unique vertex indices along that edge) . Kinda the inverse of that (used in the forthcoming C#):

And why to do that?

What means “lines or points” as input ?? You mean get points and do a mesh? … or maybe you mean that you want lines or points as output ?? - ie get the V, E Lists from a mesh.

the idea is to generate gaps, I think that the first step is to define the edges, then unweld them and finally move the vertices along the perpendicular edge.

Long way home for no reason:

  1. Sample the faces (by index) for the gap(s) - would been deleted soon.
  2. Create new ones with some sort of logic.
  3. Delete the sampled OEM faces and add the new ones.

BTW: On purpose unwelding edges has a meaning if you want to explode the mesh into submeshes where a submesh is a collection of faces that are contained within a closed loop of “unwelded” edges. Again: unwelded edges are edges where the faces that share the edge have unique mesh vertexes (not mesh topology vertexes) at both ends of the edge. That said a naked edge … er … hmm … is an unwelded one (otherwise the closed loop …).

For the unweld this edge thingy:

  1. Having EV, EF and FV conn trees on hand (easy).
  2. Arrive into a given edge and get the adj faces indices (EF). If indices,Count == 1 this means a naked edge (unwelding a naked edge is a “bit” LOL). If indices.Count > 2 … this means bananas.
  3. Given the 2 face indices get (FV) the 2 vertex indices Lists. Do a List Intersection and get a common List with 2 indices. If the vertex indices for the edge (EV) are contained in that List we have a welded edge (Plan B: the intersection has no elements [i.e. **!common.Any()**]).
  4. So … If is welded add vertices to one of the 2 faces.

But truth to be said: I hate meshes like my sins.

BTW: MTV indexing is NOT the same as MV indexing (I hate meshes):

This means that another way to spot the unwelded stuff is to test this (i acc MTV indexing) that yields vertex indices FROM vertrex topo indices:

int VIndices = MTV.MeshVertexIndices(i);
if(VIndices.Length >1) … blah, blah

Peter, I don’t understand everything you posted in the meantime.

However, meshes are the gateway to SubD. So far, creases are defined by unwelding an edge. In my mind that’s a naked edge too, but I don’t think Rhino / Grasshopper developers would agree on this…

I mentioned the Rhino weld command shows which edges are welded and which are not but developers please the highlight is difficult to see on my 4K display.

Nor do I … but who’s gonna notice it? he he.

Get your stuff (NOTHING is internalized, load R file for the demo).

Mesh_EF_FV_and_IsWelded_EntryLevel_V1C.3dm (156.8 KB) (135.4 KB)

NOTE: V1C is the latest (bug fixes) build insofar.
NOTE: Since I don’t have R6 the thing is geared towards R5.

In order to activate the IsEdgeUnwelded R6 Method:

Uncommend these lines (remove the //, that is):

Uncommend the R6 Method AND commend (add //) the R5 one

And since the task is over(?) … here’s some freaky things:

  1. A mesh has vertices that you can see … but are separated in 2 freaky classes: the topology vertices (in fact what you see) AND the vertices.
  2. Vertices MAY are more than topo vertices (notably in unwelded edges cases and/or in bananas meshes).
  3. The check for welded unvelded refers to check the 2 Lists of adjacent faces indices BUT not the topo vertices indices (LOL) : we are talking vertices indices (LOL2). If these Lists have nothing in common … then the edge is unwelded (LOL3).
  4. In order to add oil in the fire (and create more confusion/panic) I have added a “help” C# that lists for you the face topo vertices indices VS the face vertices indices per pair of adjacent faces in clothed edges [ for naked : why bother talking?]. As you can see the numbers differ.

Maybe this image (reds are topo vertices indices) explains the freaky situation where 2 faces (the adjacent to a given edge [E666] according the EF connectivity) MAY yield 2 vertex indices Lists (blue) that have nothing in common (i.e. their intersection is an empty List) : meaning that E666 is unwelded (LOL*LOL):

BTW: The main C# thing does Lists of things (V, E, F) and 4 connectivity trees. If you enable the weldE then does the check (either in R5 or R6 mode as explained above) and puts unwelded edges indices in branch {x;1} and the welded ones in {x;0}. That said if mesh.Vertices.Count == mesh.TopologyVertices.Count … this means the obvious … but since we are talking milliseconds I haven’t use that as a by-pass first check. So what you get it’s a kind of connectivity: I do hope that you know how to use connectivity against a Tree (the E [edges] Tree in this case that is optionally made if the VEF var is set to 2).

BTW: Try Sandbox against the mesh List (mOut) : what does?

BTW: The main C# has the cIdent option : this uses a LOL void Method (mesh.Vertices.CombineIdentical(true, true)) that … er … removes all the vertices that are identical (kinda Kangaroo cleans dupe points). So … IF the mesh has unwelded edges … you get (cross fingers) a mesh with welded ones. BUT if the mesh is bananas this MAY yield a non valid mesh (if is the case that mesh is skipped - NOTE: if this happens the main dimensions in the trees are NOT according the indexing in mOut List [for obvious reasons]).

What all the above mean ? Simple: I hate meshes (and computers)

A naked edge is one that has ONE adjacent face .
A clothed unwelded edge is one that has TWO adjacent faces … where their vertices indices Lists (NOT topo vertices Lists) have NOTHING in common (their intersection yields an empty List).

Moral: LOL

Well … spend some minutes to “port” the unweld edge status check into a WIP C# that does that on purpose (alias MV: vertices, MTV: topo vertices, MTE: topo edges, MF: mesh faces):

  1. Check mesh (valid, manifold, not null).
  2. Optionally run the mesh.Vertices.CombineIdentical(true,true) Method: this “resets” the mesh yielding (cross fingers) MV.Count == MTV.Count;
  3. Get a List of edges to be unwelded (the best way by 1M miles: interactively pick them - requires code) … or use any other way (good luck).
  4. Monitor sampledEdges ( bool sampledEdges = new bool[ MTE.Count]) and sampledFaces ( bool sampledFaces = new bool[ MF.Count]) … meaning never date the same girl twice.
  5. Get the adjacent faces normal angles (>=atol) status in a bool[,] angles = new bool[MF.Count, MF.Count]
  6. For each edge index in 3 check the unweld status (by intersecting the vertices indices Lists related with the adjacent to the edge 2 Faces) .
  7. If is unwelded or naked continue.
  8. If is welded remove one (by index) of the 2 adjacent faces and add to the MV List the 2 common Point3f’s from 6 and do a new MeshFace that is associated with the newly added Points PLUS the old ones NOT contained in the intersection.That said a new MeshFace is defined via the MV indices (NOT MTV ones): MeshFace newFace = new MeshFace(idx1, idx2, idx3 … and idx4 [case quad]).
  9. Insert the new MeshFace (by index).
  10. Clear the normals.

1 Like

:open_mouth: looks really well @PeterFotiadis adding vertices

The EdgeIndices INPUT belong just the Interior Edges of MeshEdges, Is like this how could work?

In the case of EdgeIndices crosses, I think this could work like an “SplitMesh by EdgesIndices” by then adding this method Mesh.ExplodeAtUnweldedEdges, maybe with another C# not in the same script. Thanks again

If you are after stuff like making on purpose edges unwelded then you need the mesh.ExplodeAtUnweldedEdges Method. This has a certain importance in cases where you need to isolate mesh portions for further study: like pieces “near by” membrane anchor plates in tensile membrane designs (critical for a good looking membrane). But if you want to create just “gaps” like in the image that you posted above … well … we are killing mosquito(s) with bazooka(s).

But the edge unwelding is the easy thing (yielding a mesh that has more vertices than topology vertices [LOL]) . The big thing is to mastermind a variety of ways (as an option to the on the fly interactive selection of edges) to pick “edge paths” that make some sense.

Here’s a WIP recursive way (when is 100% ready I’ll post it for you here): you define a direction (say via a rotated mesh Box, then via picking a Box XYZ axis) and a start edge Index and the recursion does the job for you by creating a kind of “chain edges collection”. Then you can make the edges unwelded (in fact the faces … but anyway) and get the mesh pieces (in fact … there’s a myriad of “what-if” cases … but hope dies last).

Hope that you know what is recursion: a freaky thingy where Peter calls Peter who calls Peter … who … until something happens and calls Jane (a far better option).

It is interesting using recursion to pick the edges by direction, but for now, I just need to kill mosquitos :sweat_smile: defining by Interior indices like your previous method (do not get me wrong, I would like to see both)

If it is like I mentioned before, I would be easy to generate that indices list of my specific needs, gaps and cuts predefined.

Have in mind that recursion doesn’t mean that you fire and forget: far the opposite (it’s just a matter of control of what to do and when to stop). See here using a stop option related with clothed edges plus recursion loop count restrictions.


  1. IF you want to get a mesh in pieces via some sort of edge chain loop then unwelding edges MAY be useful (but there’s other ways to do that as well).
  2. IF you want to create “gaps” also via some sort of edge chain (with a total user control upon where the chain terminates both sides) then unwelding edges has no meaning.

In both cases the core of the matter is the chain:

  1. In meshes with reasonable amount of edges (whatever this means) picking them interactively is the best way to go: for each C# loop store the insofar state of the selected edge indices - as Tree - in a parameter (volatile > permanent) and read the content (access the thing via his nickname) BEFORE the C# re executes (that requires code - obviously - but I have about 500+ cases that do that).
  2. In big meshes a computer assisted chain creation makes sense: obviously via a controlled recursion PLUS a smart way to visually locate the start edge Index (that’s easy via a kind of 3d crosshair system with a search sphere at the origin point).

1 Like

Just a thought if this is the goal, would it not make sense to just not weld the mesh at all in the first place (or simply unweld / explode all mesh faces), move the correct points, then weld (as weld will ignore the not touching verts.

You are lucky: no F1 race this w/e (forza Lewis) or MotoGP (forza Vale) … only British Superbikes (better than WSB races). So there’s time for stupid things:

Study the image: In the textDots L is for loop and E for edge index. So L0 is for the start index. Chain goes both sides (obviously). As shown no restrictions are applied meaning that recursion stops on naked points. So … what kind of restrictions/rules you want for that chain? (for instance: work only in a banana shaped mesh colored pink, work only in black non-manifold meshes, stop when you are out of cigars /Vodka… etc etc).

And here with a max loop restriction:

Q: Should I add a make gap/“slice” thingy? I.e. zero (or a startD) D at start/end and then some D (steady/cos/sin/random).

BTW: here’s some classic questions (as always: work with topo vertices and NOT vertices).

Finally “gaps” done and yes MeshTopology(Vertex-Face) was the key (Sandbox of course :sweat_smile: and standard components)

On the other hand interesting loop method definitely I would like to try.

For the “SplitMesh by EdgeIndices” any update? not for unroll just to split

Well … all that (by coincidence) have some real-life meaning since a new project emerged and one possible envelope (solely for shading in some desert - no rain expected the next 100 years) option has as follows:

Imagine a tri mesh that yields a W truss, say like this one:

Now having the truss on hand let’s focus to the envelope (out of the mesh tri Faces). Imagine a Dendrogram i.e. a recursive chain creation (with N options about what to do and when to stop) like this:

Now imagine that we modify each node in the Dendrogram by (a) taking into account the normal at a given node (requires conversion to MTV indexing since vertex normals use MV indexing) with length proportional to the node depth (b) “shifting” it - also proportional to depth - using bisectors VS the neighbor nodes.

I hear you: use a proper tensile membrane and forget stupid meshes. Indeed … but client thinks that membranes have limited life span (he’s wrong).

Thanks for all the input, unfortunately I couldn’t follow. I already ran into the next issue with Mesh.UnweldEdge requiring a list of IEnumerable?

Where do I start if I want to learn C#?