Skip to content

Commit a21995c

Browse files
EMSUSD-2803 fix import of USD with an alembic reference
- Changed all calls to USD in `meshReadUtils.cpp` to pass `UsdTimeCode::EarliestTime()`. - Added an import unit test that failed without the fix and now passes.
1 parent 983f963 commit a21995c

5 files changed

Lines changed: 97 additions & 16 deletions

File tree

lib/mayaUsd/fileio/utils/meshReadUtils.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ MIntArray getMayaFaceVertexAssignmentIds(
238238
bool isPrimitiveLeftHanded(const UsdGeomMesh& mesh)
239239
{
240240
TfToken orientation;
241-
if (!mesh.GetOrientationAttr().Get(&orientation)) {
241+
if (!mesh.GetOrientationAttr().Get(&orientation, UsdTimeCode::EarliestTime())) {
242242
return false;
243243
}
244244

@@ -255,7 +255,7 @@ bool assignUVSetPrimvarToMesh(
255255
const TfToken& primvarName = primvar.GetPrimvarName();
256256

257257
VtVec2fArray uvValues;
258-
if (!primvar.Get(&uvValues) || uvValues.empty()) {
258+
if (!primvar.Get(&uvValues, UsdTimeCode::EarliestTime()) || uvValues.empty()) {
259259
TF_WARN(
260260
"Could not read UV values from primvar '%s' on mesh: %s",
261261
primvarName.GetText(),
@@ -329,7 +329,7 @@ bool assignUVSetPrimvarToMesh(
329329
}
330330

331331
VtIntArray assignmentIndices;
332-
if (primvar.GetIndices(&assignmentIndices)) {
332+
if (primvar.GetIndices(&assignmentIndices, UsdTimeCode::EarliestTime())) {
333333
if (unauthoredValuesIndex >= 0) {
334334
// Since the unauthored value was removed above, we need to fix up
335335
// the assignment indices to replace any index equal to the
@@ -419,23 +419,23 @@ bool assignColorSetPrimvarToMesh(
419419

420420
if (typeName == SdfValueTypeNames->FloatArray) {
421421
colorRep = MFnMesh::kAlpha;
422-
if (!primvar.Get(&alphaArray) || alphaArray.empty()) {
422+
if (!primvar.Get(&alphaArray, UsdTimeCode::EarliestTime()) || alphaArray.empty()) {
423423
status = MS::kFailure;
424424
} else {
425425
numValues = alphaArray.size();
426426
}
427427
} else if (
428428
typeName == SdfValueTypeNames->Float3Array || typeName == SdfValueTypeNames->Color3fArray) {
429429
colorRep = MFnMesh::kRGB;
430-
if (!primvar.Get(&rgbArray) || rgbArray.empty()) {
430+
if (!primvar.Get(&rgbArray, UsdTimeCode::EarliestTime()) || rgbArray.empty()) {
431431
status = MS::kFailure;
432432
} else {
433433
numValues = rgbArray.size();
434434
}
435435
} else if (
436436
typeName == SdfValueTypeNames->Float4Array || typeName == SdfValueTypeNames->Color4fArray) {
437437
colorRep = MFnMesh::kRGBA;
438-
if (!primvar.Get(&rgbaArray) || rgbaArray.empty()) {
438+
if (!primvar.Get(&rgbaArray, UsdTimeCode::EarliestTime()) || rgbaArray.empty()) {
439439
status = MS::kFailure;
440440
} else {
441441
numValues = rgbaArray.size();
@@ -460,7 +460,7 @@ bool assignColorSetPrimvarToMesh(
460460

461461
VtIntArray assignmentIndices;
462462
int unauthoredValuesIndex = -1;
463-
if (primvar.GetIndices(&assignmentIndices)) {
463+
if (primvar.GetIndices(&assignmentIndices, UsdTimeCode::EarliestTime())) {
464464
// The primvar IS indexed, so the indices array is what determines the
465465
// number of color values.
466466
numValues = assignmentIndices.size();
@@ -613,7 +613,7 @@ bool assignConstantPrimvarToMesh(const UsdGeomPrimvar& primvar, MFnMesh& meshFn)
613613
}
614614

615615
VtValue primvarData;
616-
primvar.Get(&primvarData);
616+
primvar.Get(&primvarData, UsdTimeCode::EarliestTime());
617617

618618
MStatus status { MS::kSuccess };
619619
MPlug plug = meshFn.findPlug(
@@ -769,7 +769,7 @@ void UsdMayaMeshReadUtils::assignInvisibleFaces(const UsdGeomMesh& mesh, const M
769769

770770
// Set Holes
771771
VtIntArray holeIndices;
772-
mesh.GetHoleIndicesAttr().Get(&holeIndices); // not animatable
772+
mesh.GetHoleIndicesAttr().Get(&holeIndices, UsdTimeCode::EarliestTime()); // not animatable
773773
if (!holeIndices.empty()) {
774774
MUintArray mayaHoleIndices;
775775
mayaHoleIndices.setLength(holeIndices.size());
@@ -813,8 +813,10 @@ MStatus UsdMayaMeshReadUtils::assignSubDivTagsToMesh(
813813
// Vert Creasing
814814
VtIntArray subdCornerIndices;
815815
VtFloatArray subdCornerSharpnesses;
816-
mesh.GetCornerIndicesAttr().Get(&subdCornerIndices); // not animatable
817-
mesh.GetCornerSharpnessesAttr().Get(&subdCornerSharpnesses); // not animatable
816+
mesh.GetCornerIndicesAttr().Get(
817+
&subdCornerIndices, UsdTimeCode::EarliestTime()); // not animatable
818+
mesh.GetCornerSharpnessesAttr().Get(
819+
&subdCornerSharpnesses, UsdTimeCode::EarliestTime()); // not animatable
818820
if (!subdCornerIndices.empty()) {
819821
if (subdCornerIndices.size() == subdCornerSharpnesses.size()) {
820822
statusOK.clear();
@@ -875,9 +877,9 @@ MStatus UsdMayaMeshReadUtils::assignSubDivTagsToMesh(
875877
VtIntArray subdCreaseLengths;
876878
VtIntArray subdCreaseIndices;
877879
VtFloatArray subdCreaseSharpnesses;
878-
mesh.GetCreaseLengthsAttr().Get(&subdCreaseLengths);
879-
mesh.GetCreaseIndicesAttr().Get(&subdCreaseIndices);
880-
mesh.GetCreaseSharpnessesAttr().Get(&subdCreaseSharpnesses);
880+
mesh.GetCreaseLengthsAttr().Get(&subdCreaseLengths, UsdTimeCode::EarliestTime());
881+
mesh.GetCreaseIndicesAttr().Get(&subdCreaseIndices, UsdTimeCode::EarliestTime());
882+
mesh.GetCreaseSharpnessesAttr().Get(&subdCreaseSharpnesses, UsdTimeCode::EarliestTime());
881883
if (!subdCreaseLengths.empty()) {
882884
if (subdCreaseLengths.size() == subdCreaseSharpnesses.size()) {
883885
MUintArray mayaCreaseEdgeIds;
@@ -1060,7 +1062,7 @@ MStatus UsdMayaMeshReadUtils::getComponentTags(
10601062
// Get the indices out of the subset
10611063
VtIntArray faceIndices;
10621064
UsdAttribute indicesAttribute = ss.GetIndicesAttr();
1063-
indicesAttribute.Get(&faceIndices);
1065+
indicesAttribute.Get(&faceIndices, UsdTimeCode::EarliestTime());
10641066

10651067
MFnSingleIndexedComponent compFn;
10661068
MObject faceComp = compFn.create(MFn::kMeshPolygonComponent, &status);
@@ -1079,7 +1081,7 @@ MStatus UsdMayaMeshReadUtils::getComponentTags(
10791081
JsObject subsetRoundtripData;
10801082

10811083
TfToken familyName;
1082-
ss.GetFamilyNameAttr().Get(&familyName);
1084+
ss.GetFamilyNameAttr().Get(&familyName, UsdTimeCode::EarliestTime());
10831085
if (familyName != UsdMayaGeomSubsetTokens->ComponentTagFamilyName) {
10841086
subsetRoundtripData[ss.GetFamilyNameAttr().GetBaseName()]
10851087
= JsValue(familyName.GetString());

test/lib/usd/translators/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ set(TEST_SCRIPT_FILES
8181
testUsdImportInstances.py
8282
testUsdImportLight.py
8383
testUsdImportMayaReference.py
84+
testUsdImportAlembicReference.py
8485
testUsdImportMesh.py
8586
testUsdImportPointCache.py
8687
testUsdImportPreviewSurface.py
4.28 KB
Binary file not shown.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#usda 1.0
2+
(
3+
defaultPrim = "root"
4+
metersPerUnit = 0.01
5+
upAxis = "Y"
6+
)
7+
8+
def Xform "root" (
9+
prepend apiSchemas = ["GeomModelAPI"]
10+
)
11+
{
12+
def Mesh "refer" (
13+
prepend references = @./cone.abc@
14+
)
15+
{
16+
}
17+
}
18+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env mayapy
2+
#
3+
# Copyright 2026 Autodesk
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
from pxr import UsdGeom
19+
20+
import mayaUsd.lib as mayaUsdLib
21+
22+
from maya import cmds
23+
from maya import standalone
24+
25+
import os
26+
import unittest
27+
28+
import fixturesUtils
29+
30+
class testUsdImportAlembicReference(unittest.TestCase):
31+
32+
@classmethod
33+
def setUpClass(cls):
34+
inputPath = fixturesUtils.readOnlySetUpClass(__file__)
35+
36+
usdFile = os.path.join(inputPath, "UsdImportAlembicReferenceTest", "referencing-cone.usda")
37+
cmds.usdImport(file=usdFile, shadingMode=[['none', 'default'], ])
38+
39+
@classmethod
40+
def tearDownClass(cls):
41+
standalone.uninitialize()
42+
43+
def verifyUVSet(self, mesh):
44+
self.assertTrue(cmds.objExists(mesh))
45+
self.assertEqual(cmds.getAttr(mesh + ".uvSet", size=True), 1)
46+
self.assertEqual(cmds.getAttr(mesh + ".uvSet[0].uvSetName"), "st")
47+
self.assertEqual(cmds.getAttr(mesh + ".uvSet[0].uvSetPoints", size=True), 42)
48+
self.assertAlmostEqual(cmds.getAttr(mesh + ".uvSet[0].uvSetPoints[0]")[0][0], 0.73776429, places=6)
49+
self.assertAlmostEqual(cmds.getAttr(mesh + ".uvSet[0].uvSetPoints[0]")[0][1], 0.1727457, places=6)
50+
self.assertAlmostEqual(cmds.getAttr(mesh + ".uvSet[0].uvSetPoints[1]")[0][0], 0.70225441, places=6)
51+
self.assertAlmostEqual(cmds.getAttr(mesh + ".uvSet[0].uvSetPoints[1]")[0][1], 0.103053599, places=6)
52+
self.assertAlmostEqual(cmds.getAttr(mesh + ".uvSet[0].uvSetPoints[41]")[0][0], 0.5, places=6)
53+
self.assertAlmostEqual(cmds.getAttr(mesh + ".uvSet[0].uvSetPoints[41]")[0][1], 1.0, places=6)
54+
55+
def testImportPoly(self):
56+
self.verifyUVSet('refer')
57+
58+
59+
if __name__ == '__main__':
60+
unittest.main(verbosity=2)

0 commit comments

Comments
 (0)