I have stages consisting of several primitive cubes. The cubes may be rotated about the up axis, translated, and scaled. The cubes’ up axis scales and translations are the same (i.e., they are the same height and lie on the same plane). I would like a function that extracts the corners of the cubes’ footprints, and a corresponding function that takes a rectangle representing a footprint and reproduces the prim cube.
I have been experimenting with variations of the following, but I have not gotten the translation and/or scaling to work as expected:
def get_transformation_matrix_and_scale(stage, rectangle, group_idx):
# 1. Determine Translation
centroid = rectangle.centroid
translation = [centroid.x, centroid.y, 0] # Assuming z=0 for 2D space
# 2. Determine Rotation
# Assuming the first two points form one of the rectangle's edges
coords = list(rectangle.exterior.coords)
dx = coords[1][0] - coords[0][0]
dy = coords[1][1] - coords[0][1]
angle = np.arctan2(dy, dx)
# 3. Determine Scale
width = sqrt(dx**2 + dy**2)
height = sqrt((coords[2][0] - coords[1][0])**2 + (coords[2][1] - coords[1][1])**2)
scale = [width, height, 1] # Assuming uniform scaling in z=1
# 4. Compose the Transformation Matrix
# Rotation matrix around z-axis
R = np.array([
[cos(angle), -sin(angle), 0, 0],
[sin(angle), cos(angle), 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
])
print(R)
# Scale matrix
S = np.diag(scale + [1])
print(S)
# Translation matrix
T = np.array([
[1, 0, 0, translation[0]],
[0, 1, 0, translation[1]],
[0, 0, 1, translation[2]],
[0, 0, 0, 1]
])
print(T)
# Compose the transformation matrix: T * R * S
transformation_matrix = T @ R @ S
xform = UsdGeom.Xform.Define(stage, f'/Cube_{group_idx}_grp')
cube = UsdGeom.Cube.Define(stage, xform.GetPath().AppendChild(f'Cube{group_idx}'))
transform_op = cube.AddTransformOp(UsdGeom.XformOp.PrecisionDouble)
transform_op.Set(Gf.Matrix4d(transformation_matrix))
cube.AddScaleOp(UsdGeom.XformOp.PrecisionDouble).Set(value=Gf.Vec3d(scale))