Files
indigo e2f2e6668a Add OpenPose_full renderer plugin for Maya
Maya API 2.0 plugin that maps a skeleton to OpenPose_full keypoints
(BODY_25 or COCO body, 21+21 hand, 70 face) via an openposeCharacter
node, with a live Viewport 2.0 draw override, an "OpenPose" viewport
renderer plus openposeRenderSequence for PNG output, and a PySide2
mapping editor. Face can also be driven procedurally from ARKit's 52
blendshape weights instead of facial joints, for rigs with no facial
skeleton. Includes VS Code debug configs and Maya test scenes/renders.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 08:41:57 +08:00

92 lines
2.6 KiB
Python

"""MEL/Python-visible commands: ``openposeCreateCharacter`` (undoable node
creation) and ``openposeShowMappingEditor`` (launches the mapping UI).
"""
import maya.api.OpenMaya as om
from . import mapping_node
class CreateCharacterCommand(om.MPxCommand):
kCmdName = "openposeCreateCharacter"
def __init__(self):
om.MPxCommand.__init__(self)
self._modifiers = []
self._created_node_name = None
@staticmethod
def creator():
return CreateCharacterCommand()
@staticmethod
def createSyntax():
syntax = om.MSyntax()
syntax.addFlag("-n", "-name", om.MSyntax.kString)
return syntax
def doIt(self, args):
parser = om.MArgParser(self.syntax(), args)
want_name = parser.flagArgumentString("-n", 0) if parser.isFlagSet("-n") else None
self._modifiers = []
# For a shape type, MDagModifier.createNode() returns the
# auto-created *parent transform*, not the shape -- the shape itself
# is its only child, and only exists once doIt() has run.
create_modifier = om.MDagModifier()
transform_obj = create_modifier.createNode(mapping_node.NODE_NAME)
create_modifier.doIt()
self._modifiers.append(create_modifier)
shape_obj = om.MFnDagNode(transform_obj).child(0)
if want_name:
rename_modifier = om.MDagModifier()
rename_modifier.renameNode(shape_obj, want_name)
rename_modifier.doIt()
self._modifiers.append(rename_modifier)
self._created_node_name = om.MFnDagNode(shape_obj).name()
self.setResult(self._created_node_name)
def redoIt(self):
for modifier in self._modifiers:
modifier.doIt()
def undoIt(self):
for modifier in reversed(self._modifiers):
modifier.undoIt()
def isUndoable(self):
return True
class ShowMappingEditorCommand(om.MPxCommand):
kCmdName = "openposeShowMappingEditor"
@staticmethod
def creator():
return ShowMappingEditorCommand()
def doIt(self, args):
from .ui import mapping_editor
mapping_editor.show()
def isUndoable(self):
return False
def register(fn_plugin):
fn_plugin.registerCommand(
CreateCharacterCommand.kCmdName, CreateCharacterCommand.creator, CreateCharacterCommand.createSyntax
)
fn_plugin.registerCommand(ShowMappingEditorCommand.kCmdName, ShowMappingEditorCommand.creator)
def deregister(fn_plugin):
fn_plugin.deregisterCommand(ShowMappingEditorCommand.kCmdName)
fn_plugin.deregisterCommand(CreateCharacterCommand.kCmdName)