Project grid on polygon

   2278   6   0
User Avatar
Member
13 posts
Joined: Dec. 2019
Offline
Hello!

I'm learning how to place roof tiles on a roof, and want to have control over the size, spacing etc.
My plan was to loop over all of the roof polygons, which may have any tilt, shape etc..
Then divide the polygon in a grid and then copy the tiles to each point. Wanna have full control over the grids width and height.


If I do a bounds node with "Orient Bouding Box" checked I can get a grid oriented to the polygon quite nice.
Not sure though how I could cut the polygon using the grid?

I could also use the divide node with the "Bricker" option. But it seems like I have to then rotate the polygon to the XZ plane, then run the divide node, then rotate it back...? That's the step I don't know how to do.

Anyone able to help me out a bit?
Thank you in advance!
Image Not Found
Edited by veclock - May 6, 2022 03:47:37

Attachments:
A.png (540.1 KB)

User Avatar
Member
4512 posts
Joined: Feb. 2012
Offline
Hi,

You can use the transform matrix provided by the Bound SOP (Transform Attribute: On):



Invert xform code:

matrix m = detail ( 1, "xform" );
@P *= invert ( m );

Restore original xform code:

matrix m = detail ( 1, "xform" );
@P *= m;
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
User Avatar
Member
13 posts
Joined: Dec. 2019
Offline
Hi animatrix_,

That works perfectly!
Thank you very much

The divide node outputted a double faced polygon but I grouped by normal and used a split node afterwards.

Will be back if I encounter any other problems!

Cheers mate
User Avatar
Member
13 posts
Joined: Dec. 2019
Offline
Ok, there's one problem that came up,
when I loop through the polygons, the setup will orient the polygons sometimes to the XZ plane, sometimes to the YZ plane,
etc... Is there any easy way of orienting them to for example the XZ plane every time? And rotate them so that X would correspond to what was originally "down"?

If I for example want to have the grid spacing of 25 horizontally and grid spacing 50 vertically,
I would need a way of orienting them identically...

Dunno if this approach is the best one..?
Edited by veclock - May 6, 2022 08:48:51

Attachments:
D.png (444.9 KB)

User Avatar
Member
4512 posts
Joined: Feb. 2012
Offline
If you want precise alignment, here is one way:



1. Attrib Promote P to centroid (detail) using Average.

2. Outer product code (Point Wrangle):

vector P = @P - detail ( 0, "centroid" );
3@PP = outerproduct ( P, P );

3. Sum PP to detail.

4. svd decomp code (Detail Wrangle):

matrix3 U, V;
vector s;
svddecomp ( 3@PP, U, s, V );

3@M = transpose ( V );

5. transform code (Point Wrangle):

matrix3 M = detail ( 0, "M" );
    
matrix T = ident ( );
vector offset = detail ( 0, "centroid" );
translate ( T, offset );

T *= M;

4@T = T;

@P *= invert ( T );

6. restore xform code (Point Wrangle):

@P *= 4@T;
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
User Avatar
Member
40 posts
Joined: Aug. 2018
Offline
concise, clever and quite elegant. tx! I'll re-use that too
User Avatar
Member
13 posts
Joined: Dec. 2019
Offline
Hi again!

First off, thank you animatrix_ for that cleaver method! I learned some valuable stuff from your solution! Very inspiring!
However, I don't know if I made some mistake in my implementation but it didn't quite match up...
Because of the irregular shapes of the polygons, it seems like it sometimes couldn't align it properly "downwards"...
It worked perfectly on some polygons but not on the more difficult polygons.



I went on to approach it as a Houdini noob armed with math, and coded up a working solution for me!
It's a bit more limited as it requires polygons to have at least two points on the same y position.
But roof polygons will almost always have this.



Code in the find_rotation node:

float threshold = 1; // error margin, how much difference in Y should be regarded as "flat"
int i, j, id0, id1;
vector p0, p1, p2, p3, d;
float angA, angB;

for (i=0; i<npoints(0); i++) {
    p0 = point(0, "P", i);
    for (j=i+1; j<npoints(0); j++) {
        p1 = point(0, "P", j);
        if (abs(p0.y - p1.y)<threshold) {
            id0 = i; id1 = j;
            d = p0-p1;
            angA = atan2(d.z, d.x) * 180 / 3.1415;
            i = npoints(0);
            break;
        }
    }
}

for (i=0; i<npoints(0); i++) {
    if (i != id0 && i != id1) {
        p2 = point(0, "P", i);
        if (abs(p2.y-p0.y) > threshold ) break;
    }
}

angB = dot(normalize(cross(p0-p1, p1-p2)), {0, -1, 0}) * 180 / 3.1415;

setdetailattrib(0, "angA", angA, "set");
setdetailattrib(0, "angB", angB, "set");

Hope this can help anyone as well
Edited by veclock - May 13, 2022 06:57:19

Attachments:
img1.png (483.6 KB)
img2.png (463.8 KB)

  • Quick Links