5
5
# / __ `__ \/ / Licensed under Creative Commons BY-SA
6
6
# / / / / / / / http://creativecommons.org/licenses/by-sa/3.0/
7
7
# /_/ /_/ /_/_/ _________
8
- # /_________/ Revision 2 , 2017-06-26
8
+ # /_________/ Revision 3 , 2017-07-17
9
9
# _______________________________
10
10
# - -/__ Installing Python Scripts __/- - - - - - - - - - - - - - - - - - - -
11
11
#
45
45
__author__ = 'Morgan Loomis'
46
46
__license__ = 'Creative Commons Attribution-ShareAlike'
47
47
__category__ = 'animationScripts'
48
- __revision__ = 2
48
+ __revision__ = 3
49
49
50
50
try :
51
51
from PySide2 import QtGui , QtCore
60
60
61
61
try :
62
62
import ml_utilities as utl
63
- utl .upToDateCheck (30 )
63
+ utl .upToDateCheck (31 )
64
64
except ImportError :
65
65
result = mc .confirmDialog ( title = 'Module Not Found' ,
66
66
message = 'This tool requires the ml_utilities module. Once downloaded you will need to restart Maya.' ,
@@ -123,8 +123,7 @@ def __init__(self):
123
123
self .scriptJob = None
124
124
self .keypressFilter = PivotKeypressFilter (self .bakePivot , self .cleanup )
125
125
126
-
127
-
126
+
128
127
def editPivot (self , * args ):
129
128
sel = mc .ls (sl = True )
130
129
@@ -140,14 +139,85 @@ def editPivot(self, *args):
140
139
#we have a pivot handle selected
141
140
return
142
141
142
+ self .node = sel [0 ]
143
+
143
144
if is_pivot_connected (sel [0 ]):
145
+ driverAttr = pivot_driver_attr (sel [0 ])
146
+ if driverAttr :
147
+ self .editPivotDriver (driverAttr )
148
+ else :
149
+ om .MGlobal .displayWarning ('Pivot attribute is connected, unable to edit.' )
144
150
return
145
151
146
- self .node = sel [0 ]
152
+ self .editPivotHandle ()
153
+
154
+
155
+ def editPivotDriver (self , driver ):
147
156
148
- qt_maya_window .installEventFilter (self .keypressFilter )
157
+ self .pivotDriver = driver
158
+
159
+ #get driver range
160
+ node ,attr = driver .split ('.' ,1 )
161
+ value = mc .getAttr (driver )
162
+
163
+ minValue = mc .attributeQuery (attr , node = node , minimum = True )[0 ]
164
+ maxValue = mc .attributeQuery (attr , node = node , maximum = True )[0 ]
165
+
166
+ #create a ui with a slider
167
+ self .pivotDriverWindow = 'ml_pivot_editPivotDriverUI'
168
+
169
+ if mc .window (self .pivotDriverWindow , exists = True ):
170
+ mc .deleteUI (self .pivotDriverWindow )
171
+ window = mc .window (self .pivotDriverWindow , width = 1 , height = 1 )
172
+ mc .columnLayout ()
173
+ self .floatSlider = mc .floatSliderButtonGrp (label = attr ,
174
+ field = True ,
175
+ value = value ,
176
+ buttonLabel = 'Bake' ,
177
+ minValue = minValue ,
178
+ maxValue = maxValue ,
179
+ buttonCommand = self .doEditPivotDriver )
180
+ mc .showWindow ( window )
181
+ mc .window (self .pivotDriverWindow , edit = True , width = 1 , height = 1 )
182
+
183
+ def doEditPivotDriver (self , * args ):
184
+
185
+ newValue = mc .floatSliderButtonGrp (self .floatSlider , query = True , value = True )
186
+ try :
187
+ mc .deleteUI (self .pivotDriverWindow )
188
+ except :
189
+ pass
190
+
191
+ currentValue = mc .getAttr (self .pivotDriver )
192
+ if newValue == currentValue :
193
+ return
194
+
195
+ oldRP = mc .getAttr (self .node + '.rotatePivot' )[0 ]
196
+ mc .setAttr (self .pivotDriver , newValue )
197
+ newRP = mc .getAttr (self .node + '.rotatePivot' )[0 ]
198
+ mc .setAttr (self .pivotDriver , currentValue )
199
+
200
+ parentPosition = mc .group (em = True )
201
+ offsetPosition = mc .group (em = True )
202
+ offsetPosition = mc .parent (offsetPosition , parentPosition )[0 ]
203
+ mc .setAttr (offsetPosition + '.translate' , newRP [0 ]- oldRP [0 ], newRP [1 ]- oldRP [1 ], newRP [2 ]- oldRP [2 ])
204
+
205
+ mc .delete (mc .parentConstraint (self .node , parentPosition ))
206
+
207
+ utl .matchBake (source = [self .node ], destination = [parentPosition ], bakeOnOnes = True , maintainOffset = False , preserveTangentWeight = False )
208
+
209
+ mc .cutKey (self .pivotDriver )
210
+ mc .setAttr (self .pivotDriver , newValue )
211
+ mc .refresh ()
212
+ utl .matchBake (source = [offsetPosition ], destination = [self .node ], bakeOnOnes = True , maintainOffset = False , preserveTangentWeight = False , rotate = False )
213
+
214
+ mc .delete (parentPosition )
149
215
150
216
217
+ def editPivotHandle (self ):
218
+
219
+ qt_maya_window .installEventFilter (self .keypressFilter )
220
+
151
221
#create transform
152
222
self .pivotHandle = mc .group (em = True , name = 'Adjust_Pivot' )
153
223
mc .setAttr (self .pivotHandle + '.rotate' , lock = True )
@@ -236,11 +306,29 @@ def cleanup(self):
236
306
mc .lockNode (each , lock = False )
237
307
mc .delete (each )
238
308
309
+ def pivot_driver_attr (node ):
310
+ '''
311
+ Start with supporting pivots driven by remap value nodes, more support in the future as requested.
312
+ '''
313
+ #rpSrc = mc.listConnections(node+'.rotatePivot', source=True, destination=False, plugs=True)
314
+ #if rpSrc and rpSrc[0].endswith('.translate') and mc.getAttr(rpSrc[0], keyable=True):
315
+ #return rpSrc[0]
316
+
317
+ for each in ('rotatePivotX' , 'rotatePivotY' , 'rotatePivotZ' ):
318
+ src = mc .listConnections (node + '.' + each , source = True , destination = False )
319
+ if not src :
320
+ continue
321
+ srcType = mc .nodeType (src [0 ])
322
+ if srcType == 'remapValue' :
323
+ src = mc .listConnections (src [0 ]+ '.inputValue' , source = True , destination = False , plugs = True )
324
+ if src and mc .getAttr (src [0 ], keyable = True ) and not mc .getAttr (src [0 ], lock = True ):
325
+ return src [0 ]
326
+ return None
327
+
239
328
240
329
def is_pivot_connected (node ):
241
330
for each in ('rotatePivot' , 'rotatePivotX' , 'rotatePivotY' , 'rotatePivotZ' ):
242
331
if mc .listConnections (node + '.' + each , source = True , destination = False ):
243
- om .MGlobal .displayWarning ('Pivot attribute is connected, unable to edit.' )
244
332
return True
245
333
return False
246
334
@@ -256,24 +344,49 @@ def reset_pivot(*args):
256
344
om .MGlobal .displayWarning ('Only works on one node at a time.' )
257
345
return
258
346
259
- if is_pivot_connected (sel [0 ]):
260
- return
261
-
262
347
node = sel [0 ]
263
-
264
- pivotPosition = mc .getAttr (node + '.rotatePivot' )[0 ]
265
- if pivotPosition == (0.0 ,0.0 ,0.0 ):
266
- return
267
-
348
+ driver = None
349
+ driver_value = None
350
+ driver_default = None
351
+
352
+ if is_pivot_connected (node ):
353
+ driver = pivot_driver_attr (node )
354
+ if driver :
355
+ dNode ,dAttr = driver .split ('.' ,1 )
356
+ driver_value = mc .getAttr (driver )
357
+ driver_default = mc .attributeQuery (dAttr , node = dNode , listDefault = True )[0 ]
358
+ if driver_default == driver_value :
359
+ return
360
+ else :
361
+ om .MGlobal .displayWarning ('Pivot attribute is connected, unable to edit.' )
362
+ return
363
+
364
+ if not driver :
365
+ pivotPosition = mc .getAttr (node + '.rotatePivot' )[0 ]
366
+ if pivotPosition == (0.0 ,0.0 ,0.0 ):
367
+ return
368
+
268
369
tempPosition = mc .group (em = True )
269
370
tempPivot = mc .group (em = True )
270
371
tempPivot = mc .parent (tempPivot , node )[0 ]
271
- mc .setAttr (tempPivot + '.translate' , 0 ,0 ,0 )
372
+ if driver :
373
+ mc .setAttr (driver , driver_default )
374
+ newRP = mc .getAttr (node + '.rotatePivot' )[0 ]
375
+ mc .setAttr (driver , driver_value )
376
+ mc .setAttr (tempPivot + '.translate' , * newRP )
377
+ else :
378
+ mc .setAttr (tempPivot + '.translate' , 0 ,0 ,0 )
379
+
272
380
mc .setAttr (tempPivot + '.rotate' , 0 ,0 ,0 )
273
381
274
382
utl .matchBake (source = [tempPivot ], destination = [tempPosition ], bakeOnOnes = True , maintainOffset = False , preserveTangentWeight = False , rotate = False )
275
-
276
- mc .setAttr (node + '.rotatePivot' , 0 ,0 ,0 )
383
+
384
+ if driver :
385
+ mc .setAttr (driver , driver_default )
386
+ else :
387
+ mc .setAttr (node + '.rotatePivot' , 0 ,0 ,0 )
388
+
389
+ mc .refresh ()
277
390
utl .matchBake (source = [tempPosition ], destination = [node ], bakeOnOnes = True , maintainOffset = False , preserveTangentWeight = False , rotate = False )
278
391
279
392
mc .delete (tempPosition ,tempPivot )
@@ -290,3 +403,5 @@ def reset_pivot(*args):
290
403
# Revision 1: 2016-06-21 : First publish.
291
404
#
292
405
# Revision 2: 2017-06-26 : update for pySide2, maya 2017
406
+ #
407
+ # Revision 3: 2017-07-17 : initial support for attribute driven pivots
0 commit comments