Fix: vertex crease data was imported incorrectly from USD
While adding tests for subd import I discovered that our vertex crease data was imported incorrectly. This PR adds tests and fixes: - We tried to read crease sharpness data as ints instead of floats. This caused the import process to early-return, meaning we never load any data at all - Empty USD data would still cause us to create the `crease_vert` attribute unnecessarily - Sharpness data needs clamped to 0-1 to handle USD's SHARPNESS_INFINITE value of 10.0 - We need to fill the `crease_vert` span with 0's since incoming USD data may not have values set for all the verts Pull Request: https://projects.blender.org/blender/blender/pulls/131516
This commit is contained in:
committed by
Jesse Yurkovich
parent
e3c6c2c6fc
commit
76c699ada5
@@ -355,11 +355,16 @@ void USDMeshReader::read_vertex_creases(Mesh *mesh, const double motionSampleTim
|
||||
return;
|
||||
}
|
||||
|
||||
pxr::VtIntArray corner_sharpnesses;
|
||||
pxr::VtFloatArray corner_sharpnesses;
|
||||
if (!mesh_prim_.GetCornerSharpnessesAttr().Get(&corner_sharpnesses, motionSampleTime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prevent the creation of the `crease_vert` attribute if we have no data. */
|
||||
if (corner_indices.empty() || corner_sharpnesses.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* It is fine to have fewer indices than vertices, but never the other way other. */
|
||||
if (corner_indices.size() > mesh->verts_num) {
|
||||
CLOG_WARN(&LOG, "Too many vertex creases for mesh %s", prim_path_.c_str());
|
||||
@@ -375,9 +380,10 @@ void USDMeshReader::read_vertex_creases(Mesh *mesh, const double motionSampleTim
|
||||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
bke::SpanAttributeWriter creases = attributes.lookup_or_add_for_write_only_span<float>(
|
||||
"crease_vert", bke::AttrDomain::Point);
|
||||
creases.span.fill(0.0f);
|
||||
|
||||
for (size_t i = 0; i < corner_indices.size(); i++) {
|
||||
creases.span[corner_indices[i]] = corner_sharpnesses[i];
|
||||
creases.span[corner_indices[i]] = std::clamp(corner_sharpnesses[i], 0.0f, 1.0f);
|
||||
}
|
||||
creases.finish();
|
||||
}
|
||||
|
||||
@@ -198,6 +198,28 @@ class USDImportTest(AbstractUSDTest):
|
||||
coords = list(filter(lambda x: x[0] > 1.0, coords))
|
||||
self.assertGreater(len(coords), 16)
|
||||
|
||||
def test_import_mesh_subd(self):
|
||||
"""Test importing meshes with subdivision attributes."""
|
||||
|
||||
# Use the existing mesh subd test file to create the USD file
|
||||
# for import. It is validated as part of the bl_usd_export test.
|
||||
bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "usd_mesh_subd.blend"))
|
||||
testfile = str(self.tempdir / "usd_mesh_subd.usda")
|
||||
bpy.ops.wm.usd_export(filepath=testfile, export_subdivision='BEST_MATCH', evaluation_mode="RENDER")
|
||||
res = bpy.ops.wm.usd_export(filepath=testfile, export_materials=True)
|
||||
self.assertEqual({'FINISHED'}, res, f"Unable to export to {testfile}")
|
||||
|
||||
# Reload the empty file and import back in
|
||||
bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "empty.blend"))
|
||||
res = bpy.ops.wm.usd_import(filepath=testfile)
|
||||
self.assertEqual({'FINISHED'}, res, f"Unable to import USD file {testfile}")
|
||||
|
||||
# Validate crease attributes
|
||||
|
||||
mesh = bpy.data.objects["crease_verts"].data
|
||||
blender_crease_vert_data = [round(d.value, 5) for d in mesh.attributes["crease_vert"].data]
|
||||
self.assertEqual(blender_crease_vert_data, [0.3, 0.0, 0.2, 0.1, 0.8, 0.7, 1.0, 0.9])
|
||||
|
||||
def test_import_camera_properties(self):
|
||||
"""Test importing camera to ensure properties set correctly."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user