Skip to content

Commit

Permalink
usdAbc: Correctly interpret arbGeomParams from Alembic files
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Fuller committed Dec 20, 2024
1 parent 270278a commit 9bfdac1
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 9 deletions.
13 changes: 13 additions & 0 deletions pxr/usd/plugin/usdAbc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down
140 changes: 131 additions & 9 deletions pxr/usd/plugin/usdAbc/alembicReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -3067,6 +3058,137 @@ _ReadProperty(_PrimReaderContext* context, const char* name, TfToken propName, S
}
}

template<class T, class UsdValueType>
void
_ReadProperty(
_PrimReaderContext* context,
const AlembicProperty &prop,
const TfToken propName,
const SdfValueTypeName typeName)
{
if (prop.Cast<T>().isIndexed()) {
context->AddProperty(
propName,
typeName,
_CopyGeneric<T, UsdValueType, false>(prop));
context->AddProperty(
TfToken(SdfPath::JoinIdentifier(propName, UsdGeomTokens->indices)),
SdfValueTypeNames->IntArray,
_CopyIndices<T>(prop));
} else {
context->AddProperty(
propName,
typeName,
_CopyGeneric<T, UsdValueType>(prop));
}
}

static
void
_AddArbGeomProperty(
_PrimReaderContext *context,
const TfToken& propName,
const AlembicProperty& property)
{
if (property.Cast<IFloatGeomParam>().valid()) {
_ReadProperty<IFloatGeomParam, float>(
context, property, propName, SdfValueTypeNames->FloatArray);
}
else if (property.Cast<IDoubleGeomParam>().valid()) {
_ReadProperty<IDoubleGeomParam, double>(
context, property, propName, SdfValueTypeNames->DoubleArray);
}
else if (property.Cast<IV3dGeomParam>().valid()) {
_ReadProperty<IV3dGeomParam, GfVec3d>(
context, property, propName, SdfValueTypeNames->Vector3dArray);
}
else if(property.Cast<IStringGeomParam>().valid()) {
_ReadProperty<IStringGeomParam, std::string>(
context, property, propName, SdfValueTypeNames->StringArray);
}
else if (property.Cast<IV2fGeomParam>().valid()) {
_ReadProperty<IV2fGeomParam, GfVec2f>(
context, property, propName, SdfValueTypeNames->TexCoord2fArray);
}
else if (property.Cast<IV3fGeomParam>().valid()) {
_ReadProperty<IV3fGeomParam, GfVec3f>(
context, property, propName, SdfValueTypeNames->Vector3fArray);
}
else if (property.Cast<IC3fGeomParam>().valid()) {
_ReadProperty<IC3fGeomParam, GfVec3f>(
context, property, propName, SdfValueTypeNames->Color3fArray);
}
else if (property.Cast<IC4fGeomParam>().valid()) {
_ReadProperty<IC4fGeomParam, GfVec4f>(
context, property, propName, SdfValueTypeNames->Color4fArray);
}
else if(property.Cast<IN3fGeomParam>().valid()) {
_ReadProperty<IN3fGeomParam, GfVec3f>(
context, property, propName, SdfValueTypeNames->Normal3fArray);
}
else if (property.Cast<IP3fGeomParam>().valid()) {
_ReadProperty<IP3fGeomParam, GfVec3f>(
context, property, propName, SdfValueTypeNames->Point3fArray);
}
else if (property.Cast<IBoolGeomParam>().valid()) {
_ReadProperty<IBoolGeomParam, bool>(
context, property, propName, SdfValueTypeNames->BoolArray);
}
else if (property.Cast<IQuatfGeomParam>().valid()) {
_ReadProperty<IQuatfGeomParam, GfQuatf>(
context, property, propName, SdfValueTypeNames->QuatfArray);
}
else if (property.Cast<IQuatdGeomParam>().valid()) {
_ReadProperty<IQuatdGeomParam, GfQuatd>(
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<ICompoundProperty>();

// Fill usedNames.
std::set<std::string> 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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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"]
}

Binary file not shown.

0 comments on commit 9bfdac1

Please sign in to comment.