diff --git a/source/blender/editors/io/io_usd.cc b/source/blender/editors/io/io_usd.cc index b181f817d83..e6ff02cd089 100644 --- a/source/blender/editors/io/io_usd.cc +++ b/source/blender/editors/io/io_usd.cc @@ -943,6 +943,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) MEM_SAFE_FREE(op->customdata); const float scale = RNA_float_get(op->ptr, "scale"); + const float light_intensity_scale = RNA_float_get(op->ptr, "light_intensity_scale"); + const bool apply_unit_conversion_scale = RNA_boolean_get(op->ptr, "apply_unit_conversion_scale"); const bool set_frame_range = RNA_boolean_get(op->ptr, "set_frame_range"); @@ -993,8 +995,6 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) const bool import_usd_preview = RNA_boolean_get(op->ptr, "import_usd_preview"); const bool set_material_blend = RNA_boolean_get(op->ptr, "set_material_blend"); - const float light_intensity_scale = RNA_float_get(op->ptr, "light_intensity_scale"); - const eUSDMtlPurpose mtl_purpose = eUSDMtlPurpose(RNA_enum_get(op->ptr, "mtl_purpose")); const eUSDMtlNameCollisionMode mtl_name_collision_mode = eUSDMtlNameCollisionMode( RNA_enum_get(op->ptr, "mtl_name_collision_mode")); @@ -1023,12 +1023,11 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) const eUSDTexNameCollisionMode tex_name_collision_mode = eUSDTexNameCollisionMode( RNA_enum_get(op->ptr, "tex_name_collision_mode")); - const bool apply_unit_conversion_scale = RNA_boolean_get(op->ptr, "apply_unit_conversion_scale"); - USDImportParams params{}; params.prim_path_mask = prim_path_mask; params.scale = scale; params.light_intensity_scale = light_intensity_scale; + params.apply_unit_conversion_scale = apply_unit_conversion_scale; params.mesh_read_flag = mesh_read_flag; params.set_frame_range = set_frame_range; @@ -1075,8 +1074,6 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) STRNCPY(params.import_textures_dir, import_textures_dir); - params.apply_unit_conversion_scale = apply_unit_conversion_scale; - /* Switch out of edit mode to avoid being stuck in it (#54326). */ Object *obedit = CTX_data_edit_object(C); if (obedit) { diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc index dc5b2b9bf7e..89beba9b07e 100644 --- a/source/blender/io/usd/intern/usd_capi_export.cc +++ b/source/blender/io/usd/intern/usd_capi_export.cc @@ -170,7 +170,7 @@ static void ensure_root_prim(pxr::UsdStageRefPtr stage, const USDExportParams &p } if (params.convert_scene_units) { - xf_api.SetScale(pxr::GfVec3f(float(1.0 / get_meters_per_unit(¶ms)))); + xf_api.SetScale(pxr::GfVec3f(float(1.0 / get_meters_per_unit(params)))); } if (params.convert_orientation) { @@ -440,7 +440,7 @@ pxr::UsdStageRefPtr export_to_stage(const USDExportParams ¶ms, usd_stage->SetMetadata(pxr::UsdGeomTokens->upAxis, upAxis); - const double meters_per_unit = get_meters_per_unit(¶ms); + const double meters_per_unit = get_meters_per_unit(params); pxr::UsdGeomSetStageMetersPerUnit(usd_stage, meters_per_unit); ensure_root_prim(usd_stage, params); @@ -747,10 +747,10 @@ int USD_get_version() return PXR_VERSION; } -double get_meters_per_unit(const USDExportParams *params) +double get_meters_per_unit(const USDExportParams ¶ms) { double result; - switch (params->convert_scene_units) { + switch (params.convert_scene_units) { case USD_SCENE_UNITS_CENTIMETERS: result = 0.01; break; @@ -770,7 +770,7 @@ double get_meters_per_unit(const USDExportParams *params) result = 0.9144; break; case USD_SCENE_UNITS_CUSTOM: - result = double(params->custom_meters_per_unit); + result = double(params.custom_meters_per_unit); break; default: result = 1.0; diff --git a/source/blender/io/usd/intern/usd_writer_camera.cc b/source/blender/io/usd/intern/usd_writer_camera.cc index b632b264c08..a4a479b5026 100644 --- a/source/blender/io/usd/intern/usd_writer_camera.cc +++ b/source/blender/io/usd/intern/usd_writer_camera.cc @@ -58,7 +58,7 @@ static void camera_sensor_size_for_render(const Camera *camera, void USDCameraWriter::do_write(HierarchyContext &context) { - const double meters_per_unit = get_meters_per_unit(&usd_export_context_.export_params); + const double meters_per_unit = get_meters_per_unit(usd_export_context_.export_params); const float unit_scale = float(1.0 / meters_per_unit); pxr::UsdTimeCode timecode = get_export_time_code(); diff --git a/source/blender/io/usd/intern/usd_writer_transform.cc b/source/blender/io/usd/intern/usd_writer_transform.cc index aa0754e3ff4..90383d919d2 100644 --- a/source/blender/io/usd/intern/usd_writer_transform.cc +++ b/source/blender/io/usd/intern/usd_writer_transform.cc @@ -98,7 +98,7 @@ void USDTransformWriter::do_write(HierarchyContext &context) eUSDSceneUnits::USD_SCENE_UNITS_METERS) { float scale_mat[4][4]; - scale_m4_fl(scale_mat, float(1.0 / get_meters_per_unit(&usd_export_context_.export_params))); + scale_m4_fl(scale_mat, float(1.0 / get_meters_per_unit(usd_export_context_.export_params))); mul_m4_m4m4(matrix_world, scale_mat, matrix_world); } diff --git a/source/blender/io/usd/usd.hh b/source/blender/io/usd/usd.hh index b6dc99d1a30..3ff67fe051c 100644 --- a/source/blender/io/usd/usd.hh +++ b/source/blender/io/usd/usd.hh @@ -192,6 +192,7 @@ struct USDImportParams { char *prim_path_mask; float scale; float light_intensity_scale; + bool apply_unit_conversion_scale; char mesh_read_flag; bool set_frame_range; @@ -237,8 +238,6 @@ struct USDImportParams { eUSDTexNameCollisionMode tex_name_collision_mode; eUSDAttrImportMode attr_import_mode; - bool apply_unit_conversion_scale; - /** * Communication structure between the wmJob management code and the worker code. Currently used * to generate safely reports from the worker thread. @@ -336,6 +335,6 @@ void USD_register_hook(std::unique_ptr hook); void USD_unregister_hook(USDHook *hook); USDHook *USD_find_hook_name(const char idname[]); -double get_meters_per_unit(const USDExportParams *params); +double get_meters_per_unit(const USDExportParams ¶ms); }; // namespace blender::io::usd diff --git a/tests/python/bl_usd_export_test.py b/tests/python/bl_usd_export_test.py index b7312e31e2b..c34145648bd 100644 --- a/tests/python/bl_usd_export_test.py +++ b/tests/python/bl_usd_export_test.py @@ -1326,40 +1326,23 @@ class USDExportTest(AbstractUSDTest): """Test specifying stage meters per unit on export.""" bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "empty.blend")) - export_path = self.tempdir / "usd_export_units_test_cm.usda" - self.export_and_validate( - filepath=str(export_path), - convert_scene_units='CENTIMETERS' + units = ( + ("mm", 'MILLIMETERS', 0.001), ("cm", 'CENTIMETERS', 0.01), ("km", 'KILOMETERS', 1000), + ("in", 'INCHES', 0.0254), ("ft", 'FEET', 0.3048), ("yd", 'YARDS', 0.9144), + ("default", "", 1), ("custom", 'CUSTOM', 0.125) ) + for name, unit, value in units: + export_path = self.tempdir / f"usd_export_units_test_{name}.usda" + if name == "default": + self.export_and_validate(filepath=str(export_path)) + elif name == "custom": + self.export_and_validate(filepath=str(export_path), convert_scene_units=unit, meters_per_unit=value) + else: + self.export_and_validate(filepath=str(export_path), convert_scene_units=unit) - # Verify that meters per unit were set correctly - stage = Usd.Stage.Open(str(export_path)) - mpu = UsdGeom.GetStageMetersPerUnit(stage) - self.assertEqual(mpu, 0.01) - - # Export with default meters units. - export_path = self.tempdir / "usd_export_units_test_default.usda" - self.export_and_validate( - filepath=str(export_path) - ) - - # Verify that meters per unit were set correctly - stage = Usd.Stage.Open(str(export_path)) - mpu = UsdGeom.GetStageMetersPerUnit(stage) - self.assertEqual(mpu, 1.0) - - # Export with custom meters per unit. - export_path = self.tempdir / "usd_export_units_test_custom.usda" - self.export_and_validate( - filepath=str(export_path), - convert_scene_units='CUSTOM', - meters_per_unit=0.1, - ) - - # Verify that meters per unit were set correctly - stage = Usd.Stage.Open(str(export_path)) - mpu = UsdGeom.GetStageMetersPerUnit(stage) - self.assertAlmostEqual(mpu, 0.1) + # Verify that meters per unit were set correctly + stage = Usd.Stage.Open(str(export_path)) + self.assertEqual(UsdGeom.GetStageMetersPerUnit(stage), value) def test_export_native_instancing_true(self): """Test exporting instanced objects to native (scne graph) instances."""