This commit is contained in:
2025-12-07 23:00:40 +08:00
parent 52ac5cf5a6
commit 2cf75f21f4
807 changed files with 2318015 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,296 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Author: Jeremy Ernst
===============
File Attributes
===============
* **icon:** This is the image file (125x75 .png) that gets used in the RigCreatorUI
* **hoverIcon:** When you hover over the module in the module list, it will swap to this icon
(background changes to orange). There are .psd template files for these.
* **search:** These are search terms that are accepted when searching the list of modules in the
RigCreatorUI
* **class name:** The name of the class.
* **jointMover:** The relative path to the joint mover file. Relative to the ARTv2 root directory.
* **baseName:** The default name the module will get created with. Users can then add a prefix and/or
suffix to the base name.
* **rigs:** This is a simple list of what rigs this module can build. This feature isn't implemented yet,
but the plan is to query this list and present these options to the user for them to select what rigs
they want to build for the module. Right now, it will build all rigs.
* **fbxImport:** This is a list that will show the options for the module in the import mocap interface.
Normally, this list will have at least None and FK.
* **matchData:** This is a list of options that will be presented for the module in a comboBox in the
match over frame range interface. First argument is a bool as to whether the module can or can't
match. The second arg is a list of strings to display for the match options. For example:
matchData = [True, ["Match FK to IK", "Match IK to FK"]]
* **controlTypes:** This is a list of lists, where each item in the main list is a list comprised of the
name of the attribute that gets added to the network node that contains the control information.
The second arg in each list entry is a control type, like FK or IK. This is used in the select
rig controls interface for filtering out which controls on each module you want to select. On
this module, the values are: controlTypes = [["fkControls", "FK"]], which means that the
attribute that holds the control info is called fkControls, and those controls are of type FK.
.. image:: /images/selectRigControls.png
===============
Class
===============
"""
# file imports
import json
import os
from functools import partial
import maya.cmds as cmds
import System.interfaceUtils as interfaceUtils
import System.riggingUtils as riggingUtils
import System.utils as utils
from System.ART_RigModule import ART_RigModule
from ThirdParty.Qt import QtGui, QtCore, QtWidgets
# file attributes
icon = "Modules/chain.png"
hoverIcon = "Modules/hover_chain.png"
search = "chain"
className = "ART_Chain"
jointMover = "Core/JointMover/ART_Chain.ma"
baseName = "chain"
rigs = ["FK", "IK", "Dynamic"]
fbxImport = ["None", "FK", "IK", "Both"]
matchData = [True, ["Match FK to IK", "Match IK to FK"]]
controlTypes = [["fkControls", "FK"], ["ikControls", "IK"], ["dynControls", "FK"]]
class ART_Chain(ART_RigModule):
"""This class creates the chain module, which can have a minimum of 2 joints and a maximum of 99."""
def __init__(self, rigUiInst, moduleUserName):
"""Initiate the class, taking in the instance to the interface and the user specified name.
:param rigUiInst: This is the rig creator interface instance being passed in.
:param moduleUserName: This is the name specified by the user on module creation.
Instantiate the following class variables as well:
* **self.rigUiInst:** take the passed in interface instance and make it a class var
* **self.moduleUserName:** take the passed in moduleUserName and make it a class var
* **self.outlinerWidget:** an empty list that will hold all of the widgets added to the outliner
Also, read the QSettings to find out where needed paths are.
"""
self.rigUiInst = rigUiInst
self.moduleUserName = moduleUserName
self.outlinerWidgets = {}
settings = QtCore.QSettings("Epic Games", "ARTv2")
self.toolsPath = settings.value("toolsPath")
ART_RigModule.__init__(self, "ART_Chain_Module", "ART_Chain", moduleUserName)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def addAttributes(self):
"""
Add custom attributes this module needs to the network node.
Always calls on base class function first, then extends with any attributes unique to the class.
"""
# call the base class method first to hook up our connections to the master module
ART_RigModule.addAttributes(self)
# add custom attributes for this specific module
cmds.addAttr(self.networkNode, sn="Created_Bones", dt="string", keyable=False)
cmds.setAttr(self.networkNode + ".Created_Bones", "joint_01::joint_02::joint_03::", type="string", lock=True)
cmds.addAttr(self.networkNode, sn="baseName", dt="string", keyable=False)
cmds.setAttr(self.networkNode + ".baseName", baseName, type="string", lock=True)
cmds.addAttr(self.networkNode, sn="canAim", at="bool", keyable=False)
cmds.setAttr(self.networkNode + ".canAim", True, lock=True)
cmds.addAttr(self.networkNode, sn="aimMode", at="bool", keyable=False)
cmds.setAttr(self.networkNode + ".aimMode", False, lock=True)
cmds.addAttr(self.networkNode, sn="numJoints", keyable=False)
cmds.setAttr(self.networkNode + ".numJoints", 3, lock=True)
cmds.addAttr(self.networkNode, sn="hasDynamics", at="bool", keyable=False)
cmds.setAttr(self.networkNode + ".hasDynamics", False, lock=True)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def skeletonSettings_UI(self, name):
"""
This is the UI for the module that has all of the configuration settings.
:param name: user given name of module (prefix + base_name + suffix)
:param width: width of the skeleton settings groupBox. 335 usually
:param height: height of the skeleton settings groupBox.
:param checkable: Whether or not the groupBox can be collapsed.
Build the groupBox that contains all of the settings for this module. Parent the groupBox
into the main skeletonSettingsUI layout.
Lastly, call on updateSettingsUI to populate the UI based off of the network node values.
.. image:: /images/skeletonSettings.png
"""
# width, height, checkable
networkNode = self.returnNetworkNode
font = QtGui.QFont()
font.setPointSize(8)
headerFont = QtGui.QFont()
headerFont.setPointSize(8)
headerFont.setBold(True)
# groupbox all modules get
ART_RigModule.skeletonSettings_UI(self, name, 335, 288, True)
# STANDARD BUTTONS
# create a VBoxLayout to add to our Groupbox and then add a QFrame for our signal/slot
self.mainLayout = QtWidgets.QVBoxLayout(self.groupBox)
self.frame = QtWidgets.QFrame(self.groupBox)
self.mainLayout.addWidget(self.frame)
self.frame.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed))
self.frame.setMinimumSize(QtCore.QSize(320, 270))
self.frame.setMaximumSize(QtCore.QSize(320, 270))
# create layout that is a child of the frame
self.layout = QtWidgets.QVBoxLayout(self.frame)
# mirror module
self.mirrorModLayout = QtWidgets.QHBoxLayout()
self.layout.addLayout(self.mirrorModLayout)
self.mirrorModuleLabel = QtWidgets.QLabel("Mirror Module: ")
self.mirrorModuleLabel.setFont(font)
self.mirrorModLayout.addWidget(self.mirrorModuleLabel)
mirror = cmds.getAttr(networkNode + ".mirrorModule")
if mirror == "":
mirror = "None"
self.mirrorMod = QtWidgets.QLabel(mirror)
self.mirrorMod.setFont(font)
self.mirrorMod.setAlignment(QtCore.Qt.AlignHCenter)
self.mirrorModLayout.addWidget(self.mirrorMod)
# current parent
self.currentParentMod = QtWidgets.QHBoxLayout()
self.layout.addLayout(self.currentParentMod)
self.currentParentLabel = QtWidgets.QLabel("Current Parent: ")
self.currentParentLabel.setFont(font)
self.currentParentMod.addWidget(self.currentParentLabel)
parent = cmds.getAttr(networkNode + ".parentModuleBone")
self.currentParent = QtWidgets.QLabel(parent)
self.currentParent.setFont(font)
self.currentParent.setAlignment(QtCore.Qt.AlignHCenter)
self.currentParentMod.addWidget(self.currentParent)
# button layout for name/parent
self.buttonLayout = QtWidgets.QHBoxLayout()
self.layout.addLayout(self.buttonLayout)
self.changeNameBtn = QtWidgets.QPushButton("Change Name")
self.changeParentBtn = QtWidgets.QPushButton("Change Parent")
self.mirrorModuleBtn = QtWidgets.QPushButton("Mirror Module")
self.buttonLayout.addWidget(self.changeNameBtn)
self.buttonLayout.addWidget(self.changeParentBtn)
self.buttonLayout.addWidget(self.mirrorModuleBtn)
self.changeNameBtn.setObjectName("blueButton")
self.changeParentBtn.setObjectName("blueButton")
self.mirrorModuleBtn.setObjectName("blueButton")
# button signal/slots
self.changeNameBtn.clicked.connect(partial(self.changeModuleName, baseName, self, self.rigUiInst))
self.changeParentBtn.clicked.connect(partial(self.changeModuleParent, self, self.rigUiInst))
self.mirrorModuleBtn.clicked.connect(partial(self.setMirrorModule, self, self.rigUiInst))
# bake offsets button
self.bakeToolsLayout = QtWidgets.QHBoxLayout()
self.layout.addLayout(self.bakeToolsLayout)
# Bake OFfsets
self.bakeOffsetsBtn = QtWidgets.QPushButton("Bake Offsets")
self.bakeOffsetsBtn.setFont(headerFont)
self.bakeToolsLayout.addWidget(self.bakeOffsetsBtn)
self.bakeOffsetsBtn.clicked.connect(self.bakeOffsets)
self.bakeOffsetsBtn.setToolTip("Bake the offset mover values up to the global movers to get them in sync")
self.bakeOffsetsBtn.setObjectName("blueButton")
# Rig Settings
spacerItem = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self.layout.addItem(spacerItem)
self.hasDynamics = QtWidgets.QCheckBox("Has Dynamics")
self.layout.addWidget(self.hasDynamics)
self.hasDynamics.setChecked(False)
# self.hasDynamics.clicked.connect(partial(self.applyModuleChanges, self))
spacerItem = QtWidgets.QSpacerItem(20, 30, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self.layout.addItem(spacerItem)
# Number of joints in chain
self.numJointsLayout = QtWidgets.QHBoxLayout()
self.layout.addLayout(self.numJointsLayout)
self.numJointsLabel = QtWidgets.QLabel("Number of Joints in Chain: ")
self.numJointsLabel.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
self.numJointsLabel.setMinimumSize(QtCore.QSize(200, 20))
self.numJointsLabel.setMaximumSize(QtCore.QSize(200, 20))
self.numJointsLayout.addWidget((self.numJointsLabel))
self.numJoints = QtWidgets.QSpinBox()
self.numJoints.setMaximum(99)
self.numJoints.setMinimum(2)
self.numJoints.setMinimumSize(QtCore.QSize(100, 20))
self.numJoints.setMaximumSize(QtCore.QSize(100, 20))
self.numJoints.setValue(3)
self.numJoints.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self.numJointsLayout.addWidget(self.numJoints)
# rebuild button
spacerItem = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
self.layout.addItem(spacerItem)
self.applyButton = QtWidgets.QPushButton("Apply Changes")
self.layout.addWidget(self.applyButton)
self.applyButton.setFont(headerFont)
self.applyButton.setMinimumSize(QtCore.QSize(300, 40))
self.applyButton.setMaximumSize(QtCore.QSize(300, 40))
self.applyButton.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self.applyButton.setEnabled(False)
self.applyButton.clicked.connect(partial(self.applyModuleChanges, self))
# signal slot for groupbox checkbox
self.groupBox.toggled.connect(self.frame.setVisible)
self.groupBox.setChecked(False)
# add custom skeletonUI settings name, parent, rig types to install, mirror module, etc.
# add to the rig cretor UI's module settings layout VBoxLayout
self.rigUiInst.moduleSettingsLayout.addWidget(self.groupBox)
# Populate the settings UI based on the network node attributes
# self.updateSettingsUI()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#standard imports
import maya.cmds as cmds
import json
from functools import partial
from ThirdParty.Qt import QtGui, QtCore, QtWidgets
#external imports
from System.ART_RigModule import ART_RigModule
import System.riggingUtils as riggingUtils
import System.interfaceUtils as interfaceUtils
#file attributes
icon = "Core/Icons/Modules/root.png"
search = "Root"
className = "ART_Root"
baseName = "root"
fbxImport = ["None", "Root Motion: Offset", "Root Motion: Master", "Root Motion: Root"]
matchData = [False, None]
controlTypes = [["rootControls", "FK"]]
class ART_Root(ART_RigModule):
def __init__(self, rigUiInst, moduleUserName):
self.rigUiInst = rigUiInst
self.moduleUserName = moduleUserName
self.outlinerWidgets = {}
ART_RigModule.__init__(self, "ART_Root_Module", "ART_Root", moduleUserName)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def addAttributes(self):
#call the base class method first to hook up our connections to the master module
ART_RigModule.addAttributes(self)
#add custom attributes for this specific module
cmds.addAttr(self.networkNode, sn = "Created_Bones", dt = "string", keyable = False)
cmds.setAttr(self.networkNode + ".Created_Bones", "root", type = "string", lock = True)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def skeletonSettings_UI(self, name):
#groupbox all modules get
ART_RigModule.skeletonSettings_UI(self, name, 335, 85, False)
#add a label to the root module saying this module cannot be edited or removed
self.layout = QtWidgets.QVBoxLayout(self.groupBox)
self.label = QtWidgets.QLabel("All rigs must have a root module. This module cannot be edited or removed.")
self.layout.addWidget(self.label)
self.label.setGeometry(QtCore.QRect(10, 20, 300, 60))
self.label.setMinimumHeight(60)
self.label.setWordWrap(True)
#add to the rig cretor UI's module settings layout VBoxLayout
self.rigUiInst.moduleSettingsLayout.addWidget(self.groupBox)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def pickerUI(self, center, animUI, networkNode, namespace):
#create qBrushes
yellowBrush = QtCore.Qt.yellow
blueBrush = QtGui.QColor(100,220,255)
purpleBrush = QtGui.QColor(111,48,161)
clearBrush = QtGui.QBrush(QtCore.Qt.black)
clearBrush.setStyle(QtCore.Qt.NoBrush)
#create border item
if networkNode.find(":") != -1:
moduleNode = networkNode.partition(":")[2]
else:
moduleNode = networkNode
borderItem = interfaceUtils.pickerBorderItem(center.x() - 40, center.y() - 70, 50, 98, clearBrush, moduleNode)
#get controls + namespace
networkNode = self.returnNetworkNode
controls = json.loads(cmds.getAttr(networkNode + ".rootControls"))
#master anim button
masterBtn = interfaceUtils.pickerButton(30, 30, [10,2], namespace + controls[0], yellowBrush, borderItem)
interfaceUtils.addTextToButton("M", masterBtn)
#offset anim button
offsetBtn = interfaceUtils.pickerButton(30, 30, [10,34], namespace + controls[1], blueBrush, borderItem)
interfaceUtils.addTextToButton("O", offsetBtn)
#root anim button
rootBtn = interfaceUtils.pickerButton(30, 30, [10,66], namespace + controls[2], purpleBrush, borderItem)
interfaceUtils.addTextToButton("R", rootBtn)
#=======================================================================
# #Create scriptJob for selection. Set scriptJob number to borderItem.data(5)
#=======================================================================
scriptJob = cmds.scriptJob(event = ["SelectionChanged", partial(self.selectionScriptJob_animUI,[[masterBtn,namespace + controls[0], yellowBrush],[offsetBtn, namespace + controls[1], blueBrush],[rootBtn, namespace + controls[2], purpleBrush]])], kws = True)
borderItem.setData(5, scriptJob)
animUI.selectionScriptJobs.append(scriptJob)
return [borderItem, False, scriptJob]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def addJointMoverToOutliner(self):
index = self.rigUiInst.treeWidget.topLevelItemCount()
#Add the module to the tree widget in the outliner tab of the rig creator UI
self.outlinerWidgets[self.name + "_treeModule"] = QtWidgets.QTreeWidgetItem(self.rigUiInst.treeWidget)
self.rigUiInst.treeWidget.topLevelItem(index).setText(0, self.name)
foreground = QtGui.QBrush(QtGui.QColor(255, 255, 255))
self.outlinerWidgets[self.name + "_treeModule"].setForeground(0, foreground)
#add the buttons
self.createGlobalMoverButton(self.name, self.outlinerWidgets[self.name + "_treeModule"], self.rigUiInst)
#create selection script job for module
self.updateBoneCount()
self.createScriptJob()
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildRigCustom(self, textEdit, uiInst):
if textEdit != None:
textEdit.append(" Building Root Rig..")
#get the created joint
networkNode = self.returnNetworkNode
rootJoint = cmds.getAttr(networkNode + ".Created_Bones")
#create the rig grp
rigGrp = cmds.group(empty = True, name = "rig_grp")
#Need to build 3 controls, the master, the offset, and the root control
masterControls = riggingUtils.createControlFromMover(rootJoint, networkNode, False, True)
#rename controls
masterControl = cmds.rename(masterControls[0], "master_anim")
masterCtrlGrp = cmds.rename(masterControls[1], "master_anim_grp")
masterSpaceSwitch = cmds.rename(masterControls[2], "master_anim_space_switcher")
masterSpace = cmds.rename(masterControls[3], "master_anim_space_switcher_follow")
cmds.parent(masterSpace, rigGrp)
#scale masterControl
cmds.setAttr(masterControl + ".scale", 2, 2, 2, type = "double3")
cmds.makeIdentity(masterControl, t = 1, r = 1, s = 1, apply = True)
#alias attr master control
cmds.aliasAttr("globalScale", masterControl + ".scaleZ")
cmds.connectAttr(masterControl + ".globalScale", masterControl + ".scaleX")
cmds.connectAttr(masterControl + ".globalScale", masterControl + ".scaleY")
cmds.setAttr(masterControl + ".scaleX", keyable = False)
cmds.setAttr(masterControl + ".scaleY", keyable = False)
cmds.setAttr(masterControl + ".visibility", lock = True, keyable = False)
#create offset anim control
offsetAnim = riggingUtils.createControl("circle", 40, "offset_anim", False)
cmds.parent(offsetAnim, masterControl)
cmds.setAttr(offsetAnim + ".overrideEnabled", 1)
cmds.setAttr(offsetAnim + ".overrideColor", 18)
for attr in [".visibility", ".scaleX", ".scaleY", ".scaleZ"]:
cmds.setAttr(offsetAnim + attr, lock = True, keyable = False)
#create the root control
rootAnim = riggingUtils.createControl("sphere", 5, "root_anim", False)
cmds.parent(rootAnim, offsetAnim)
cmds.makeIdentity(rootAnim, t = 1, r = 1, s = 1, apply = True)
cmds.setAttr(rootAnim + ".overrideEnabled", 1)
cmds.setAttr(rootAnim + ".overrideColor", 30)
cmds.parentConstraint(rootAnim, "driver_root")
cmds.scaleConstraint(rootAnim, "driver_root")
for attr in [".visibility", ".scaleX", ".scaleY", ".scaleZ"]:
cmds.setAttr(rootAnim + attr, lock = True, keyable = False)
if not cmds.objExists(networkNode + ".rootControls"):
cmds.addAttr(networkNode, ln = "rootControls", dt = "string")
controlList = [masterControl, offsetAnim, rootAnim]
jsonString = json.dumps(controlList)
cmds.setAttr(networkNode + ".rootControls", jsonString, type = "string")
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def importFBX(self, importMethod, character):
returnControls = []
if importMethod == "Root Motion: Offset":
cmds.parentConstraint("root", character + ":" + "offset_anim")
returnControls.append(character + ":" + "offset_anim")
if importMethod == "Root Motion: Master":
cmds.parentConstraint("root", character + ":" + "master_anim")
returnControls.append(character + ":" + "master_anim")
if importMethod == "Root Motion: Root":
cmds.parentConstraint("root", character + ":" + "root_anim")
returnControls.append(character + ":" + "root_anim")
if importMethod == "None":
pass
return returnControls

File diff suppressed because it is too large Load Diff