Maya简易控制器

Maya教程笔记,过程中会记录自己所遇到的问题和新知识

效果展示

控制器的简易添加,缩放控制器,控制器的颜色选择

GIF 2020-8-24 22-52-16

QLabel

QLabel提供了一个文本或者图像的显示,没有提供交互功能,在建议控制器中我利用QLabel进行了文字的显示和背景颜色显示

self.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(父约束):约束位移和旋转

思路

1.首先要获取选中的物体,然后判断是否为joint骨骼类型,如果是则获取选中物体的所有子物体
2.根据joint数量生成一定的控制器,调整控制器的旋转和位置与joint一致
3.进行parent约束限制,这样生成的Circle就可以控制joints
4.利用Pyside2进行GUI的设置,完成交互

OverrideColor设置问题

首先OverrideColor指的是Shape下的设置

image-20200824230019419

这里我需要将颜色设置为RGB而非索引,所以需要一下代码,这里应该可以直接设置overrideColorRGB属性的,但不知道哪里出了问题,所以我就曲线救国

            #获取选中物体的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"))

image-20200824230220071

Circle Scale问题

这里不是直接缩放Circle,而是缩放Circle的controlVertics(控制顶点),这样就可以直接连续缩放

    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:]")

源码

# -*- 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()
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2021 Opda
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信