mayaUSDImport crashes Maya when a mesh has authored normals and a dualQuaternion skinningMethod
- 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