USD: export to a single root prim by default

This PR adds the following changes:

A single root is always set as default. After talking to Wave and
Spiff, we settled on root being the best default. Users who don't
want a single root prim inserted, can choose to clear the field
The root prim no longer requires the user to prefix the field with /.
It will implicitly insert that for them.

On export, the root_prim hierarchy is now defined all as Xform
instead of just the final prim in the path. Each prim also has
custom metadata added to show that it was generated by Blender.
This follows convention in other DCCs as well.

On import, the code now finds the hierarchy of generated prims
using that metadata. It then skips importing them. This means that
you can roundtrip hierarchies even with an inserted root.

Co-authored-by: Dhruv Govil <dgovil2@apple.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/113187
This commit is contained in:
Michael B Johnson
2023-10-20 10:53:51 -04:00
committed by Michael Kowalski
parent 89e3ba4e25
commit b262655d39
7 changed files with 84 additions and 13 deletions

View File

@@ -97,11 +97,11 @@ class USDExportTest(AbstractUSDTest):
# if prims are missing, the exporter must have skipped some objects
stats = UsdUtils.ComputeUsdStageStats(str(export_path))
self.assertEqual(stats["totalPrimCount"], 15, "Unexpected number of prims")
self.assertEqual(stats["totalPrimCount"], 16, "Unexpected number of prims")
# validate the overall world bounds of the scene
stage = Usd.Stage.Open(str(export_path))
scenePrim = stage.GetPrimAtPath("/scene")
scenePrim = stage.GetPrimAtPath("/root/scene")
bboxcache = UsdGeom.BBoxCache(Usd.TimeCode.Default(), [UsdGeom.Tokens.default_])
bounds = bboxcache.ComputeWorldBound(scenePrim)
bound_min = bounds.GetRange().GetMin()
@@ -110,15 +110,15 @@ class USDExportTest(AbstractUSDTest):
self.compareVec3d(bound_max, Gf.Vec3d(1, 2.9515805244, 2.7985136508))
# validate the locally authored extents
prim = stage.GetPrimAtPath("/scene/BigCube/BigCubeMesh")
prim = stage.GetPrimAtPath("/root/scene/BigCube/BigCubeMesh")
extent = UsdGeom.Boundable(prim).GetExtentAttr().Get()
self.compareVec3d(Gf.Vec3d(extent[0]), Gf.Vec3d(-1, -1, -2.7985137))
self.compareVec3d(Gf.Vec3d(extent[1]), Gf.Vec3d(1, 1, 2.7985137))
prim = stage.GetPrimAtPath("/scene/LittleCube/LittleCubeMesh")
prim = stage.GetPrimAtPath("/root/scene/LittleCube/LittleCubeMesh")
extent = UsdGeom.Boundable(prim).GetExtentAttr().Get()
self.compareVec3d(Gf.Vec3d(extent[0]), Gf.Vec3d(-1, -1, -1))
self.compareVec3d(Gf.Vec3d(extent[1]), Gf.Vec3d(1, 1, 1))
prim = stage.GetPrimAtPath("/scene/Volume/Volume")
prim = stage.GetPrimAtPath("/root/scene/Volume/Volume")
extent = UsdGeom.Boundable(prim).GetExtentAttr().Get()
self.compareVec3d(
Gf.Vec3d(extent[0]), Gf.Vec3d(-0.7313742, -0.68043584, -0.5801515)
@@ -143,7 +143,7 @@ class USDExportTest(AbstractUSDTest):
# Inspect and validate the exported USD for the opaque blend case.
stage = Usd.Stage.Open(str(export_path))
shader_prim = stage.GetPrimAtPath("/_materials/Material/Principled_BSDF")
shader_prim = stage.GetPrimAtPath("/root/_materials/Material/Principled_BSDF")
shader = UsdShade.Shader(shader_prim)
opacity_input = shader.GetInput('opacity')
self.assertEqual(opacity_input.HasConnectedSource(), False,
@@ -170,7 +170,7 @@ class USDExportTest(AbstractUSDTest):
# Inspect and validate the exported USD for the alpha clip case.
stage = Usd.Stage.Open(str(export_path))
shader_prim = stage.GetPrimAtPath("/_materials/Material/Principled_BSDF")
shader_prim = stage.GetPrimAtPath("/root/_materials/Material/Principled_BSDF")
shader = UsdShade.Shader(shader_prim)
opacity_input = shader.GetInput('opacity')
opacity_thres_input = shader.GetInput('opacityThreshold')
@@ -189,7 +189,7 @@ class USDExportTest(AbstractUSDTest):
# Inspect and validate the exported USD for the alpha blend case.
stage = Usd.Stage.Open(str(export_path))
shader_prim = stage.GetPrimAtPath("/_materials/Material/Principled_BSDF")
shader_prim = stage.GetPrimAtPath("/root/_materials/Material/Principled_BSDF")
shader = UsdShade.Shader(shader_prim)
opacity_input = shader.GetInput('opacity')
opacity_thres_input = shader.GetInput('opacityThreshold')