aboutsummaryrefslogtreecommitdiff
path: root/Core/Scripts/Interfaces/ART_SkinTools.py
diff options
context:
space:
mode:
authorMobileMachine\jeremy <[email protected]>2017-06-06 22:59:03 -0400
committerMobileMachine\jeremy <[email protected]>2017-06-06 22:59:03 -0400
commit24725fa8681f906ab44d80687c09fecc171a2896 (patch)
tree312a601df29aca7f8db9f44082d96ebc7a679138 /Core/Scripts/Interfaces/ART_SkinTools.py
parentInitial commit (diff)
downloadartv2-24725fa8681f906ab44d80687c09fecc171a2896.tar.xz
artv2-24725fa8681f906ab44d80687c09fecc171a2896.zip
Initial Submission
First submission of current state of ARTv2. Currently considered to be in Alpha. There are a couple of animation tools not implemented yet, and one module not implemented yet, as well as incomplete documentation.
Diffstat (limited to 'Core/Scripts/Interfaces/ART_SkinTools.py')
-rw-r--r--Core/Scripts/Interfaces/ART_SkinTools.py2878
1 files changed, 2878 insertions, 0 deletions
diff --git a/Core/Scripts/Interfaces/ART_SkinTools.py b/Core/Scripts/Interfaces/ART_SkinTools.py
new file mode 100644
index 0000000..782f5bf
--- /dev/null
+++ b/Core/Scripts/Interfaces/ART_SkinTools.py
@@ -0,0 +1,2878 @@
+import math
+import os
+from functools import partial
+
+import maya.OpenMayaUI as mui
+import maya.cmds as cmds
+import maya.mel as mel
+
+from ThirdParty.Qt import QtGui, QtCore, QtWidgets
+
+# maya 2016< maya2017> compatability
+try:
+ import shiboken as shiboken
+except:
+ import shiboken2 as shiboken
+
+import System.utils as utils
+import System.riggingUtils as riggingUtils
+
+
+def getMainWindow():
+ import maya.OpenMayaUI as mui
+ pointer = mui.MQtUtil.mainWindow()
+ # pyside QMainWindow takes in a QWidget rather than QObject
+ return shiboken.wrapInstance(long(pointer), QtWidgets.QWidget)
+
+
+class ART_SkinTools(QtWidgets.QMainWindow):
+ def __init__(self, mainUI, attachToRigInterface, parent):
+
+ super(ART_SkinTools, self).__init__(parent=None)
+
+ # get the directory path of the tools
+ settings = QtCore.QSettings("Epic Games", "ARTv2")
+ self.toolsPath = settings.value("toolsPath")
+ self.iconsPath = settings.value("iconPath")
+ self.mainUI = mainUI
+
+ # build the UI
+ self.buildSkinToolsUI(attachToRigInterface)
+
+ # UI Skin Cluster
+ self.skinCluster = None
+
+ # how to run the UI
+ if attachToRigInterface:
+ self.mainUI.toolModeStack.addWidget(self.deformationTabWidget)
+
+ # standalone (WORK IN PROGRESS)
+ else:
+ self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed))
+ self.setMinimumSize(QtCore.QSize(580, 600))
+ self.setMaximumSize(QtCore.QSize(580, 900))
+ self.setContentsMargins(0, 0, 0, 0)
+ self.resize(580, 900)
+ self.setCentralWidget(self.deformationTabWidget)
+
+ self.show()
+ self.weightTable_scriptJob()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def buildSkinToolsUI(self, attachToRigInterface):
+
+ # font
+ headerFont = QtGui.QFont()
+ headerFont.setPointSize(8)
+ headerFont.setBold(True)
+
+ # load stylesheet
+ styleSheetFile = utils.returnNicePath(self.toolsPath, "Core/Scripts/Interfaces/StyleSheets/mainScheme.qss")
+ f = open(styleSheetFile, "r")
+ self.style = f.read()
+ f.close()
+
+ styleSheetFile = utils.returnNicePath(self.toolsPath,
+ "Core/Scripts/Interfaces/StyleSheets/toolbarButtonsScheme.qss")
+ f = open(styleSheetFile, "r")
+ self.toolStyle = f.read()
+ f.close()
+
+ self.setStyleSheet(self.style)
+
+ # add the widget to the stacked widget
+ self.deformationTabWidget = QtWidgets.QWidget()
+ self.deformation_mainLayout = QtWidgets.QVBoxLayout(self.deformationTabWidget)
+
+ # create the menu bar
+ if attachToRigInterface:
+ self.deformation_menuBar = QtWidgets.QMenuBar()
+ self.deformation_menuBar.setMaximumHeight(20)
+ self.deformation_mainLayout.addWidget(self.deformation_menuBar)
+
+ # add items to menu bar
+ debugMenu = self.deformation_menuBar.addMenu("Development Tools")
+ debugMenu.addAction("Test Building Rigs", self.debugRigs)
+
+ # create the toolbar layout
+ self.deformation_toolFrame = QtWidgets.QFrame()
+ self.deformation_toolFrame.setStyleSheet(self.toolStyle)
+ self.deformation_toolFrame.setObjectName("dark")
+ self.deformation_toolFrame.setMaximumHeight(52)
+
+ self.deformation_mainLayout.addWidget(self.deformation_toolFrame)
+
+ self.deformation_toolbarLayout = QtWidgets.QHBoxLayout(self.deformation_toolFrame)
+ self.deformation_toolbarLayout.setDirection(QtWidgets.QBoxLayout.LeftToRight)
+ self.deformation_toolbarLayout.setSpacing(10)
+
+ # toolbar buttons
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/paintWeights.png")
+ self.weightTable_paintWeightsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_paintWeightsBtn)
+ self.weightTable_paintWeightsBtn.setMinimumSize(35, 35)
+ self.weightTable_paintWeightsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_paintWeightsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_paintWeightsBtn.setIcon(icon)
+ self.weightTable_paintWeightsBtn.clicked.connect(self.weightTable_paintWeightsMode)
+ self.weightTable_paintWeightsBtn.setToolTip("Paint Skin Weights Mode")
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/addRemove.png")
+ self.weightTable_addRemoveInfsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_addRemoveInfsBtn)
+ self.weightTable_addRemoveInfsBtn.setMinimumSize(35, 35)
+ self.weightTable_addRemoveInfsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_addRemoveInfsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_addRemoveInfsBtn.setIcon(icon)
+ self.weightTable_addRemoveInfsBtn.clicked.connect(self.addOrRemoveInfs_UI)
+ self.weightTable_addRemoveInfsBtn.setToolTip("Add or Remove Influences")
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/mirrorWeights.png")
+ self.weightTable_mirrorWeightsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_mirrorWeightsBtn)
+ self.weightTable_mirrorWeightsBtn.setMinimumSize(35, 35)
+ self.weightTable_mirrorWeightsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_mirrorWeightsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_mirrorWeightsBtn.setIcon(icon)
+ self.weightTable_mirrorWeightsBtn.clicked.connect(self.paintSkinWeights_mirrorSkinWeights)
+ self.weightTable_mirrorWeightsBtn.setToolTip("Mirror Skin Weights")
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/importSkin.png")
+ self.weightTable_importSkinWeightsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_importSkinWeightsBtn)
+ self.weightTable_importSkinWeightsBtn.setMinimumSize(35, 35)
+ self.weightTable_importSkinWeightsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_importSkinWeightsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_importSkinWeightsBtn.setIcon(icon)
+ self.weightTable_importSkinWeightsBtn.setFont(headerFont)
+ self.weightTable_importSkinWeightsBtn.clicked.connect(self.paintSkinWeights_importSkinWeights)
+ self.weightTable_importSkinWeightsBtn.setToolTip("Import Skin Weights")
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/exportSkin.png")
+ self.weightTable_exportSkinWeightsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_exportSkinWeightsBtn)
+ self.weightTable_exportSkinWeightsBtn.setMinimumSize(35, 35)
+ self.weightTable_exportSkinWeightsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_exportSkinWeightsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_exportSkinWeightsBtn.setIcon(icon)
+ self.weightTable_exportSkinWeightsBtn.clicked.connect(self.paintSkinWeights_exportSkinWeights)
+ self.weightTable_exportSkinWeightsBtn.setToolTip("Export Skin Weights")
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/smartCopy.png")
+ self.weightTable_smartCopyWeightsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_smartCopyWeightsBtn)
+ self.weightTable_smartCopyWeightsBtn.setMinimumSize(35, 35)
+ self.weightTable_smartCopyWeightsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_smartCopyWeightsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_smartCopyWeightsBtn.setIcon(icon)
+ self.weightTable_smartCopyWeightsBtn.clicked.connect(self.paintSkinWeights_copySkinWeights)
+ self.weightTable_smartCopyWeightsBtn.setToolTip("Copy Skin Weights")
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/moveInfs.png")
+ self.weightTable_moveInfsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_moveInfsBtn)
+ self.weightTable_moveInfsBtn.setMinimumSize(35, 35)
+ self.weightTable_moveInfsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_moveInfsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_moveInfsBtn.setIcon(icon)
+ self.weightTable_moveInfsBtn.clicked.connect(partial(self.moveInfluences_UI))
+ self.weightTable_moveInfsBtn.setToolTip("Move Influence Tool")
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/fixWeights.png")
+ self.weightTable_fixWeightsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_fixWeightsBtn)
+ self.weightTable_fixWeightsBtn.setMinimumSize(35, 35)
+ self.weightTable_fixWeightsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_fixWeightsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_fixWeightsBtn.setIcon(icon)
+ self.weightTable_fixWeightsBtn.setFont(headerFont)
+ self.weightTable_fixWeightsBtn.setToolTip("Fix Skin Weights")
+ self.weightTable_fixWeightsBtn.clicked.connect(riggingUtils.fixSkinWeights)
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/hammer.png")
+ self.weightTable_hammerWeightsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_hammerWeightsBtn)
+ self.weightTable_hammerWeightsBtn.setMinimumSize(35, 35)
+ self.weightTable_hammerWeightsBtn.setMaximumSize(35, 35)
+ self.weightTable_hammerWeightsBtn.setToolTip("Hammer Weights Tool")
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_hammerWeightsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_hammerWeightsBtn.setIcon(icon)
+ self.weightTable_hammerWeightsBtn.clicked.connect(self.paintSkinWeights_hammerSkinWeights)
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/wizard.png")
+ self.weightTable_weightWizardBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_weightWizardBtn)
+ self.weightTable_weightWizardBtn.setMinimumSize(35, 35)
+ self.weightTable_weightWizardBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_weightWizardBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_weightWizardBtn.setIcon(icon)
+ self.weightTable_weightWizardBtn.clicked.connect(self.paintSkinWeights_deformationWizardLaunch)
+ self.weightTable_weightWizardBtn.setToolTip("Launch Skinning Wizard")
+
+ buttonBkrd = utils.returnNicePath(self.iconsPath, "System/bindTool.png")
+ self.weightTable_bindWeightsBtn = QtWidgets.QPushButton()
+ self.deformation_toolbarLayout.addWidget(self.weightTable_bindWeightsBtn)
+ self.weightTable_bindWeightsBtn.setMinimumSize(35, 35)
+ self.weightTable_bindWeightsBtn.setMaximumSize(35, 35)
+ icon = QtGui.QIcon(buttonBkrd)
+ self.weightTable_bindWeightsBtn.setIconSize(QtCore.QSize(30, 30))
+ self.weightTable_bindWeightsBtn.setIcon(icon)
+ self.weightTable_bindWeightsBtn.clicked.connect(self.paintSkinWeights_smoothSkinUI)
+ self.weightTable_bindWeightsBtn.setToolTip("Smooth Bind Tool")
+
+ self.deformation_toolbarLayout.addSpacerItem(
+ QtWidgets.QSpacerItem(500, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed))
+
+ # Add Items to the Menu Bar
+
+ # Add the main widget that will house all of the main UI components
+ self.defomation_mainWidget = QtWidgets.QStackedWidget()
+ self.defomation_mainWidget.setObjectName("dark")
+ self.defomation_mainWidget.setMinimumSize(QtCore.QSize(560, 400))
+ self.defomation_mainWidget.setMaximumSize(QtCore.QSize(560, 900))
+ self.deformation_mainLayout.addWidget(self.defomation_mainWidget)
+
+ # add pages to the stackedwidget
+ self.defomation_subWidget = QtWidgets.QWidget()
+ self.defomation_mainWidget.addWidget(self.defomation_subWidget)
+ self.deformationPaintWeightsWidget = QtWidgets.QWidget()
+ self.defomation_mainWidget.addWidget(self.deformationPaintWeightsWidget)
+
+ # add hbox layout that splits tools and channel box
+ self.deformation_hBoxLayout = QtWidgets.QHBoxLayout(self.defomation_subWidget)
+ self.defomation_mainWidget.setCurrentIndex(0)
+
+ # tools layout scroll layout
+ self.weightTableScrollArea = QtWidgets.QScrollArea()
+ self.weightTableScrollArea.setMinimumSize(QtCore.QSize(310, 500))
+ self.weightTableScrollArea.setMaximumSize(QtCore.QSize(310, 6000))
+ self.weightTableScrollArea.setSizePolicy(
+ QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding))
+ self.weightTableScrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+ self.deformation_hBoxLayout.addWidget(self.weightTableScrollArea)
+
+ # frame
+ self.deformation_toolsLayout = QtWidgets.QFrame()
+ self.deformation_toolsLayout.setObjectName("dark")
+ self.deformation_toolsLayout.setMinimumSize(QtCore.QSize(290, 850))
+ self.deformation_toolsLayout.setMaximumSize(QtCore.QSize(290, 6000))
+ self.weightTableScrollArea.setWidget(self.deformation_toolsLayout)
+
+ self.weightTableMainLayout = QtWidgets.QVBoxLayout(self.deformation_toolsLayout)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # weight table
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ # weight table selection
+ self.weightTableSelectionFrame = QtWidgets.QGroupBox("Selection")
+ self.weightTableSelectionFrame.setFont(headerFont)
+ self.weightTableSelectionFrame.setObjectName("light")
+ self.weightTableSelectionFrame.setMinimumSize(QtCore.QSize(275, 100))
+ self.weightTableSelectionFrame.setMaximumSize(QtCore.QSize(275, 100))
+ self.weightTableSelectionMain = QtWidgets.QVBoxLayout(self.weightTableSelectionFrame)
+ self.weightTableSelection = QtWidgets.QHBoxLayout()
+ self.weightTableSelectionMain.addLayout(self.weightTableSelection)
+ self.weightTableMainLayout.addWidget(self.weightTableSelectionFrame)
+
+ self.growSelection = QtWidgets.QPushButton("Grow")
+ self.weightTableSelection.addWidget(self.growSelection)
+ self.growSelection.clicked.connect(partial(self.weightTable_growOrShrink, 1))
+ self.growSelection.setToolTip("Grow Selection")
+ self.growSelection.setObjectName("blueButton")
+
+ self.shrinkSelection = QtWidgets.QPushButton("Shrink")
+ self.weightTableSelection.addWidget(self.shrinkSelection)
+ self.shrinkSelection.clicked.connect(partial(self.weightTable_growOrShrink, 2))
+ self.shrinkSelection.setToolTip("Shrink Selection")
+ self.shrinkSelection.setObjectName("blueButton")
+
+ self.selectLoop = QtWidgets.QPushButton("Loop")
+ self.weightTableSelection.addWidget(self.selectLoop)
+ self.selectLoop.clicked.connect(partial(self.weightTable_loopOrRing, "loop"))
+ self.selectLoop.setToolTip("Select Edge Loop from Selection")
+ self.selectLoop.setObjectName("blueButton")
+
+ self.selectRing = QtWidgets.QPushButton("Ring")
+ self.weightTableSelection.addWidget(self.selectRing)
+ self.selectRing.clicked.connect(partial(self.weightTable_loopOrRing, "ring"))
+ self.selectRing.setToolTip("Select Edge Ring from Selection")
+ self.selectRing.setObjectName("blueButton")
+
+ self.selectShell = QtWidgets.QPushButton("Shell")
+ self.weightTableSelection.addWidget(self.selectShell)
+ self.selectShell.clicked.connect(self.weightTable_shell)
+ self.selectShell.setToolTip("Select Element")
+ self.selectShell.setObjectName("blueButton")
+
+ self.weightTableIsoLayout = QtWidgets.QHBoxLayout()
+ self.weightTableSelectionMain.addLayout(self.weightTableIsoLayout)
+
+ self.isolateSelection = QtWidgets.QPushButton("Isolate Selection")
+ self.weightTableIsoLayout.addWidget(self.isolateSelection)
+ self.isolateSelection.setCheckable(True)
+ self.isolateSelection.clicked.connect(self.weightTable_isolate)
+ self.isolateSelection.setToolTip("Isolate Selection")
+ self.isolateSelection.setObjectName("blueButton")
+
+ # preset weight values
+ self.weightTablePresetsFrame = QtWidgets.QGroupBox("Preset Weight Values")
+ self.weightTablePresetsFrame.setFont(headerFont)
+ self.weightTablePresetsFrame.setObjectName("light")
+ self.weightTablePresetsFrame.setMinimumSize(QtCore.QSize(275, 60))
+ self.weightTablePresetsFrame.setMaximumSize(QtCore.QSize(275, 60))
+ self.weightTablePresets = QtWidgets.QHBoxLayout(self.weightTablePresetsFrame)
+ self.weightTableMainLayout.addWidget(self.weightTablePresetsFrame)
+
+ self.weightPreset1 = QtWidgets.QPushButton("0")
+ self.weightTablePresets.addWidget(self.weightPreset1)
+ self.weightPreset1.clicked.connect(partial(self.weightTable_addWeight, 0.0))
+ self.weightPreset1.setObjectName("greenButton")
+
+ self.weightPreset2 = QtWidgets.QPushButton(".1")
+ self.weightTablePresets.addWidget(self.weightPreset2)
+ self.weightPreset2.clicked.connect(partial(self.weightTable_addWeight, 0.1))
+ self.weightPreset2.setObjectName("greenButton")
+
+ self.weightPreset3 = QtWidgets.QPushButton(".25")
+ self.weightTablePresets.addWidget(self.weightPreset3)
+ self.weightPreset3.clicked.connect(partial(self.weightTable_addWeight, 0.25))
+ self.weightPreset3.setObjectName("greenButton")
+
+ self.weightPreset4 = QtWidgets.QPushButton(".5")
+ self.weightTablePresets.addWidget(self.weightPreset4)
+ self.weightPreset4.clicked.connect(partial(self.weightTable_addWeight, 0.5))
+ self.weightPreset4.setObjectName("greenButton")
+
+ self.weightPreset5 = QtWidgets.QPushButton(".75")
+ self.weightTablePresets.addWidget(self.weightPreset5)
+ self.weightPreset5.clicked.connect(partial(self.weightTable_addWeight, 0.75))
+ self.weightPreset5.setObjectName("greenButton")
+
+ self.weightPreset6 = QtWidgets.QPushButton("1.0")
+ self.weightTablePresets.addWidget(self.weightPreset6)
+ self.weightPreset6.clicked.connect(partial(self.weightTable_addWeight, 1.0))
+ self.weightPreset6.setObjectName("greenButton")
+
+ # custom weight values
+ self.weightTableCustomFrame = QtWidgets.QGroupBox("Custom Weight Values")
+ self.weightTableCustomFrame.setFont(headerFont)
+ self.weightTableCustomFrame.setObjectName("light")
+ self.weightTableCustomFrame.setMinimumSize(QtCore.QSize(275, 80))
+ self.weightTableCustomFrame.setMaximumSize(QtCore.QSize(275, 80))
+ self.weightTableCustom = QtWidgets.QVBoxLayout(self.weightTableCustomFrame)
+ self.weightTableMainLayout.addWidget(self.weightTableCustomFrame)
+
+ self.setCustomWeightLayout = QtWidgets.QHBoxLayout()
+ self.weightTableCustom.addLayout(self.setCustomWeightLayout)
+
+ self.scaleCustomWeightLayout = QtWidgets.QHBoxLayout()
+ self.weightTableCustom.addLayout(self.scaleCustomWeightLayout)
+
+ # set weight
+ self.setCustomWeight = QtWidgets.QPushButton("Set Weight")
+ self.setCustomWeightLayout.addWidget(self.setCustomWeight)
+ self.setCustomWeight.clicked.connect(partial(self.weightTable_addWeight, None))
+ self.customWeightField = QtWidgets.QDoubleSpinBox()
+ self.setCustomWeightLayout.addWidget(self.customWeightField)
+ self.customWeightField.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
+ self.setCustomWeight.setObjectName("blueButton")
+ self.setCustomWeight.setMinimumHeight(25)
+
+ self.customWeightField.setRange(0.0, 1.0)
+ self.customWeightField.setValue(0.1)
+ self.customWeightField.setSingleStep(.01)
+
+ self.setCustomWeightIncrease = QtWidgets.QPushButton("+")
+ self.setCustomWeightLayout.addWidget(self.setCustomWeightIncrease)
+ self.setCustomWeightIncrease.setMinimumWidth(30)
+ self.setCustomWeightIncrease.setMaximumWidth(30)
+ self.setCustomWeightIncrease.clicked.connect(partial(self.weightTable_inrementWeight, "up"))
+ self.setCustomWeightIncrease.setObjectName("blueButton")
+ self.setCustomWeightIncrease.setMinimumHeight(25)
+
+ self.setCustomWeightDecrease = QtWidgets.QPushButton("-")
+ self.setCustomWeightLayout.addWidget(self.setCustomWeightDecrease)
+ self.setCustomWeightDecrease.setMinimumWidth(30)
+ self.setCustomWeightDecrease.setMaximumWidth(30)
+ self.setCustomWeightDecrease.clicked.connect(partial(self.weightTable_inrementWeight, "down"))
+ self.setCustomWeightDecrease.setObjectName("blueButton")
+ self.setCustomWeightDecrease.setMinimumHeight(25)
+
+ # scale weight
+ self.scaleCustomWeight = QtWidgets.QPushButton("Scale Weight")
+ self.scaleCustomWeightLayout.addWidget(self.scaleCustomWeight)
+ self.scaleCustomWeight.clicked.connect(partial(self.weightTable_scaleWeight, None))
+ self.scaleCustomWeight.setObjectName("blueButton")
+ self.scaleCustomWeight.setMinimumHeight(25)
+
+ self.scaleCustomWeightField = QtWidgets.QDoubleSpinBox()
+ self.scaleCustomWeightLayout.addWidget(self.scaleCustomWeightField)
+ self.scaleCustomWeightField.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
+
+ self.scaleCustomWeightField.setRange(0.0, 1.0)
+ self.scaleCustomWeightField.setValue(0.9)
+ self.scaleCustomWeightField.setSingleStep(.01)
+
+ self.scaleCustomWeightIncrease = QtWidgets.QPushButton("+")
+ self.scaleCustomWeightLayout.addWidget(self.scaleCustomWeightIncrease)
+ self.scaleCustomWeightIncrease.setMinimumWidth(30)
+ self.scaleCustomWeightIncrease.setMaximumWidth(30)
+ self.scaleCustomWeightIncrease.clicked.connect(partial(self.weightTable_scaleWeight, "up"))
+ self.scaleCustomWeightIncrease.setObjectName("blueButton")
+ self.scaleCustomWeightIncrease.setMinimumHeight(25)
+
+ self.scaleCustomWeightDecrease = QtWidgets.QPushButton("-")
+ self.scaleCustomWeightLayout.addWidget(self.scaleCustomWeightDecrease)
+ self.scaleCustomWeightDecrease.setMinimumWidth(30)
+ self.scaleCustomWeightDecrease.setMaximumWidth(30)
+ self.scaleCustomWeightDecrease.clicked.connect(partial(self.weightTable_scaleWeight, "down"))
+ self.scaleCustomWeightDecrease.setObjectName("blueButton")
+ self.scaleCustomWeightDecrease.setMinimumHeight(25)
+
+ # Value Transfer
+ self.weightTablevalueXferFrame = QtWidgets.QGroupBox("Value Transfer")
+ self.weightTablevalueXferFrame.setFont(headerFont)
+ self.weightTablevalueXferFrame.setObjectName("light")
+ self.weightTablevalueXferFrame.setMinimumSize(QtCore.QSize(275, 60))
+ self.weightTablevalueXferFrame.setMaximumSize(QtCore.QSize(275, 60))
+ self.weightTableXferLayout = QtWidgets.QHBoxLayout(self.weightTablevalueXferFrame)
+ self.weightTableMainLayout.addWidget(self.weightTablevalueXferFrame)
+
+ self.weightTable_copyValues = QtWidgets.QPushButton("Copy")
+ self.weightTableXferLayout.addWidget(self.weightTable_copyValues)
+ self.weightTable_copyValues.clicked.connect(self.weightTable_copyWeight)
+ self.weightTable_copyValues.setObjectName("blueButton")
+
+ self.weightTable_pasteValues = QtWidgets.QPushButton("Paste")
+ self.weightTableXferLayout.addWidget(self.weightTable_pasteValues)
+ self.weightTable_pasteValues.clicked.connect(self.weightTable_pasteWeight)
+ self.weightTable_pasteValues.setObjectName("blueButton")
+
+ self.weightTable_blendValues = QtWidgets.QPushButton("Blend")
+ self.weightTableXferLayout.addWidget(self.weightTable_blendValues)
+ self.weightTable_blendValues.clicked.connect(self.weightTable_blendWeight)
+ self.weightTable_blendValues.setObjectName("blueButton")
+
+ # vertex buffer
+ self.vertexBufferLayout = QtWidgets.QLineEdit()
+ self.vertexBufferLayout.setReadOnly(True)
+ self.weightTableMainLayout.addWidget(self.vertexBufferLayout)
+ self.vertexBufferLayout.setPlaceholderText("No vertex data copied...")
+
+ # List of skin joints
+ self.weightTablevalueskinJointsFrame = QtWidgets.QGroupBox("Skin Joints")
+ self.weightTablevalueskinJointsFrame.setFont(headerFont)
+ self.weightTablevalueskinJointsFrame.setObjectName("light")
+ self.weightTablevalueskinJointsFrame.setMinimumSize(QtCore.QSize(275, 200))
+ self.weightTablevalueskinJointsFrame.setMaximumSize(QtCore.QSize(275, 200))
+ self.weightTablevalueskinJointsLayout = QtWidgets.QHBoxLayout(self.weightTablevalueskinJointsFrame)
+ self.weightTableMainLayout.addWidget(self.weightTablevalueskinJointsFrame)
+
+ self.weightTable_skinJoints = QtWidgets.QListWidget()
+ self.weightTablevalueskinJointsLayout.addWidget(self.weightTable_skinJoints)
+ self.weightTable_skinJoints.itemClicked.connect(partial(self.weightTable_connectInfluenceLists, True, False))
+
+ # button layout
+ self.weightTableSkinJointsButtons = QtWidgets.QVBoxLayout()
+ self.weightTablevalueskinJointsLayout.addLayout(self.weightTableSkinJointsButtons)
+
+ # add show influenced verts button
+ self.weightTableShowInfVerts = QtWidgets.QPushButton()
+ self.weightTableSkinJointsButtons.addWidget(self.weightTableShowInfVerts)
+ self.weightTableShowInfVerts.setMinimumSize(QtCore.QSize(32, 32))
+ self.weightTableShowInfVerts.setMaximumSize(QtCore.QSize(32, 32))
+ self.weightTableShowInfVerts.setToolTip("Show vertices influenced by selected joint in list.")
+ self.weightTableShowInfVerts.clicked.connect(partial(self.weightTable_showInfluencedVerts, False))
+ icon = QtGui.QIcon(os.path.join(self.iconsPath, "System/showVerts.png"))
+ self.weightTableShowInfVerts.setIconSize(QtCore.QSize(30, 30))
+ self.weightTableShowInfVerts.setIcon(icon)
+
+ # show influenced verts in selection button
+ self.weightTableShowInfVertsSel = QtWidgets.QPushButton()
+ self.weightTableSkinJointsButtons.addWidget(self.weightTableShowInfVertsSel)
+ self.weightTableShowInfVertsSel.setMinimumSize(QtCore.QSize(32, 32))
+ self.weightTableShowInfVertsSel.setMaximumSize(QtCore.QSize(32, 32))
+ self.weightTableShowInfVertsSel.setToolTip("Show vertices influenced by selected joint in current selection.")
+ self.weightTableShowInfVertsSel.clicked.connect(partial(self.weightTable_showInfluencedVerts, True))
+ icon = QtGui.QIcon(os.path.join(self.iconsPath, "System/showVertsInSel.png"))
+ self.weightTableShowInfVertsSel.setIconSize(QtCore.QSize(30, 30))
+ self.weightTableShowInfVertsSel.setIcon(icon)
+
+ # toggle joint selection filter
+ self.weightTableJointSel = QtWidgets.QPushButton()
+ self.weightTableSkinJointsButtons.addWidget(self.weightTableJointSel)
+ self.weightTableJointSel.setMinimumSize(QtCore.QSize(32, 32))
+ self.weightTableJointSel.setMaximumSize(QtCore.QSize(32, 32))
+ self.weightTableJointSel.setToolTip("Toggle Joint Selection Filter.")
+ self.weightTableJointSel.setCheckable(True)
+ self.weightTableJointSel.clicked.connect(self.weightTable_toggleJointSelectMode)
+ icon = QtGui.QIcon(os.path.join(self.iconsPath, "System/jointFilter.png"))
+ self.weightTableJointSel.setIconSize(QtCore.QSize(30, 30))
+ self.weightTableJointSel.setIcon(icon)
+
+ # list of vertices' joints/influence amounts
+ self.weightTablevalueVertsFrame = QtWidgets.QGroupBox("Vertex Skin Info")
+ self.weightTablevalueVertsFrame.setObjectName("light")
+ self.weightTablevalueVertsFrame.setFont(headerFont)
+ self.weightTablevalueVertsFrame.setMinimumSize(QtCore.QSize(275, 200))
+ self.weightTablevalueVertsFrame.setMaximumSize(QtCore.QSize(275, 200))
+ self.weightTablevalueVertsLayout = QtWidgets.QHBoxLayout(self.weightTablevalueVertsFrame)
+ self.weightTableMainLayout.addWidget(self.weightTablevalueVertsFrame)
+ self.weightTableSplitter = QtWidgets.QSplitter()
+ self.weightTablevalueVertsLayout.addWidget(self.weightTableSplitter)
+
+ # vertex list
+ self.weightTableVertList = QtWidgets.QListWidget()
+ self.weightTableSplitter.addWidget(self.weightTableVertList)
+ self.weightTableVertList.itemClicked.connect(partial(self.weightTable_connectInfluenceLists, False, True))
+
+ # set context menu policy on groupbox
+ self.weightTableVertList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
+ self.weightTableVertList.customContextMenuRequested.connect(self.createContextMenuWeightTable)
+
+ # create the header
+ customColor = QtGui.QColor(25, 175, 255)
+ labelItem = QtWidgets.QListWidgetItem("Joint")
+ labelItem.setFont(headerFont)
+ labelItem.setFlags(QtCore.Qt.NoItemFlags)
+ labelItem.setForeground(customColor)
+ labelItem.setBackground(QtCore.Qt.black)
+ labelItem.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
+ self.weightTableVertList.addItem(labelItem)
+
+ # influence list
+ self.weightTableInfList = QtWidgets.QListWidget()
+ self.weightTableSplitter.addWidget(self.weightTableInfList)
+
+ # create the header
+ labelValue = QtWidgets.QListWidgetItem("Avg. Weight")
+ labelValue.setFont(headerFont)
+ labelValue.setFlags(QtCore.Qt.NoItemFlags)
+ labelValue.setForeground(customColor)
+ labelValue.setBackground(QtCore.Qt.black)
+ labelValue.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
+ self.weightTableInfList.addItem(labelValue)
+
+ # space
+ self.weightTableMainLayout.addSpacerItem(
+ QtWidgets.QSpacerItem(0, 50, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding))
+
+ # channel box layout frame
+ self.deformation_cbLayout = QtWidgets.QFrame()
+ self.deformation_cbLayout.setObjectName("dark")
+
+ # set dimensions of channel box frame
+ self.deformation_cbLayout.setMinimumSize(QtCore.QSize(220, 500))
+ self.deformation_cbLayout.setMaximumSize(QtCore.QSize(220, 900))
+ self.deformation_hBoxLayout.addWidget(self.deformation_cbLayout)
+
+ # add channel box layout
+ self.deformation_channelBoxLayout = QtWidgets.QVBoxLayout(self.deformation_cbLayout)
+
+ # add the channel box from Maya to the UI
+ channelBoxWidget = cmds.channelBox(w=150, h=600)
+ pointer = mui.MQtUtil.findControl(channelBoxWidget)
+ self.channelBox = shiboken.wrapInstance(long(pointer), QtWidgets.QWidget)
+ self.deformation_channelBoxLayout.addWidget(self.channelBox)
+ self.channelBox.show()
+ self.channelBox.setObjectName("darkImg")
+
+ self.deformation_channelBoxLayout.addSpacerItem(
+ QtWidgets.QSpacerItem(220, 500, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding))
+
+ # add the bottom buttons for Edit Setup and Build Rig
+ self.deformation_bottomButtonLayout = QtWidgets.QHBoxLayout()
+ self.deformation_bottomButtonLayout.setContentsMargins(25, 0, 0, 0)
+
+ if attachToRigInterface:
+ # edit setup
+ self.deformation_editSetupBtn = QtWidgets.QPushButton("Edit Setup")
+ self.deformation_editSetupBtn.setMinimumHeight(50)
+ self.deformation_editSetupBtn.setMaximumHeight(50)
+ self.deformation_bottomButtonLayout.addWidget(self.deformation_editSetupBtn)
+ self.deformation_mainLayout.addLayout(self.deformation_bottomButtonLayout)
+ self.deformation_editSetupBtn.clicked.connect(self.mainUI.editSetup)
+ self.deformation_editSetupBtn.setObjectName("blueButtonSpecial")
+ self.deformation_editSetupBtn.setProperty("boldFont", True)
+
+ # build rig
+ self.deformation_buildRigBtn = QtWidgets.QPushButton("Build Rig")
+ self.deformation_buildRigBtn.setMinimumHeight(50)
+ self.deformation_buildRigBtn.setMaximumHeight(50)
+ self.deformation_bottomButtonLayout.addWidget(self.deformation_buildRigBtn)
+ self.deformation_mainLayout.addLayout(self.deformation_bottomButtonLayout)
+ self.deformation_buildRigBtn.clicked.connect(self.mainUI.buildRig)
+ self.deformation_buildRigBtn.setObjectName("blueButtonSpecial")
+ self.deformation_buildRigBtn.setProperty("boldFont", True)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # PAINT SKIN WEIGHTS #
+ # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ # create the vertical layout
+ self.psw_topLevelLayout = QtWidgets.QVBoxLayout(self.deformationPaintWeightsWidget)
+
+ # create the scrollLayout
+ self.psw_paintWeightsScroll = QtWidgets.QScrollArea()
+ self.psw_topLevelLayout.addWidget(self.psw_paintWeightsScroll)
+ self.psw_paintWeightsScroll.setMinimumSize(QtCore.QSize(500, 500))
+ self.psw_paintWeightsScroll.setMaximumSize(QtCore.QSize(500, 6000))
+ self.psw_paintWeightsScroll.setSizePolicy(
+ QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed))
+ self.psw_paintWeightsScroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+
+ self.psw_paintWeightsScrollFrame = QtWidgets.QFrame(self.psw_paintWeightsScroll)
+ self.psw_paintWeightsScrollFrame.setObjectName("dark")
+ self.psw_paintWeightsScrollFrame.setMinimumSize(QtCore.QSize(500, 1100))
+ self.psw_paintWeightsScrollFrame.setMaximumSize(QtCore.QSize(500, 6000))
+ self.psw_paintWeightsScrollFrame.setSizePolicy(
+ QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding))
+
+ self.psw_paintWeightsScroll.setWidget(self.psw_paintWeightsScrollFrame)
+ self.psw_mainLayout = QtWidgets.QVBoxLayout(self.psw_paintWeightsScrollFrame)
+
+ # create the groupbox for influences
+ self.psw_groupBox = QtWidgets.QGroupBox("Influences")
+ self.psw_groupBox.setObjectName("light")
+ self.psw_groupBox.setMinimumSize(QtCore.QSize(470, 650))
+ self.psw_groupBox.setMaximumSize(QtCore.QSize(470, 650))
+ self.psw_groupBox.setFont(headerFont)
+ self.psw_mainLayout.addWidget(self.psw_groupBox)
+ self.psw_influenceLayout = QtWidgets.QVBoxLayout(self.psw_groupBox)
+
+ # # # influence searches # # #
+ self.psw_influenceSearchesLayout = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_influenceSearchesLayout)
+
+ self.psw_modSearchBar = QtWidgets.QLineEdit()
+ self.psw_modSearchBar.setPlaceholderText("Search Modules...")
+ self.psw_influenceSearchesLayout.addWidget(self.psw_modSearchBar)
+ self.psw_modSearchBar.textChanged.connect(self.paintSkinWeights_searchModules)
+
+ self.psw_infSearchBar = QtWidgets.QLineEdit()
+ self.psw_infSearchBar.setPlaceholderText("Search Influences...")
+ self.psw_influenceSearchesLayout.addWidget(self.psw_infSearchBar)
+ self.psw_infSearchBar.textChanged.connect(self.paintSkinWeights_searchInfluences)
+
+ # # # INFLUENCES # # #
+ self.psw_influenceListsLayout = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_influenceListsLayout)
+
+ # module list
+ self.psw_moduleInfluenceList = QtWidgets.QListWidget()
+ self.psw_influenceListsLayout.addWidget(self.psw_moduleInfluenceList)
+ self.psw_moduleInfluenceList.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
+ self.psw_moduleInfluenceList.itemSelectionChanged.connect(self.paintSkinWeights_populateInfs)
+
+ # influence list
+ self.psw_influenceList = QtWidgets.QListWidget()
+ self.psw_influenceListsLayout.addWidget(self.psw_influenceList)
+ self.psw_influenceList.itemClicked.connect(self.paintSkinWeights_changeInf)
+
+ # set context menu policy on influence list
+ self.psw_influenceList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
+ self.psw_influenceList.customContextMenuRequested.connect(self.paintSkinWeights_createContextMenu)
+
+ # paint mode
+ self.psw_paintModeLayout = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_paintModeLayout)
+ modeLabel = QtWidgets.QLabel("Mode: ")
+ modeLabel.setStyleSheet("background: transparent;")
+ modeLabel.setFont(headerFont)
+ self.psw_paintModeLayout.addWidget(modeLabel)
+
+ self.psw_paintModeButtonGrp = QtWidgets.QButtonGroup()
+
+ self.psw_paintMode_paint = QtWidgets.QRadioButton("Paint")
+ self.psw_paintModeLayout.addWidget(self.psw_paintMode_paint)
+ self.psw_paintMode_paint.setChecked(True)
+ self.psw_paintMode_paint.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "skinPaintMode", str(1), self.psw_paintMode_paint))
+
+ self.psw_paintMode_select = QtWidgets.QRadioButton("Select")
+ self.psw_paintModeLayout.addWidget(self.psw_paintMode_select)
+ self.psw_paintMode_select.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "skinPaintMode", str(0), self.psw_paintMode_select))
+
+ self.psw_paintMode_paintSelect = QtWidgets.QRadioButton("Paint Select")
+ self.psw_paintModeLayout.addWidget(self.psw_paintMode_paintSelect)
+ self.psw_paintMode_paintSelect.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "skinPaintMode", str(2), self.psw_paintMode_paintSelect))
+
+ self.psw_paintModeButtonGrp.addButton(self.psw_paintMode_paint, 1)
+ self.psw_paintModeButtonGrp.addButton(self.psw_paintMode_select, 2)
+ self.psw_paintModeButtonGrp.addButton(self.psw_paintMode_paintSelect, 3)
+
+ # paint select
+ self.psw_paintSelectLayout = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_paintSelectLayout)
+ paintSelectLabel = QtWidgets.QLabel("Paint Select: ")
+ paintSelectLabel.setStyleSheet("background: transparent;")
+ paintSelectLabel.setFont(headerFont)
+ self.psw_paintSelectLayout.addWidget(paintSelectLabel)
+
+ self.psw_paintSelectButtonGrp = QtWidgets.QButtonGroup()
+
+ self.psw_paintSelect_Add = QtWidgets.QRadioButton("Add")
+ self.psw_paintSelectLayout.addWidget(self.psw_paintSelect_Add)
+ self.psw_paintSelect_Add.setChecked(True)
+ self.psw_paintSelect_Add.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "paintSelectMode", str(1), self.psw_paintSelect_Add))
+
+ self.psw_paintSelect_Remove = QtWidgets.QRadioButton("Remove")
+ self.psw_paintSelectLayout.addWidget(self.psw_paintSelect_Remove)
+ self.psw_paintSelect_Remove.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "paintSelectMode", str(2), self.psw_paintSelect_Remove))
+
+ self.psw_paintSelect_Toggle = QtWidgets.QRadioButton("Toggle")
+ self.psw_paintSelectLayout.addWidget(self.psw_paintSelect_Toggle)
+ self.psw_paintSelect_Toggle.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "paintSelectMode", str(3), self.psw_paintSelect_Toggle))
+
+ self.psw_paintSelectButtonGrp.addButton(self.psw_paintSelect_Add, 1)
+ self.psw_paintSelectButtonGrp.addButton(self.psw_paintSelect_Remove, 2)
+ self.psw_paintSelectButtonGrp.addButton(self.psw_paintSelect_Toggle, 3)
+
+ # paint operation
+ self.psw_paintOperationLayout = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_paintOperationLayout)
+ paintOperationLabel = QtWidgets.QLabel("Paint Operation: ")
+ paintOperationLabel.setStyleSheet("background: transparent;")
+ paintOperationLabel.setFont(headerFont)
+ self.psw_paintOperationLayout.addWidget(paintOperationLabel)
+
+ self.psw_paintOperation = QtWidgets.QComboBox()
+ self.psw_paintOperationLayout.addWidget(self.psw_paintOperation)
+ self.psw_paintOperation.currentIndexChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "selectedattroper", "paintOp", self.psw_paintOperation))
+
+ self.psw_paintOperation.addItem("Add")
+ self.psw_paintOperation.addItem("Replace")
+ self.psw_paintOperation.addItem("Scale")
+ self.psw_paintOperation.addItem("Smooth")
+
+ # paint profile
+ self.paintProfileButtons = []
+ self.psw_paintProfileLayout = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_paintProfileLayout)
+ paintProfileLabel = QtWidgets.QLabel("Profile: ")
+ paintProfileLabel.setStyleSheet("background: transparent;")
+ paintProfileLabel.setFont(headerFont)
+ self.psw_paintProfileLayout.addWidget(paintProfileLabel)
+
+ self.paintProfile_buttonGrp = QtWidgets.QButtonGroup()
+
+ self.psw_paintProfile_Gaussian = QtWidgets.QPushButton()
+ self.psw_paintProfile_Gaussian.setMinimumSize(QtCore.QSize(35, 35))
+ self.psw_paintProfile_Gaussian.setMaximumSize(QtCore.QSize(35, 35))
+ self.psw_paintProfile_Gaussian.setIconSize(QtCore.QSize(30, 30))
+ self.psw_paintProfileLayout.addWidget(self.psw_paintProfile_Gaussian)
+ self.psw_paintProfile_Gaussian.setCheckable(True)
+ img = utils.returnNicePath(self.iconsPath, "System/gaussian.png")
+ self.psw_paintProfile_Gaussian.clicked.connect(
+ partial(self.paintSkinWeights_togglePaintProfile, self.psw_paintProfile_Gaussian, img))
+ self.paintProfileButtons.append([self.psw_paintProfile_Gaussian, img])
+ self.psw_paintProfile_Gaussian.setChecked(True)
+ self.psw_paintProfile_Gaussian.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "stampProfile", "\"" + "gaussian" + "\"",
+ self.psw_paintProfile_Gaussian))
+
+ self.psw_paintProfile_Soft = QtWidgets.QPushButton()
+ self.psw_paintProfile_Soft.setMinimumSize(QtCore.QSize(35, 35))
+ self.psw_paintProfile_Soft.setMaximumSize(QtCore.QSize(35, 35))
+ self.psw_paintProfile_Soft.setIconSize(QtCore.QSize(30, 30))
+ self.psw_paintProfileLayout.addWidget(self.psw_paintProfile_Soft)
+ self.psw_paintProfile_Soft.setCheckable(True)
+ img = utils.returnNicePath(self.iconsPath, "System/soft.png")
+ self.psw_paintProfile_Soft.clicked.connect(
+ partial(self.paintSkinWeights_togglePaintProfile, self.psw_paintProfile_Soft, img))
+ self.paintProfileButtons.append([self.psw_paintProfile_Soft, img])
+ self.psw_paintProfile_Soft.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "stampProfile", "\"" + "poly" + "\"", self.psw_paintProfile_Soft))
+
+ self.psw_paintProfile_Solid = QtWidgets.QPushButton()
+ self.psw_paintProfile_Solid.setMinimumSize(QtCore.QSize(35, 35))
+ self.psw_paintProfile_Solid.setMaximumSize(QtCore.QSize(35, 35))
+ self.psw_paintProfile_Solid.setIconSize(QtCore.QSize(30, 30))
+ self.psw_paintProfileLayout.addWidget(self.psw_paintProfile_Solid)
+ self.psw_paintProfile_Solid.setCheckable(True)
+ img = utils.returnNicePath(self.iconsPath, "System/solid.png")
+ self.psw_paintProfile_Solid.clicked.connect(
+ partial(self.paintSkinWeights_togglePaintProfile, self.psw_paintProfile_Solid, img))
+ self.paintProfileButtons.append([self.psw_paintProfile_Solid, img])
+ self.psw_paintProfile_Solid.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "stampProfile", "\"" + "solid" + "\"",
+ self.psw_paintProfile_Solid))
+
+ self.psw_paintProfile_Square = QtWidgets.QPushButton()
+ self.psw_paintProfile_Square.setMinimumSize(QtCore.QSize(35, 35))
+ self.psw_paintProfile_Square.setMaximumSize(QtCore.QSize(35, 35))
+ self.psw_paintProfile_Square.setIconSize(QtCore.QSize(30, 30))
+ self.psw_paintProfileLayout.addWidget(self.psw_paintProfile_Square)
+ self.psw_paintProfile_Square.setCheckable(True)
+ img = utils.returnNicePath(self.iconsPath, "System/square.png")
+ self.psw_paintProfile_Square.clicked.connect(
+ partial(self.paintSkinWeights_togglePaintProfile, self.psw_paintProfile_Square, img))
+ self.paintProfileButtons.append([self.psw_paintProfile_Square, img])
+ self.psw_paintProfile_Square.clicked.connect(
+ partial(self.paintSkinWeights_updateCTX, "stampProfile", "\"" + "square" + "\"",
+ self.psw_paintProfile_Square))
+
+ self.paintProfile_buttonGrp.addButton(self.psw_paintProfile_Gaussian, 1)
+ self.paintProfile_buttonGrp.addButton(self.psw_paintProfile_Soft, 2)
+ self.paintProfile_buttonGrp.addButton(self.psw_paintProfile_Solid, 3)
+ self.paintProfile_buttonGrp.addButton(self.psw_paintProfile_Square, 4)
+
+ # opacity
+ line = QtWidgets.QFrame()
+ line.setMinimumSize(400, 3)
+ line.setFrameShape(QtWidgets.QFrame.HLine)
+ line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ self.psw_influenceLayout.addWidget(line)
+
+ self.psw_opacityLayoutTop = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_opacityLayoutTop)
+
+ opacLabel = QtWidgets.QLabel("Opacity: ")
+ opacLabel.setStyleSheet("background: transparent;")
+ opacLabel.setFont(headerFont)
+ self.psw_opacityLayoutTop.addWidget(opacLabel)
+
+ # # # opacity slider # # #
+ self.psw_opacitySlider = QtWidgets.QSlider()
+ self.psw_opacityLayoutTop.addWidget(self.psw_opacitySlider)
+ self.psw_opacitySlider.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.psw_opacitySlider.setRange(0, 100)
+ self.psw_opacitySlider.setValue(100)
+ self.psw_opacitySlider.setSingleStep(1)
+ self.psw_opacitySlider.setPageStep(1)
+ self.psw_opacitySlider.setTickPosition(QtWidgets.QSlider.TicksAbove)
+ self.psw_opacitySlider.setTickInterval(20)
+
+ # # # opacity field # # #
+ self.psw_opacityField = QtWidgets.QDoubleSpinBox()
+ self.psw_opacityLayoutTop.addWidget(self.psw_opacityField)
+ self.psw_opacityField.setValue(1.00)
+ self.psw_opacityField.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
+ self.psw_opacityField.setReadOnly(True)
+
+ # # # opacity signals/slots # # #
+ self.psw_opacitySlider.valueChanged.connect(
+ partial(self.paintSkinWeights_UpdateSliders, self.psw_opacitySlider, self.psw_opacityField, True))
+ self.psw_opacitySlider.valueChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "opacity", "sliderEdit", self.psw_opacitySlider))
+
+ # # # opacity presets # # #
+ self.psw_opacityLayoutBottom = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_opacityLayoutBottom)
+
+ label = QtWidgets.QLabel("Presets: ")
+ label.setStyleSheet("background: transparent;")
+ label.setFont(headerFont)
+ self.psw_opacityLayoutBottom.addWidget(label)
+
+ self.psw_opacPreset1 = QtWidgets.QPushButton("0.00")
+ self.psw_opacPreset1.setMaximumSize(40, 20)
+ self.psw_opacPreset1.setMinimumSize(40, 20)
+ self.psw_opacityLayoutBottom.addWidget(self.psw_opacPreset1)
+ self.psw_opacPreset1.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_opacitySlider, 0))
+ self.psw_opacPreset1.setObjectName("blueButton")
+ self.psw_opacPreset1.setMinimumHeight(25)
+
+ self.psw_opacPreset2 = QtWidgets.QPushButton("0.10")
+ self.psw_opacPreset2.setMaximumSize(40, 20)
+ self.psw_opacPreset2.setMinimumSize(40, 20)
+ self.psw_opacityLayoutBottom.addWidget(self.psw_opacPreset2)
+ self.psw_opacPreset2.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_opacitySlider, 10))
+ self.psw_opacPreset2.setObjectName("blueButton")
+ self.psw_opacPreset2.setMinimumHeight(25)
+
+ self.psw_opacPreset3 = QtWidgets.QPushButton("0.25")
+ self.psw_opacPreset3.setMaximumSize(40, 20)
+ self.psw_opacPreset3.setMinimumSize(40, 20)
+ self.psw_opacityLayoutBottom.addWidget(self.psw_opacPreset3)
+ self.psw_opacPreset3.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_opacitySlider, 25))
+ self.psw_opacPreset3.setObjectName("blueButton")
+ self.psw_opacPreset3.setMinimumHeight(25)
+
+ self.psw_opacPreset4 = QtWidgets.QPushButton("0.50")
+ self.psw_opacPreset4.setMaximumSize(40, 20)
+ self.psw_opacPreset4.setMinimumSize(40, 20)
+ self.psw_opacityLayoutBottom.addWidget(self.psw_opacPreset4)
+ self.psw_opacPreset4.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_opacitySlider, 50))
+ self.psw_opacPreset4.setObjectName("blueButton")
+ self.psw_opacPreset4.setMinimumHeight(25)
+
+ self.psw_opacPreset5 = QtWidgets.QPushButton("0.75")
+ self.psw_opacPreset5.setMaximumSize(40, 20)
+ self.psw_opacPreset5.setMinimumSize(40, 20)
+ self.psw_opacityLayoutBottom.addWidget(self.psw_opacPreset5)
+ self.psw_opacPreset5.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_opacitySlider, 75))
+ self.psw_opacPreset5.setObjectName("blueButton")
+ self.psw_opacPreset5.setMinimumHeight(25)
+
+ self.psw_opacPreset6 = QtWidgets.QPushButton("1.00")
+ self.psw_opacPreset6.setMaximumSize(40, 20)
+ self.psw_opacPreset6.setMinimumSize(40, 20)
+ self.psw_opacityLayoutBottom.addWidget(self.psw_opacPreset6)
+ self.psw_opacPreset6.clicked.connect(
+ partial(self.paintSkinWeights_SetSliderValues, self.psw_opacitySlider, 100))
+ self.psw_opacPreset6.setObjectName("blueButton")
+ self.psw_opacPreset6.setMinimumHeight(25)
+
+ self.psw_opacityLayoutBottom.setSpacing(20)
+ self.psw_opacityLayoutBottom.addSpacerItem(
+ QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed))
+
+ # value
+ line = QtWidgets.QFrame()
+ line.setMinimumSize(400, 3)
+ line.setFrameShape(QtWidgets.QFrame.HLine)
+ line.setFrameShadow(QtWidgets.QFrame.Sunken)
+ self.psw_influenceLayout.addWidget(line)
+
+ self.psw_valueLayoutTop = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_valueLayoutTop)
+
+ valueLabel = QtWidgets.QLabel("Value: ")
+ valueLabel.setStyleSheet("background: transparent;")
+ valueLabel.setFont(headerFont)
+ self.psw_valueLayoutTop.addWidget(valueLabel)
+
+ # # # value slider # # #
+ self.psw_valueSlider = QtWidgets.QSlider()
+ self.psw_valueLayoutTop.addWidget(self.psw_valueSlider)
+ self.psw_valueSlider.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.psw_valueSlider.setRange(0, 100)
+ self.psw_valueSlider.setValue(100)
+ self.psw_valueSlider.setSingleStep(1)
+ self.psw_valueSlider.setPageStep(1)
+ self.psw_valueSlider.setTickPosition(QtWidgets.QSlider.TicksAbove)
+ self.psw_valueSlider.setTickInterval(20)
+
+ # # # value field # # #
+ self.psw_valueField = QtWidgets.QDoubleSpinBox()
+ self.psw_valueLayoutTop.addWidget(self.psw_valueField)
+ self.psw_valueField.setValue(1.00)
+ self.psw_valueField.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
+ self.psw_valueField.setReadOnly(True)
+
+ # # # value signals/slots # # #
+ self.psw_valueSlider.valueChanged.connect(
+ partial(self.paintSkinWeights_UpdateSliders, self.psw_valueSlider, self.psw_valueField, True))
+ self.psw_valueSlider.valueChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "value", "sliderEdit", self.psw_valueSlider))
+
+ # # # value presets # # #
+ self.psw_valueLayoutBottom = QtWidgets.QHBoxLayout()
+ self.psw_influenceLayout.addLayout(self.psw_valueLayoutBottom)
+
+ label = QtWidgets.QLabel("Presets: ")
+ label.setStyleSheet("background: transparent;")
+ label.setFont(headerFont)
+ self.psw_valueLayoutBottom.addWidget(label)
+
+ self.psw_valuePreset1 = QtWidgets.QPushButton("0.00")
+ self.psw_valuePreset1.setMaximumSize(40, 20)
+ self.psw_valuePreset1.setMinimumSize(40, 20)
+ self.psw_valueLayoutBottom.addWidget(self.psw_valuePreset1)
+ self.psw_valuePreset1.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_valueSlider, 0))
+ self.psw_valuePreset1.setObjectName("blueButton")
+ self.psw_valuePreset1.setMinimumHeight(25)
+
+ self.psw_valuePreset2 = QtWidgets.QPushButton("0.10")
+ self.psw_valuePreset2.setMaximumSize(40, 20)
+ self.psw_valuePreset2.setMinimumSize(40, 20)
+ self.psw_valueLayoutBottom.addWidget(self.psw_valuePreset2)
+ self.psw_valuePreset2.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_valueSlider, 10))
+ self.psw_valuePreset2.setObjectName("blueButton")
+ self.psw_valuePreset2.setMinimumHeight(25)
+
+ self.psw_valuePreset3 = QtWidgets.QPushButton("0.25")
+ self.psw_valuePreset3.setMaximumSize(40, 20)
+ self.psw_valuePreset3.setMinimumSize(40, 20)
+ self.psw_valueLayoutBottom.addWidget(self.psw_valuePreset3)
+ self.psw_valuePreset3.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_valueSlider, 25))
+ self.psw_valuePreset3.setObjectName("blueButton")
+ self.psw_valuePreset3.setMinimumHeight(25)
+
+ self.psw_valuePreset4 = QtWidgets.QPushButton("0.50")
+ self.psw_valuePreset4.setMaximumSize(40, 20)
+ self.psw_valuePreset4.setMinimumSize(40, 20)
+ self.psw_valueLayoutBottom.addWidget(self.psw_valuePreset4)
+ self.psw_valuePreset4.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_valueSlider, 50))
+ self.psw_valuePreset4.setObjectName("blueButton")
+ self.psw_valuePreset4.setMinimumHeight(25)
+
+ self.psw_valuePreset5 = QtWidgets.QPushButton("0.75")
+ self.psw_valuePreset5.setMaximumSize(40, 20)
+ self.psw_valuePreset5.setMinimumSize(40, 20)
+ self.psw_valueLayoutBottom.addWidget(self.psw_valuePreset5)
+ self.psw_valuePreset5.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_valueSlider, 75))
+ self.psw_valuePreset5.setObjectName("blueButton")
+ self.psw_valuePreset5.setMinimumHeight(25)
+
+ self.psw_valuePreset6 = QtWidgets.QPushButton("1.00")
+ self.psw_valuePreset6.setMaximumSize(40, 20)
+ self.psw_valuePreset6.setMinimumSize(40, 20)
+ self.psw_valueLayoutBottom.addWidget(self.psw_valuePreset6)
+ self.psw_valuePreset6.clicked.connect(partial(self.paintSkinWeights_SetSliderValues, self.psw_valueSlider, 100))
+ self.psw_valuePreset6.setObjectName("blueButton")
+ self.psw_valuePreset6.setMinimumHeight(25)
+
+ self.psw_valueLayoutBottom.setSpacing(20)
+ self.psw_valueLayoutBottom.addSpacerItem(
+ QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed))
+
+ # flood weights
+ self.psw_floodWeightsBtn = QtWidgets.QPushButton("Flood Weights")
+ self.psw_floodWeightsBtn.setFont(headerFont)
+ self.psw_floodWeightsBtn.setMaximumHeight(40)
+ self.psw_floodWeightsBtn.setMinimumHeight(40)
+ self.psw_influenceLayout.addWidget(self.psw_floodWeightsBtn)
+ self.psw_floodWeightsBtn.clicked.connect(self.paintSkinWeights_floodWeights)
+ self.psw_floodWeightsBtn.setObjectName("blueButton")
+
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # create the groupbox for stroke #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ self.psw_groupBoxStroke = QtWidgets.QGroupBox("Stroke")
+ self.psw_groupBoxStroke.setObjectName("light")
+ self.psw_groupBoxStroke.setMinimumSize(QtCore.QSize(470, 150))
+ self.psw_groupBoxStroke.setMaximumSize(QtCore.QSize(470, 150))
+ self.psw_groupBoxStroke.setFont(headerFont)
+ self.psw_mainLayout.addWidget(self.psw_groupBoxStroke)
+ self.psw_strokeLayout = QtWidgets.QVBoxLayout(self.psw_groupBoxStroke)
+
+ # # # radius(U) # # #
+ self.psw_radiusULayout = QtWidgets.QHBoxLayout()
+ self.psw_strokeLayout.addLayout(self.psw_radiusULayout)
+
+ radiusULabel = QtWidgets.QLabel("Radius(U): ")
+ radiusULabel.setStyleSheet("background: transparent;")
+ radiusULabel.setFont(headerFont)
+ self.psw_radiusULayout.addWidget(radiusULabel)
+
+ # # # radius(U) slider # # #
+ self.psw_radiusUSlider = QtWidgets.QSlider()
+ self.psw_radiusULayout.addWidget(self.psw_radiusUSlider)
+ self.psw_radiusUSlider.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.psw_radiusUSlider.setRange(0, 50)
+ self.psw_radiusUSlider.setValue(10)
+ self.psw_radiusUSlider.setSingleStep(1)
+ self.psw_radiusUSlider.setPageStep(1)
+ self.psw_radiusUSlider.setTickPosition(QtWidgets.QSlider.TicksAbove)
+ self.psw_radiusUSlider.setTickInterval(10)
+
+ # # # radius(U) field # # #
+ self.psw_radiusUField = QtWidgets.QDoubleSpinBox()
+ self.psw_radiusULayout.addWidget(self.psw_radiusUField)
+ self.psw_radiusUField.setValue(10.00)
+ self.psw_radiusUField.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
+ self.psw_radiusUField.setReadOnly(True)
+
+ # # # radius(U) signals/slots # # #
+ self.psw_radiusUSlider.valueChanged.connect(
+ partial(self.paintSkinWeights_UpdateSliders, self.psw_radiusUSlider, self.psw_radiusUField, False))
+ self.psw_radiusUSlider.valueChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "radius", "slider", self.psw_radiusUSlider))
+
+ # # # radius(L) # # #
+ self.psw_radiuslLayout = QtWidgets.QHBoxLayout()
+ self.psw_strokeLayout.addLayout(self.psw_radiuslLayout)
+
+ radiuslLabel = QtWidgets.QLabel("Radius(L): ")
+ radiuslLabel.setStyleSheet("background: transparent;")
+ radiuslLabel.setFont(headerFont)
+ self.psw_radiuslLayout.addWidget(radiuslLabel)
+
+ # # # radius(L) slider # # #
+ self.psw_radiuslSlider = QtWidgets.QSlider()
+ self.psw_radiuslLayout.addWidget(self.psw_radiuslSlider)
+ self.psw_radiuslSlider.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.psw_radiuslSlider.setRange(0, 50)
+ self.psw_radiuslSlider.setValue(0)
+ self.psw_radiuslSlider.setSingleStep(1)
+ self.psw_radiuslSlider.setPageStep(1)
+ self.psw_radiuslSlider.setTickPosition(QtWidgets.QSlider.TicksAbove)
+ self.psw_radiuslSlider.setTickInterval(10)
+
+ # # # radius(L) field # # #
+ self.psw_radiuslField = QtWidgets.QDoubleSpinBox()
+ self.psw_radiuslLayout.addWidget(self.psw_radiuslField)
+ self.psw_radiuslField.setValue(0.00)
+ self.psw_radiuslField.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
+ self.psw_radiuslField.setReadOnly(True)
+
+ # # # radius(L) signals/slots # # #
+ self.psw_radiuslSlider.valueChanged.connect(
+ partial(self.paintSkinWeights_UpdateSliders, self.psw_radiuslSlider, self.psw_radiuslField, False))
+ self.psw_radiuslSlider.valueChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "lowerradius", "slider", self.psw_radiuslSlider))
+
+ # # # reflection # # #
+ self.psw_reflectionTopLayout = QtWidgets.QHBoxLayout()
+ self.psw_strokeLayout.addLayout(self.psw_reflectionTopLayout)
+
+ self.psw_reflectionToggleCB = QtWidgets.QCheckBox("Reflection")
+ self.psw_reflectionTopLayout.addWidget(self.psw_reflectionToggleCB)
+ self.psw_reflectionToggleCB.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "reflection", None, self.psw_reflectionToggleCB))
+
+ self.psw_reflectionBottomLayout = QtWidgets.QHBoxLayout()
+ self.psw_strokeLayout.addLayout(self.psw_reflectionBottomLayout)
+
+ reflectLabel = QtWidgets.QLabel("Reflection Axis: ")
+ reflectLabel.setStyleSheet("background: transparent;")
+ reflectLabel.setFont(headerFont)
+ self.psw_reflectionBottomLayout.addWidget(reflectLabel)
+
+ self.psw_reflectAxisX = QtWidgets.QCheckBox("X")
+ self.psw_reflectionBottomLayout.addWidget(self.psw_reflectAxisX)
+ self.psw_reflectAxisX.setAutoExclusive(True)
+ self.psw_reflectAxisX.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "reflectionaxis", "\"" + "x" + "\"", self.psw_reflectAxisX))
+
+ self.psw_reflectAxisY = QtWidgets.QCheckBox("Y")
+ self.psw_reflectionBottomLayout.addWidget(self.psw_reflectAxisY)
+ self.psw_reflectAxisY.setAutoExclusive(True)
+ self.psw_reflectAxisY.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "reflectionaxis", "\"" + "y" + "\"", self.psw_reflectAxisY))
+
+ self.psw_reflectAxisZ = QtWidgets.QCheckBox("Z")
+ self.psw_reflectionBottomLayout.addWidget(self.psw_reflectAxisZ)
+ self.psw_reflectAxisZ.setAutoExclusive(True)
+ self.psw_reflectAxisZ.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "reflectionaxis", "\"" + "z" + "\"", self.psw_reflectAxisZ))
+
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # create the groupbox for stylus pressure #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ self.psw_groupBoxStylus = QtWidgets.QGroupBox("Stylus Pressure")
+ self.psw_groupBoxStylus.setObjectName("light")
+ self.psw_groupBoxStylus.setMinimumSize(QtCore.QSize(470, 100))
+ self.psw_groupBoxStylus.setMaximumSize(QtCore.QSize(470, 100))
+ self.psw_groupBoxStylus.setFont(headerFont)
+ self.psw_mainLayout.addWidget(self.psw_groupBoxStylus)
+ self.psw_stylusLayout = QtWidgets.QVBoxLayout(self.psw_groupBoxStylus)
+
+ self.psw_stylusPressureLayout = QtWidgets.QHBoxLayout()
+ self.psw_stylusLayout.addLayout(self.psw_stylusPressureLayout)
+
+ self.psw_stylusPressureToggle = QtWidgets.QCheckBox("Stylus Pressure")
+ self.psw_stylusPressureLayout.addWidget(self.psw_stylusPressureToggle)
+ self.psw_stylusPressureToggle.setChecked(True)
+ self.psw_stylusPressureToggle.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "usepressure", None, self.psw_stylusPressureToggle))
+
+ spLabel = QtWidgets.QLabel("Pressure Mapping: ")
+ spLabel.setStyleSheet("background: transparent;")
+ spLabel.setFont(headerFont)
+ self.psw_stylusPressureLayout.addWidget(spLabel)
+
+ self.psw_stylusPressureOptions = QtWidgets.QComboBox()
+ self.psw_stylusPressureLayout.addWidget(self.psw_stylusPressureOptions)
+ self.psw_stylusPressureOptions.currentIndexChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "mappressure", "mapping", self.psw_stylusPressureOptions))
+ self.psw_stylusPressureOptions.addItem("Opacity")
+ self.psw_stylusPressureOptions.addItem("Radius")
+ self.psw_stylusPressureOptions.addItem("Both")
+
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # create the groupbox for display settings #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # #
+ self.psw_groupBoxDisplay = QtWidgets.QGroupBox("Display")
+ self.psw_groupBoxDisplay.setObjectName("light")
+ self.psw_groupBoxDisplay.setMinimumSize(QtCore.QSize(470, 150))
+ self.psw_groupBoxDisplay.setMaximumSize(QtCore.QSize(470, 150))
+ self.psw_groupBoxDisplay.setFont(headerFont)
+ self.psw_mainLayout.addWidget(self.psw_groupBoxDisplay)
+ self.psw_displayLayout = QtWidgets.QVBoxLayout(self.psw_groupBoxDisplay)
+
+ # # # top settings # # #
+ self.psw_displaySettingsTop = QtWidgets.QHBoxLayout()
+ self.psw_displayLayout.addLayout(self.psw_displaySettingsTop)
+
+ self.psw_displayDrawBrush = QtWidgets.QCheckBox("Draw Brush")
+ self.psw_displaySettingsTop.addWidget(self.psw_displayDrawBrush)
+ self.psw_displayDrawBrush.setChecked(True)
+ self.psw_displayDrawBrush.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "outline", None, self.psw_displayDrawBrush))
+
+ self.psw_displayDrawBrushPaint = QtWidgets.QCheckBox("Draw Brush While Painting")
+ self.psw_displaySettingsTop.addWidget(self.psw_displayDrawBrushPaint)
+ self.psw_displayDrawBrushPaint.setChecked(True)
+ self.psw_displayDrawBrushPaint.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "outwhilepaint", None, self.psw_displayDrawBrushPaint))
+
+ # # # mid settings # # #
+ self.psw_displaySettingsMid = QtWidgets.QHBoxLayout()
+ self.psw_displayLayout.addLayout(self.psw_displaySettingsMid)
+
+ self.psw_displayDrawBrushTangent = QtWidgets.QCheckBox("Draw Brush Tangent Outline")
+ self.psw_displaySettingsMid.addWidget(self.psw_displayDrawBrushTangent)
+ self.psw_displayDrawBrushTangent.setChecked(True)
+ self.psw_displayDrawBrushTangent.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "tangentOutline", None, self.psw_displayDrawBrushTangent))
+
+ self.psw_displayDrawBrushFeedback = QtWidgets.QCheckBox("Draw Brush Feedback")
+ self.psw_displaySettingsMid.addWidget(self.psw_displayDrawBrushFeedback)
+ self.psw_displayDrawBrushFeedback.setChecked(True)
+ self.psw_displayDrawBrushFeedback.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "brushfeedback", None, self.psw_displayDrawBrushFeedback))
+
+ # # # bottom settings # # #
+ self.psw_displaySettingsBot1 = QtWidgets.QHBoxLayout()
+ self.psw_displayLayout.addLayout(self.psw_displaySettingsBot1)
+
+ self.psw_displayShowWires = QtWidgets.QCheckBox("Show Wireframe")
+ self.psw_displaySettingsBot1.addWidget(self.psw_displayShowWires)
+ self.psw_displayShowWires.setChecked(True)
+ self.psw_displayShowWires.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "showactive", None, self.psw_displayShowWires))
+
+ self.psw_displayColorFeedback = QtWidgets.QCheckBox("Color Feedback")
+ self.psw_displaySettingsBot1.addWidget(self.psw_displayColorFeedback)
+ self.psw_displayColorFeedback.setChecked(True)
+ self.psw_displayColorFeedback.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "colorfeedback", None, self.psw_displayColorFeedback))
+
+ # # # bottom settings 2 # # #
+ self.psw_displaySettingsBot2 = QtWidgets.QHBoxLayout()
+ self.psw_displayLayout.addLayout(self.psw_displaySettingsBot2)
+
+ self.psw_displayXRayJoints = QtWidgets.QCheckBox("X-Ray Joints")
+ self.psw_displaySettingsBot2.addWidget(self.psw_displayXRayJoints)
+ self.psw_displayXRayJoints.setChecked(False)
+ self.psw_displayXRayJoints.stateChanged.connect(
+ partial(self.paintSkinWeights_updateCTX, "xrayJoints", None, self.psw_displayXRayJoints))
+
+ # spacer
+ self.psw_mainLayout.addSpacerItem(
+ QtWidgets.QSpacerItem(500, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding))
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_scriptJob(self):
+ # create selection script job for populating weight table
+
+ jobs = cmds.scriptJob(listJobs=True)
+ try:
+ if self.wtScriptJob in jobs:
+ cmds.scriptJob(kill=self.wtScriptJob, force=True)
+ except:
+ pass
+
+ # create the script job
+ self.wtScriptJob = cmds.scriptJob(event=["SelectionChanged", self.weightTable_getInfs], kws=True)
+ return self.wtScriptJob
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_paintWeightsMode(self):
+
+ # paint weights mode
+ mel.eval("ArtPaintSkinWeightsTool;")
+
+ # change current index of the stack widget
+ self.defomation_mainWidget.setCurrentIndex(1)
+
+ # kick off script job to monitor when tool changes
+ self.paintWeightScriptJob = cmds.scriptJob(event=["ToolChanged", self.paintSkinWeightsScriptJob], runOnce=True,
+ kws=True)
+
+ # check artAttrSkinPaintCtx settings
+ currentCtx = cmds.currentCtx()
+
+ # # # influences # # #
+ skinPaintMode = cmds.artAttrSkinPaintCtx(currentCtx, q=True, skinPaintMode=True)
+ paintSelectMode = cmds.artAttrSkinPaintCtx(currentCtx, q=True, paintSelectMode=True)
+ selectedattroper = cmds.artAttrSkinPaintCtx(currentCtx, q=True, selectedattroper=True)
+ stampProfile = cmds.artAttrSkinPaintCtx(currentCtx, q=True, stampProfile=True)
+ opacity = cmds.artAttrSkinPaintCtx(currentCtx, q=True, opacity=True)
+ value = cmds.artAttrSkinPaintCtx(currentCtx, q=True, value=True)
+
+ if skinPaintMode == 0:
+ self.psw_paintMode_select.setChecked(True)
+ if skinPaintMode == 1:
+ self.psw_paintMode_paint.setChecked(True)
+ if skinPaintMode == 2:
+ self.psw_paintMode_paintSelect.setChecked(True)
+
+ if paintSelectMode == 1:
+ self.psw_paintSelect_Add.setChecked(True)
+ if paintSelectMode == 2:
+ self.psw_paintSelect_Remove.setChecked(True)
+ if paintSelectMode == 3:
+ self.psw_paintSelect_Toggle.setChecked(True)
+
+ if selectedattroper == "additive":
+ self.psw_paintOperation.setCurrentIndex(0)
+ if selectedattroper == "absolute":
+ self.psw_paintOperation.setCurrentIndex(1)
+ if selectedattroper == "scale":
+ self.psw_paintOperation.setCurrentIndex(21)
+ if selectedattroper == "smooth":
+ self.psw_paintOperation.setCurrentIndex(3)
+
+ if stampProfile == "gaussian":
+ self.psw_paintProfile_Gaussian.setChecked(True)
+ self.psw_paintProfile_Gaussian.click()
+ if stampProfile == "soft":
+ self.psw_paintProfile_Soft.setChecked(True)
+ self.psw_paintProfile_Soft.click()
+ if stampProfile == "solid":
+ self.psw_paintProfile_Solid.setChecked(True)
+ self.psw_paintProfile_Solid.click()
+ if stampProfile == "square":
+ self.psw_paintProfile_Square.setChecked(True)
+ self.psw_paintProfile_Square.click()
+
+ self.psw_opacitySlider.setValue(opacity * 100)
+ self.psw_valueSlider.setValue(value * 100)
+
+ # stroke
+ radius = cmds.artAttrSkinPaintCtx(currentCtx, q=True, radius=True)
+ lowerRadius = cmds.artAttrSkinPaintCtx(currentCtx, q=True, lowerradius=True)
+ reflection = cmds.artAttrSkinPaintCtx(currentCtx, q=True, reflection=True)
+ reflectionaxis = cmds.artAttrSkinPaintCtx(currentCtx, q=True, reflectionaxis=True)
+
+ self.psw_radiusUSlider.setValue(int(radius))
+ self.psw_radiuslSlider.setValue(lowerRadius)
+ self.psw_reflectionToggleCB.setChecked(reflection)
+
+ if reflectionaxis == "x":
+ self.psw_reflectAxisX.setChecked(True)
+ if reflectionaxis == "y":
+ self.psw_reflectAxisY.setChecked(True)
+ if reflectionaxis == "z":
+ self.psw_reflectAxisZ.setChecked(True)
+
+ # stylus pressure
+ usepressure = cmds.artAttrSkinPaintCtx(currentCtx, q=True, usepressure=True)
+ mappressure = cmds.artAttrSkinPaintCtx(currentCtx, q=True, mappressure=True)
+
+ self.psw_stylusPressureToggle.setChecked(usepressure)
+
+ if mappressure == "Opacity":
+ self.psw_stylusPressureOptions.setCurrentIndex(0)
+ if mappressure == "Radius":
+ self.psw_stylusPressureOptions.setCurrentIndex(1)
+ if mappressure == "Both":
+ self.psw_stylusPressureOptions.setCurrentIndex(2)
+
+ # display
+ outline = cmds.artAttrSkinPaintCtx(currentCtx, q=True, outline=True)
+ outwhilepaint = cmds.artAttrSkinPaintCtx(currentCtx, q=True, outwhilepaint=True)
+ tangentOutline = cmds.artAttrSkinPaintCtx(currentCtx, q=True, tangentOutline=True)
+ brushfeedback = cmds.artAttrSkinPaintCtx(currentCtx, q=True, brushfeedback=True)
+ showactive = cmds.artAttrSkinPaintCtx(currentCtx, q=True, showactive=True)
+ colorfeedback = cmds.artAttrSkinPaintCtx(currentCtx, q=True, colorfeedback=True)
+ xrayJoints = cmds.artAttrSkinPaintCtx(currentCtx, q=True, xrayJoints=True)
+
+ self.psw_displayDrawBrush.setChecked(outline)
+ self.psw_displayDrawBrushPaint.setChecked(outwhilepaint)
+ self.psw_displayDrawBrushTangent.setChecked(tangentOutline)
+ self.psw_displayDrawBrushFeedback.setChecked(brushfeedback)
+ self.psw_displayShowWires.setChecked(showactive)
+ self.psw_displayColorFeedback.setChecked(colorfeedback)
+ self.psw_displayXRayJoints.setChecked(xrayJoints)
+
+ # populate influence lists
+ self.paintSkinWeights_populateModules()
+ self.paintSkinWeights_populateInfs()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def paintSkinWeightsScriptJob(self):
+
+ # check current context
+ currentTool = cmds.currentCtx()
+
+ # if current context is not artAttrSkinCtx, setCurrentIndex back to 0
+ if currentTool != "artAttrSkinContext":
+ self.defomation_mainWidget.setCurrentIndex(0)
+
+ currentSelection = cmds.ls(sl=True)
+ cmds.select(clear=True)
+ cmds.select(currentSelection)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_populateModules(self):
+
+ # clear list
+ self.psw_moduleInfluenceList.clear()
+
+ # add modules to list
+ modules = utils.returnRigModules()
+ for module in modules:
+ name = cmds.getAttr(module + ".moduleName")
+ self.psw_moduleInfluenceList.addItem(name)
+
+ # select all modules, populating the entire influence list
+ self.psw_moduleInfluenceList.selectAll()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def paintSkinWeights_populateInfs(self):
+
+ # find the selected mesh
+ selection = cmds.ls(sl=True)
+
+ # clear influences in list
+ influences = []
+ self.psw_influenceList.clear()
+
+ # check if valid selection
+ if len(selection) >= 1:
+ mesh = selection[0]
+ if cmds.nodeType(mesh) == "transform":
+
+ # check for skinCluster
+ skinClusters = cmds.ls(type='skinCluster')
+
+ # go through each found skin cluster, and if we find a skin cluster whose geometry matches our selection
+ # get influences
+ for cluster in skinClusters:
+ geometry = cmds.skinCluster(cluster, q=True, g=True)[0]
+ geoTransform = cmds.listRelatives(geometry, parent=True)[0]
+ if geoTransform == mesh:
+ skinCluster = cluster
+ influences = cmds.skinCluster(cluster, q=True, inf=True)
+
+ # compare influences in list to selected modules
+ createdJoints = []
+ modules = utils.returnRigModules()
+ selectedModules = self.psw_moduleInfluenceList.selectedItems()
+
+ for each in selectedModules:
+ selectedText = each.text()
+ for module in modules:
+ modName = cmds.getAttr(module + ".moduleName")
+ if modName == selectedText:
+ # get joints of that module
+ createdBones = cmds.getAttr(module + ".Created_Bones")
+ splitJoints = createdBones.split("::")
+
+ for bone in splitJoints:
+ if bone != "":
+ createdJoints.append(bone)
+
+ # add the influneces to the list
+ if len(influences) > 0:
+ for inf in influences:
+ if inf in createdJoints:
+ lockColor = QtGui.QColor(0, 0, 0)
+ lockBkgrd = QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense2Pattern)
+ lockFont = QtGui.QFont()
+ lockFont.setPointSize(8)
+ lockFont.setBold(True)
+
+ item = QtWidgets.QListWidgetItem(inf)
+ locked = cmds.skinCluster(self.skinCluster, q=True, inf=inf, lw=True)
+ if locked:
+ item.setFont(lockFont)
+ item.setForeground(lockColor)
+ item.setBackground(lockBkgrd)
+ self.psw_influenceList.addItem(item)
+
+ # auto select the first item in the list
+ self.psw_influenceList.setCurrentRow(0)
+ self.paintSkinWeights_changeInf()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_changeInf(self):
+ try:
+ selected = self.psw_influenceList.selectedItems()
+ selected = selected[0].text()
+ currentCtx = cmds.currentCtx()
+ cmds.artAttrSkinPaintCtx(currentCtx, edit=True, influence=selected)
+
+ # loop through all of the influences in the list and set the tool to not have them selected
+ for i in range(self.psw_influenceList.count()):
+ item = self.psw_influenceList.item(i)
+ influence = item.text()
+ string = "artSkinInflListChanging " + "\"" + influence + "\"" + " 0;"
+ mel.eval(string)
+ string = "artSkinInflListChanged artAttrSkinPaintCtx;"
+ mel.eval(string)
+
+ # turn on the selected influence
+ string = "artSkinInflListChanging " + "\"" + selected + "\"" + " 1;"
+ mel.eval(string)
+ string = "artSkinInflListChanged artAttrSkinPaintCtx;"
+ mel.eval(string)
+ except:
+ pass
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_mirrorSkinWeights(self):
+
+ # get the current selection
+ selection = cmds.ls(sl=True, flatten=True)
+
+ # if the whole object is selected, use Maya's mirroring
+ if selection[0].find(".vtx") == -1:
+ mel.eval("MirrorSkinWeightsOptions;")
+
+ # if holding shift, use Maya's mirroring:
+ mods = cmds.getModifiers()
+ if (mods & 1) > 0:
+ mel.eval("MirrorSkinWeightsOptions;")
+
+ # otherwise, use custom mirroring
+ else:
+ # get selection and determine if selection is an object or component selection
+ selectionType = None
+
+ if len(selection) > 0:
+ if selection[0].find(".vtx") != -1:
+ selectionType = "vertex"
+ selectedVerts = selection
+ # find the object name
+ objectName = selection[0].partition(".vtx")[0]
+
+ else:
+ cmds.warning("No vertices selected.")
+ return
+
+ # find total number of vertices in object
+ totalNumVerts = cmds.polyEvaluate(objectName, v=True)
+ cmds.select(objectName + ".vtx[*]")
+ allVerts = cmds.ls(sl=True, flatten=True)
+ mirrorVertices = []
+
+ # find all joints in the object's skinCluster
+ skinClusters = cmds.ls(type='skinCluster')
+
+ # go through each found skin cluster, and if we find a skin cluster whose geometry matches our selection, get influences
+ for cluster in skinClusters:
+ geometry = cmds.skinCluster(cluster, q=True, g=True)[0]
+ geoTransform = cmds.listRelatives(geometry, parent=True)[0]
+ if geoTransform == objectName:
+ skinCluster = cluster
+ influences = cmds.skinCluster(cluster, q=True, inf=True)
+
+ # create the master list that will hold the vertex, its mirror, the influences of the vertex, the influences of the mirror, and the values
+ masterInfDataList = []
+ mirrorVertex = None
+
+ for vert in selectedVerts:
+ pos = cmds.pointPosition(vert)
+ mirrorVertPosition = [pos[0] * -1, pos[1], pos[2]]
+ mirrorVertPosX = mirrorVertPosition[0] * 1000
+ mirrorVertPosX = math.floor(mirrorVertPosX)
+
+ for i in range(totalNumVerts):
+ testPos = cmds.pointPosition(allVerts[i])
+ if testPos == mirrorVertPosition:
+ mirrorVertex = allVerts[i]
+ mirrorVertices.append(mirrorVertex)
+
+ # get this vert's influence information
+ vertexInfs = cmds.skinPercent(skinCluster, vert, q=True, ignoreBelow=0.0001, transform=None)
+ infValues = cmds.skinPercent(skinCluster, vert, q=True, ignoreBelow=0.0001, value=True)
+
+ # get the world position of the vertexInfs
+ mirrorInfs = []
+ for inf in vertexInfs:
+ worldPos = cmds.xform(inf, q=True, ws=True, t=True)
+
+ # try to get the mirror influence
+ mirrorPos = [round(worldPos[0] * -1, 2), round(worldPos[1], 2), round(worldPos[2], 2)]
+
+ for each in influences:
+ infPos = cmds.xform(each, q=True, ws=True, t=True)
+ newPos = [round(infPos[0], 2), round(infPos[1], 2), round(infPos[2], 2)]
+ if newPos == mirrorPos:
+ mirrorInfs.append(each)
+
+ # now we have all of the data needed to perform the mirror
+ data = [vert, mirrorVertex, vertexInfs, mirrorInfs, infValues]
+
+ # perform mirror
+ vert = data[1]
+ infs = data[3]
+ vals = data[4]
+
+ # transformValueList
+ if vert != None:
+ if len(data[2]) == len(data[3]):
+ cmds.skinPercent(skinCluster, vert, transformValue=[infs[0], 1.0])
+
+ transformValueList = []
+ for i in range(len(infs)):
+ transformValueList.append((str(infs[i]), float(vals[i])))
+
+ cmds.skinPercent(skinCluster, vert, transformValue=transformValueList)
+
+ else:
+ cmds.warning("skipping " + str(data[1]) + ". Missing symmetrical influence.")
+
+ if len(mirrorVertices) > 0:
+ cmds.select(mirrorVertices)
+ else:
+ cmds.select(selection)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_copySkinWeights(self):
+
+ selection = cmds.ls(sl=True)
+
+ if len(selection) > 1:
+ fromObj = selection[0]
+
+ fromSkinCluster = riggingUtils.findRelatedSkinCluster(fromObj)
+ fromJoints = cmds.skinCluster(fromSkinCluster, q=True, inf=True)
+
+ cmds.select(selection[1])
+ cmds.select(fromJoints, tgl=True)
+
+ mel.eval("doEnableNodeItems false all;")
+ cmds.dagPose(r=True, g=True, bp=True)
+
+ newSkinCluster = cmds.skinCluster(tsb=True, mi=0, dr=4, sm=0)[0]
+ cmds.copySkinWeights(ss=fromSkinCluster, ds=newSkinCluster, noMirror=True)
+ mel.eval("doEnableNodeItems true all;")
+ else:
+ cmds.warning("Please select a source and target mesh.")
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_hammerSkinWeights(self):
+
+ try:
+ mel.eval("weightHammerVerts;")
+
+ except:
+ cmds.confirmDialog(icon="warning", title="Hammer Skin Weights",
+ message="The weight hammer works on polygon vertices. Please select at least 1 vertex.")
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_growOrShrink(self, mode):
+
+ # validate selection
+ valid = False
+ selection = cmds.ls(sl=True, flatten=True)
+ for each in selection:
+ if each.find("vtx") != -1:
+ valid = True
+
+ if valid:
+ cmds.polySelectConstraint(t=0x0001, pp=mode)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_loopOrRing(self, mode):
+
+ # check length of selection
+ valid = False
+ selection = cmds.ls(sl=True, flatten=True)
+ for each in selection:
+ if each.find("vtx") != -1:
+ valid = True
+
+ # check length of selection
+ if valid:
+ if len(selection) >= 2:
+ # convert the selection to edges
+ edges = cmds.polyListComponentConversion(fv=True, te=True, internal=True)
+ cmds.select(edges)
+
+ # get the edge loop or ring
+ if mode == "loop":
+ cmds.polySelectSp(loop=True)
+ if mode == "ring":
+ cmds.polySelectSp(ring=True)
+
+ # set back to verts
+ verts = cmds.polyListComponentConversion(fe=True, tv=True)
+ cmds.select(verts)
+ else:
+ cmds.warning("Please select at least two vertices.")
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_shell(self):
+
+ # validate selection
+ valid = False
+ selection = cmds.ls(sl=True, flatten=True)
+ for each in selection:
+ if each.find("vtx") != -1:
+ valid = True
+ if valid:
+ cmds.ConvertSelectionToShell()
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_isolate(self):
+
+ # get button state
+ state = self.isolateSelection.isChecked()
+
+ # validate selection
+ valid = False
+ selection = cmds.ls(sl=True, flatten=True)
+ for each in selection:
+ if each.find("vtx") != -1:
+ valid = True
+
+ if valid:
+ if state:
+ # convert selection to faces, grab shell, then back to verts
+ cmds.select(cmds.polyListComponentConversion(tf=True))
+ cmds.ConvertSelectionToShell()
+
+ # isolate selection
+ isoPnl = cmds.getPanel(wf=True)
+ isoCrnt = cmds.isolateSelect(isoPnl, q=True, s=True)
+ mel.eval('enableIsolateSelect %s %d' % (isoPnl, not isoCrnt))
+
+ # convert back to verts
+ cmds.select(cmds.polyListComponentConversion(tv=True))
+
+ # change the button text to exit isolation mode
+ self.isolateSelection.setText("Exit Isolation Mode")
+
+ if not state:
+ isoPnl = cmds.getPanel(wf=True)
+ isoCrnt = cmds.isolateSelect(isoPnl, q=True, s=True)
+ mel.eval('enableIsolateSelect %s %d' % (isoPnl, not isoCrnt))
+
+ # change the button text to exit isolation mode
+ self.isolateSelection.setText("Isolate Selection")
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_addWeight(self, amount):
+
+ # if no amount passed in, get amount from setWeight spin box
+ if amount == None:
+ amount = self.customWeightField.value()
+
+ # get the selected transform from either list
+ selectedTransformData = self.weightTable_getSelectedTransform()
+ selectedTransform = selectedTransformData[0]
+ lockInfs = selectedTransformData[1]
+ length = selectedTransformData[2]
+
+ # get skin cluster for selected verts
+ cluster = self.weightTable_getSkinForSelected(selectedTransform, lockInfs)
+
+ # skin the selected verts to the selected trasnform with the incoming amount
+ canProceed = self.weightTable_checkIfLocked()
+ if canProceed:
+ if selectedTransform != None:
+ if length > 2:
+ cmds.undoInfo(openChunk=True)
+ cmds.skinPercent(cluster, transformValue=[selectedTransform, amount])
+ cmds.undoInfo(closeChunk=True)
+ if selectedTransform != None:
+ if length == 2:
+ if len(self.weightTable_skinJoints.selectedItems()) > 0:
+ cmds.undoInfo(openChunk=True)
+ cmds.skinPercent(cluster, transformValue=[selectedTransform, amount])
+ cmds.undoInfo(closeChunk=True)
+
+ if selectedTransform == None:
+ cmds.warning("No influence selected in list to add weight to.")
+
+ if lockInfs:
+ self.weightTable_lockInfs(selectedTransform, lockInfs, cluster, False)
+
+ # refresh UI
+ self.weightTable_getInfs()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_getSelectedTransform(self):
+
+ # get the selected transform from either list
+ selectedTransform = None
+ lockInfs = False
+ length = self.weightTableVertList.count()
+
+ if len(self.weightTable_skinJoints.selectedItems()) > 0:
+ selectedTransformItem = self.weightTable_skinJoints.selectedItems()
+ selectedTransform = selectedTransformItem[0].text()
+
+ if len(self.weightTableVertList.selectedItems()) > 0:
+ selectedTransformItem = self.weightTableVertList.selectedItems()
+ selectedTransform = selectedTransformItem[0].text()
+ lockInfs = True
+
+ return [selectedTransform, lockInfs, length]
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_getSkinForSelected(self, selectedTransform, lockInfs):
+ # if vertices are selected, get that selection
+ if self.weightTableVertList.count() > 0:
+ selection = cmds.ls(sl=True, fl=True)
+ # find the shape node associated with the seleted vertices
+ shape = cmds.listRelatives(cmds.ls(sl=True), parent=True)[0]
+ # find the transform of the shape
+ transform = cmds.listRelatives(shape, parent=True)[0]
+ # find the skin cluster associated with the shape node
+ connnections = cmds.listConnections(shape, connections=True)
+ for c in connnections:
+ if cmds.nodeType(c) == "skinCluster":
+ cluster = c
+ if selectedTransform != None:
+ # now if lockInfs is True, lock all influences not in the weightTableVertList
+ if lockInfs:
+ self.weightTable_lockInfs(selectedTransform, lockInfs, c, True)
+ return cluster
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_checkIfLocked(self):
+
+ numLocked = []
+ for i in range(self.weightTableVertList.count()):
+ item = self.weightTableVertList.item(i)
+ jointName = item.text()
+
+ # check to see if the joint is locked
+ if cmds.objExists(jointName):
+ locked = cmds.skinCluster(self.skinCluster, q=True, inf=jointName, lw=True)
+ if locked:
+ numLocked.append(jointName)
+
+ if len(numLocked) < (self.weightTableVertList.count() - 1):
+ return True
+ else:
+ return False
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_lockInfs(self, selectedTransform, lockInfs, cluster, lock):
+ # get all of the influences
+ allInfs = []
+ previouslyLocked = []
+ allInfItems = self.weightTable_skinJoints.count()
+ for i in range(allInfItems):
+ allInfs.append(self.weightTable_skinJoints.item(i).text())
+
+ # get the influences in the weightTableVertList
+ doNotLock = []
+ vertsInfs = self.weightTableVertList.count()
+ for i in range(vertsInfs):
+ jointName = self.weightTableVertList.item(i).text()
+ if cmds.objExists(jointName):
+ locked = cmds.skinCluster(cluster, q=True, inf=jointName, lw=True)
+ if not locked:
+ doNotLock.append(self.weightTableVertList.item(i).text())
+ if locked:
+ previouslyLocked.append(self.weightTableVertList.item(i).text())
+
+ # lock infs not in doNotLock list
+ if lock:
+ for inf in allInfs:
+ if inf not in doNotLock:
+ cmds.skinCluster(cluster, edit=True, inf=inf, lockWeights=True)
+
+ if lock == False:
+ # unlock infs not in doNotLock list
+ for inf in allInfs:
+ if inf not in doNotLock:
+ cmds.skinCluster(cluster, edit=True, inf=inf, lockWeights=False)
+ for inf in previouslyLocked:
+ cmds.skinCluster(cluster, edit=True, inf=inf, lockWeights=True)
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_getInfs(self):
+
+ currentSelection = None
+ listWidget = None
+ # get current selection in lists
+ if len(self.weightTable_skinJoints.selectedItems()) > 0:
+ currentSelection = self.weightTable_skinJoints.selectedItems()[0].text()
+ listWidget = self.weightTable_skinJoints
+
+ if len(self.weightTableVertList.selectedItems()) > 0:
+ currentSelection = self.weightTableVertList.selectedItems()[0].text()
+ listWidget = self.weightTableVertList
+
+ # clear the influence list
+ self.weightTable_skinJoints.clear()
+ self.weightTableVertList.clear()
+ self.weightTableInfList.clear()
+
+ # find the selected mesh
+ selection = cmds.ls(sl=True)
+ if len(selection) >= 1:
+ mesh = selection[0]
+
+ if cmds.nodeType(mesh) == "transform":
+ self.weightTable_populateSkinJoints(mesh)
+ if cmds.nodeType(mesh) == "mesh":
+ shapeNode = cmds.listRelatives(mesh, parent=True)
+ if shapeNode != None:
+ transformNode = cmds.listRelatives(shapeNode[0], parent=True)
+ if transformNode != None:
+ cluster = self.weightTable_populateSkinJoints(transformNode[0])
+
+ # vertex influence list
+ self.weightTable_populateVertexJoints(selection, cluster)
+
+ # reselect
+ if currentSelection != None:
+ items = listWidget.findItems(currentSelection, QtCore.Qt.MatchExactly)
+ if len(items) == 1:
+ row = listWidget.row(items[0])
+ listWidget.setCurrentRow(row)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_populateSkinJoints(self, mesh):
+
+ # check for skinCluster
+ skinClusters = cmds.ls(type='skinCluster')
+ self.influences = []
+
+ # go through each found skin cluster, and if we find a skin cluster whose geometry matches our selection, get influences
+ for cluster in skinClusters:
+ geometry = cmds.skinCluster(cluster, q=True, g=True)[0]
+ geoTransform = cmds.listRelatives(geometry, parent=True)[0]
+ if geoTransform == mesh:
+ self.skinCluster = cluster
+ self.influences = cmds.skinCluster(cluster, q=True, inf=True)
+
+ # add the influneces to the list
+ if len(self.influences) > 0:
+ for inf in self.influences:
+ self.weightTable_skinJoints.addItem(inf)
+
+ # return info
+ if self.skinCluster != None:
+ return self.skinCluster
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_populateVertexJoints(self, vertices, cluster):
+
+ # find all of the influences of the selected vertices
+ influenceJoints = []
+ for vertex in vertices:
+ infs = cmds.skinPercent(cluster, vertex, q=True, transform=None, ib=.001)
+ for inf in infs:
+ influenceJoints.append(inf)
+
+ # remove duplicates from the influence joints list
+ vertInfluences = []
+ vertInfluences = list(set(influenceJoints))
+
+ # re-create the headers
+ headerFont = QtGui.QFont()
+ headerFont.setPointSize(8)
+ headerFont.setBold(True)
+
+ customColor = QtGui.QColor(25, 175, 255)
+ labelItem = QtWidgets.QListWidgetItem("Joint")
+ labelItem.setFont(headerFont)
+ labelItem.setFlags(QtCore.Qt.NoItemFlags)
+ labelItem.setForeground(customColor)
+ labelItem.setBackground(QtCore.Qt.black)
+ labelItem.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
+ self.weightTableVertList.addItem(labelItem)
+
+ # add these to the weightTableVertList
+ lockColor = QtGui.QColor(255, 0, 0)
+ lockFont = QtGui.QFont()
+ lockFont.setPointSize(8)
+ lockFont.setBold(True)
+
+ for each in vertInfluences:
+
+ item = QtWidgets.QListWidgetItem(each)
+ locked = cmds.skinCluster(cluster, q=True, inf=each, lw=True)
+ if locked:
+ item.setFont(lockFont)
+ item.setForeground(lockColor)
+
+ self.weightTableVertList.addItem(item)
+
+ # find average weights
+ self.weightTable_populateAvgWeight(vertices, cluster, vertInfluences)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_populateAvgWeight(self, vertices, cluster, influences):
+
+ # find the infleunce values for each vertex
+ averages = []
+ for influence in influences:
+ data = []
+ for vert in vertices:
+ value = cmds.skinPercent(cluster, vert, q=True, transform=influence)
+ data.append(value)
+ avg = sum(data) / float(len(data))
+ averages.append(avg)
+
+ # recreate the header
+ customColor = QtGui.QColor(25, 175, 255)
+ headerFont = QtGui.QFont()
+ headerFont.setPointSize(8)
+ headerFont.setBold(True)
+
+ labelValue = QtWidgets.QListWidgetItem("Avg. Weight")
+ labelValue.setFont(headerFont)
+ labelValue.setFlags(QtCore.Qt.NoItemFlags)
+ labelValue.setForeground(customColor)
+ labelValue.setBackground(QtCore.Qt.black)
+ labelValue.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
+ self.weightTableInfList.addItem(labelValue)
+
+ # add averages
+ for each in averages:
+ entry = '{0:.10f}'.format(each)
+ self.weightTableInfList.addItem(str(entry))
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_inrementWeight(self, direction):
+
+ # get the amount from setWeight
+ amount = self.customWeightField.value()
+
+ # get the selected transform from either list
+ selectedTransformData = self.weightTable_getSelectedTransform()
+ selectedTransform = selectedTransformData[0]
+ lockInfs = selectedTransformData[1]
+ length = selectedTransformData[2]
+
+ # get skin cluster for selected verts
+ cluster = self.weightTable_getSkinForSelected(selectedTransform, lockInfs)
+
+ # skin the selected verts to the selected trasnform with the incoming amount
+ if length > 1:
+ if selectedTransform != None:
+ if direction == "up":
+ cmds.undoInfo(openChunk=True)
+ cmds.skinPercent(cluster, relative=True, transformValue=[selectedTransform, amount])
+ cmds.undoInfo(closeChunk=True)
+
+ if direction == "down":
+ cmds.undoInfo(openChunk=True)
+ cmds.skinPercent(cluster, relative=True, transformValue=[selectedTransform, (amount * -1)])
+ cmds.undoInfo(closeChunk=True)
+
+ if lockInfs:
+ self.weightTable_lockInfs(selectedTransform, lockInfs, cluster, False)
+
+ # refresh UI
+ self.weightTable_getInfs()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_scaleWeight(self, direction):
+
+ # if no amount passed in, get amount from setWeight spin box
+ amount = self.scaleCustomWeightField.value()
+
+ # get the selected transform from either list
+ selectedTransformData = self.weightTable_getSelectedTransform()
+ selectedTransform = selectedTransformData[0]
+ lockInfs = selectedTransformData[1]
+ length = selectedTransformData[2]
+
+ # get skin cluster for selected verts
+ cluster = self.weightTable_getSkinForSelected(selectedTransform, lockInfs)
+
+ # skin the selected verts to the selected trasnform with the incoming amount
+ selection = cmds.ls(sl=True, fl=True)
+ for each in selection:
+ currentValue = cmds.skinPercent(cluster, each, transform=selectedTransform, q=True)
+ if length > 2:
+ if selectedTransform != None:
+ if direction == None:
+ cmds.undoInfo(openChunk=True)
+ cmds.skinPercent(cluster, transformValue=[selectedTransform, (currentValue * amount)])
+ cmds.undoInfo(closeChunk=True)
+
+ if direction == "up":
+ cmds.undoInfo(openChunk=True)
+ cmds.skinPercent(cluster, transformValue=[selectedTransform,
+ (((currentValue * 5) / 100) + currentValue)])
+ cmds.undoInfo(closeChunk=True)
+
+ if direction == "down":
+ cmds.undoInfo(openChunk=True)
+ cmds.skinPercent(cluster, transformValue=[selectedTransform,
+ (currentValue - ((currentValue * 5) / 100))])
+ cmds.undoInfo(closeChunk=True)
+
+ if lockInfs:
+ self.weightTable_lockInfs(selectedTransform, lockInfs, cluster, False)
+
+ # refresh UI
+ self.weightTable_getInfs()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_copyWeight(self):
+
+ self.weightCopy_infList = []
+ self.weightCopy_valList = []
+
+ selection = cmds.ls(sl=True, flatten=True)
+ if len(selection) > 1:
+ cmds.warning("Please select only 1 vertex.")
+ return
+
+ else:
+ if selection[0].find(".vtx") != -1:
+ # get weight values
+ self.weightCopy_infList = cmds.skinPercent(self.skinCluster, selection[0], q=True, transform=None,
+ ib=.001)
+ self.weightCopy_valList = cmds.skinPercent(self.skinCluster, selection[0], q=True, value=True, ib=.001)
+
+ # update line edit
+ self.vertexBufferLayout.setText(selection[0] + " copied to buffer")
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_pasteWeight(self):
+
+ proceed = False
+
+ # get selected vertices and determine if selection is valid
+ selection = cmds.ls(sl=True, flatten=True)
+ for each in selection:
+ if each.find(".vtx") != -1:
+ proceed = True
+
+ # if selection is valid, paste the weights from the buffer
+ if proceed:
+ for each in selection:
+ transformPairs = []
+ try:
+ if len(self.weightCopy_infList) > 0:
+ for i in range(len(self.weightCopy_infList)):
+ transformPairs.append((self.weightCopy_infList[i], self.weightCopy_valList[i]))
+
+ cmds.undoInfo(openChunk=True)
+ cmds.skinPercent(self.skinCluster, each, transformValue=transformPairs)
+ cmds.undoInfo(closeChunk=True)
+
+ except:
+ pass
+
+ self.weightTable_getInfs()
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_blendWeight(self):
+
+ proceed = False
+
+ # get selected vertices and determine if selection is valid
+ selection = cmds.ls(sl=True, flatten=True)
+ for each in selection:
+ if each.find(".vtx") != -1:
+ proceed = True
+
+ # if selection is valid, grow the selection
+ cmds.polySelectConstraint(t=0x0001, pp=1)
+ cmds.polySelectConstraint(t=0x0001, pp=1)
+ newSelection = cmds.ls(sl=True, flatten=True)
+
+ # filter out original selection from new selection
+ for vert in newSelection:
+ if vert in selection:
+ cmds.select(vert, tgl=True)
+
+ vertsToBlend = cmds.ls(sl=True, flatten=True)
+
+ # weight hammer
+ mel.eval("weightHammerVerts;")
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_connectInfluenceLists(self, topLevel, vertLevel, *args):
+
+ # connect the skin joints list the the vertex skin info joint list so that only 1 item can be selected in either list at a time
+ if topLevel:
+ if len(self.weightTableVertList.selectedItems()) > 0:
+ self.weightTableVertList.clearSelection()
+ if vertLevel:
+ if len(self.weightTable_skinJoints.selectedItems()) > 0:
+ self.weightTable_skinJoints.clearSelection()
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_showInfluencedVerts(self, inSelection):
+
+ # store current selection
+ currentSelection = cmds.ls(sl=True, fl=True)
+
+ # get selected joint in influence list
+ selected = self.weightTable_skinJoints.selectedItems()
+ if len(selected) > 1:
+ cmds.warning("Please select only 1 joint in the list.")
+ if len(selected) == 1:
+ joint = selected[0].text()
+ cmds.selectMode(component=True)
+ cmds.skinCluster(self.skinCluster, edit=True, siv=joint)
+ newSelection = cmds.ls(sl=True, fl=True)
+
+ # if the new selection is nothing new, select the original selection and put the mesh in the correct selectMode
+ if len(newSelection) == 1:
+ if cmds.nodeType(newSelection[0]) == "mesh":
+ if len(currentSelection) == 1:
+ cmds.selectMode(object=True)
+ cmds.select(currentSelection)
+ cmds.warning("No influenced vertices for that joint.")
+
+ # if inSelection arg is True, compare the original selection to the new selection
+ if inSelection:
+ selectSet = []
+ for each in newSelection:
+ if each in currentSelection:
+ selectSet.append(each)
+
+ # select new selectSet
+ cmds.select(selectSet)
+
+ # refresh UI
+ self.weightTable_getInfs()
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def weightTable_focusInfluencedVerts(self):
+
+ # store current selection
+ currentSelection = cmds.ls(sl=True, fl=True)
+
+ # get selected joint in influence list
+ selected = self.psw_influenceList.selectedItems()
+ if len(selected) > 1:
+ cmds.warning("Please select only 1 joint in the list.")
+ if len(selected) == 1:
+ joint = selected[0].text()
+ cmds.selectMode(component=True)
+ cmds.skinCluster(self.skinCluster, edit=True, siv=joint)
+
+ # fit and view
+ utils.fitSelection()
+
+ # select original selection
+ cmds.select(currentSelection)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_focusInfluencedJoint(self):
+
+ # store current selection
+ currentSelection = cmds.ls(sl=True, fl=True)
+
+ # get selected joint in influence list
+ selected = self.psw_influenceList.selectedItems()
+ if len(selected) > 1:
+ cmds.warning("Please select only 1 joint in the list.")
+ if len(selected) == 1:
+ joint = selected[0].text()
+ cmds.select(joint)
+
+ # fit and view
+ utils.fitSelection()
+
+ # select original selection
+ cmds.select(currentSelection)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def weightTable_toggleJointSelectMode(self):
+
+ selectable = self.weightTableJointSel.isChecked()
+
+ if selectable:
+ cmds.selectType(joint=False)
+ else:
+ cmds.selectType(joint=True)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def createContextMenuWeightTable(self, point):
+
+ contextMenu = QtWidgets.QMenu()
+ contextMenu.addAction("Unlock Joint", self.contextMenu_unlockJoint)
+ contextMenu.addAction("Lock Joint", self.contextMenu_lockJoint)
+ contextMenu.exec_(self.weightTableVertList.mapToGlobal(point))
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def contextMenu_unlockJoint(self):
+
+ try:
+ selected = self.weightTableVertList.selectedItems()
+ selected = selected[0].text()
+ cmds.skinCluster(self.skinCluster, edit=True, inf=selected, lw=False)
+ self.weightTable_getInfs()
+ except:
+ pass
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def contextMenu_lockJoint(self):
+
+ try:
+ selected = self.weightTableVertList.selectedItems()
+ selected = selected[0].text()
+ cmds.skinCluster(self.skinCluster, edit=True, inf=selected, lw=True)
+ self.weightTable_getInfs()
+ except:
+ pass
+
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_searchModules(self):
+ searchKey = self.psw_modSearchBar.text()
+ searchKeys = []
+
+ if searchKey.find(",") != -1:
+ searchKeys = searchKey.split(",")
+ else:
+ searchKeys.append(searchKey)
+
+ # get all items in the joint list
+ allItems = []
+ for i in range(self.psw_moduleInfluenceList.count()):
+ item = self.psw_moduleInfluenceList.item(i)
+ itemName = item.text()
+ allItems.append([item, itemName])
+
+ # hide all items in list
+ for item in allItems:
+ item[0].setHidden(True)
+ item[0].setSelected(False)
+
+ # find items in list with search key and show item
+ if searchKey.find("*") == 0:
+ matchedItems = self.psw_moduleInfluenceList.findItems(searchKey, QtCore.Qt.MatchFlag.MatchWildcard)
+ for item in matchedItems:
+ item.setHidden(False)
+ item.setSelected(True)
+
+ else:
+ matchedItems = []
+ for searchKey in searchKeys:
+ matchedItems.extend(
+ self.psw_moduleInfluenceList.findItems(searchKey, QtCore.Qt.MatchFlag.MatchContains))
+
+ for item in matchedItems:
+ item.setHidden(False)
+ item.setSelected(True)
+
+ # populate infs
+ self.paintSkinWeights_populateInfs()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def paintSkinWeights_searchInfluences(self):
+
+ searchKey = self.psw_infSearchBar.text()
+ # get all items in the joint list
+ allItems = []
+ for i in range(self.psw_influenceList.count()):
+ item = self.psw_influenceList.item(i)
+ itemName = item.text()
+ allItems.append([item, itemName])
+
+ # hide all items in list
+ for item in allItems:
+ item[0].setHidden(True)
+ item[0].setSelected(False)
+
+ # find items in list with search key and show item
+ if searchKey.find("*") == 0:
+ matchedItems = self.psw_influenceList.findItems(searchKey, QtCore.Qt.MatchFlag.MatchWildcard)
+ for item in matchedItems:
+ item.setHidden(False)
+ item.setSelected(True)
+
+ else:
+ matchedItems = self.psw_influenceList.findItems(searchKey, QtCore.Qt.MatchFlag.MatchContains)
+ for item in matchedItems:
+ item.setHidden(False)
+ item.setSelected(True)
+ print "selecting" + str(item.text())
+ self.paintSkinWeights_changeInf()
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_createContextMenu(self, point):
+
+ contextMenu = QtWidgets.QMenu()
+ contextMenu.addAction("Unlock Selected Joint", partial(self.paintSkinWeights_lockJoint, False, True))
+ contextMenu.addAction("Unlock Unselected Joints", partial(self.paintSkinWeights_lockJoint, False, False))
+ contextMenu.addAction("Lock Selected Joint", partial(self.paintSkinWeights_lockJoint, True, True))
+ contextMenu.addAction("Lock Unselected Joints", partial(self.paintSkinWeights_lockJoint, True, False))
+
+ contextMenu.addAction("Focus Vertices Influenced by Joint", self.weightTable_focusInfluencedVerts)
+ contextMenu.addAction("Focus Selected Joint", self.weightTable_focusInfluencedJoint)
+
+ contextMenu.exec_(self.psw_influenceList.mapToGlobal(point))
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def paintSkinWeights_lockJoint(self, lock, selected):
+
+ try:
+ selectedItem = self.psw_influenceList.selectedItems()
+ selectedItem = selectedItem[0].text()
+
+ if selected:
+ cmds.skinCluster(self.skinCluster, edit=True, inf=selectedItem, lw=lock)
+
+ if not selected:
+ for i in range(self.psw_influenceList.count()):
+ item = self.psw_influenceList.item(i).text()
+ if item != selectedItem:
+ cmds.skinCluster(self.skinCluster, edit=True, inf=item, lw=lock)
+
+ self.paintSkinWeights_populateInfs()
+ except:
+ pass
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_updateCTX(self, attribute, value, widget, *args):
+
+ # special cases
+ if value == None:
+ value = str(widget.isChecked())
+
+ if value == "mapping":
+ index = self.psw_stylusPressureOptions.currentIndex()
+ if index == 0:
+ value = str("\"" + "Opacity" + "\"")
+ if index == 1:
+ value = str("\"" + "Radius" + "\"")
+ if index == 2:
+ value = str("\"" + "Both" + "\"")
+
+ if value == "paintOp":
+ index = self.psw_paintOperation.currentIndex()
+ if index == 0:
+ value = str("\"" + "additive" + "\"")
+ if index == 1:
+ value = str("\"" + "absolute" + "\"")
+ if index == 2:
+ value = str("\"" + "scale" + "\"")
+ if index == 3:
+ value = str("\"" + "smooth" + "\"")
+
+ if value == "slider":
+ value = str(widget.value())
+
+ if value == "sliderEdit":
+ value = str(float(widget.value()) / 100)
+ currentCtx = cmds.currentCtx()
+ execString = "cmds.artAttrSkinPaintCtx(" + "\"" + currentCtx + "\"" + ", edit = True, " + attribute + " = " + value + ")"
+ try:
+ exec execString
+ except Exception as e:
+ print e
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_togglePaintProfile(self, button, img):
+
+ for each in self.paintProfileButtons:
+ widget = each[0]
+ image = each[1]
+
+ icon = QtGui.QIcon(image)
+ widget.setIcon(icon)
+
+ state = button.isChecked()
+
+ if state:
+ icon = QtGui.QIcon(image)
+ widget.setIcon(icon)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_UpdateSliders(self, getValueFrom, putValueOn, doMath, *args):
+
+ # if getting the value from the slider, divide by 100 when setting doubleSpinBox
+ value = getValueFrom.value()
+
+ if doMath:
+ if value > 1:
+ value = float(value) / 100
+ putValueOn.setValue(value)
+ if value == 0:
+ putValueOn.setValue(float(0.00))
+
+ if not doMath:
+ putValueOn.setValue(value)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_SetSliderValues(self, slider, value, *args):
+
+ slider.setValue(value)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def paintSkinWeights_floodWeights(self):
+
+ value = self.psw_valueSlider.value()
+ value = value / 100
+
+ currentCtx = cmds.currentCtx()
+ currentMode = cmds.artAttrSkinPaintCtx(currentCtx, q=True, sao=True)
+ if currentMode == "additive":
+ cmds.artAttrSkinPaintCtx(currentCtx, edit=True, clear=True)
+ else:
+ cmds.artAttrSkinPaintCtx(currentCtx, edit=True, clear=value)
+
+
+ ###############################################################################################################
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # EXTERNAL FILES CALLED
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ ###############################################################################################################
+
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ def paintSkinWeights_deformationWizardLaunch(self):
+
+ import ART_WeightWizard as aww
+ reload(aww)
+ aww.run(self)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def paintSkinWeights_smoothSkinUI(self):
+
+ import ART_WeightWizard as aww
+ reload(aww)
+ aww.runOnlySkinTools(self)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def paintSkinWeights_importSkinWeights(self):
+
+ import ART_ImportWeights
+ reload(ART_ImportWeights)
+ ART_ImportWeights.ART_ImportSkinWeights(self)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def paintSkinWeights_exportSkinWeights(self):
+
+ import ART_ExportWeights
+ reload(ART_ExportWeights)
+ ART_ExportWeights.ART_ExportSkinWeights(self)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def addOrRemoveInfs_UI(self):
+
+ import ART_AddOrRemoveInfluences
+ reload(ART_AddOrRemoveInfluences)
+ ART_AddOrRemoveInfluences.ART_AddOrRemoveInfluences(self)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def moveInfluences_UI(self):
+
+ import ART_MoveInfluences
+ reload(ART_MoveInfluences)
+ ART_MoveInfluences.ART_MoveInfluences(self)
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ def debugRigs(self):
+ # Original Author: Jeremy Ernst
+
+ # run publish process
+ import ART_DebugRigs
+ reload(ART_DebugRigs)
+ ART_DebugRigs.ART_DebugRigs(self.mainUI)