Hey hey, so here is the code(simplified) that I ended up with to make my guide cube ;D
from pxr import Gf, Sdf, Usd, UsdGeom
# Path to the USD file that will contain the guide mesh
guide_path = "./guide.usda"
def get_extent(stage, prim):
"""
Calculates & sets the extentsHint of a prim based on its World Bounds
Args:
stage (Usd.Stage): The USD stage containing the primitive.
prim (str or Usd.Prim): The address to the primitive such as '/root/cube_model'
or the prim object itself.
Returns:
extents_hint (Vec3fArray): A two-by-three array containing the endpoints of the
axis-aligned, object-space extent.
"""
# Convert prim_path string to prim
if isinstance(prim, str):
prim_path = prim
prim = stage.GetPrimAtPath(prim_path)
# Create a BBoxCache to compute the bounding box
bbox_cache = UsdGeom.BBoxCache(Usd.TimeCode.Default(),
includedPurposes=[UsdGeom.Tokens.default_,
UsdGeom.Tokens.render],
useExtentsHint=False,
ignoreVisibility=False)
# Compute the world bounds of the primitive
bbox_bounds = bbox_cache.ComputeWorldBound(prim)
bound_align = bbox_bounds.ComputeAlignedBox()
bbox_min = bound_align.GetMin()
bbox_max = bound_align.GetMax()
def convert_to_float(number):
# Corrects floating-point formatting issues
if "e" in str(number):
string_min = str(number)
correction = string_min.split("e")
return float(correction[0])
return number
# Correct the bounding box values
corrected_min = [convert_to_float(number) for number in bbox_min]
corrected_max = [convert_to_float(number) for number in bbox_max]
# Compute extents
extents = [
corrected_min,
corrected_max
]
print(extents)
# Define vertex points for the cube mesh
vertex_points = [
Gf.Vec3d(corrected_max[0], corrected_min[1], corrected_max[2]),
Gf.Vec3d(corrected_min[0], corrected_min[1], corrected_max[2]),
Gf.Vec3d(corrected_max[0], corrected_max[1], corrected_max[2]),
Gf.Vec3d(corrected_min[0], corrected_max[1], corrected_max[2]),
Gf.Vec3d(corrected_min[0], corrected_min[1], corrected_min[2]),
Gf.Vec3d(corrected_max[0], corrected_min[1], corrected_min[2]),
Gf.Vec3d(corrected_min[0], corrected_max[1], corrected_min[2]),
Gf.Vec3d(corrected_max[0], corrected_max[1], corrected_min[2]),
]
return extents, vertex_points
def create_cube_mesh(stage, bbox_extent, vertex_points, default_prim):
"""
Creates a cube mesh in the USD stage.
Args:
stage (Usd.Stage): The USD stage where the cube mesh will be created.
bbox_extent (Vec3fArray): Extents of the bounding box.
vertex_points (list of Gf.Vec3d): List of vertex points for the cube.
default_prim (Usd.Prim): The default primitive where the cube will be added.
Returns:
Usd.Prim: The created cube mesh primitive.
"""
# Create hierarchy for the cube mesh
asset_prim = stage.DefinePrim(f"{default_prim.GetPath()}", "Xform")
model_prim = stage.DefinePrim(f"{default_prim.GetPath()}/model", "Xform")
guide_prim = stage.DefinePrim(f"{default_prim.GetPath()}/model/guide", "Xform")
cube_mesh = stage.DefinePrim(f"{default_prim.GetPath()}/model/guide/box", "Mesh")
# Define attributes for the cube mesh
face_vertex_counts_attribute = cube_mesh.CreateAttribute("faceVertexCounts", Sdf.ValueTypeNames.Int)
face_vertex_counts_attribute.Set([4, 4, 4, 4, 4, 4])
points_attribute = cube_mesh.CreateAttribute("points", Sdf.ValueTypeNames.Point3f)
points_attribute.Set(vertex_points)
extents_cube = cube_mesh.CreateAttribute("extent", Sdf.ValueTypeNames.Vector3fArray)
extents_cube.Set(bbox_extent)
face_vertex_indices_attribute = cube_mesh.CreateAttribute("faceVertexIndices", Sdf.ValueTypeNames.Int)
face_vertex_indices_attribute.Set([0, 1, 3, 2, 4, 5, 7, 6, 6, 7, 2, 3, 5, 4, 1, 0, 5, 0, 2, 7, 1, 4, 6, 3])
return cube_mesh
# Path to the USD file containing the model
model_path = "./geo.usda"
# Open the USD stage for the model
model_stage = Usd.Stage.Open(model_path)
# Get the default prim of the model
asset_prim = model_stage.GetDefaultPrim()
print(f"Auto Guide will be calculated for: {asset_prim.GetPath()}")
# Calculate bounding box extent and vertex points
bbox_extent, vertex_points = get_extent(model_stage, asset_prim)
# Create a new USD stage for the guide and create the cube mesh
stage = Usd.Stage.CreateNew(guide_path)
cube_mesh = create_cube_mesh(stage, bbox_extent, vertex_points, asset_prim)
# Save the new USD stage with the cube mesh
stage.Save()