Autodesk / Autodesk/3dsmax-usd
Broken mesh and absent skeleton if not modeled under a common parent
- Dominant language
- C++
- Stars
- 94
- Forks
- 6
- Avg merge
- 6d 20h
- Merged PRs (30d)
- 1
Description
**Describe the bug**
If a Mesh is skinned but its Skeleton is not placed under a common parent:
- the Skeleton is not exported
- the export Mesh is broken (as it does not have any properties beyond its transform
**Steps to reproduce**
The scene attached to this issues contains three elements:
- `SkinnedMeshRoot` contains a skeleton and a skinned mesh
- `JustASkeletonRoot` contains a skeleton, without a mesh
- `BoxC` is skinned by the Skeleton `BottomC/MiddleC/TopC`, but they don't have a common parent.
When exported with these options:
Then:
- OK: `SkinnedMeshRoot` is exported as expected: a Mesh and Skel nested under a SkelRoot
- OK: `JustASkeletonRoot` is exported as expected: a Skel under a Skelroot
- PROBLEM: `BoxC` is only exported as a transform and does not contain other properties
- PROBLEM: `BottomC/MiddleC/TopC` is not exported at all
**Expected behavior**
First, the mesh should not be broken.
Second, I think that we should export both the Mesh and the Skeleton **without a SkelRoot**. The SkelRoot itself does not have properties that are authored to represent the skinning of the mesh. SkelRoot are "only" needed when the USD is consumed down the line by something that needs the skinning operation to be **computed**, but not **represented**. By requiring a top level 3ds Max node, we force an uneeded scene structure convention: we might want to export just a Skeleton from a scene, without a SkelRoot, to be assembled later by another process down the pipeline.
It's actually a very common workflow for our gaming pipeline, where the assembly is not even done in USD but by the game engine itself: we just need to transfer a Skeleton and a skinned Mesh.
For new scenes, it would be possible to always create this common toplevel node. The problem we're facing is with current production scenes: it forces us to adapt our export scripts to temporarily reparent the objects to be exported under a common node, export, then de-parent the exported objects and deal with an USD structure that does not match the 3ds Max original scene structure.
I think the right way would be for 3ds Max to:
- export the most top-level node as a `SkelRoot` to indicate that this stage subtree is Skinned
- just not have a `SkelRoot` if there is no top level node
In the example below:
- `b` will become a `SkelRoot`, because the subtree below has skinned prims
- `Mesh003` and `Skel003` do not have a `SkelRoot` ancestor, and that's exactly the intent
```
.
├── a/
│ └── b/
│ ├── Mesh001 (skinned by Skel001)
│ ├── d/
│ │ └── Skel001
│ └── e/
│ ├── Mesh002 (skinned by Skel002)
│ └── Skel002
├── Mesh003 (Skinned by Skel003)
└── Skel003
```
**Attachments**
[test-no-skelroot.zip](https://github.com/user-attachments/files/30104114/test-no-skelroot.zip)
Contains:
- `test-no-skelroot.max`, the sample scene above
- `test-no-skelroot.usda`, the full exported usda
**Specs (if applicable):**
- 3ds Max version: 2024.2.11
- 3ds USD version: 0.15.0.14
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the attached test-no-skelroot.max scene and compare its exported test-no-skelroot.usda, focusing on handling of skinned meshes and skeletons without a common parent. Reproduce the BoxC and BottomC/MiddleC/TopC cases, then verify that the mesh retains its properties and the skeleton exports without requiring a common SkelRoot.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-graphics, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100