Skip to content

Commit 857daff

Browse files
committed
updates for space switching and other fixes
1 parent bfa686a commit 857daff

File tree

2 files changed

+187
-39
lines changed

2 files changed

+187
-39
lines changed

scripts/ml_puppet.py

Lines changed: 119 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181

8282
try:
8383
import ml_utilities as utl
84-
utl.upToDateCheck(32)
84+
utl.upToDateCheck(35)
8585
except ImportError:
8686
result = mc.confirmDialog( title='Module Not Found',
8787
message='This tool requires the ml_utilities module. Once downloaded you will need to restart Maya.',
@@ -111,6 +111,7 @@
111111

112112

113113
PUP_ID_PREFIX = 'pupID_'
114+
CONTROL_ATTR = PUP_ID_PREFIX+'control'
114115

115116
def main():
116117
initPuppetContextMenu()
@@ -145,6 +146,61 @@ def fkIkSwitchUI(*args):
145146
annotation='Bake selected element from FK to IK and vice versa.')
146147

147148

149+
class SpaceSwitchUI(object):
150+
151+
win_name = 'spaceSwitchWin'
152+
153+
def __init__(self, title='SpaceSwitch', width=400, height=200):
154+
155+
156+
sel = mc.ls(sl=True)
157+
if not sel:
158+
return
159+
160+
spaces = None
161+
nodes = []
162+
for each in sel:
163+
data = getSpaceSwitchData(each)
164+
if not data:
165+
continue
166+
nodes.append(each)
167+
theseSpaces = set(data['space']['enumValues'])
168+
if not spaces:
169+
spaces = theseSpaces
170+
else:
171+
spaces.intersection(theseSpaces)
172+
173+
if not spaces:
174+
return
175+
176+
self.width = width
177+
self.height = height
178+
179+
self.close()
180+
181+
mc.window(self.win_name, title=title, iconName=title, width=self.width, height=self.height, menuBar=True)
182+
self.column = mc.columnLayout(adj=True)
183+
184+
for space in list(spaces):
185+
mc.button(space, command=partial(self.setSpace, nodes, space))
186+
187+
self.show()
188+
189+
190+
def setSpace(self, nodes, space, *args):
191+
switchSpace(nodes=nodes, toSpace=space, switchRange=True, bakeOnOnes=False)
192+
self.close()
193+
194+
def close(self):
195+
if mc.window(self.win_name, exists=True):
196+
mc.deleteUI(self.win_name)
197+
198+
def show(self):
199+
mc.showWindow(self.win_name)
200+
mc.window(self.win_name, edit=True, width=self.width, height=self.height)
201+
202+
203+
148204
def fkIkSwitchSel(*args):
149205
fkIkSwitch()
150206

@@ -154,7 +210,8 @@ def fkIkSwitchRangeSel(*args):
154210

155211

156212
def getPuppets(node=None):
157-
213+
214+
#LEGACY:
158215
if node:
159216
puppets = []
160217
if not isinstance(node, (list,tuple)):
@@ -322,6 +379,8 @@ def getTag(node, tag):
322379

323380

324381
def getNodeType(node):
382+
if mc.attributeQuery('asset_type', node=node, exists=True):
383+
return mc.getAttr(node+'.asset_type', asString=True)
325384
return getTag(node, 'nodeType')
326385

327386

@@ -338,7 +397,6 @@ def getNodesOfType(nodeType, namespaceFromNodes=None):
338397
namespaces.append(utl.getNamespace(each))
339398
else:
340399
namespaces = ['*:','']
341-
342400
for ns in list(set(namespaces)):
343401
if nodeType == 'control' or nodeType == 'element' or nodeType == 'puppet':
344402
#special case for commonly queried nodes, for speed
@@ -715,7 +773,19 @@ def switchSpace(nodes=None, toSpace=None, switchRange=False, bakeOnOnes=False):
715773

716774
if switchRange:
717775
start, end = utl.frameRange()
718-
776+
777+
#check for dynamics
778+
for node in nodes:
779+
nucleus = utl.getNucleusHistory(node)
780+
if not nucleus:
781+
parent = mc.listRelatives(node, parent=True, pa=True)
782+
if parent:
783+
nucleus = utl.getNucleusHistory(parent[0])
784+
if nucleus:
785+
if mc.getAttr(nucleus+'.enable'):
786+
start = mc.getAttr(nucleus+'.startFrame')
787+
bakeOnOnes = True
788+
break
719789
#need to support this eventually for controls which have multiple space attributes.
720790
selChan = utl.getSelectedChannels()
721791

@@ -733,7 +803,8 @@ def switchSpace(nodes=None, toSpace=None, switchRange=False, bakeOnOnes=False):
733803
else:
734804
#silly, but take the shortest one, as that's usually default
735805
ssAttr = min(ssData.keys(), key=len)
736-
806+
807+
value = None
737808
if isinstance(toSpace, basestring):
738809
for i, e in enumerate(ssData[ssAttr]['enumValues']):
739810
if e.lower() == toSpace.lower():
@@ -774,7 +845,7 @@ def switchSpace(nodes=None, toSpace=None, switchRange=False, bakeOnOnes=False):
774845
return
775846

776847
if switchRange:
777-
utl.matchBake(controls, locators, maintainOffset=True)
848+
utl.matchBake(controls, locators, maintainOffset=True, bakeOnOnes=bakeOnOnes)
778849

779850
for ctrl, attr, value in zip(controls, attributes, values):
780851
if mc.keyframe(ctrl+'.'+attr, query=True, name=True):
@@ -901,8 +972,7 @@ def initPuppetContextMenu():
901972

902973

903974
def isNodePuppetControl(node):
904-
905-
if mc.attributeQuery(PUP_ID_PREFIX+'nodeType', exists=True, node=node):
975+
if mc.attributeQuery(PUP_ID_PREFIX+'control', exists=True, node=node):
906976
return True
907977
if getNodeType(node) == 'control':
908978
return True
@@ -918,11 +988,11 @@ def getSpaceSwitchData(node):
918988
if not attrs:
919989
return data
920990

921-
ssAttrs = [x for x in attrs if 'paceSwitch' in x]
991+
ssAttrs = [x for x in attrs if 'paceSwitch' in x or x == 'space']
922992
for attr in ssAttrs:
923993
enumValues = []
924994
spaceEnum = 'space'
925-
if attr == 'spaceSwitch':
995+
if attr == 'spaceSwitch' or attr == 'space':
926996
if not 'space' in attrs:
927997
spaceEnum = 'spaceSwitch'
928998
enumValues = mc.attributeQuery(spaceEnum, node=node, listEnum=True)
@@ -1139,6 +1209,14 @@ def convertRotateOrderUI(nodes, *args):
11391209
# __________________________________
11401210
# == POSE AND ANIM MIRRORING =======
11411211

1212+
def getMirrorName(node, a='Lf_', b='Rt_'):
1213+
if a in node:
1214+
return node.replace(a,b)
1215+
elif b in node:
1216+
return node.replace(b,a)
1217+
1218+
1219+
11421220
def getMirrorMap(nodes=None):
11431221
'''
11441222
Returns a map of all paired nodes within a puppet
@@ -1172,11 +1250,16 @@ def getMirrorPairs(nodes):
11721250
'''
11731251

11741252
nodes = mc.ls(nodes, long=True)
1175-
mirrorMap = getMirrorMap(nodes)
1253+
#mirrorMap = getMirrorMap(nodes)
11761254
mirrorPairs = {}
1255+
#for each in nodes:
1256+
#if each in mirrorMap:
1257+
#mirrorPairs[each] = mirrorMap[each]
11771258
for each in nodes:
1178-
if each in mirrorMap:
1179-
mirrorPairs[each] = mirrorMap[each]
1259+
mirror = getMirrorName(each)
1260+
if mc.objExists(mirror):
1261+
mirrorPairs[each] = mirror
1262+
11801263
return mirrorPairs
11811264

11821265

@@ -1239,7 +1322,13 @@ def copyPose(fromNode, toNode, flip=False):
12391322
except:pass
12401323

12411324

1242-
def mirrorPose(nodes, *args):
1325+
def mirrorPose(nodes=None, *args):
1326+
1327+
if not nodes:
1328+
nodes = mc.ls(sl=True)
1329+
1330+
if not nodes:
1331+
raise RuntimeError('No nodes provided to mirror.')
12431332

12441333
pairs = getMirrorPairs(nodes)
12451334
done = []
@@ -1249,7 +1338,13 @@ def mirrorPose(nodes, *args):
12491338
done.append(mirror)
12501339

12511340

1252-
def flipPose(nodes, *args):
1341+
def flipPose(nodes=None, *args):
1342+
1343+
if not nodes:
1344+
nodes = mc.ls(sl=True)
1345+
1346+
if not nodes:
1347+
raise RuntimeError('No nodes provided to mirror.')
12531348

12541349
nodes = mc.ls(nodes, long=True)
12551350

@@ -1273,7 +1368,7 @@ def flipPose(nodes, *args):
12731368

12741369

12751370
def copyAnimation(fromNode, toNode):
1276-
1371+
print 'copy', fromNode.split('|')[-1], toNode.split('|')[-1]
12771372
mc.copyKey(fromNode)
12781373
mc.pasteKey(toNode, option='replaceCompletely')
12791374
for axis in getMirrorAxis(toNode):
@@ -1326,8 +1421,14 @@ def swapAnimation(fromNode, toNode):
13261421
mc.scaleKey(fromNode, attribute=axis, valueScale=-1)
13271422

13281423

1329-
def mirrorAnimation(nodes, *args):
1330-
1424+
def mirrorAnimation(nodes=None, *args):
1425+
1426+
if not nodes:
1427+
nodes = mc.ls(sl=True)
1428+
1429+
if not nodes:
1430+
raise RuntimeError('No nodes provided to mirror.')
1431+
13311432
pairs = getMirrorPairs(nodes)
13321433
done = []
13331434
for node, mirror in pairs.items():

0 commit comments

Comments
 (0)