3
$\begingroup$

I've been looking for a way to distribute instances on a mesh and align the rotation of each instance to the direction of the border it would be place at. For instance: Exemple of my current result vs. the final desired result

On this exemple, "A" is the current result I'm in, a simple "Mesh to Points" > "Instance to Points" distribution. The nodes look like this: This is the simple geo nodes setup I'm currently using

"B" is the result I'm looking for. Where the instances face the border edge of the face they're instanced on.

The final goal of this would be to distribute houses and buildings on a large scale neighborhood in a more accurate way, where they all face the correct direction and using plane meshes for every city block

"C" is a most advanced version of what I would need, where a larger plane can be used as source mesh, and only the faces touching the border of the plane would be instanced on, leaving an empty space in the middle. but don't know if it is possible, so "B" would be fine for now.

I'm not the most advanced user of Geometry Nodes, quite the opposite really. I learn the most I can from tutorials and try to apply the principles learned to my specific problem, but I haven't being able to find any sort of reference on how to create this specific type of alignment. I would appreciate any solution or direction on how to achieve this.

$\endgroup$
3
  • $\begingroup$ Easy. Use a switch to store a vector attribute in face corner domain. If Edge Neighbors = 1: store (self_position - face_position), otherwise store <0, 0, 0>. Then interpolate this attribute to faces. Now for each face the attribute is either <0, 0, 0> (internal face), or a direction towards the edge (can be diagonal, but it's easy to detect such case and then multiply by <0, 1, 0> vector) Then Align Euler to Vector using this direction. $\endgroup$ Commented May 3, 2023 at 22:07
  • $\begingroup$ Oh, a single face is a special case with <0, 0, 0> direction like with internal faces, but I guess it's not hard to support this special case. $\endgroup$ Commented May 3, 2023 at 22:12
  • 1
    $\begingroup$ @MarkusvonBroady I don't know how much experience Paulo has with Geometry Nodes, I'm quite good at Blender in general but not GN in particular. Could you elaborate this to a real answer? How do I "interpolate this attribute to faces"? The only thing I get is the corner tiles pointing diagonally outwards, all others stay the same... $\endgroup$ Commented May 4, 2023 at 8:24

2 Answers 2

5
$\begingroup$

  • If the grid height = 1, make all arrows up (the input geometry is a tile with an arrow pointing up, that is $+y$).
  • If the grid width = 1, make all arrows point left (just realized maybe you want the top to point up and bottom to point down, but it's the easier part of the tree…)
  • For all other cases as I wrote in the comment.
  • Detect borders by checking number of neighbors = 1 and capture that on edges.
  • For the face corners lying on those borders, capture the difference of their position and their face position (direction from face center to border-face-corner).
  • For face corners not lying on the borders, just capture $<0, 0, 0>$ vector.
  • Convert faces to points, so the face corner attribute interpolates to face domain, and then is copied to newly spawned points positioned at faces centers.
  • The interpolation from face corners to face simply averages the directions.
  • On a side it's an average of two same directions and two zeroes, making it still the same direction just with half of magnitude.
  • On a corner the average produces the direction of the corner, which is the problem Gordon Brinkmann mentions.
  • On a face inside, all corners have zeroes, so the average is also $0$.
  • Spawn the input geometry (the tile) on those new points.
  • I wonder if someone reads those walls of text.
  • Check the length of the averaged vector is bigger than zero (the $0.1$ value is just a threshold for precision-related safety).
  • Convert the boolean to integer implicitly: false = 0, true = 1.
  • Use the integer as an index of the instance: 0 is the just created single quad, 1 is the input geometry (arrow tile).
  • Set the rotation by aligning Euler to Vector.
  • The vector to align to is either the original vector, if there was no $y$ component (so either left or right), or the vector with $x$ component removed (as I wrote in the comment; so either up or down).

Vertical line patch

$\endgroup$
1
  • 1
    $\begingroup$ Markus I can't believe how detailed and thorough your answer is. Thank you SO MUCH for taking the time to not only explain, but to also document and illustrate your answer! I'm new to the forum and having my first post answered so thoroughly and with so much care leaves me with no words! I'll be studying your demo file as I'm sure there's a lot to learn from it. Once again, you have my total appreciation! Thank you so very much! $\endgroup$ Commented May 4, 2023 at 16:33
1
$\begingroup$

This is perhaps a much more reasonable answer, instead of mental gymnastics, just calculate and spawn 5 zones separately:

$\endgroup$
2
  • $\begingroup$ Markus, do you want your other answer to be downvoted? seriously... ; ) $\endgroup$
    – lemon
    Commented May 4, 2023 at 18:56
  • 2
    $\begingroup$ @lemon I'm thinking about writing a 3rd answer… $\endgroup$ Commented May 4, 2023 at 18:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .