From 67136bfcfef107031b6349b67b774fadcefa580e Mon Sep 17 00:00:00 2001 From: Matt McLin Date: Mon, 19 Dec 2022 15:16:50 -0800 Subject: [PATCH 1/5] Fix T103354: Author extents on UsdGeomMesh * Author extent attribute on all meshes * Move extent authoring to USDAbstractWriter, add support for hair and volumes Code review changes: use Blender's own bounds cache for meshes --- .../io/usd/intern/usd_writer_abstract.cc | 36 +++++++++++++++++++ .../io/usd/intern/usd_writer_abstract.h | 3 ++ .../blender/io/usd/intern/usd_writer_hair.cc | 2 ++ .../blender/io/usd/intern/usd_writer_mesh.cc | 10 ++++++ 4 files changed, 51 insertions(+) diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index f4ae9d20e52..1d263114ef7 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -5,12 +5,15 @@ #include "usd_writer_material.h" #include +#include #include "BKE_customdata.h" #include "BLI_assert.h" #include "DNA_mesh_types.h" +#include "WM_api.h" + /* TfToken objects are not cheap to construct, so we do it once. */ namespace usdtokens { /* Materials */ @@ -149,4 +152,37 @@ bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const return true; } +void USDAbstractWriter::author_extent(const pxr::UsdTimeCode timecode, pxr::UsdGeomBoundable &prim) +{ + /* Compute the bounds for a boundable prim, and author the result as the extent attribute. + * + * Although this method works for any boundable prim, it is preferred to use Blender's own + * cached bounds when possible. + * + * This method does not author the extentsHint attribute, which is also important to provide. + * Whereas the extent attribute can only be authored on prims inheriting from UsdGeomBoundable, + * an extentsHint can be provided on any prim, including scopes. This extentsHint should be + * authored on every prim in a hierarchy being exported. + * + * Note that this hint is only useful when importing or inspecting layers, and should not be + * taken into account when computing extents during export. + * + * TODO: also provide method for authoring extentsHint on every prim in a hierarchy. + */ + + /* do not use any existing extentsHint that may authored, instead recompute the extent when authoring it */ + const bool useExtentsHint = false; + const pxr::TfTokenVector includedPurposes{pxr::UsdGeomTokens->default_}; + pxr::UsdGeomBBoxCache bboxCache(timecode, includedPurposes, useExtentsHint); + pxr::GfBBox3d bounds = bboxCache.ComputeLocalBound(prim.GetPrim()); + if (pxr::GfBBox3d() == bounds) { + /* This will occur, for example, if a mesh does not have any vertices. */ + WM_reportf(RPT_ERROR, "USD Export: no bounds could be computed for %s", prim.GetPrim().GetName().GetText()); + return; + } + + pxr::VtArray extent{ (pxr::GfVec3f)bounds.GetRange().GetMin(), (pxr::GfVec3f)bounds.GetRange().GetMax() }; + prim.CreateExtentAttr().Set(extent); +} + } // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h index 8adc054c2c2..157c2c53aac 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.h +++ b/source/blender/io/usd/intern/usd_writer_abstract.h @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -67,6 +68,8 @@ class USDAbstractWriter : public AbstractHierarchyWriter { * Reference the original data instead of writing a copy. */ virtual bool mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim); + + virtual void author_extent(const pxr::UsdTimeCode timecode, pxr::UsdGeomBoundable &prim); }; } // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_writer_hair.cc b/source/blender/io/usd/intern/usd_writer_hair.cc index 8ec1447b505..bff00eb8a74 100644 --- a/source/blender/io/usd/intern/usd_writer_hair.cc +++ b/source/blender/io/usd/intern/usd_writer_hair.cc @@ -62,6 +62,8 @@ void USDHairWriter::do_write(HierarchyContext &context) colors.push_back(pxr::GfVec3f(cache[0]->col)); curves.CreateDisplayColorAttr(pxr::VtValue(colors)); } + + this->author_extent(timecode, curves); } bool USDHairWriter::check_is_animated(const HierarchyContext & /*context*/) const diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 62656c902d0..207cf7f24e7 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -247,6 +248,15 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh) if (usd_export_context_.export_params.export_materials) { assign_materials(context, usd_mesh, usd_mesh_data.face_groups); } + + /* Blender grows its bounds cache to cover animated meshes, so only author once. */ + float bound_min[3]; + float bound_max[3]; + INIT_MINMAX(bound_min, bound_max); + BKE_mesh_minmax(mesh, bound_min, bound_max); + pxr::VtArray extent{ pxr::GfVec3f{ bound_min[0], bound_min[1], bound_min[2]}, + pxr::GfVec3f{ bound_max[0], bound_max[1], bound_max[2]} }; + usd_mesh.CreateExtentAttr().Set(extent); } static void get_vertices(const Mesh *mesh, USDMeshData &usd_mesh_data) -- 2.30.2 From be1c115617a105dfc73ee3f3345065826029262c Mon Sep 17 00:00:00 2001 From: Matt McLin Date: Tue, 17 Jan 2023 13:29:30 -0800 Subject: [PATCH 2/5] Update to comments as requested by Sybren --- .../io/usd/intern/usd_writer_abstract.cc | 18 +----------------- .../io/usd/intern/usd_writer_abstract.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index 1d263114ef7..a540acf7573 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -154,23 +154,7 @@ bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const void USDAbstractWriter::author_extent(const pxr::UsdTimeCode timecode, pxr::UsdGeomBoundable &prim) { - /* Compute the bounds for a boundable prim, and author the result as the extent attribute. - * - * Although this method works for any boundable prim, it is preferred to use Blender's own - * cached bounds when possible. - * - * This method does not author the extentsHint attribute, which is also important to provide. - * Whereas the extent attribute can only be authored on prims inheriting from UsdGeomBoundable, - * an extentsHint can be provided on any prim, including scopes. This extentsHint should be - * authored on every prim in a hierarchy being exported. - * - * Note that this hint is only useful when importing or inspecting layers, and should not be - * taken into account when computing extents during export. - * - * TODO: also provide method for authoring extentsHint on every prim in a hierarchy. - */ - - /* do not use any existing extentsHint that may authored, instead recompute the extent when authoring it */ + /* Do not use any existing `extentsHint` that may be authored, instead recompute the extent when authoring it. */ const bool useExtentsHint = false; const pxr::TfTokenVector includedPurposes{pxr::UsdGeomTokens->default_}; pxr::UsdGeomBBoxCache bboxCache(timecode, includedPurposes, useExtentsHint); diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h index 157c2c53aac..f477a691cac 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.h +++ b/source/blender/io/usd/intern/usd_writer_abstract.h @@ -69,6 +69,22 @@ class USDAbstractWriter : public AbstractHierarchyWriter { */ virtual bool mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim); + /** + * Compute the bounds for a boundable prim, and author the result as the `extent` attribute. + * + * Although this method works for any boundable prim, it is preferred to use Blender's own + * cached bounds when possible. + * + * This method does not author the `extentsHint` attribute, which is also important to provide. + * Whereas the `extent` attribute can only be authored on prims inheriting from `UsdGeomBoundable`, + * an `extentsHint` can be provided on any prim, including scopes. This `extentsHint` should be + * authored on every prim in a hierarchy being exported. + * + * Note that this hint is only useful when importing or inspecting layers, and should not be + * taken into account when computing extents during export. + * + * TODO: also provide method for authoring extentsHint on every prim in a hierarchy. + */ virtual void author_extent(const pxr::UsdTimeCode timecode, pxr::UsdGeomBoundable &prim); }; -- 2.30.2 From a60f0ec2c87b3625d0b83caba669b4255241becd Mon Sep 17 00:00:00 2001 From: Dhruv Govil Date: Thu, 26 Jan 2023 23:38:49 -0800 Subject: [PATCH 3/5] Add USD Export Python Test Initial test uses USD Compliance Checker to validate an exported USD file. Test includes the ability to skip certain tests if so desired. Requires https://developer.blender.org/D17041 to be merged before it will succeed. The test asset used does not cover https://developer.blender.org/D17072 as we'll need to craft a test asset for that, and we need to work through that process first. I don't think that should hold up this CI test being integrated, since it wouldn't change the test itself. --- tests/python/CMakeLists.txt | 6 ++ tests/python/bl_usd_export_test.py | 95 ++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 tests/python/bl_usd_export_test.py diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 2dc3e560e35..20a7e2e000a 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -910,6 +910,12 @@ if(WITH_ALEMBIC) endif() if(WITH_USD) + add_blender_test( + usd_export_test + --python ${CMAKE_CURRENT_LIST_DIR}/bl_usd_export_test.py + -- + --testdir "${TEST_SRC_DIR}/usd" + ) add_blender_test( usd_import_test --python ${CMAKE_CURRENT_LIST_DIR}/bl_usd_import_test.py diff --git a/tests/python/bl_usd_export_test.py b/tests/python/bl_usd_export_test.py new file mode 100644 index 00000000000..e9bc7541df2 --- /dev/null +++ b/tests/python/bl_usd_export_test.py @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +import enum +import pathlib +import pprint +import sys +import tempfile +import unittest +from pxr import UsdUtils + +import bpy + +args = None + + +class Result(str, enum.Enum): + finished = "FINISHED" + cancelled = "CANCELLED" + + +class AbstractUSDTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls._tempdir = tempfile.TemporaryDirectory() + cls.testdir = args.testdir + cls.tempdir = pathlib.Path(cls._tempdir.name) + + return cls + + def setUp(self): + self.assertTrue( + self.testdir.exists(), "Test dir {0} should exist".format(self.testdir) + ) + + def tearDown(self): + self._tempdir.cleanup() + + +class USDExportTest(AbstractUSDTest): + def test_export_usdchecker(self): + """Test exporting a scene and verifying it passes the usdchecker test suite""" + bpy.ops.wm.open_mainfile( + filepath=str(self.testdir / "usd_materials_export.blend") + ) + export_path = self.tempdir / "usdchecker.usda" + res = bpy.ops.wm.usd_export( + filepath=str(export_path), + export_materials=True, + evaluation_mode="RENDER", + ) + self.assertEqual({Result.finished}, res, f"Unable to export to {export_path}") + + checker = UsdUtils.ComplianceChecker( + arkit=False, + skipARKitRootLayerCheck=False, + rootPackageOnly=False, + skipVariants=False, + verbose=False, + ) + checker.CheckCompliance(str(export_path)) + + collection = {} + + to_skip = ("MissingReferenceChecker",) + for rule in checker._rules: + name = rule.__class__.__name__ + if name in to_skip: + continue + + issues = rule.GetFailedChecks() + rule.GetWarnings() + rule.GetErrors() + if not issues: + continue + + collection[name] = issues + + self.assertFalse(collection, pprint.pformat(collection)) + + +def main(): + global args + import argparse + + if "--" in sys.argv: + argv = [sys.argv[0]] + sys.argv[sys.argv.index("--") + 1 :] + else: + argv = sys.argv + + parser = argparse.ArgumentParser() + parser.add_argument("--testdir", required=True, type=pathlib.Path) + args, remaining = parser.parse_known_args(argv) + + unittest.main(argv=remaining) + + +if __name__ == "__main__": + main() -- 2.30.2 From 5089928eb0fbc261a4e3eb22bb2c8de591d6630a Mon Sep 17 00:00:00 2001 From: Matt McLin Date: Fri, 27 Jan 2023 22:26:08 -0800 Subject: [PATCH 4/5] Add unit test for authoring extent. Also apply additional formatting changes suggested during review. Requires the following new files: lib/tests/usd/usd_extent_test.blend lib/tests/usd/textures/small_cloud.vdb --- .../io/usd/intern/usd_writer_abstract.cc | 12 +++-- .../io/usd/intern/usd_writer_abstract.h | 10 ++-- .../blender/io/usd/intern/usd_writer_hair.cc | 2 +- .../blender/io/usd/intern/usd_writer_mesh.cc | 8 +-- tests/python/bl_usd_export_test.py | 54 ++++++++++++++++++- 5 files changed, 71 insertions(+), 15 deletions(-) diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index a540acf7573..b5f24fa9885 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -154,18 +154,22 @@ bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const void USDAbstractWriter::author_extent(const pxr::UsdTimeCode timecode, pxr::UsdGeomBoundable &prim) { - /* Do not use any existing `extentsHint` that may be authored, instead recompute the extent when authoring it. */ + /* Do not use any existing `extentsHint` that may be authored, instead recompute the extent when + * authoring it. */ const bool useExtentsHint = false; const pxr::TfTokenVector includedPurposes{pxr::UsdGeomTokens->default_}; pxr::UsdGeomBBoxCache bboxCache(timecode, includedPurposes, useExtentsHint); pxr::GfBBox3d bounds = bboxCache.ComputeLocalBound(prim.GetPrim()); if (pxr::GfBBox3d() == bounds) { /* This will occur, for example, if a mesh does not have any vertices. */ - WM_reportf(RPT_ERROR, "USD Export: no bounds could be computed for %s", prim.GetPrim().GetName().GetText()); + WM_reportf(RPT_ERROR, + "USD Export: no bounds could be computed for %s", + prim.GetPrim().GetName().GetText()); return; } - - pxr::VtArray extent{ (pxr::GfVec3f)bounds.GetRange().GetMin(), (pxr::GfVec3f)bounds.GetRange().GetMax() }; + + pxr::VtArray extent{(pxr::GfVec3f)bounds.GetRange().GetMin(), + (pxr::GfVec3f)bounds.GetRange().GetMax()}; prim.CreateExtentAttr().Set(extent); } diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h index f477a691cac..e6ac6a8ba21 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.h +++ b/source/blender/io/usd/intern/usd_writer_abstract.h @@ -7,9 +7,9 @@ #include #include +#include #include #include -#include #include @@ -68,7 +68,7 @@ class USDAbstractWriter : public AbstractHierarchyWriter { * Reference the original data instead of writing a copy. */ virtual bool mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim); - + /** * Compute the bounds for a boundable prim, and author the result as the `extent` attribute. * @@ -76,9 +76,9 @@ class USDAbstractWriter : public AbstractHierarchyWriter { * cached bounds when possible. * * This method does not author the `extentsHint` attribute, which is also important to provide. - * Whereas the `extent` attribute can only be authored on prims inheriting from `UsdGeomBoundable`, - * an `extentsHint` can be provided on any prim, including scopes. This `extentsHint` should be - * authored on every prim in a hierarchy being exported. + * Whereas the `extent` attribute can only be authored on prims inheriting from + * `UsdGeomBoundable`, an `extentsHint` can be provided on any prim, including scopes. This + * `extentsHint` should be authored on every prim in a hierarchy being exported. * * Note that this hint is only useful when importing or inspecting layers, and should not be * taken into account when computing extents during export. diff --git a/source/blender/io/usd/intern/usd_writer_hair.cc b/source/blender/io/usd/intern/usd_writer_hair.cc index bff00eb8a74..31c41909480 100644 --- a/source/blender/io/usd/intern/usd_writer_hair.cc +++ b/source/blender/io/usd/intern/usd_writer_hair.cc @@ -62,7 +62,7 @@ void USDHairWriter::do_write(HierarchyContext &context) colors.push_back(pxr::GfVec3f(cache[0]->col)); curves.CreateDisplayColorAttr(pxr::VtValue(colors)); } - + this->author_extent(timecode, curves); } diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 207cf7f24e7..8363f9f8b35 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -3,9 +3,9 @@ #include "usd_writer_mesh.h" #include "usd_hierarchy_iterator.h" +#include #include #include -#include #include #include @@ -248,14 +248,14 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh) if (usd_export_context_.export_params.export_materials) { assign_materials(context, usd_mesh, usd_mesh_data.face_groups); } - + /* Blender grows its bounds cache to cover animated meshes, so only author once. */ float bound_min[3]; float bound_max[3]; INIT_MINMAX(bound_min, bound_max); BKE_mesh_minmax(mesh, bound_min, bound_max); - pxr::VtArray extent{ pxr::GfVec3f{ bound_min[0], bound_min[1], bound_min[2]}, - pxr::GfVec3f{ bound_max[0], bound_max[1], bound_max[2]} }; + pxr::VtArray extent{pxr::GfVec3f{bound_min[0], bound_min[1], bound_min[2]}, + pxr::GfVec3f{bound_max[0], bound_max[1], bound_max[2]}}; usd_mesh.CreateExtentAttr().Set(extent); } diff --git a/tests/python/bl_usd_export_test.py b/tests/python/bl_usd_export_test.py index e9bc7541df2..bb89db073c7 100644 --- a/tests/python/bl_usd_export_test.py +++ b/tests/python/bl_usd_export_test.py @@ -5,7 +5,10 @@ import pprint import sys import tempfile import unittest +from pxr import Usd from pxr import UsdUtils +from pxr import UsdGeom +from pxr import Gf import bpy @@ -74,13 +77,62 @@ class USDExportTest(AbstractUSDTest): self.assertFalse(collection, pprint.pformat(collection)) + def compareVec3d(self, first, second): + places = 5 + self.assertAlmostEqual(first[0], second[0], places) + self.assertAlmostEqual(first[1], second[1], places) + self.assertAlmostEqual(first[2], second[2], places) + + def test_export_extents(self): + """Test that exported scenes contain have a properly authored extent attribute on each boundable prim""" + bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "usd_extent_test.blend")) + export_path = self.tempdir / "usd_extent_test.usda" + res = bpy.ops.wm.usd_export( + filepath=str(export_path), + export_materials=True, + evaluation_mode="RENDER", + ) + self.assertEqual({Result.finished}, res, f"Unable to export to {export_path}") + + # 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") + + # validate the overall world bounds of the scene + stage = Usd.Stage.Open(str(export_path)) + scenePrim = stage.GetPrimAtPath("/scene") + bboxcache = UsdGeom.BBoxCache(Usd.TimeCode.Default(), [UsdGeom.Tokens.default_]) + bounds = bboxcache.ComputeWorldBound(scenePrim) + bound_min = bounds.GetRange().GetMin() + bound_max = bounds.GetRange().GetMax() + self.compareVec3d(bound_min, Gf.Vec3d(-5.752975881, -1, -2.798513651)) + self.compareVec3d(bound_max, Gf.Vec3d(1, 2.9515805244, 2.7985136508)) + + # validate the locally authored extents + prim = stage.GetPrimAtPath("/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") + 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") + extent = UsdGeom.Boundable(prim).GetExtentAttr().Get() + self.compareVec3d( + Gf.Vec3d(extent[0]), Gf.Vec3d(-0.7313742, -0.68043584, -0.5801515) + ) + self.compareVec3d( + Gf.Vec3d(extent[1]), Gf.Vec3d(0.7515701, 0.5500924, 0.9027928) + ) + def main(): global args import argparse if "--" in sys.argv: - argv = [sys.argv[0]] + sys.argv[sys.argv.index("--") + 1 :] + argv = [sys.argv[0]] + sys.argv[sys.argv.index("--") + 1:] else: argv = sys.argv -- 2.30.2 From e3d170cd9573e703707ee07bed867c56197b9ab7 Mon Sep 17 00:00:00 2001 From: Matt McLin Date: Mon, 13 Feb 2023 08:45:50 -0800 Subject: [PATCH 5/5] Updates from Sybren code review --- .../io/usd/intern/usd_writer_abstract.cc | 2 +- tests/python/bl_usd_export_test.py | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index b5f24fa9885..79cb521aacd 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -162,7 +162,7 @@ void USDAbstractWriter::author_extent(const pxr::UsdTimeCode timecode, pxr::UsdG pxr::GfBBox3d bounds = bboxCache.ComputeLocalBound(prim.GetPrim()); if (pxr::GfBBox3d() == bounds) { /* This will occur, for example, if a mesh does not have any vertices. */ - WM_reportf(RPT_ERROR, + WM_reportf(RPT_WARNING, "USD Export: no bounds could be computed for %s", prim.GetPrim().GetName().GetText()); return; diff --git a/tests/python/bl_usd_export_test.py b/tests/python/bl_usd_export_test.py index bb89db073c7..80edb89a9b3 100644 --- a/tests/python/bl_usd_export_test.py +++ b/tests/python/bl_usd_export_test.py @@ -14,12 +14,6 @@ import bpy args = None - -class Result(str, enum.Enum): - finished = "FINISHED" - cancelled = "CANCELLED" - - class AbstractUSDTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -50,7 +44,7 @@ class USDExportTest(AbstractUSDTest): export_materials=True, evaluation_mode="RENDER", ) - self.assertEqual({Result.finished}, res, f"Unable to export to {export_path}") + self.assertEqual({'FINISHED'}, res, f"Unable to export to {export_path}") checker = UsdUtils.ComplianceChecker( arkit=False, @@ -61,8 +55,11 @@ class USDExportTest(AbstractUSDTest): ) checker.CheckCompliance(str(export_path)) - collection = {} + failed_checks = {} + # The ComplianceChecker does not know how to resolve tags, so + # it will flag "textures/test_grid_.png" as a missing reference. + # That reference is in fact OK, so we skip the rule for this test. to_skip = ("MissingReferenceChecker",) for rule in checker._rules: name = rule.__class__.__name__ @@ -73,9 +70,9 @@ class USDExportTest(AbstractUSDTest): if not issues: continue - collection[name] = issues + failed_checks[name] = issues - self.assertFalse(collection, pprint.pformat(collection)) + self.assertFalse(failed_checks, pprint.pformat(failed_checks)) def compareVec3d(self, first, second): places = 5 @@ -92,7 +89,7 @@ class USDExportTest(AbstractUSDTest): export_materials=True, evaluation_mode="RENDER", ) - self.assertEqual({Result.finished}, res, f"Unable to export to {export_path}") + self.assertEqual({'FINISHED'}, res, f"Unable to export to {export_path}") # if prims are missing, the exporter must have skipped some objects stats = UsdUtils.ComputeUsdStageStats(str(export_path)) -- 2.30.2