效果展示
控制器的简易添加,缩放控制器,控制器的颜色选择
QLabel
QLabel提供了一个文本或者图像的显示,没有提供交互功能,在建议控制器中我利用QLabel进行了文字的显示和背景颜色显示
COPYself.controlScale_label = QtWidgets.QLabel(u"控制器Scale",alignment=QtCore.Qt.AlignCenter)
#设置格式
self.controlScale_label.setStyleSheet("background-color:rgb(0,0,0,255)")
Constraints(约束)
point constraints(点约束):约束位移
orient constraints(反向约束):约束旋转
parent constraints(父约束):约束位移和旋转
思路
COPY1.首先要获取选中的物体,然后判断是否为joint骨骼类型,如果是则获取选中物体的所有子物体
2.根据joint数量生成一定的控制器,调整控制器的旋转和位置与joint一致
3.进行parent约束限制,这样生成的Circle就可以控制joints
4.利用Pyside2进行GUI的设置,完成交互
OverrideColor设置问题
首先OverrideColor指的是Shape下的设置
这里我需要将颜色设置为RGB而非索引,所以需要一下代码,这里应该可以直接设置overrideColorRGB属性的,但不知道哪里出了问题,所以我就曲线救国
COPY #获取选中物体的shape
shape = cmds.listRelatives(tempControl,children=True)[0]
cmds.setAttr(shape+".overrideEnabled",True)
cmds.setAttr(shape+".overrideRGBColors",1)
#设置颜色值
cmds.setAttr(shape+".overrideColorR ",self.color.redF())
cmds.setAttr(shape + ".overrideColorG ", self.color.greenF())
cmds.setAttr(shape + ".overrideColorB ", self.color.blueF())
#print(cmds.getAttr(shape+".overrideColor"))
Circle Scale问题
这里不是直接缩放Circle,而是缩放Circle的controlVertics(控制顶点),这样就可以直接连续缩放
COPY def smallScale(self):
#获得选中的物体
selectionControl = cmds.ls(selection=True)
#获取缩放值
scaleFactor = self.scale_DoubleSpinBox.value()
for tempControl in selectionControl:
# Scale控制顶点
cmds.scale(1-scaleFactor,1-scaleFactor,1-scaleFactor,tempControl+".cv[0:]")
源码
COPY# -*- coding: GBK -*-
from PySide2 import QtWidgets,QtGui,QtCore
from shiboken2 import wrapInstance
from maya import OpenMayaUI as omui
import maya.cmds as cmds
#maya主窗口
def maya_main_window():
main_window_ptr = omui.MQtUtil.mainWindow()
return wrapInstance(long(main_window_ptr),QtWidgets.QWidget)
window_w = 200
window_h = 168
class RigTools_Dialog(QtWidgets.QDialog):
def __init__(self,parent = maya_main_window()):
super(RigTools_Dialog, self).__init__(parent)
#设置默认颜色
self.color = QtGui.QColor("#FFFFFF")
self.control_list=[]
self.offset_list=[]
#设置窗口名称
self.setWindowTitle("RigTools")
#设置窗口大小
self.setFixedWidth(window_w)
self.setFixedHeight(window_h)
#关闭问号按钮
self.setWindowFlags(self.windowFlags() ^ QtCore.Qt.WindowContextHelpButtonHint)
self.createWidgets()
self.createLayouts()
self.createConnects()
def createWidgets(self):
self.rig_btn = QtWidgets.QPushButton("Rig")
self.rig_btn.setFixedWidth(window_w)
self.rig_btn.setFixedHeight(40)
self.controlScale_label = QtWidgets.QLabel(u"控制器Scale",alignment=QtCore.Qt.AlignCenter)
#设置格式
self.controlScale_label.setStyleSheet("background-color:rgb(0,0,0,255)")
self.scale_DoubleSpinBox = QtWidgets.QDoubleSpinBox()
#设置范围,经度,步长
self.scale_DoubleSpinBox.setRange(0,1)
self.scale_DoubleSpinBox.setDecimals(2)
self.scale_DoubleSpinBox.setSingleStep(0.05)
self.smallScale_btn = QtWidgets.QPushButton("Small")
self.bigScale_btn = QtWidgets.QPushButton("Big")
self.controlColor_label = QtWidgets.QLabel(u"控制器颜色",alignment=QtCore.Qt.AlignCenter)
self.controlColor_label.setStyleSheet("background-color:rgb(0,0,0,255)")
self.color_pick_label = QtWidgets.QLabel()
self.color_pick_label.setStyleSheet("background-color:rgb(255,255,255,255)")
self.color_pick_btn = QtWidgets.QPushButton(u"颜色选择")
self.color_set_btn = QtWidgets.QPushButton(u"颜色设置")
pass
def createLayouts(self):
#主层级
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.setMargin(0)
main_layout.setSpacing(0)
main_layout.addWidget(self.rig_btn)
main_layout.addWidget(self.controlScale_label)
HLayout = QtWidgets.QHBoxLayout()
main_layout.setSpacing(5)
HLayout.addWidget(self.scale_DoubleSpinBox)
HLayout.addWidget(self.smallScale_btn)
HLayout.addWidget(self.bigScale_btn)
main_layout.addLayout(HLayout)
main_layout.addWidget(self.controlColor_label)
H_Color_Layout = QtWidgets.QHBoxLayout()
H_Color_Layout.addWidget(self.color_pick_label)
H_Color_Layout.addWidget(self.color_pick_btn)
main_layout.addLayout(H_Color_Layout)
main_layout.addWidget(self.color_set_btn)
pass
def createConnects(self):
self.rig_btn.clicked.connect(self.rig_function)
self.smallScale_btn.clicked.connect(self.smallScale)
self.bigScale_btn.clicked.connect(self.bigScale)
self.color_pick_btn.clicked.connect(self.color_pick)
self.color_set_btn.clicked.connect(self.color_set)
def smallScale(self):
#获得选中的物体
selectionControl = cmds.ls(selection=True)
#获取缩放值
scaleFactor = self.scale_DoubleSpinBox.value()
for tempControl in selectionControl:
# Scale控制顶点
cmds.scale(1-scaleFactor,1-scaleFactor,1-scaleFactor,tempControl+".cv[0:]")
pass
def bigScale(self):
# 获得选中的物体
selectionControl = cmds.ls(selection=True)
# 获取缩放值
scaleFactor = self.scale_DoubleSpinBox.value()
print(scaleFactor)
for tempControl in selectionControl:
#Scale控制顶点
cmds.scale(1.0 + scaleFactor, 1.0 + scaleFactor, 1.0 + scaleFactor, tempControl+".cv[0:]")
pass
def color_pick(self):
#获取颜色选择
color = QtWidgets.QColorDialog.getColor()
self.color = color
self.color_pick_label.setStyleSheet("background-color: {0}".format(color.name()))
def color_set(self):
#获取选中的物体
selectionControl = cmds.ls(selection=True)
#设置颜色值
for tempControl in selectionControl:
#获取选中物体的shape
shape = cmds.listRelatives(tempControl,children=True)[0]
cmds.setAttr(shape+".overrideEnabled",True)
cmds.setAttr(shape+".overrideRGBColors",1)
#设置颜色值
cmds.setAttr(shape+".overrideColorR ",self.color.redF())
cmds.setAttr(shape + ".overrideColorG ", self.color.greenF())
cmds.setAttr(shape + ".overrideColorB ", self.color.blueF())
#print(cmds.getAttr(shape+".overrideColor"))
pass
def rig_function(self):
# 获取选中的物体
selected = cmds.ls(selection=True)
# 判断选择物体是否为空
if len(selected) == 0:
cmds.warning(u"请选中物体!!!")
QtWidgets.QMessageBox.warning(self,u"警告",u"请选中物体!!!")
elif len(selected) > 1:
cmds.warning(u"只能选中一个物体!!!")
QtWidgets.QMessageBox.warning(self, u"警告", u"只能选中一个物体!!!")
else:
# 判断类型是否为joint骨骼
if cmds.objectType(selected[0]) != "joint":
cmds.warning(u"选择物体类型不为joint!!!")
QtWidgets.QMessageBox.warning(self, u"警告", u"选择物体类型不为joint!!!")
else:
# 选择该物体的包含的所有子物体和自身
cmds.select(selected[0], hierarchy=True)
# 获取选择的物体
all_Joints = cmds.ls(selection=True)
# 骨骼数
joints_number = len(all_Joints)
# 循环生成circle控制器
for i in range(joints_number - 1):
# 生成circle
control = cmds.circle(name=all_Joints[i] + "_control")
# 旋转变换
cmds.rotate(0, 90, 0, control[0])
# 冻结变换
cmds.makeIdentity(apply=True)
# 删除变换历史
cmds.DeleteHistory()
# 创建group组
offset_grp = cmds.group(name=all_Joints[i] + "_offset", empty=True)
# 设置父类
cmds.parent(control[0], offset_grp)
# 获取骨骼的位置Position
joint_position = cmds.xform(all_Joints[i], query=True, translation=True, worldSpace=True)
# 将控制器移动到骨骼位置
cmds.xform(offset_grp, translation=joint_position)
# 利用orient约束将圆环旋转到骨骼方向一致
orient_cons = cmds.orientConstraint(all_Joints[i], offset_grp)
# 删除旋转约束
cmds.delete(orient_cons)
# parent约束,用于控制器控制骨骼移动
cmds.parentConstraint(control[0], all_Joints[i])
# 添加到list
self.control_list.append(control[0])
self.offset_list.append(offset_grp)
# 重新设置父类关系
for i in range(joints_number - 2):
cmds.parent(self.offset_list[i + 1], self.control_list[i])
if __name__ == '__main__':
try:
rigTools_dialog.close()
rigTools_dialog.deleteLater()
except:
pass
rigTools_dialog = RigTools_Dialog()
rigTools_dialog.show()
转载自opda的博客