Ordering a list of connected surfaces

Here’s a problem that I managed to solve (I think), but I can’t help thinking I did it the hard way. I’m hoping there’s a more elegant solution, perhaps without having to write code (which is what I ended up doing).

The problem: take a set of longish surfaces, coincident on their long edges, and produce an ORDERED list of the surfaces and the edges that they share. (Imagine an accordion-folded piece of paper.) See the file for the real deal, but the geometry is essentially the same. For input, all I have is the surfaces, in some random order. By the way, the direction doesn’t matter - starting with either “outside” surface is fine.

I used the very useful brep analysis tools to start, then wrote a longish Python component to order everything. (I’m an experienced programmer, but fairly new to Python, so apologies for any bad style…)

Again, I feel like I did this the hard way, with brute force and awkwardness :slight_smile: Is there a simpler way to get this result? Thanks for any comments/criticism.

SampleSurfaces.3dm (2.2 MB)
SampleSurfaces.gh (10.4 KB)

Your four surfaces are already in sequence! So I added Jitter to mix them up. No Python in this solution, just standard components (white group). Results are the same as your ‘surfaceList’ output.

It relies on an assumption that won’t necessarily be true… that a World XY plane can cut through all the surfaces. That might be abstracted to work with different surface arrangements?

SampleSurfaces_2022Sep19a.gh (48.2 KB)

Surfaces are internalized, no need for Rhino file.

P.S. This is the surface sequence after Jitter:


This idea intrigued me so I added to the code… The yellow group is a “test bench” that rotates the randomized surfaces in three planes. The orange group is just a visual aid to see where the derived cutting plane will be as you rotate the surfaces. The modified code (white group) works in all cases, though the list gets reversed in some orientations. Your code (purple group) seems to always keep the same sequence. I’m tempted to fix mine to do the same but will not bother with that.

SampleSurfaces_2022Sep19b.gh (59.4 KB)

By the way, your code reconstructs the surfaces using Loft which is not strictly correct, eh? Isn’t there a way for you to use the original surfaces as I did?

P.S. I just noticed something interesting… If I connect your ‘surfaceList’ to my Point List, the list reverses depending on the Jitter ‘Seed’ slider value, whereas mine does not. However, your sequenced ‘surfaceList’ is stable for different rotations, whereas mine is not. Curious… :thinking:

It really pays to have a complete set of test cases before tackling a problem like this. My version ‘b’ was an improvement but I could easily imagine shapes where it would fail - like a folded paper fan, for example. So I modified (simplified?!) the code (white group) and added a pink group at the top to generate fan shapes. The dark gray ‘Shape Switch’ group uses a Value List to switch between the two (‘Original’ and ‘Fan’).

SampleSurfaces_2022Sep19c.gh (57.7 KB)

Your code fails to handle the fan shape.

Wow! Thank you ten thousand times, Joseph, for taking an interest, and for your insightful comments/simpler code.

(I realized after I posted that the surfaces were already ordered for in that particular example, D’oh!, but the problem remains, of course, and many of the other dozen or so cases I need this for will NOT be ordered…)

Another wrinkle: I should have made this clearer in my post, but the EDGES are my main target here: I need an ordered list of edges, starting with either outside edge and marching across the set of surfaces in order, ending with the opposite outside edge. The ordered surface output is just there in case it is useful later for something :slight_smile: Sorry I didn’t make that clearer at the outset.

In any case, I suspect I can use your general scheme to bypass my too-complicated Python code, I’ll go play with it right now.

For the record, I don’t need the general case (though as a programmer I always appreciate it!). In my case, a gigantic sculpture in development, the surface groups will alway be near vertical, so your World XY approach will work fine, and the surfaces will never come together in a point, like your fan example. Nevertheless, I’ll keep it as general as is practical, given my time constraints.

Again, thanks! I’m off to study your solutions…

The thread title says “Ordering a list of connected surfaces”, no mention of edges. :roll_eyes:
Presenting a list of surfaces instead of joining them into a brep means that there are two curves for each “edge”, not just one. How a problem is described changes everything!

I added a tan colored “Sort Edges” group to the bottom of my version ‘c’ from yesterday that presents a sequential list of edges, re-using some of the code from the “Sort Faces” white group above it. So now you have both.

SampleSurfaces_2022Sep20a.gh (63.5 KB)

The fan shape is only one example that would fail using my versions ‘a’ and ‘b’. Coming together at a point has nothing to do with it; they would fail on the fan due to the “cutting plane” approach.

P.S. Here is a way to number BOTH the surfaces (black) and edges (purple) using Entwine:
(changed only the cyan groups)

SampleSurfaces_2022Sep20b.gh (59.3 KB)

I’m guessing you paid no attention to my actual Python code (the heart of the matter) and I can’t blame you :slight_smile: And my apologies for not describing the problem perfectly and completely, though I certainly said I needed edges too, in the original post. But what I neglected to mention is that I need an ordered list of the edges WITH DUPLICATES REMOVED. I tried several ways to just take the list of edges and remove duplicates, and none of them were trustworthy enough.

In general, I’m hoping to duplicate the functionality of that Python module I wrote, in a more elegant and easy-to-read fashion. It’s not absolutely critical - the Python code does the job - I’m just looking for more insight, and different ways of approaching the problem, and you’re given me that, so thank you.


Except for the fan shape test case.

Why are you working with separate faces (surfaces) instead of a joined brep? For one thing, there are no duplicate edges to worry about.

Why are you working with separate faces (surfaces) instead of a joined brep? For one thing, there are no duplicate edges to worry about.

Simply because that’s what I get: I am given a bunch of surfaces that have been hand digitized from a small scale model made of plastic. Most (but not all) of these surfaces form “connected groups”, connected on their long edges (call them rails), like my example. I need to “massage” every rail (including the outside ones) to make them manufacturable, basically decomposing them into a series of connected simple arcs that closely mimic the original curve. That’s the basics.

So once I have that ordered list of rails, then I can decompose them (in order), and loft new surfaces from the modified rails (in order). THOSE surfaces are the input to a whole 'nother set of Grasshopper scripts that are beyond the scope of this conversation :slight_smile:

All your comments have taught me things that I can bring to bear on the problem, I think. And certainly on other problems! In this case, maybe I’ll just go comment my Python source a little better so 2 years from now I can tell what I did, and move on. I just had such a hard time with this problem I thought for sure I was just being dense somehow, and wanted to ask the hive mind about it.

Thanks again!

That being the case, I’m surprised that Brep Join works so well joining the four surfaces you posted, with no naked edges: (this is a baked Join)

Or have these already been “massaged” (fixed) to make sure that happens?

The beauty of Grasshopper is that you don’t need Python or C# or VB to build elaborate models and solve complex problems.