Skip to content

[EMSUSD-3926] Exporting skinned mesh with hidden bones creates mismatched skel:joints list and invalid jointIndices #39

Open

Description

@charlesfleche

Describe the bug

When exporting a mesh skinned to hidden bones, joint weights indices are still exported but the joints attribute do not have the hidden bones, making the indices invalid.

In the example below:

  • In the skeleton chain BoneA, BoneA/BoneB and BoneA/BoneC...
  • ...BoneA does not skin any vertex
  • ...BoneB and BoneC skin different vertices
  • ...BoneB and BoneC are hidden
Image

When exporting to USD without the Hidden Objects options:

Image

then the exported USD does not export hidden bones, but still exports joints attributes with invalid indices.

Image

Steps to reproduce
Steps to reproduce the behavior:

  1. Open the attached scene
  2. Export USD
  3. Do not select the Hidden Objects
  4. Export

Expected behavior

Not sure what the right behavior should be:

  1. still export skel:joints even if hidden
  2. or export primvars:skel:* as an empty list [] to be consistent with the skel:joints = []

Attachments

Script to recreate the scene:

/*
    recreate_issue39_scene.ms

    Rebuilds the scene from GitHub issue Autodesk/3dsmax-usd#39:
    a skinned mesh whose *deforming* bones are hidden.

    Hierarchy that gets created:

        SkelRootNode                 (Point helper, visible)
        |-- BoneA                    (bone, VISIBLE, NOT skinned)
        |   |-- BoneB                (bone, HIDDEN, skins the left/red half)
        |   +-- BoneC                (bone, HIDDEN, skins the right/white half)
        +-- SkinMesh                 (Editable Mesh + Skin bound to BoneB, BoneC)

    The point of the repro: BoneB and BoneC are hidden but drive the Skin
    modifier. Exporting with "Hidden Objects" OFF used to drop them from
    skel:joints while jointIndices still referenced them (issue #39).

    Run: MAXScript > Run Script, or drag into a viewport.
*/

(
resetMaxFile #noPrompt
units.SystemType = #Centimeters

-- --- geometry constants --------------------------------------------------
local meshLen    = 120.0   -- length along X
local meshWidth  = 24.0    -- width along Y
local meshThick  = 1.5     -- thickness along Z
local widthSegs  = 24      -- segments along X so the weight gradient is smooth
local halfLen    = meshLen / 2.0

-- --- root helper -----------------------------------------------------------
local skelRoot = Point name:"SkelRootNode" pos:[0,0,0] \
    size:30 box:true cross:true axistripod:false centermarker:false wirecolor:(color 180 180 180)

-- --- bones -----------------------------------------------------------------
-- BoneA: vertical, pointing straight down from the mesh centre. Visible,
--        acts as the parent / root joint but is NOT part of the skin.
local boneA = BoneSys.createBone [0,0,0] [0,0,-45] [0,1,0]
boneA.name   = "BoneA"
boneA.width  = 12.0
boneA.height = 12.0
boneA.wirecolor = color 226 200 96

-- BoneB: runs from centre out to the left (-X). Skins the left (red) half.
local boneB = BoneSys.createBone [0,0,0] [-halfLen,0,0] [0,0,1]
boneB.name   = "BoneB"
boneB.width  = 8.0
boneB.height = 8.0

-- BoneC: runs from centre out to the right (+X). Skins the right (white) half.
local boneC = BoneSys.createBone [0,0,0] [halfLen,0,0] [0,0,1]
boneC.name   = "BoneC"
boneC.width  = 8.0
boneC.height = 8.0

-- --- parenting (world transforms are preserved) ---------------------------
boneA.parent = skelRoot
boneB.parent = boneA
boneC.parent = boneA

-- --- mesh ------------------------------------------------------------------
-- Long thin strip centred on the origin, extended along X.
local skinMesh = Box name:"SkinMesh" length:meshWidth width:meshLen height:meshThick \
    lengthsegs:1 widthsegs:widthSegs heightsegs:1 pos:[0,0,(-meshThick/2.0)]
convertToMesh skinMesh                 -- collapse to "Editable Mesh"
skinMesh.parent = skelRoot

-- --- skin ------------------------------------------------------------------
local skinMod = Skin()
addModifier skinMesh skinMod

-- Add ONLY the deforming bones (BoneB, BoneC). BoneA is intentionally left out.
select skinMesh
max modify mode
modPanel.setCurrentObject skinMod node:skinMesh
skinOps.addBone skinMod boneB 1        -- bone index 1
skinOps.addBone skinMod boneC 1        -- bone index 2

-- Paint an explicit red->white gradient along X:
--   left  end (x = -halfLen) -> fully BoneB
--   right end (x = +halfLen) -> fully BoneC
local numVerts = skinMesh.mesh.numverts
for v = 1 to numVerts do
(
    local p  = getVert skinMesh.mesh v            -- object space ~= world (mesh at origin)
    local t  = (p.x + halfLen) / meshLen          -- 0 at left, 1 at right
    t = amin (amax t 0.0) 1.0
    local wB = 1.0 - t
    local wC = t
    skinOps.replaceVertexWeights skinMod v #(1, 2) #(wB, wC) node:skinMesh
)

-- --- visibility: hide the two deforming bones -----------------------------
boneB.isHidden = true
boneC.isHidden = true
-- BoneA, SkinMesh, SkelRootNode stay visible.

-- --- leave it looking like the screenshot ---------------------------------
select skinMesh
max modify mode
modPanel.setCurrentObject skinMod node:skinMesh
try ( subobjectLevel = 1 ) catch ()   -- enter Skin > Edit Envelopes (cosmetic)

format "Issue #39 repro scene created: SkelRootNode / BoneA / (hidden BoneB, BoneC) / SkinMesh\n"
)

Specs (if applicable):

  • OS & version : Microsoft Windows 11 Entreprise 10.0.26100 Build 26100
  • 3ds Max version: 2024.2.11 Security Fix, 26.0 - 26.2.11.20199
  • USD for 3ds Max 2024: 0.15.0.14

Activity

  1. antonkhelou commented on Jul 8, 2026

    @antonkhelou
    Collaborator

    Hey @charlesfleche, thanks for the detailed ticket submission. We're going to have a look at it internally and get back to you soon.

  2. changed the title [-]Exporting skinned mesh with hidden bones creates mismatched skel:joints list and invalid jointIndices[/-] [+][EMSUSD-3926] Exporting skinned mesh with hidden bones creates mismatched skel:joints list and invalid jointIndices[/+] on Jul 23, 2026
  3. charlesfleche commented on Aug 28, 2026

    @charlesfleche
    ContributorAuthor

    I fixed the repro script, it was wrong, I probably fumbled a copy / paste.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions