Autodesk / Autodesk/maya-usd

mayaUSDImport crashes Maya when a mesh has authored normals and a dualQuaternion skinningMethod

Open
#4,663 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Wolfram Language
Stars
905
Forks
223
Avg merge
2d 9h
Merged PRs (30d)
17

Description

### Summary

`mayaUSDImport` hard-crashes Maya when the imported layer carries **authored `normals`** together with a **`primvars:skel:skinningMethod = dualQuaternion`** binding. Both halves are required: a linear skin with normals imports fine, and a dual-quaternion skin whose normals were removed imports fine.

The crash is easy to miss because `mayaUSDExport` only authors normals when the mesh is written as polygonal (`defaultMeshScheme="none"`); with the default `catmullClark` scheme USD ignores normals, none are authored, and the same rig round-trips cleanly. Rigging exports are polygonal, so this is on the common path for character work.

The script below was run on **Maya 2025.3.2 (mayaUsd 0.32.0 / USD 23.11), Maya 2026 (0.34.0 / USD 24.11) and Maya 2027 (0.35.0 / USD 25.11)** on macOS 26.5 (Apple Silicon): all three terminate. It happens in a clean session, with no other plug-in or Python module involved.

### Steps to reproduce

Run in the Script Editor of a freshly opened Maya (it crashes on the last line):

```python
from maya import cmds
import tempfile

cmds.loadPlugin("mayaUsdPlugin", quiet=True)
cmds.file(new=True, force=True)

names = ("root", "spine", "chest", "shoulder", "elbow", "wrist")
grp = cmds.group(empty=True, name="rig")
cmds.select(clear=True)
joints = [cmds.joint(name=n, position=(0.0, float(i), 0.0))
for i, n in enumerate(names)]
cmds.parent(joints[0], grp)

mesh = cmds.polySphere(name="body", subdivisionsX=8, subdivisionsY=6)[0]
cmds.parent(mesh, grp)
skin = cmds.skinCluster(*joints, mesh, toSelectedBones=True)[0]
cmds.setAttr(skin + ".skinningMethod", 1) # dual quaternion

path = tempfile.mkdtemp() + "/dq.usda"
cmds.mayaUSDExport(file=path, exportSkels="auto", exportSkin="auto",
defaultMeshScheme="none") # polygonal: normals ARE authored

cmds.file(new=True, force=True)
cmds.mayaUSDImport(file=path) # <-- Maya crashes here
```

**Expected:** the mesh is imported and bound to a skinCluster with `skinningMethod = 1`.
**Actual:** Maya terminates. This warning is always printed immediately before the crash:

```
// Warning: Cycle on 'skinCluster_body.outputGeometry[0]' may not evaluate as expected.
```

### Isolation

Editing the very same exported layer with `pxr` before importing it shows that both ingredients are necessary — either edit makes the import succeed:

| Layer content | Import result |
| --- | --- |
| dualQuaternion + authored `normals` (as exported) | **crash** |
| dualQuaternion, `normals` property removed | OK — `skinningMethod = 1` restored |
| `normals` kept, `skinningMethod` set to `classicLinear` | OK |
| exported with the default `catmullClark` scheme (no normals authored) | OK — `skinningMethod = 1` restored |

Removing the `subdivisionScheme` difference alone is *not* enough: setting `subdivisionScheme = "catmullClark"` on a layer that still carries authored `normals` still crashes. The mesh scheme only matters because it decides whether normals get authored.

### Stack

From the macOS microstackshot report captured during the crash (`/Library/Logs/DiagnosticReports/Maya_*.cpu_resource.diag`), the import triggers a DG evaluation of the still half-connected network, and the skinCluster dies in the dual-quaternion normal path:

```
mayaUSDImport
MFnMesh::MFnMesh(MObject const&, MStatus*)
MFnBase::setObject(MObject const&)
MFnMesh::objectChanged(...)
TmeshShape::inMeshData() const
TdataBlockDG::value(Tattribute const&)
Tplug::evaluateValue(...)
TdependNode::dbEvaluate(TmsgEval&)
TDNskinCluster::computePlug(Tplug const&, TdataBlock&)
TdnGeometryFilter::computePlug(Tplug const&, TdataBlock&)
TDNskinCluster::deformGeom(...)
TDNskinCluster::deformNormalsQuat(T4dDblMatrix const&, T3dFltVectorArray&, float, maya_zamboni::DeformCache*)
libtbb.12.14.dylib
_sigtramp
```

`deformNormalsQuat` runs only for dual-quaternion skinning, which matches the observed conjunction: linear skins never reach it, and with no authored normals there is nothing for it to deform during the import.

### Workaround

Strip the `normals` property from the skinned meshes of the exported layer before importing. Normals of a skinned mesh are derived data (Maya recomputes them from the deformed geometry), so nothing is lost:

```python
from pxr import Usd

stage = Usd.Stage.Open(path)
for prim in stage.Traverse():
prim.RemoveProperty("normals")
stage.Save()
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Run the provided Maya Script Editor reproduction with mayaUsdImport and mayaUSDExport, then compare the authored-normals and dualQuaternion cases described in the isolation table. Trace the import-time evaluation around the reported MFnMesh, TmeshShape, and skinCluster deformNormalsQuat stack; done means the dual-quaternion mesh imports without a crash and retains skinningMethod = 1.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.