diff --git a/pxr/usd/plugin/usdAbc/CMakeLists.txt b/pxr/usd/plugin/usdAbc/CMakeLists.txt index f5923e2db5..ff5f9af4a5 100644 --- a/pxr/usd/plugin/usdAbc/CMakeLists.txt +++ b/pxr/usd/plugin/usdAbc/CMakeLists.txt @@ -129,6 +129,11 @@ pxr_install_test_dir( DEST testUsdAbcIndexedGeomArb ) +pxr_install_test_dir( + SRC testenv/testUsdAbcIndexedGeomArbLoad + DEST testUsdAbcIndexedGeomArbLoad +) + pxr_install_test_dir( SRC testenv/testUsdAbcInstancing DEST testUsdAbcInstancing @@ -234,6 +239,14 @@ pxr_register_test(testUsdAbcIndexedGeomArb USD_ABC_TESTSUFFIX=def ) +pxr_register_test(testUsdAbcIndexedGeomArbLoad + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/usdcat test_indexed_primvar.abc --out good_indexed_primvar.usda" + DIFF_COMPARE good_custom_indexed_primvar.usda + EXPECTED_RETURN_CODE 0 + ENV + USD_ABC_TESTSUFFIX=def +) + pxr_register_test(testUsdAbcInstancing PYTHON COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testUsdAbcInstancing" diff --git a/pxr/usd/plugin/usdAbc/alembicReader.cpp b/pxr/usd/plugin/usdAbc/alembicReader.cpp index 7f3d28ce3c..7412e518db 100644 --- a/pxr/usd/plugin/usdAbc/alembicReader.cpp +++ b/pxr/usd/plugin/usdAbc/alembicReader.cpp @@ -2987,15 +2987,6 @@ _ReadGprim(_PrimReaderContext* context) context->Extract(GeomBaseSchemaInfo::defaultName()); } -static -void -_ReadArbGeomParams(_PrimReaderContext* context) -{ - // Add primvars. - context->AddOutOfSchemaProperty( - UsdAbcPropertyNames->primvars, context->ExtractSchema(".arbGeomParams")); -} - static void _ReadUserProperties(_PrimReaderContext* context) @@ -3067,6 +3058,137 @@ _ReadProperty(_PrimReaderContext* context, const char* name, TfToken propName, S } } +template +void +_ReadProperty( + _PrimReaderContext* context, + const AlembicProperty &prop, + const TfToken propName, + const SdfValueTypeName typeName) +{ + if (prop.Cast().isIndexed()) { + context->AddProperty( + propName, + typeName, + _CopyGeneric(prop)); + context->AddProperty( + TfToken(SdfPath::JoinIdentifier(propName, UsdGeomTokens->indices)), + SdfValueTypeNames->IntArray, + _CopyIndices(prop)); + } else { + context->AddProperty( + propName, + typeName, + _CopyGeneric(prop)); + } +} + +static +void +_AddArbGeomProperty( + _PrimReaderContext *context, + const TfToken& propName, + const AlembicProperty& property) +{ + if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->FloatArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->DoubleArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->Vector3dArray); + } + else if(property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->StringArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->TexCoord2fArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->Vector3fArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->Color3fArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->Color4fArray); + } + else if(property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->Normal3fArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->Point3fArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->BoolArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->QuatfArray); + } + else if (property.Cast().valid()) { + _ReadProperty( + context, property, propName, SdfValueTypeNames->QuatdArray); + } +} + +static +void +_ReadArbGeomParams(_PrimReaderContext* context) +{ + // Get property info. + std::string name(UsdAbcPropertyNames->primvars); + AlembicProperty& property = context->ExtractSchema(".arbGeomParams"); + const PropertyHeader* header = property.GetHeader(); + if (!header) { + // No such property. + return; + } + + // .ArbGeomParams is a compound + if (!header->isCompound()) { + return; + } + + ICompoundProperty compound = property.Cast(); + + // Fill usedNames. + std::set usedNames; + for (size_t i = 0, n = compound.getNumProperties(); i != n; ++i) { + usedNames.insert(compound.getPropertyHeader(i).getName()); + } + + // Add each geom property + for (size_t i = 0, n = compound.getNumProperties(); i != n; ++i) { + const std::string rawName = + compound.getPropertyHeader(i).getName(); + const std::string cleanName = + _CleanName(rawName, " .", usedNames, + _AlembicFixName(), + &SdfPath::IsValidIdentifier); + const TfToken namespacedName = + TfToken(SdfPath::JoinIdentifier(name, cleanName)); + const SdfPath childPath = context->GetPath().AppendProperty(namespacedName); + + _AddArbGeomProperty( + context, + namespacedName, + AlembicProperty(childPath, rawName, compound)); + } +} + static void _ReadOrientation(_PrimReaderContext* context) diff --git a/pxr/usd/plugin/usdAbc/testenv/testUsdAbcIndexedGeomArbLoad/baseline/good_indexed_primvar.usda b/pxr/usd/plugin/usdAbc/testenv/testUsdAbcIndexedGeomArbLoad/baseline/good_indexed_primvar.usda new file mode 100644 index 0000000000..c9887e98fc --- /dev/null +++ b/pxr/usd/plugin/usdAbc/testenv/testUsdAbcIndexedGeomArbLoad/baseline/good_indexed_primvar.usda @@ -0,0 +1,63 @@ +#usda 1.0 +( + defaultPrim = "cube" + endTimeCode = 1.0000000298 + startTimeCode = 0 + upAxis = "Y" +) + +def Mesh "cube" +{ + float3[] extent.timeSamples = { + 1.0000000298: [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)], + } + int[] faceVertexCounts.timeSamples = { + 1.0000000298: [4, 4, 4, 4, 4, 4], + } + int[] faceVertexIndices.timeSamples = { + 1.0000000298: [0, 1, 2, 3, 4, 5, 2, 1, 6, 7, 5, 4, 0, 3, 7, 6, 5, 7, 3, 2, 6, 4, 1, 0], + } + normal3f[] normals ( + interpolation = "faceVarying" + ) + normal3f[] normals.timeSamples = { + 1.0000000298: [(0, 0, -1), (0, 0, -1), (0, 0, -1), (0, 0, -1), (1, 0, 0), (1, 0, 0), (1, 0, 0), (1, 0, 0), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (-1, 0, 0), (-1, 0, 0), (-1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0), (0, -1, 0), (0, -1, 0), (0, -1, 0), (0, -1, 0)], + } + uniform token orientation = "leftHanded" + point3f[] points ( + interpolation = "vertex" + ) + point3f[] points.timeSamples = { + 1.0000000298: [(-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, 0.5)], + } + point3f[] primvars:custom ( + interpolation = "faceVarying" + ) + point3f[] primvars:custom.timeSamples = { + 0: [(0, 0, 1), (0, 0, -1), (0, 1, 0), (0, -1, 0), (1, 0, 0), (-1, 0, 0)], + } + int[] primvars:custom:indices ( + interpolation = "faceVarying" + ) + int[] primvars:custom:indices.timeSamples = { + 0: [1, 1, 1, 1, 4, 4, 4, 4, 0, 0, 0, 0, 5, 5, 5, 5, 2, 2, 2, 2, 3, 3, 3, 3], + } + texCoord2f[] primvars:st ( + interpolation = "faceVarying" + ) + texCoord2f[] primvars:st.timeSamples = { + 1.0000000298: [(0.375, 0), (0.625, 0), (0.375, 0.25), (0.625, 0.25), (0.375, 0.5), (0.625, 0.5), (0.375, 0.75), (0.625, 0.75), (0.375, 1), (0.625, 1), (0.125, 0), (0.875, 0), (0.125, 0.25), (0.875, 0.25)], + } + int[] primvars:st:indices ( + interpolation = "faceVarying" + ) + int[] primvars:st:indices.timeSamples = { + 1.0000000298: [6, 7, 5, 4, 1, 3, 13, 11, 0, 2, 3, 1, 10, 12, 2, 0, 3, 2, 4, 5, 8, 9, 7, 6], + } + uniform token subdivisionScheme = "none" + matrix4d xformOp:transform.timeSamples = { + 1.0000000298: ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ), + } + uniform token[] xformOpOrder = ["xformOp:transform"] +} + diff --git a/pxr/usd/plugin/usdAbc/testenv/testUsdAbcIndexedGeomArbLoad/test_indexed_primvar.abc b/pxr/usd/plugin/usdAbc/testenv/testUsdAbcIndexedGeomArbLoad/test_indexed_primvar.abc new file mode 100644 index 0000000000..0fb9e99404 Binary files /dev/null and b/pxr/usd/plugin/usdAbc/testenv/testUsdAbcIndexedGeomArbLoad/test_indexed_primvar.abc differ