Source code for bgdev.api.blendshape

"""API methods for blendshapes.

:author: Benoit Gielly (benoit.gielly@gmail.com)
"""
from maya import cmds
from maya.api import OpenMaya

from . import attribute, core, deformer


[docs]def copy_target_weights(source, destination): """Copy a blendshape's target weights to another target. Args: source (str): Name of the blendshape's source plug destination (str): Name of the blendshape's destination plug """ handle = core.as_plug(source).asMDataHandle() plug = core.as_plug(destination) plug.setMDataHandle(handle) plug.destructHandle(handle)
[docs]def reset_target_delta(blendshape, shape, targets=None): """Reset given shape delta in the blendshape node.""" targets = targets or attribute.get_node_aliases(blendshape, indices=True) if not isinstance(targets, dict): targets = attribute.get_node_aliases(blendshape, indices=True) index = targets.get(shape) if index: cmds.blendShape(blendshape, edit=True, resetTargetDelta=[0, index])
[docs]def add_blendshape_targets(blendshape, shape, alias=None): """Add and update targets on the given blendShape.""" alias = alias or shape # check that shape exists if not core.obj_exists(shape): raise RuntimeError("Shape to add doesn't exists: {}".format(shape)) # get blendshape index targets = attribute.get_node_aliases(blendshape, indices=True) or {} plug = "{}.weight".format(blendshape) index = targets.get(shape) or attribute.get_next_index(plug) # add shape and update targets dict geometry = deformer.get_output_geometry(blendshape)[0] cmds.blendShape(blendshape, edit=True, target=(geometry, index, shape, 1)) disconnect_target(blendshape, shape) plug = core.as_plug("{}.weight[{}]".format(blendshape, index)) if attribute.get_alias(plug) != alias: attribute.set_alias(plug, alias) if attribute.is_free(plug): plug.setFloat(0.0)
[docs]def disconnect_target(blendshape, shape): """Disconnect given shape from blendshape node.""" modifier = OpenMaya.MDGModifier() shape_dag = core.as_dag(shape, to_shape=True) for plug in deformer.as_filter(blendshape).getConnections(): source = plug.source() if plug.isDestination and source.node() == shape_dag.node(): modifier.disconnect(source, plug) modifier.doIt()
[docs]def delete_blendshape_target(blendshape, index): """Delete given target index on blendshape node.""" node = core.as_node(blendshape) modifier = OpenMaya.MDGModifier() # clear the weight attribute plug = core.as_plug("{}.weight[{}]".format(blendshape, index)) alias = plug.partialName(useLongNames=True) node.setAlias("", alias, plug, add=False) modifier.removeMultiInstance(plug, True) it_plug = node.findPlug("inputTarget", 0) for i in it_plug.getExistingArrayAttributeIndices(): itg_plug = node.findPlug("inputTargetGroup", 0) itg_plug.selectAncestorLogicalIndex(i, it_plug.attribute()) itg_plug.selectAncestorLogicalIndex(index) # remove inbetweens iti_plug = node.findPlug("inputTargetItem", 0) iti_plug.selectAncestorLogicalIndex(i, it_plug.attribute()) iti_plug.selectAncestorLogicalIndex(index, itg_plug.attribute()) for j in iti_plug.getExistingArrayAttributeIndices(): iti_plug.selectAncestorLogicalIndex(j) modifier.removeMultiInstance(iti_plug, True) # remove target weights tw_plug = node.findPlug("targetWeights", 0) tw_plug.selectAncestorLogicalIndex(i, it_plug.attribute()) tw_plug.selectAncestorLogicalIndex(index, itg_plug.attribute()) modifier.removeMultiInstance(tw_plug, True) # remove target group modifier.removeMultiInstance(itg_plug, True) modifier.doIt()
[docs]def disable_target_weights(blendshape): """Disable all weights on blendshape node.""" restore_data = {} modifier = OpenMaya.MDagModifier() for each in attribute.get_node_aliases(blendshape) or []: info = {} info["plug"] = plug = core.as_plug("{}.{}".format(blendshape, each)) info["value"] = plug.asFloat() info["locked"] = plug.isLocked if plug.isConnected: info["source"] = source = plug.source() modifier.disconnect(source, plug) plug.isLocked = False modifier.newPlugValueFloat(plug, 0) restore_data[each] = info modifier.doIt() return restore_data
[docs]def restore_target_weights(restore_data): """Restore blendshape weights based on previous data.""" modifier = OpenMaya.MDagModifier() for info in restore_data.values(): plug = info["plug"] source = info.get("source") if source: modifier.connect(source, plug) else: modifier.newPlugValueFloat(plug, info["value"]) modifier.doIt() for info in restore_data.values(): info["plug"].isLocked = info["locked"]