Cull all but "top" faces

I’ve tried a lot of ways to do this now, and am probably missing something really obvious. Posting three of the failed attempts. I’m sure you brilliant people know how to make it work.

Given three surfaces (actually a messy collection of surfaces and breps) — they are surface plots, the original surfaces come in as split in two (attached); I then join them and split them with each other to produce the three surfaces in the definition — how can I keep a combination of their “uppermost” faces?

I want to end up with a single surface that combines the face fragments that don’t have a fragment above them, if that makes sense. If we created a bounding box and picked the top surface, I want to keep the faces closest to that surface, and cull all others.

Just to complicate matters: the definition needs to be parametrically solid so as to work with (more or less) any surfaces we chuck at it, and if it can be done without meshes, that would be great.


Magnus (62.5 KB)

Probably should have mentioned that all surfaces are reparameterised between 0 and 1, so no need to consider irregular alternatives outside of this range.


Can you post just the surfaces you want at the end. It is not supper clear what you want, so post what the result should be.

Hi David,

Thanks for picking up the thread and sorry about not being very clear.

File attached. Surface A is red, surface B is purple, surface C is green. Surfaces can coexist.

Does that make sense?


190918_GH-question.3dm (180.8 KB)

Well … I have a variety of “similar” solutions for entirely different purposes.

  • Imagine joining the Breps (per branch) and then removing the co-planar faces. Let’s call them splitters and sample them into the splittersList.

  • Imagine finding the min contained Box (shown as WireFrame with the white wires below) with regard each splitter and then scaling it a bit (inwards) - that one for dealing with ccx tolerance issues and the likes,

  • Imagine a recursive Loop that does bool intersections between the box at Loop 0 (and/or the resulting breps from the previous Loop) VS the splittersList[Loop] taking into account splitter’s aggregate Normal Dot Product VS the global Z (in order to control what to take into the next recursion Loop: splitter’s “orientation” is critical for that).

All these are very easy via code (C#) … but I have no idea how to do them (especially the sheet orientation control [and the optional flip shown below in red] AND the removal of co-planar faces) via native components.

Anyway …if you are interested for a 100% C# based solution, notify:

Reply from the Dark Side!

Thank you so much Peter.

I’ll ponder your points over the weekend as I’m not on speaking terms with dot products yet.

I have no beef with C# as long as it does the trick, so please hereby accept my notification.

The silliest thing about this is that I made it work by extracting each surface down and checking the others for inclusion in the resulting brep, but since some surfaces don’t extrude into closed breps, it keeps failing. So solving that would be another way of achieving the same result.

Again, many thanks for taking your time with this!

Have a great weekend,

Well … get the hand grenade and be happy (kinda). (166.4 KB)

BTW: the grenade part:

  1. The whole thingy is how to split a solid (the min box as Brep) with sheet like splitters THAT can yield some sort of rational orientation result (the DotProduct thingy) in order to auto manage what piece to keep and what not: this means that I can think a zillion of “splitters” that can’t work with the Method(s) used here (in the 2nd C#).
  2. The result is a list of solids (but you can get the faces that you want by comparing them VS the OEM min box faces: anyway if this appears Greek to you … I’ll add some lines more).
  3. Code is not a red (or blue) pill … meaning that is written with regard specific input/goals in mind. If you deviate (even slightly) you’ll get bananas.That said I should implement some smarter way to deal with the problem … but right now is F1 time (forza Lewis) AND MotoGP time (forza Vale).
  4. Theoretically you can write a thing that always delivers (kinda) … but you’ll need a lot of lines more in order to check a myriad of things that may go wrong.
  5. Results are tricky due to tolerance issues. If you are brave you can change the tolerance and enjoy bananas (splitted bananas in fact).

Moral: bananas.

In any case … always remember:


Lord P:

The ability to destroy a planet truly is insignificant next to the power of the Force.

You will surely find my lack of faith disturbing, but I shall have to ponder this for another day or so yet. I sort of get it, but need to play with it a bit more. Also need to muster courage enough to face the splitted bananas.

Most importantly though: it does the trick. Thank you ever so much.

Two quick follow-up questions:

  1. I’ll have to somehow retain info about which surface is which so that I can recolour them post-your-amazing-splitting technique. This may be the Greek you refer to above. Any ideas for how to keep track of them?

  2. I could probably solve (sort of) the above if the surfaces weren’t scaled down. Tried scaling them up using BoxMap, but that still doesn’t get it quite right. Is there a good way of bringing the surfaces back to exactly fit the 1 x 1 x 1 units envelope post-splitter action?

I remain your humble servant,

Indeed but it helps in quite a few occasions.

That said … well … I had a hint about the F1 things to come (Singapore … where Mercedes did the sum of all “smart” things together > … > Lewis 4th > Porca Miseria) and thus haven’t started doing the proper approach on that (quite complex in fact IF your stuff is partially intersecting each other).

Hope dies last:

If Lewis delivers in this w/e race (Russia) I’ll do the great upgrade (or at least an update with regard your questions/goals).

I have literally and practically zero knowledge of F1, but now find myself totally rooting for Hamilton.

If, in your no doubt galactically vast archives of stuff, you happen to have something that turns a less-than-perfect (bloody) brep (surface) into a (bloody) closed brep when extruding it down in z, that would possibly also do the trick, as I’ve got what I think is a working definition save for that tiny(?) detail.

Forza Lewis!

Well … important matters first: F1 is solely after dollars (and “connections”) these days: for instance in the latest Monza Leclerc did a very dangerous block-pass to Lewis (that could end up rather easily into some sort of fatal accident) … but stewards (obviously in Ferrari’s pay list) … were looking to the other side of the fence. Later they said something about promoting “hard racing” (not to mention “honest”) … blah, blah.

In less important matters: I have any thing that you can imagine (about 50K C#'s and counting) … but in order to avoid the obvious … post here some indicative test cases (the more the better) for that Bloody Mary issue of yours.


That said for the “topology” of your initial issue the challenging thing is to do something when the breps partially intersect each other.

Moral: Forza Lewis.

Hard F1 racing turning into fatal accidents sounds… dangerous.

I was thinking something like the attached could do the trick. It’s not there yet (as you can see), but if the force is with us etc etc.

I like Marc Syp’s excellent Telepathy plug-in (possibly a little too much?); you might need to get that for this one to work.

Thanks. And forza Lewis indeed. Godspeed. (29.2 KB)

In Spa (previous to Monza) Hubert killed by someone else: the very same thing could happen in Monza … but when dollars talk nothing else matters.

That said I never work with anything other than C# code thus these things …

But IF your stuff (per branch) “fits” to the very same box and/or the boxes contain each other meaning that there’s a min box around that is contained by the rest … then the initial solution posted rather works: but is an answer to a very tiny fragment of a very big question.

That said what exactly are you after? Some building envelope? a cat? a dog? a splitted [ortho] banana?

Gee. And he was 22 I see - what a horrible waste of a life.

So I’ve rebuilt the definition to hopefully get rid of the unrecognized objects. Not quite sure as to why you’re getting warnings for Split Brep Multiple and Multiplication though, as those should be native components? (Are we on different Rhino versions or am I once again missing something really obvious?)

This is getting fairly close, but it’s still not working, due (I think) to the brep that doesn’t want to close. I’ve marked it with a scribble in the def. It’s obviously not a very “clean” method, but I’m thinking the number of points could be increased if need be to get a better “catch”. Also, the surface plots I generate (from earlier in the process) are made up of two surfaces, hence the joining at the beginning.

So this could perhaps be an alternative to your method, or ideas from the two could somehow get merged?

I’m always after splitted ortho bananas (aren’t we all?), but this time around I’m literally trying to build combined surface plots. I’m writing this academic thing on how illustrations based on phase diagrams could be used to visualise material qualities, and this is pretty much the final knot to untie.

Have a great weekend. (72.7 KB)

That’s questionable: P1 was a bit miserable (Lewis on yellows, mind: meaning that Totto/James are after some PlanB [but fellas … do you know that the track is a very low grip one?]). Let’s hope for better things in P2.

On trivial matters: 50% better results (glass half empty, mind):

Best advise: if you have plans to become (a) a pro, (b) an one in high demand > start learning the ways of the Force ASAP : time flies and when you realize it is always toooooooo late.

Moral: bananas.

Have a non-fatal weekend?

Trivially, hmmm:

So how do we get around this one?

And yes, the best time to plant that tree was 20 years ago and the second best right now, but alas this bloody (mary) paper won’t write itself while I go to Force prep school.

Moral: needs to happen at night. Moral 2: which would have been possible in a pre-kids life. Moral 3: bananas indeed.

It’s a banana (i.e. Catch 22) thingy I guess: I suspect that your stuff in an R6/GH1 component while I work with R5 (for the usage of R/GH in the practice there’s no need to upgrade).

I have a C# that does this (results are so-so mind … but who’s gonna notice it?).

Other than that given a ref Vector … if you join your demo stuff in the 3 branches (the first step towards Nirvana) … you’ll get sheet bodies (the splitters, that is) with different orientation (say the DotProduct of the BrepFaces normals aggregate VS the refVector ) meaning that unless you check them (and “equalize”/flip) properly … the bool ops could yield bananas (or the recursive bool ops). This is the tricky part in the general case: what may be the right DotProduct check/result? And is the normals aggregate the thing to use? And if the splitter has points with the same X,Y but different Z (or a line using the ref Vector returns more that one ccx event) … then what?

Moral: You tell me.

Hm. Right.

Does the attached work with your version of R5?

And (not only because I’m too lazy to google it myself, but also because I’d rather hear your than the official version): how did the important stuff go this weekend? (29.2 KB)

Hero delivered: Totto’s Plan B worked and Lewis did the rest.

BTW: a Virtual Safety Car played a small roll … plus the wingman did what he should.

BTW: 190930 still has mysterious things MIA > Karma, what else?

Moral: Japan (next race) is the D-day