1

I'm trying to scatter houses to given lots (one lot = one face). I know i can scale my instances to fit the face size but i want to do it the other way around because the house size should be fixed. So i need a setup which measures every face and decides which house should fit into it. Is this possible to do with geometry-nodes ?

thanks in advance

2 Answers2

2

To ensure instances fit, at least in geometry consisting of rectangles, you need to check the shortest edge of the rectangle. The easiest solution would be to just read 3 corners of the rectangle and get the maximum of $\overline{AB}$ vs $\overline{BC}$, but I made it harder on myself and subdivided a plane in a way that created ngons, so I delete points that lie on a straight line between other points (points that are unnecessary after edge splitting), and then also the geometry doesn't consist of rectangles - while taking a short edge of let's say a hexagon will largely underestimate available space, it will at least guarantee no overlap for convex figures… So I calculate neighboring edge length for each corner, store the smaller one, and then on each face take the smallest one using sorting.

Thinking of it now, it would be a better strategy to use Geometry Proximity in Edge mode, at the stage the islands are separated. Oh well…

There are two arbitrary elements:

  1. εpsilon $= 1.57$ - not really arbitrary, it's just slightly less than $π \over 2$ or 90d (you can type it in the field and it will be converted to radians automatically by Blender, similarly the same stuff can be done by Python when radians(90) is typed) - the idea is to avoid checking for both possible directions which would have to be done when comparing to $0°$ (if direction is calculated with the wrong order of Subtract operands, you get $180°$ instead)
  2. Divide by $5$ - it just so happens the shortest edge of the biggest rectangle in my setup is a little over $5$. You could obtain an exact number using an Attribute Statistic node, but why bother if you still need to use the…
  3. …Color Ramp - it has 4 color swatches: 1st has color $<0, 0, 0>$, which is the only color that converts to False boolean - so it defines the only range of sizes that don't spawn an instance at all (the Color output is connected to Selection); 2nd color is $<0.1, 0.1, 0.1>$, which converts to an integer $0$; 3rd color $<1, 1, 1>$ converts to integer $1$, 4th color $<2, 2, 2>$ converts to integer $2$… Objects in the collection are sorted by size:

And here's the effect:

Markus von Broady
  • 36,563
  • 3
  • 30
  • 99
  • Thanks Markus, youre a genius :) Thats amazing, can i buy you a coffe? :D A big advantage would be if the instances of the collection were measured, allowing you to find the appropriate objects for the faces. – BlenderLearner Sep 27 '23 at 19:58
  • I tried to take quellenforms solution for instance measuring and deleted every instance that is bigger than that value. With the remaining instances i tried to get the instance count to use it as max value. Its kinda working altough bigger objects spawn at small faces and smaller at the big faces. Changing the comparison doesn't work. I don't know if its the way to go. Maybe you could have another look

    https://blend-exchange.com/b/AKs25W8w/

    – BlenderLearner Sep 27 '23 at 21:08
  • @BlenderLearner I took a look. The dimensions are calculated correctly, but what you're doing with them you just delete some objects from the collection before instancing, based on $y$ dimension. What you want to do instead is to incorporate the dimensions into the instance index calculation. For example, you could create a quad for each bounding box, starting at $x$ equal the largest horizontal dimension of the bounding box of the original instance it represents. Then if you sort those quads with the biggest one on the top, you can raycast down, for each face, from the... – Markus von Broady Sep 28 '23 at 12:06
  • ... $<x, 0, 0>$ vector, where $x$ equals the smallest dimension of the face (calculated in my answer), and so it inevitably will miss quads representing objects that are too large, but because of the sorting, it will take the largest object that fits. – Markus von Broady Sep 28 '23 at 12:07
  • Hey Markus, thank you for hanging on. I managed to get my collection sorted from the smallest to the biggest object. Right now i'm still struggling with the comparison per scatter point to get the right range of indexes of possible houses. – BlenderLearner Sep 29 '23 at 10:24
1

There is this Face Area node that you can use to capture the area of faces and then you can just compare that area to some value and if it meets the condition, select the faces you want to make into points that you can use then for instances of the house:

enter image description here

Just area does not guarantee the house can fit the face. It depends on the shape of the face as well. Long narrow faces will still have bigger area.

Martynas Žiemys
  • 24,274
  • 2
  • 34
  • 77
  • Pretty sure they want it so that bigger faces have bigger houses. – TheJeran Sep 27 '23 at 12:27
  • @TheJeran Why do you think so? It was clearly said that "the house size should be fixed". – Martynas Žiemys Sep 27 '23 at 12:28
  • "decides which house should fit into it." Suggests multiple houses.

    And they mentioned "I know i can scale my instances to fit the face size" suggesting the house size should be proportional to the face size.

    So the problem is selecting the correct sized house based on face size,

    – TheJeran Sep 27 '23 at 12:32
  • First of all thank you for your answer. The Jeran is right. I have houses with different sizes. So houses that are too big for a lot should be filtered out, so that houses are not exceeding the property borders – BlenderLearner Sep 27 '23 at 12:33
  • If you have only a few variants of the houses, you could make conditions for each manually this way. If you had many different houses, you'll need another solution. – Martynas Žiemys Sep 27 '23 at 12:36
  • 1
    Normalize the face area (or just divide it by / multiply it by a number to make sure the biggest area is less than $1$), and pass that through a Color Ramp. In the Color Ramp output colors of value e.g. $0$, $0.1$, $0.2$… multiply that output by $10$ and you get an index you can use in the "Instance Index". – Markus von Broady Sep 27 '23 at 12:46
  • Hey markus. I would go with your solutions but as Martynas already mentioned that long narrow faces will result in wrong sized houses. So i need a method to measure the "width" of a faces and make my decision based on that value instead of the whole area. And of course this is more to setup and i'm looking for a resolution that measures the instances and takes the one that its in. – BlenderLearner Sep 27 '23 at 14:01