Examples

The plugin ships with sample files in advBlendshapeTools/examples/ to let you test the main workflows without needing your own data.

Examples

File

Description

base_mesh.obj

Base mesh with matching topology to example.deltas

example.deltas

Pre-exported blendshape data for base_mesh.obj

lod_mesh.obj

Lower-resolution mesh with similar UVs

example.bweights

Pre-painted deformer mask and target paint weights for base_mesh

example.components

Named vertex sets (eyes, mouth, neck) captured on base_mesh

Example 1: Import onto a matching mesh (Index)

base_mesh.obj and example.deltas share the same vertex count and order, making them ideal for exact methods.

Steps (UI)

  1. File I/O tab → set Import Mesh to base_mesh and Import File to example.deltas

  2. Set method to Index

  3. Click Import Blendshape

Python example

import maya.cmds as cmds
from pathlib import Path
import advBlendshapeTools

EXAMPLES = Path(advBlendshapeTools.__file__).parent / 'examples'
cmds.file(str(EXAMPLES / 'base_mesh.obj'), i=True, type='OBJ')

cmds.loadPlugin('advBlendshapeTools', quiet=True)
from advBlendshapeTools.api.commands import find_or_create_blendshape
new_blendshape = cmds.advBlendshapeImport(
    blendshape=find_or_create_blendshape('base_mesh'),
    inputFile=str(EXAMPLES / 'example.deltas'),
    method='index',
)
cmds.viewFit()

Example 2: Transfer to a different-topology mesh (UV)

lod_mesh.obj has fewer vertices than base_mesh but shares the same UV layout, so UV-based interpolation produces clean results.

Steps (UI)

  1. First complete Example 1 so a blendshape node exists on base_mesh

  2. Transfer tab → set Source Blendshape to the blendshape on base_mesh

  3. Add lod_mesh to the target list

  4. Set method to UV

  5. Click Transfer Blendshape

Python example

import maya.cmds as cmds
from pathlib import Path
import advBlendshapeTools

EXAMPLES = Path(advBlendshapeTools.__file__).parent / 'examples'
cmds.file(str(EXAMPLES / 'lod_mesh.obj'), i=True, type='OBJ')

# Assumes base_mesh already has base_mesh_blendShape from Example 1
cmds.loadPlugin('advBlendshapeTools', quiet=True)
from advBlendshapeTools.api.commands import find_or_create_blendshape
new_blendshapes = cmds.advBlendshapeTransfer(
    sourceBlendshape='base_mesh_blendShape',
    sourceMesh='base_mesh',
    targetMeshes=['lod_mesh'],
    targetBlendshapes=[find_or_create_blendshape('lod_mesh')],
    method='uv',
)
cmds.viewFit()

Connect the source blendshape weights to all transferred nodes:

from advBlendshapeTools.api.blendshape_node import connect_blendshape_targets, BlendShapeNode
source_node = BlendShapeNode('base_mesh_blendShape')
target_nodes = [BlendShapeNode(blendshape) for blendshape in new_blendshapes]
connect_blendshape_targets(source_node, target_nodes)

Example 3: Production pipeline (export → query → import → transfer)

Continues from Examples 1 and 2. Demonstrates a full pipeline process: export, query the file to pick the right import method, import onto the target, and transfer to target meshes.

import maya.cmds as cmds
from pathlib import Path
import advBlendshapeTools
from advBlendshapeTools.api.commands import DEFAULT_FILE_PATH

cmds.loadPlugin('advBlendshapeTools', quiet=True)

EXAMPLES = Path(advBlendshapeTools.__file__).parent / 'examples'

# -------------------------------------------------------------------
# 1. Export blendshape data from the source blendshape node to temp dir
# -------------------------------------------------------------------
cmds.advBlendshapeExport(
    blendshape='base_mesh_blendShape',
    outputFile=DEFAULT_FILE_PATH,
)

# -------------------------------------------------------------------
# 2. Query the exported file's vertex count and compare with the
#    intended import target to choose the appropriate import method.
#    advBlendshapeFile() returns the vertex count stored in the file.
# -------------------------------------------------------------------

# Create a new scene and import base mesh and transfer deltas to lod_mesh
cmds.file(new=True, force=True)
# Import example meshes
cmds.file(str(EXAMPLES / 'base_mesh.obj'), i=True, type='OBJ')
cmds.file(str(EXAMPLES / 'lod_mesh.obj'), i=True, type='OBJ')

# Query the vertex count in the file
file_vertex_count = cmds.advBlendshapeFile(
    DEFAULT_FILE_PATH,
    query=True,
    vertexCount=True,
)

target_mesh = 'base_mesh'
target_vertex_count = cmds.polyEvaluate(target_mesh, vertex=True)

if file_vertex_count == target_vertex_count:
    import_method = 'index'   # topology matches
else:
    import_method = 'uv'      # different topology

print(
    f'File verts: {file_vertex_count}  |  '
    f'Target verts: {target_vertex_count}  |  '
    f'Method: {import_method}'
)

# -------------------------------------------------------------------
# 3. Import onto the target mesh using the selected method
# -------------------------------------------------------------------

from advBlendshapeTools.api.commands import find_or_create_blendshape

imported_blendshape = cmds.advBlendshapeImport(
    blendshape=find_or_create_blendshape(target_mesh),
    inputFile=DEFAULT_FILE_PATH,
    method=import_method,
)

# -------------------------------------------------------------------
# 4. Transfer to LOD meshes (UV method handles topology differences)
# -------------------------------------------------------------------
lod_meshes = ['lod_mesh']

transferred = cmds.advBlendshapeTransfer(
    sourceBlendshape=imported_blendshape,
    sourceMesh=target_mesh,
    targetMeshes=lod_meshes,
    targetBlendshapes=[find_or_create_blendshape(m) for m in lod_meshes],
    method='uv',
)

# Wire all blendshape nodes to the base blendshape weights
from advBlendshapeTools.api.blendshape_node import connect_blendshape_targets, BlendShapeNode

source_node = BlendShapeNode(imported_blendshape)
lod_nodes = [BlendShapeNode(bs) for bs in transferred]
connect_blendshape_targets(source_node, lod_nodes)

print('Pipeline complete.')
print(f'Source blendshape : {imported_blendshape}')
print(f'LOD blendshapes   : {transferred}')
cmds.viewFit()

Example 4: Import and transfer blendshape weight maps (.bweights)

Continues from Examples 1 and 2. base_mesh_blendShape must exist in the scene and lod_mesh must carry a blendshape node from the Example 2 transfer.

example.bweights has a pre-painted deformer envelope mask (base weights) and one target’s paint weights.

import maya.cmds as cmds
from pathlib import Path
import advBlendshapeTools

cmds.loadPlugin('advBlendshapeTools', quiet=True)

EXAMPLES = Path(advBlendshapeTools.__file__).parent / 'examples'
WEIGHTS_FILE = str(EXAMPLES / 'example.bweights')
BS = 'base_mesh_blendShape'

# Inspect the shipped weight maps before importing
targets = cmds.advBWeightsFile(WEIGHTS_FILE, query=True, targets=True)
vtx_count = cmds.advBWeightsFile(WEIGHTS_FILE, query=True, vertexCount=True)
print(f'Targets in file : {targets}')
print(f'Source vtx count: {vtx_count}')

# Apply an envelope blendshape mask and target paint weights onto base_mesh_blendShape.
# Matching topology uses the index method.
cmds.advBWeightImport(
    mesh='base_mesh',
    inputFile=WEIGHTS_FILE,
    method='index',
)


# Transfer the same weight maps to the LOD mesh. UV remapping handles the differing topology.
cmds.advBWeightTransfer(
    sourceBlendshape=BS,
    targetMeshes=['lod_mesh'],
    method='uv',
)
cmds.viewFit()

⚠️ The topology method matches vertices by object-space position. If a mesh is offset from the source, use uv instead. UV remapping is independent of where the meshes sit.


Example 5: Import and remap component selections (.components)

example.components has three named component sets (eyes, mouth, and neck), captured on base_mesh. Named sets make production selections data-driven and remove the need to hard-code component indices in code.

⚠️ Component sets do not preserve their exact count when remapped across differing topology. The uv and topology methods match each component to its nearest neighbor on the target, so where the target is denser or sparser than the source, overlapping regions resolve to more or fewer components than the original set.

import maya.cmds as cmds
from pathlib import Path
import advBlendshapeTools
from advBlendshapeTools.utils import component_tags

cmds.loadPlugin('advBlendshapeTools', quiet=True)

EXAMPLES = Path(advBlendshapeTools.__file__).parent / 'examples'
COMPONENTS_FILE = str(EXAMPLES / 'example.components')


# Discover the named sets in the file rather than assuming them
names = cmds.advComponentFile(COMPONENTS_FILE, query=True, names=True)
print(f'Sets in file    : {names}')   # ['eyes', 'mouth', 'neck']

# Restore every named set onto base_mesh (matching topology -> index method)
base_shape = cmds.listRelatives('base_mesh', shapes=True, noIntermediate=True)[0]
base_inj = component_tags.get_injection_node(base_shape, create=True)
for set_name in names:
    components = cmds.advComponentsImport(
        mesh='base_mesh',
        file=COMPONENTS_FILE,
        setName=set_name,
        method='index',
    )
    rel_comps = component_tags.to_relative_components(components)
    component_tags.write_tag(
        base_inj, set_name, rel_comps
    )
    print(f'{set_name}: {len(components)} components')

# Remap a single set onto the LOD mesh (different topology -> uv method) and
# store it as a componentTag there too.
lod_shape = cmds.listRelatives('lod_mesh', shapes=True, noIntermediate=True)[0]
lod_inj = component_tags.get_injection_node(lod_shape, create=True)
mouth_lod = cmds.advComponentsImport(
    mesh='lod_mesh',
    file=COMPONENTS_FILE,
    setName='mouth',
    method='uv',
)
rel_comps = component_tags.to_relative_components(mouth_lod)
component_tags.write_tag(
    lod_inj, 'mouth', rel_comps
)
cmds.select(mouth_lod, replace=True)
print(f'LOD mouth components: {mouth_lod}')

Example 6: Bake through a live wrap (advBlendshapeWrap)

Starts from a new scene. Instead of transferring deltas directly, this workflow live-binds lod_mesh to base_mesh with an advBlendshapeWrap deformer, then bakes the source blendShape’s targets through that live wrap into a new blendShape on a lod_mesh__custom duplicate. Since lod_mesh shares base_mesh’s UV layout, the uv method gives the cleanest correspondence.

Steps (UI)

  1. Import base_mesh.obj and lod_mesh.obj

  2. File I/O tab → set Import Mesh to base_mesh and Import File to example.deltas, method Index, click Import Blendshape

  3. Wrap Tool → Wrap Setup: assign Source Mesh to base_mesh and Target Mesh to lod_mesh

  4. Set Method to UV, then click Create Wrap

  5. Bake: set Source Blendshape to base_mesh_blendShape

  6. Click Bake It

Python example

import maya.cmds as cmds
from pathlib import Path
import advBlendshapeTools
from advBlendshapeTools.api.commands import find_or_create_blendshape, create_wrap, transfer_deltas

cmds.loadPlugin('advBlendshapeTools', quiet=True)

EXAMPLES = Path(advBlendshapeTools.__file__).parent / 'examples'

# Start clean and import both meshes
cmds.file(new=True, force=True)
cmds.file(str(EXAMPLES / 'base_mesh.obj'), i=True, type='OBJ')
cmds.file(str(EXAMPLES / 'lod_mesh.obj'), i=True, type='OBJ')

# Build the source blendShape on base_mesh from the shipped deltas (matching
# topology, so 'index' applies exactly as in Example 1)
base_blendshape = cmds.advBlendshapeImport(
    blendshape=find_or_create_blendshape('base_mesh'),
    inputFile=str(EXAMPLES / 'example.deltas'),
    method='index',
)

# Live-bind lod_mesh to base_mesh by UV correspondence
wrap_node = create_wrap(
    source_mesh='base_mesh',
    target_mesh='lod_mesh',
    method='uv',
    source_uv_set='map1',
    target_uv_set='map1',
)
print(f'Wrap deformer: {wrap_node}')

# Activate each base_mesh_blendShape target in turn, capture lod_mesh's live
# wrapped pose, and build lod_mesh__custom_blendShape from those snapshots.
baked = transfer_deltas(
    source_blendshape=base_blendshape,
    source_mesh='base_mesh',
    target_meshes=['lod_mesh'],
    method='custom',
)
print(f'Baked blendshape: {baked}')
cmds.viewFit()

⚠️ create_wrap deletes any existing advBlendshapeWrap node in target_mesh’s history before creating a new one, so re-running it rebuilds the deformer from scratch rather than stacking wraps.