Automatic distance space (Abstandsflächen), is there a better solution than mine?

That’s the very first thing that occurred to me as well, before my first post. A far simpler problem since bounding boxes are consistently constructed. There is still the issue of rotated buildings though, so the BBox would have to be rotated too… Still, the more I’ve played with this, the more confused I get. I’ve seen some bizarre grafting behavior trying to handle multiple buildings, and dealing with sloped sides is no easy trick either.

@max.scheerle can you please clarify? Will bounding boxes suffice?

P.S. This is driving me CRAZY. It makes no difference whether the input to the second DeBrep is grafted or not, the “MYSTERY?” output remains a mystery to me? (14.1 KB)

Same mysterious result using a Graft component. :thinking:

AHA! Here’s a clue. The ugly merge… Ugh. :man_facepalming: WHAT A PAIN!!!

Flattening the input to Graft reverses the two branches because of their path names.

Even Suirify doesn’t help. Here’s the fix: :man_facepalming: :man_facepalming: :man_facepalming:

(Flattening the output of Entwine isn’t required and makes no difference. It works because it flattens the branches anyway.)

@DavidRutten this is truly ABSURD and proof that flatten is indeed required sometimes.

1 Like

This version gives up on the complexities previously mentioned of angled sides and pitched roofs, as exemplified in five sample buildings. It rotates the sides of aligned bounding boxes around their bottom edges to be horizontal. The light purple group derives an aligned plane for each building’s BBox.

abstandsflä (36.9 KB)

Thanks @inno for endorsing this simpler approach, the other way is full of pitfalls.


Inspired by @Joseph_Oster :

And adjusted to work with NGons:

Abstandsflä (24.4 KB)


Wow first of all thank you for all those replies! I was really overwhelmed with the amount of interest in this by you guys :slight_smile:
I need to look at all the solutions later, when I have more time.

But so far to answer your question, it is a little bit more complicated in real life of course :sweat_smile:
Here you can see the general idea of the rule, to regulate the volume of the building, the “distance spaces” are not allowed to overlap the borders of the site (in most cases, but there are exceptions as well)

The regulation got updated and since then you are using the real projection of the facade like shown here, literally folding down the sides of the building as they are

sometimes you are allowed to use only a factor of it depending where you build (inner cities are sometimes allowed to be build more dense).

Anyway, thats roughly the basics of this rule. It is actually not easy to “automate” the complete process in grasshopper it seems, but as far as I’ve seen it is good for simple first drafts or with simpler structures to get a direct feedback, as you adjust the volume.

Working with the bounding box is already enough I think, sometimes maybe even better cause it gives you a buffer. Creating a first volume study often starts with cubes anyway.

In my head doing that task in grasshopper was really straight forward and easy in my head first, but turns out, it actually isnt that easy at all :grinning_face_with_smiling_eyes:

You are all using nodes I never touch honestly, so I will need some time to learn what you did. But this is perfect, I want to get more knowledge about how to use lists more efficient!


That’s partly because there isn’t much activity on the forum. so there’s nothing else to do.

Your reply suggests two additional factors that weren’t considered previously:

  1. the “distance spaces” are not allowed to overlap the borders of the site

This gives a context and rationale for the rule that was previously missing, though I’m not sure it affects GH algorithms unless property boundaries are provided. However, it does explain why bounding boxes are not adequate for the task.

  1. The diagrams showing how roof pitch affects height considerations also argues against bounding boxes and complicates the problem considerably.

Of the many complexities that I encountered yesterday (rotating surfaces OUT instead of IN, buildings that are not square to ‘World XY’, missing bottoms, sloped walls, pitched roofs), the most significant are “walls” that consist of multiple faces.


  1. The triangles below pitched roofs drawn separately from the wall below.

  2. Each wall of floors in a multi-level building drawn separately, even though they are co-planar.

  3. Sides of a building that are fragmented as in his image you posted:

Agreed, it’s not easy at all.

P.S. A slight simplification to finding an aligned plane for each building’s BBox. (purple group)

abstandsflä (32.8 KB)

Your “NGons” geometry is not internalized?

no, it was just an extruded hexagon.

It looks like an extruded pentagon to me.

you are right, I can’t count(anymore)

obtaining the extrusion vector by the cross product is obviously a bit better:

1 Like


The method quickly falls apart when the shape is irregular: (14.0 KB)

Yes, but only if the base polyline of the extrusion is constructed as expected. In this case, the list of division points needs to be reversed to be correct (or the polyline curve must be flipped).

P.S. Or you could Flip the curve segments from Branch, but how do you know? This is one of the complexities I was dealing with yesterday. (rotating surfaces OUT instead of IN)

Probably the safest would be to offset the polygon and then make a vector from each midpoint of the segment of the midpoint of the offsetted. But it is definelty not a nice solution.

My solution was to sort points and reconstruct the base polyline. It doesn’t matter whether the initial list of points is reversed or not. This also works when rotating the walls instead of extruding the base segments. It does get complicated, eh? (15.6 KB)

I know you dont like to use scripted components, I am sure you can do it by comparing vectors.
Just wanted to mention I found there is a Curve.ClosedCurveOrientation Method in Rhino common, which could be used like this:

private void RunScript(Curve crv, ref object A)

    A = crv.ClosedCurveOrientation(Plane.WorldXY) == CurveOrientation.Clockwise ? true : false;


File: (5.1 KB)

yeah, something like that came me in mind too.

Just for kicks, I started playing with a shape similar to the diagram posted yesterday:


And found that sorting points along a circle failed miserably in reconstructing the base curve, even when it was already oriented correctly. So I looked at your C#ClosedCurveOrientation()’ component and thought it would be better if it returned the curve I want instead of a Boolean result that requires more handling, basically a conditional Flip Curve.

I tried it in Python and hit a snag I couldn’t solve, so started a new thread just for that: :man_facepalming:

I can feel your anger. When I started scripting(I didn’t have any knowledge of any language) I tried P, but the rhinoscriptsyntax and rc thing confused me even more. That’s basically why I started with c#

By the way, it’s an honor for me, I found something you consider worth using a scripting component:)
Here is how it could be in C#, also I thought a plane input could be useful.

  private void RunScript(Curve crv, Plane plane, ref object A)

    bool isCCW = crv.ClosedCurveOrientation(plane) == CurveOrientation.Clockwise ? true : false;

    A = crv;

File: (2.4 KB)

I really tried to hide it but yes, I am beyond frustrated. Happens almost every time I mess with Rhino API methods. Despite being a professional programmer (retired) with extensive experience in a vast list of programming languages, the Rhino APIs have always blocked me.

More comments in the new thread but your updated C# is the only thing that works so far!
(though it always returns a CCW curve instead of both CW and CCW)

Some “pro tips” to improve it:

  1. Internalize a World XY plane on the ‘P’ input as a default.

  2. Instead of this:

bool isCCW = crv.ClosedCurveOrientation(plane) == CurveOrientation.Clockwise ? true : false;

you need only this:

bool isCCW = crv.ClosedCurveOrientation(plane) == CurveOrientation.Clockwise;

  1. Since you are using ‘isCCW’ only once, you could it this way:
if(crv.ClosedCurveOrientation(plane) == CurveOrientation.Clockwise) crv.Reverse();
A = crv;

Thanks. :sunglasses:

Probably also some exception handling and maybe Casting could be useful too.I am always too lazy for these ones

That’s nicer indeed.

No need for that after all since ‘ClosedCurveOrientation()’ assumes ‘World XY’ plane when the plane parameter is undefined.