forked from shizuo-kaji/ProbeDeformerMaya
/
ui_probeDeformer.py
195 lines (174 loc) · 9.2 KB
/
ui_probeDeformer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# -*- coding: utf-8 -*-
# User interface for ProbeDeformer plugin
# The last object in the selected ones will be the target while the others will serve as "probes."
# @author Shizuo KAJI
# @date 2013/5/13
# for debug
#import debugmaya
#debugmaya.startDebug()
# Import Maya Modules
import maya.cmds as cmds
import pymel.core as pm
#deformerTypes = ["probeDeformer","probeDeformerARAP","probeDeformerPy","probeLocator"]
deformerTypes = ["probeDeformer","probeDeformerARAP","probeLocator"]
for type in deformerTypes:
try:
cmds.loadPlugin(type)
except:
print("Plugin %s already loaded" %(type))
## prepare interface
class UI_ProbeDeformer:
uiID = "ProbeDeformer"
title = "ProbeDeformerPlugin"
deformers = []
probes = {}
## Constructor
def __init__(self):
if pm.window(self.uiID, exists=True):
pm.deleteUI(self.uiID)
win = pm.window(self.uiID, title=self.title, menuBar=True)
with win:
pm.menu( label='Create', tearOff=True )
for type in deformerTypes:
pm.menuItem( label=type, c=pm.Callback( self.initPlugin, type) )
self._parentLayout = pm.columnLayout( adj=True )
with self._parentLayout:
self.createUISet()
def createUISet(self):
self._childLayout = pm.columnLayout( adj=True )
with self._childLayout:
self.deformers = [pm.ls(type=deformerTypes[i]) for i in range(len(deformerTypes))]
for i in range(len(deformerTypes)):
for node in self.deformers[i]:
self.probes[node] = pm.listConnections(node.pm)
# "probeDeformer" specific
for node in self.deformers[0]:
frameLayout = pm.frameLayout( label=node.name(), collapsable = True)
with frameLayout:
self.createRamp(node)
self.createCommonAttr(node, deformerTypes[0])
indices = cmds.getAttr(node+".pm", multiIndices=True)
if indices:
for j in indices:
with pm.rowLayout(numberOfColumns=1) :
pm.attrFieldSliderGrp(label=node.prw[j].getAlias(), min=0, max=10.0, attribute=node.prw[j])
with pm.rowLayout(numberOfColumns=3) :
pm.attrControlGrp( label="Frechet sum", attribute= node.fs)
pm.attrControlGrp( label="visualisation", attribute= node.vm)
pm.attrFieldSliderGrp( label="visualisation multiplier", min=0.001, max=1000, attribute=node.vmp)
# "probeDeformerARAP" specific
for node in self.deformers[1]:
frameLayout = pm.frameLayout( label=node.name(), collapsable = True)
with frameLayout:
self.createRamp(node)
self.createCommonAttr(node, deformerTypes[1])
indices = cmds.getAttr(node+".pm", multiIndices=True)
if indices:
for j in indices:
with pm.rowLayout(numberOfColumns=2) :
pm.attrFieldSliderGrp(label=node.prw[j].getAlias(), min=0, max=1.0, attribute=node.prw[j])
pm.attrFieldSliderGrp(label=node.prcr[j].getAlias(), min=0, max=1.0, attribute=node.prcr[j])
with pm.rowLayout(numberOfColumns=3) :
pm.button( l="Set supervisor", c=pm.Callback( self.setSupervisor, node))
pm.attrControlGrp( label="tet mode", attribute= node.tm)
pm.attrFieldSliderGrp( label="translation weight", min=0.0, max=1.0, attribute=node.tw)
with pm.rowLayout(numberOfColumns=3) :
pm.attrControlGrp( label="constraint mode", attribute= node.ctm)
pm.attrFieldSliderGrp( label="constraint weight", min=0.001, max=1000, attribute=node.cw)
pm.attrFieldSliderGrp(label="constraint radius", min=0.001, max=10.0, attribute=node.cr)
with pm.rowLayout(numberOfColumns=3) :
pm.attrFieldSliderGrp( label="iteration", min=1, max=20, attribute=node.it)
pm.attrControlGrp( label="visualisation", attribute= node.vm)
pm.attrFieldSliderGrp( label="visualisation multiplier", min=0.001, max=1000, attribute=node.vmp)
with pm.rowLayout(numberOfColumns=3) :
pm.attrControlGrp( label="stiffness mode", attribute=node.stiffnessMode)
# "probeDeformerPy" specific
# for node in self.deformers[2]:
# frameLayout = pm.frameLayout( label=node.name(), collapsable = True)
# with frameLayout:
# self.createRamp(node)
# self.createCommonAttr(node, deformerTypes[2])
# with pm.rowLayout(numberOfColumns=1) :
# pm.attrControlGrp( label="translation mode", attribute= node.tm)
# create deformer node and connection
def initPlugin(self, deformerType):
if deformerType=="probeLocator":
cmds.createNode('probeLocator')
return
# get transform nodes for the selected objects
transforms = pm.selected(tr=1)
if not transforms:
return
pm.select( transforms[-1]) # the deformer is attached to the last selected object
node = pm.ls(cmds.deformer(type=deformerType)[0])[0]
cmds.makePaintable(deformerType, 'weights', attrType='multiFloat', shapeMode='deformer')
if len(transforms)>1:
self.addProbe(node,deformerType,transforms[:-1])
self.updateUI()
# add selected transform as a new probe
def addProbe(self,node,deformerType,newProbes):
indexes = cmds.getAttr(node+".pm", multiIndices=True)
if not indexes:
n=0
else:
n=indexes[-1]+1
# connect pm first to avoid unnecessary arap computations
for j in range(len(newProbes)):
cmds.connectAttr(newProbes[j]+".worldMatrix", node+".pm[%s]" %(j+n))
if deformerType=="probeDeformerARAP" or deformerType=="probeDeformer":
pm.aliasAttr(newProbes[j].name()+"_weight%s" %(j+n), node.prw[j+n].name())
if deformerType=="probeDeformerARAP":
pm.aliasAttr(newProbes[j].name()+"_constraintRadius%s" %(j+n), node.prcr[j+n].name())
for j in range(len(newProbes)):
node.ipm[j+n].set(newProbes[j].worldMatrix.get())
# add selected transform as a new probe
def addSelectedProbe(self,node,deformerType):
newProbes = pm.selected(tr=1)
self.addProbe(node,deformerType,newProbes)
self.updateUI()
# delete deformer node
def deleteNode(self,node):
cmds.delete(node.name())
self.updateUI()
# set selected shapes as supervised mesh
def setSupervisor(self,node):
meshes = pm.selected(tr=1)
if not meshes:
return
for i in range(len(meshes)):
shape=meshes[i].getShapes()[0]
cmds.connectAttr(shape+".outMesh", node.name()+".supervisedMesh[%s]" %(i), force=True)
self.updateUI()
# delete a probe
def deleteProbe(self,node,j):
cmds.disconnectAttr(self.probes[node][j]+".worldMatrix", node+".pm[%s]" %(j) )
self.updateUI()
# redraw UI
def updateUI(self):
pm.deleteUI( self._childLayout )
pm.setParent(self._parentLayout)
self.createUISet()
# create common attributes
def createRamp(self,node):
with pm.rowLayout(numberOfColumns=6) :
pm.text(l='Weight Curve R')
pm.gradientControl( at='%s.wcr' % node.name() )
pm.text(l='S')
pm.gradientControl( at='%s.wcs' % node.name() )
pm.text(l='L')
pm.gradientControl( at='%s.wcl' % node.name() )
def createCommonAttr(self,node,deformerType):
with pm.rowLayout(numberOfColumns=len(self.probes[node])+2) :
pm.button( l="Delete deformer", c=pm.Callback( self.deleteNode, node))
pm.button( l="Add selection to probes", c=pm.Callback( self.addSelectedProbe, node, deformerType) )
for j in range(len(self.probes[node])):
pm.button( l=self.probes[node][j].name(), c=pm.Callback( self.deleteProbe, node, j) )
with pm.rowLayout(numberOfColumns=2) :
pm.attrControlGrp( label="blend mode", attribute= node.bm)
# pm.attrControlGrp( label="world mode", attribute= node.worldMode)
pm.attrControlGrp( label="rotation consistency", attribute= node.rc)
with pm.rowLayout(numberOfColumns=4) :
pm.attrControlGrp( label="Weight mode", attribute= node.wtm)
pm.attrFieldSliderGrp(label="effect radius", min=0.001, max=20.0, attribute=node.er)
pm.attrControlGrp( label="normalise weight", attribute= node.nw)
pm.attrControlGrp( label="normExponent", attribute=node.ne)