Nodes/Melite Autorig Nodes/πŸ‘• Kimodo Transfer Weights (Clean β†’ Clothed)
ComfyUI Node

πŸ‘• Kimodo Transfer Weights (Clean β†’ Clothed)

Kimodo Transfer Weights moves skin weights onto the clothed mesh

By JayDataEngineerΒ·Created 2 months agoΒ·Updated 5 days agoΒ· 1
πŸ‘• Kimodo Transfer Weights (Clean β†’ Clothed)
    • output_path
    β—„rigged_pathβ–Ί
    β—„target_pathβ–Ί

    Auto-riggers work far better on a clean body than on a person wearing a coat. So the pipeline everyone lands on generates two meshes from the same depth/seed: a clean near-nude body that gets rigged, and a clothed one with hair and fabric that looks good but has no skeleton. This node is the hand-off between them.

    It copies the rig from the clean mesh onto the clothed mesh. Skeleton, joint hierarchy, inverse bind matrices, per-vertex skin weights - all of it. The clothed mesh inherits the clean mesh's rig and then deforms correctly when animated. There's no cloth simulation anywhere in this: the clothing is static geometry that rides along with the body's nearest bones.

    SOMA-rigged clean GLB ─┐
                           β”œβ”€β†’ KimodoTransferWeights β†’ clothed + rigged GLB
    clothed GLB (no rig) β”€β”€β”˜                                    β”‚
                                                                β–Ό
                                                   KimodoExportFBX (retarget)
    

    The mechanism, in one paragraph

    It reads both GLBs directly - no Blender, no subprocess - and does the whole job in the ComfyUI process. First it estimates a similarity transform between the two meshes using their axis-aligned bounding boxes: centres matched, one uniform scale factor (the mean of the per-axis size ratios). That's deliberately dumber than a Kabsch/Umeyama fit, and the source says why: AABB alignment never collapses when it's fed imperfect correspondences. For two meshes of the same body it's enough. Then torch.cdist does nearest-neighbour on the GPU in chunks, each clothed vertex takes the joints and weights of its nearest clean vertex, weights get renormalised, and the output GLB is assembled from the clothed geometry, textures and materials plus the clean armature. The bones and inverse bind matrices are transformed through that same alignment matrix, because otherwise the armature lives in a different space than the vertices and animation produces what the source cheerfully calls an "abomination".

    One nice detail the tooltips won't tell you: the output rebuilds the skeleton into the canonical Mixamo hierarchy. The upstream rig it inherits from nests bones wrongly and pads itself with Extra_XX bones that hold weight but never animate, so this pass restructures them.

    Cost: about ten seconds for 500K vertices on a 4090. On CPU it still runs, but the chunk size drops and you'll measure it in minutes.

    Inputs and output

    Two required inputs, both STRING sockets (forceInput), so you wire them rather than type them:

    • rigged_path - the CLEAN body that's already SOMA-rigged. It must have JOINTS_0/WEIGHTS_0 and an armature. This is the source of the rig.
    • target_path - the CLOTHED mesh: geometry and textures, no rig. It receives the rig from rigged_path.

    One output: output_path, a STRING at output/3D/KimodoClothed_<timestamp>.glb. Feed it into KimodoExportFBX for retargeting, or onward to whatever consumes a GLB path. Note the asymmetry - this node always writes GLB, no FBX option.

    Install

    cd /path/to/ComfyUI/custom_nodes
    git clone https://github.com/JayDataEngineer/melite-autorig-nodes.git
    

    Restart ComfyUI, or install via Manager by searching "melite". The pack's requirements.txt is just trimesh, scipy, requests - but this particular node also needs PyTorch, which you already have, and a CUDA device if you want it fast. No Blender, no model downloads, no API keys.

    Where people get burned

    Both meshes have to be the same body, in the same pose, at the same scale. That's the whole assumption, and it's an AABB one - if the clothed mesh is a chunk taller or includes hair that balloons the bounding box, the alignment scale is off and every nearest-neighbour lookup is slightly wrong. Clothing near the body takes the right bones. Loose sleeves and long hair, which are far from any clean-body vertex, tend to inherit the nearest body bone and then move rigidly with it.

    The other consequence worth internalising: nearest-vertex is not nearest-surface-along-the-skin. Regions where two body parts are close in space but far along the surface - armpits, inner thighs - can borrow a bone from the wrong limb. It's the same class of error that the pack's RayCleanWeights node exists to clean up, which is a decent hint about the right order of operations:

    SOMA-rigged clean GLB β†’ KimodoTransferWeights β†’ RayCleanWeights β†’ RaySyncSiblingWeights β†’ KimodoExportFBX
    

    And a boring one: paths resolve against absolute β†’ ComfyUI input/ β†’ output/ β†’ a recursive walk of output/. If you pass a filename that exists in an old output subfolder and nowhere else, it'll happily use the stale one.

    If your character's clothing needs to actually move like cloth - a skirt that swings, a cape that trails - you're in the wrong tool. This gives you a rigged, correctly deforming garment, not a simulated one.

    CategoryMelite/AutoRig

    Inputs (2)

    NameTypeDefaultDescription
    rigged_pathSTRINGPath to the CLEAN mesh that has already been SOMA-rigged (has JOINTS_0/WEIGHTS_0 + armature). The source of the rig + weights.
    target_pathSTRINGPath to the CLOTHED mesh (geometry + textures, no rig). Receives the rig from rigged_path.

    Outputs (1)

    NameTypeDescription
    output_pathSTRINGβ€”