Reputation: 93
I am pretty new to python and scripting/coding in general.
I am currently working on a small script that serves the purpose of selecting edges of an object in my scene, based on their angle. I have two intfields for the user to specify a min and a max value. Based on the input, I want a button to select all edges within the min/max range.
Everything works so far, except when clicking the button, the min/max input is NOT taken into account. Maya only selects all edges with the default value of 0,
instead of selecting all edges in the min/max range and I can't figure out why.
From my limited knowledge, it seems the "selEdges" function is the issue. The "ab=" flag usually takes two integer values and if i define it like this: ab=(0, 30), it works, but I don't want it hard coded. I just can't get my head around how to pass the user input from the two infields to the "selEdges" function.
Here is my script:
import maya.cmds as cmds
if cmds.window('myWindow', exists=True):
cmds.deleteUI('myWindow')
cmds.window('myWindow', title='myWindow', wh=[200, 100])
cmds.rowColumnLayout(numberOfColumns=2)
minNormalAngle = cmds.intField(minValue=0, maxValue=360)
minNA = cmds.intField(minNormalAngle, query=True, value=True)
maxNormalAngle = cmds.intField(minValue=0, maxValue=360)
maxNA = cmds.intField(maxNormalAngle, query=True, value=True)
def selEdges(*pArgs):
cmds.polySelectConstraint(m=3, a=True, w=2, ab=(minNA, maxNA))
cmds.polySelectConstraint(m=0)
def sofEdges(*pArgs):
cmds.polySoftEdge(a=180)
cmds.button(label='select', command=selEdges)
cmds.button(label='soften', command=sofEdges)
cmds.showWindow()
Here is a screenshot for better understanding of the UI in maya. !(http://abload.de/image.php?img=selscriptq9kcy.jpg)
EDIT:
This is what i have now:
# Selection Script by David Sikorsky
#Alpha Version 0.5
# - NOT FEATURE COMPLETE
# - BUGS MAY OCCURE WHILE USING THIS SCRIPT
import maya.cmds as cmds
import functools
# Close window if it already exists
if cmds.window('myWindow', exists=True):
cmds.deleteUI('myWindow')
# Create a Window
myWindow = cmds.window('myWindow', title='Selection Script', resizeToFitChildren=True)
# Column 1: How To Text
cmds.columnLayout('columnLayoutName01', adjustableColumn=True)
cmds.frameLayout('layoutFrame01', label='How To Use:', collapsable=True, collapse=False, borderVisible=False)
cmds.separator(h=1, style='none')
cmds.text('howTo', font='boldLabelFont', label='How to use:', align="center")
cmds.separator()
cmds.text('desciption', font='boldLabelFont', align="center", label='''- Select an Object in your scene.
- Specify min/max Edge Angle.
- Select all Edges In Range.
- Soften or harden or Selected Edges.''')
cmds.separator(h=1, style='none')
cmds.setParent('..')
# Column 2: Soft/Hard Text
cmds.rowColumnLayout('columnLayoutName02', numberOfColumns=3, cw=[(1, 102),(2, 20), (3, 102)])
cmds.text(label='<-Soft->', align='center', font='boldLabelFont')
cmds.separator(h=1, style='none')
cmds.text(label='<-Hard->', align='center', font='boldLabelFont')
cmds.setParent('..')
# Column 2: min/max Text
cmds.rowColumnLayout('columnLayoutName03', numberOfColumns=7, cw=[(1, 51), (2, 51), (3, 20), (4, 51), (5, 51)])
cmds.text(label='Min', align='left')
cmds.text(label='Max', align='right')
cmds.separator(h=1, style='none')
cmds.text(label='Min', align='left')
cmds.text(label='Max', align='right')
cmds.setParent('..')
#Column 3: Infields
cmds.rowColumnLayout('columnLayoutName04', numberOfColumns=7, cw=[(1, 50), (2, 2), (3, 50), (4, 20), (5, 50), (6, 2), (7, 50)])
def selSoftIRFunc(*pArgs):
minSoftNA = cmds.intField(minSoftNormalAngle, query=True, value=True)
maxSoftNA = cmds.intField(maxSoftNormalAngle, query=True, value=True)
cmds.polySelectConstraint(m=3, t=0x8000, a=True, w=2, sm=0, ab=(minSoftNA, maxSoftNA))
cmds.polySelectConstraint(m=0, a=False)
minSoftNormalAngle = cmds.intField(minValue=0, maxValue=180, enterCommand=selSoftIRFunc)
cmds.separator(h=1, style='none')
maxSoftNormalAngle = cmds.intField(minValue=0, maxValue=180, enterCommand=selSoftIRFunc)
cmds.separator(h=1, style='none')
def selHardIRFunc(*pArgs):
minHardNA = cmds.intField(minHardNormalAngle, query=True, value=True)
maxHardNA = cmds.intField(maxHardNormalAngle, query=True, value=True)
cmds.polySelectConstraint(m=3, t=0x8000, a=True, w=2, sm=0, ab=(minHardNA, maxHardNA))
cmds.polySelectConstraint(m=0, a=False)
minHardNormalAngle = cmds.intField(minValue=0, maxValue=180, enterCommand=selHardIRFunc)
cmds.separator(h=1, style='none')
maxHardNormalAngle = cmds.intField(minValue=0, maxValue=180, enterCommand=selHardIRFunc)
cmds.setParent('..')
#column 4: Buttons Layout
cmds.rowColumnLayout('columnLayoutName05', numberOfColumns=3, cw=[(1,102),(2,20),(3,102)])
for i in range(3):
cmds.separator(h=5, style='none')
cmds.button(label='Select Edges', command=selSoftIRFunc)
cmds.separator(h=5, style='none')
cmds.button(label='Select Edges', command=selHardIRFunc)
for i in range(3):
cmds.separator(h=5, style='none')
def softEFunc(*pArgs):
cmds.polySoftEdge(a=180)
cmds.button(label='Soften Edges', command=softEFunc)
cmds.separator(h=5, style='none')
def hardenEFunc(*pArgs):
cmds.polySoftEdge(a=0)
cmds.button(label='Harden Edges', command=hardenEFunc)
for i in range(3):
cmds.separator(h=5, style='none')
def selSoftEFunc(*pArgs):
cmds.polySelectConstraint(m=3, t=0x8000, w=2, sm=2)
cmds.polySelectConstraint(m=0)
cmds.button(label='Select Soft Edges', command=selSoftEFunc)
cmds.separator(h=5, style='none')
def selHardEFunc(*pArgs):
cmds.polySelectConstraint(m=3, t=0x8000, w=2, sm=1)
cmds.polySelectConstraint(m=0)
cmds.button(label='Select Hard Edges', command=selHardEFunc)
for i in range(3):
cmds.separator(h=5, style='none')
def selInvertFunc(*pArgs):
cmds.InvertSelection('*', tgl=True)
cmds.button(label='Invert Selection', command=selInvertFunc)
cmds.separator(h=5, style='none')
cmds.setParent('myWindow')
# Close Button Layout
cmds.rowColumnLayout('columnLayoutName06', numberOfColumns=3, cw=[(1,102),(2,20),(3,102)])
def closeCallback(*pArgs):
if cmds.window('myWindow', exists=True):
cmds.deleteUI('myWindow')
for i in range(20):
cmds.separator(h=10, style='none')
cmds.button(label='Close', command=closeCallback)
cmds.showWindow('myWindow')
Upvotes: 2
Views: 1929
Reputation: 58553
Flags a
, w
and ab
are only available in Vertex, Edge, Face and Texture Modes. You need to use polySelectConstraint()
in Edge Mode.
Here is a Python version of code you should add to your script:
cmds.polyListComponentConversion( te = 1 )
cmds.ls( sl = 1 )
Look also at MEL equivalent:
ConvertSelectionToEdges;
string $sel[] = `ls -sl`;
Upvotes: 0
Reputation: 12218
Typically you'd want to do this with a sequence like this:
It's a good idea to write that function so it doesn't change the selection, since it's easy to accidentally deselect things with a bad value. The minimum version would be something like this (notice how it resets the selection at the end)
def edges_by_angle(selection, min_angle, max_angle):
'''return the edges in selection with a crossing angle between <min_angle> and <max_angle>'''
result = []
try:
edges = cmds.polyListComponentConversion(selection, te=True)
cmds.select(edges)
cmds.polySelectConstraint(mode =3, type = 0x8000, a = 1, ab = (min_angle,max_angle))
result = cmds.ls(sl=True) or []
finally:
cmds.polySelectConstraint(dis=True)
cmds.select(selection)
return result
You can simplify the GUI by using an intFieldGrp
instead of two intFields
. It's a good idea to get in the habit of building your gui inside a function -- the code you have written above will work in the listener but will behave oddly if imported from a module file. Putting things into a function is a cheap way to control the scope of the variables so there's not difficulty in figuring out where the callback functions you need are living. Here's a very minimal example:
def selection_window():
# callbacks
def select_by_angle(a, b):
old_sel = cmds.ls(sl=True, o=True) or []
new_sel = (edges_by_angle(old_sel, a, b))
if new_sel:
cmds.select(new_sel)
def smooth_edges(*_):
cmds.polySoftEdge(a=180)
def harden_edges(*_):
cmds.polySoftEdge(a=0)
# gui....
w = cmds.window(title='select by edges')
c = cmds.columnLayout()
ifg = cmds.intFieldGrp(label = 'angles', nf = 2, cc = select_by_angle)
cmds.rowLayout(nc=2)
cmds.button('Soften', c= smooth_edges)
cmds.button('Harden', c= harden_edges)
#show the window and return it if you need it's name later...
cmds.showWindow(w)
return w
You can keep the edges_by_angle()
function separate from this because it's likely to be useful in other cases.
Upvotes: 1