Move & Align all Prims to 0,0,0

   1831   1   2
User Avatar
Member
1 posts
Joined: Sept. 2021
Offline
Hello

I would like to move all the of these diamond prims to the center of the grid & have them all pointing the same direction so I can do some deformations before restoring their transform to their original place.

Getting them to the center isn't the issue, it's aligning them so they all point the same direction. My thought process is to orient them to the Z axis along the longest edge. Just not sure how in VEX.

Attachments:
Screenshot 2023-01-23 113039.png (691.7 KB)

User Avatar
Member
406 posts
Joined: April 2017
Offline
What you need to do is compute a transform matrix from two vectors that can be defined consistently on each of those primitives. The primitive normal of each diamond prim there is one easy one to get; the VEX function prim_normal() can return it. The second vector you can get by normalizing the difference in position of two points (as long as those points are consistent from primitive to primitive). If the point order of each diamond is the same, you could get the vectors like this in a primitive wrangle:

vector up = prim_normal(0, @primnum, 0.5, 0.5);
int pts[] = primpoints(0, @primnum);
vector P1 = point(0, "P", pts[0]);
vector P2 = point(0, "P", pts[1]);
vector N = normalize(P2-P1);

matrix m = maketransform(N, up, @P);
// creating the transform with primitive @P as the translate means the center of the primitive
// will be moved to the origin when inverting this matrix.
4@xform = m;

This creates a `xform` primitive attribute that you can pass to the Transform by Attribute SOP in inverted mode to transform the primitives. If you change the points used for creating P1 and P2, such as using pts and pts, you'll align the prims to a different axis. Again, this assumes that the point order is consistent from diamond to diamond. If it's not, you could probably define P1 and P2 by the closest and farthest points from the origin per-primitive. This makes for a slightly more complicated loop:

vector up = prim_normal(0, @primnum, 0.5, 0.5);
int pts[] = primpoints(0, @primnum);

float mindist = 999999;
float maxdist = 0;
int maxpt = -1;
int minpt = -1;
foreach(int pt; pts) {
    vector P = point(0, "P", pt);
    float dist = length(P); // the length of P is the distance from the origin
    if(dist > maxdist) {
        maxdist = dist;
        maxpt = pt;
    } if(dist < mindist) {
        mindist = dist;
        minpt = pt;
    }
}

vector P1 = point(0, "P", minpt);
vector P2 = point(0, "P", maxpt);
vector N = normalize(P2-P1);

matrix m = maketransform(N, up, @P);
// creating the transform with primitive @P as the translate means the center of the primitive
// will be moved to the origin when inverting this matrix.
4@xform = m;

Attachments:
center_prims.hip (184.0 KB)

MOPs (Motion Operators for Houdini): http://www.motionoperators.com [www.motionoperators.com]
  • Quick Links