From 7de3d8d5f9de4d72425c2706d6f3e2c86dbd3de0 Mon Sep 17 00:00:00 2001 From: Alex Fuller Date: Fri, 20 Dec 2024 11:26:58 +1100 Subject: [PATCH] usdAbc: Correctly interpret arbGeomParams from Alembic files --- pxr/usd/plugin/usdAbc/CMakeLists.txt | 13 ++ pxr/usd/plugin/usdAbc/alembicReader.cpp | 140 ++++++++++++++++-- .../baseline/good_indexed_primvar.usda | 63 ++++++++ .../test_indexed_primvar.abc | Bin 0 -> 3128 bytes 4 files changed, 207 insertions(+), 9 deletions(-) create mode 100644 pxr/usd/plugin/usdAbc/testenv/testUsdAbcIndexedGeomArbLoad/baseline/good_indexed_primvar.usda create mode 100644 pxr/usd/plugin/usdAbc/testenv/testUsdAbcIndexedGeomArbLoad/test_indexed_primvar.abc diff --git a/pxr/usd/plugin/usdAbc/CMakeLists.txt b/pxr/usd/plugin/usdAbc/CMakeLists.txt index f5923e2db5..92bd25fa75 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_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 0000000000000000000000000000000000000000..0fb9e99404c8a8e1e731e3a860856ed965a5816f GIT binary patch literal 3128 zcmb_eeQXp}5PydhXv;3bM1cc}@CR_++uOEF?rzWBy`v=( z*C5b93=qN}pa!jC2!9wsgJ~4RCW<72iGc7AC`1Uv@L@Ds69H%T&0Ef^Rg6wDnK!@p z-pst;ytmm!t;$;E9`muG%$0%M{AnDT%2+Mob(4=?xmn+{>d>s;_Gptt}T!(v6%DG|BZtQyPv9Y_#zMS^WXLs)OewE+L{INsp zzukFY{ivpWTh7gW#&>tKe;8xOX7ect&jo_M1ByOccOJ&>JXrK=$w!O6Lq1vtK1wr= zQE(m>Fh&`3*WR#w<*9WWTZcD%-`cs>x1HmxxTq@gUiXHUF{39ud95eX&EebP z5VWd4^Z&0C1v_swo;`Z;#MI)|n`d3Q{z}*{PE1TXRFWfbx*{Gvo)&b?9LapXA~~ld zttAuSCi#ZQdOD%2nuX+{#F0Ia`DE8|>xCY|7dq}D=%z?X0}uC7PLcj8OKVT|FjV#eocMk=b9N(vx}4anvggGMjJ2Y}K}$(zZ}BkL#oGue@3U#CV4#TN-Z zmR!TwxYF^Pj+Ce)c1;f-XCE#x-86upS|jW}RzEcLOJ=D()wg@>O))gU)&Hm((S?@aVu zT`>5_*68K73qAEqU#?_tPdojC`Tp|7hv%Cm`^ERA4_l%=QOdldprQkW`^h%b{3fa( zrs%P{q?U^7>T{ZD=|(z2t`v}~_&?6qJJgV1*P2ge$AU{uxuM-QAf? zQdbolw>B82t+h)5zg#I#mxJ#7Q;MxEheq03I?~jZbt46;q(DVDR2i4x-EHG(I` zZr9u&L;qp^o-2D_B)oaqvVAr5yuLQAt+omiH1PwwcwcGe&~;hj6@5Nx}A{q1d5d%>Ebgb8xi`$l8DWVBh$wAH4pI z0SEfK@PASMr~(e+M*HI)M>)H_kRvxo#8TU|loF|nt4LKWY9u=rXjWS+7pUe_^@^o6 zbpXv`39dsBmbCn*-IQQad`**XC+{c7t0C-uwH_`=vjSgfEEk&H58hv3u`kTuIseAt ar`Z(;K0zo>551zx^olb0(*pQ@vVQ