Maya Push/Relax Script

Maya Push/Relax Script

Admiral.Pixel
Enthusiast Enthusiast
4,016 Views
10 Replies
Message 1 of 11

Maya Push/Relax Script

Admiral.Pixel
Enthusiast
Enthusiast

Hi all. I'm trying to make a custom script that replicates/imitates the Maya Sculpt Geometry Tool. Basically I have 2 radio buttons, Push and Relax[which imitates the push and relax from the sculpt parameters obviously], a value slider[replicates the max displacement slider]. The radio and reset button works perfectly however I'm having problems with coding the slider. Any help for this one? Thanks in advance.

 

Untitled.png

 

Code:

import maya.cmds as cmds
import maya.mel as mel


if cmds.window("cusWin", exists = True):
    cmds.deleteUI("cusWin")
        
    

customwindow = cmds.window("cusWin",t= "Push/Relax", wh = (200, 117), s= False, mnb= False, mxb= False)
cmds.frameLayout( label='Push/Relax Modifier', borderStyle='in', cll= False)
cmds.columnLayout(adj = True, columnOffset= ("both", 3))


cmds.radioCollection()
cmds.radioButton(l = "Push", onc= "mel.eval('artUpdatePuttyOperation artPuttyCtx push ;')")
cmds.radioButton(l = "Relax", onc= "mel.eval('artUpdatePuttyOperation artPuttyCtx relax ;')")

cmds.separator(style= "none", h= 3)

DynFsgCol1 = 30
DynFsgCol2 = 50
DynFsgCol3 = 100
 
valSlider = cmds.floatSliderGrp(l = "Value", field = True, min = 0, max= 5, precision = 4, cw3= (DynFsgCol1, DynFsgCol2, DynFsgCol3 ))
cmds.separator(style= "none", h= 3)

cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,98),(2,100)], columnOffset=[(1,'left',1),(2,'right',95)])
cmds.button(l = "Apply", w= 92, c= 'slider()')
cmds.button(l = "Reset", w= 91, c= 'resetButton()')

cmds.showWindow( customwindow )


def slider():
    valueSlider = cmds.floatSliderGrp(valSlider, q= True, value= True)
    mel.eval('artPuttyCtx -e -maxdisp valueSlider `currentCtx`;')
    
def resetButton():
    mel.eval('resetTool artPuttyContext;')
    
    
    
    

 

0 Likes
Accepted solutions (1)
4,017 Views
10 Replies
Replies (10)
Message 2 of 11

kevin.picott
Alumni
Alumni

I assume that you're having trouble getting the value to the Mel command in the slider() function. To do this you need to do two things. First, define a changeCommand argument for the floatSliderGrp command:

 

valSlider = cmds.floatSliderGrp(changeCommand=slider, l = "Value", field = True, min = 0, max= 5, precision = 4, cw3= (DynFsgCol1, DynFsgCol2, DynFsgCol3 ))

 

Next, change the slider() function to accept the new value as a parameter, and then construct the Mel string using that new value. (Be sure to define the slider() function before the above call, so that it knows where to find it.)

 

 

def slider(value):
    print 'Changed value to {}'.format(value)
    mel.eval('artPuttyCtx -e -maxdisp ' + str(value) + '`currentCtx`;')

 

 



Kevin "Father of the DG" Picott

Senior Principal Engineer
0 Likes
Message 3 of 11

Admiral.Pixel
Enthusiast
Enthusiast

@kevin.picott Hi there sir and thanks for reply. The values from the slider matches the one from the sculpt geometry tool now. Thanks for that. However, when I click the apply button I'm getting an error:

"# Error: TypeError: file <maya console> line 1: slider() takes exactly 1 argument (0 given) # " and obviously this is from the "slider" def. I don't know what to change there and I would be glad if you can help me there. Thanks a lot. 

Here's my script so far.

import maya.cmds as cmds
import maya.mel as mel


if cmds.window("cusWin", exists = True):
    cmds.deleteUI("cusWin")



customwindow = cmds.window("cusWin",t= "Push/Relax", wh = (200, 117), s= False, mnb= False, mxb= False)
cmds.frameLayout( label='Push/Relax Modifier', borderStyle='in', cll= False)
cmds.columnLayout(adj = True, columnOffset= ("both", 3))


cmds.radioCollection()
push = lambda _: cmds.artPuttyCtx(cmds.currentCtx(), e = True,  mtm='push')
relax = lambda _: cmds.artPuttyCtx(cmds.currentCtx(), e = True, mtm='relax')


cmds.radioButton(l = "Push", onc= push, select = True)
cmds.radioButton(l = "Relax", onc=relax)

cmds.separator(style= "none", h= 3)

cmds.separator(style= "none", h= 3)

DynFsgCol1 = 30
DynFsgCol2 = 50
DynFsgCol3 = 100

valSlider = cmds.floatSliderGrp(changeCommand=slider, l = "Value", field = True, min = 0, max= 5, precision = 4, cw3= (DynFsgCol1, DynFsgCol2, DynFsgCol3 ))
cmds.separator(style= "none", h= 3)

cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,98),(2,100)], columnOffset=[(1,'left',1),(2,'right',95)])
cmds.button(l = "Apply", w= 92, c= 'slider()')
cmds.button(l = "Reset", w= 91, c= 'resetButton()')

cmds.showWindow( customwindow )


# put the defs here, where the names of the slider are known
    
def slider(value):
    print 'Changed value to {}'.format(value)
    mel.eval('artPuttyCtx -e -maxdisp ' + str(value) + '`currentCtx`;')

def resetButton(*_):
    cmds.resetTool(cmds.currentCtx())
0 Likes
Message 4 of 11

kevin.picott
Alumni
Alumni

Move the definition of slider() up to the top of your script - you're probably just picking up the earlier definition that didn't have the value parameter.



Kevin "Father of the DG" Picott

Senior Principal Engineer
0 Likes
Message 5 of 11

Admiral.Pixel
Enthusiast
Enthusiast

@kevin.picott Thanks for the quick response. I moved the def slider at top but still getting the same error. Untitled.png

0 Likes
Message 6 of 11

kevin.picott
Alumni
Alumni

That's odd. Does "help(slider)" show the version with a parameter in it?



Kevin "Father of the DG" Picott

Senior Principal Engineer
0 Likes
Message 7 of 11

Admiral.Pixel
Enthusiast
Enthusiast

@kevin.picott I think yes sir or no clue. But here's the actual code I made. The script is super basic since I'm still a beginner. I'm trying to replicate the deform modifier in XSI which has a push and relax modifiers. The advantage of it is it relaxes the mesh without changing the volume in which Maya doesn't have at the moment so I'm trying to look for an alternative, hence making the script. Sorry for all the inconveniences

Push/Relax Modifer Script: https://drive.google.com/open?id=0B5bE2wRtMZWPLXBJNjdTSUc2M2M

 

0 Likes
Message 8 of 11

kevin.picott
Alumni
Alumni
Accepted solution

Ah, I see now, even though it's been there all along. My solution made the values update when you moved the slider but you actually want the value to be read out when you hit the Apply button. Now it makes sense. In that case a slightly different modification is in order, which is closer to your original, only changing the call to mel.eval in the slider() function:

 

import maya.cmds as cmds
import maya.mel as mel

if cmds.window("cusWin", exists = True):
    cmds.deleteUI("cusWin")
    
  
customwindow = cmds.window("cusWin",t= "Push/Relax", wh = (200, 117), s= False, mnb= False, mxb= False)
cmds.frameLayout( label='Push/Relax Modifier', borderStyle='in', cll= False)
cmds.columnLayout(adj = True, columnOffset= ("both", 3))


cmds.radioCollection()
push = lambda _: cmds.artPuttyCtx(cmds.currentCtx(), e = True,  mtm='push')
relax = lambda _: cmds.artPuttyCtx(cmds.currentCtx(), e = True, mtm='relax')


cmds.radioButton(l = "Push", onc= push, select = True)
cmds.radioButton(l = "Relax", onc=relax)

cmds.separator(style= "none", h= 3)

cmds.separator(style= "none", h= 3)

DynFsgCol1 = 30
DynFsgCol2 = 50
DynFsgCol3 = 100

valSlider = cmds.floatSliderGrp(l = "Value", field = True, min = 0, max= 5, precision = 4, cw3= (DynFsgCol1, DynFsgCol2, DynFsgCol3 ))
cmds.separator(style= "none", h= 3)

cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,98),(2,100)], columnOffset=[(1,'left',1),(2,'right',95)])
cmds.button(l = "Apply", w= 92, c= 'slider()')
cmds.button(l = "Reset", w= 91, c= 'resetButton()')

cmds.showWindow( customwindow )

# put the defs here, where the names of the slider are known
def slider():
    value = cmds.floatSliderGrp( valSlider, query=True, value=True )
    print 'Changed value to {}'.format(value)
    mel.eval('artPuttyCtx -e -maxdisp ' + str(value) + '`currentCtx`;')

def resetButton(*_):
    cmds.resetTool(cmds.currentCtx())

By the way, a very useful technique for this kind of UI manipulation is to put all of the methods into a class. That way you can avoid using global variables.



Kevin "Father of the DG" Picott

Senior Principal Engineer
Message 9 of 11

Admiral.Pixel
Enthusiast
Enthusiast

@kevin.picott Excactly sir. I do hope that Maya will have those features in the future like in XSI. They're really useful for topology's equal distribution without affecting the mesh volume. Furthermore, the Apply button is actually for/like the "Flood" in the Sculpt parameters which I'm aiming for. Thank you for all the support and time 🙂Untitled.png

0 Likes
Message 10 of 11

mspeer
Consultant
Consultant

Hi!

 

Is the problem solved?

Please mark every answer that solves your problem as solution, so others interested in this thread will get a better overview.

0 Likes
Message 11 of 11

Admiral.Pixel
Enthusiast
Enthusiast

Hi there! It's partially but I'll accept the last replies as a solution.

0 Likes