Hampus
Hampus

Reputation: 11

Getting variables and calling functions with UI. Maya python

I am currently working on a little script that creates a crane-like rig automatically in Autodesk Maya, the user gets to choose the amount of joints by a UI.

My question is how do I take the integer input of the user and use it as the variable value for my "jointAmount"?

I am also wondering how I would be able to call my function(AutoCraneRig) to actually run the script from the UI. I have a "apply"-button but I am unsure how to connect it to my function.

I have seen similar posts like mine but I feel that the solutions shown are somewhat hard for me to understand and/or I can't really relate what is shown to my own problem.

If anything is unclear or more information is needed from me please don't hesitate to call me out.

Here is what my current UI look like

import maya.cmds as cmds
import pymel.core as pm


def jntctrl():
number = pm.intField(jnt, q=1, v=1)
print(number)

if pm.window("stuff", exists = True):
pm.deleteUI("stuff")

pm.window("stuff", t = "Crane Rig Generator", w=400, h=200)
pm.columnLayout(adj = True)

pm.text(label="Joint Amount:")
jnt = pm.intField(changeCommand = 'jntctrl()')

pm.button(label="Create Crane")

pm.showWindow()


#Defining how many joints the user want to have for their crane rig
jointAmmount = 5

#Defining how many controllers the user want to have to orient the crane. 
#May not exceed the joint amount
controllerAmount = 5

def autoCraneRig():
#Creating the joints
for i in range(jointAmmount):
  pm.joint()
  pm.move(0, i, 0)

#Creating the controllers
for i in range(controllerAmount):
    pm.circle()
    pm.rotate (0,90,0)
    pm.makeIdentity (apply= True)

#Creating the groups    
for i in range(controllerAmount):
    pm.group()

#Somehow one of the nurbs get parented to a group when running the script, here i select both the groups and then unparent them.
pm.select("group*", "nurbsCircle*")
pm.parent(world = True)

#Creating lists/dictionaries for the groups
#Since I wanted to parent my objects by their number I had to put all objects in lists/dictionries to get access.
groups = pm.ls('group*')
nbs = [int(n.split('group')[-1]) for n in groups]
groupDic = dict(zip(nbs, groups))

#Create a list/dictionary for the joints
joint = pm.ls('joint*', type='joint')
nbs = [int(n.split('joint')[-1]) for n in joint]
jointDic = dict(zip(nbs, joint))

common = list(set(groupDic.keys())&set(jointDic.keys()))

#Parenting the groups to the joints
for i in common:
    pm.parent(groupDic[i], jointDic[i])

#Reseting the transformations of the groups and then unparenting them to still have the transformation data of the joints    
pm.select("group*")
pm.makeIdentity()
pm.parent(world = True)

#Creating a list/dictionary for the nurbs aswell that will be parented to the groups in numeric order
nurbs_sh = pm.ls('nurbsCircle*', type='nurbsCurve')

#I had to get the transformation information from the nurbs before parenting them with anything would work(took a long time to get it right).
nurbs_tr = pm.listRelatives(nurbs_sh, p=1)
nbs = [int(n.split('nurbsCircle')[-1]) for n in nurbs_tr]
curveDic = dict(zip(nbs, nurbs_tr))

common = list(set(groupDic.keys())&set(curveDic.keys()))

#Parent the nurbs to the groups
for i in common:
    pm.parent(curveDic[i], groupDic[i])

#Select the nurbs and reset transformations and then freeze transform
pm.select("nurbsCircle*")
pm.makeIdentity()

#Orient constrain the controllers/nurbs to the joints
for i in common:
    pm.orientConstraint(curveDic[i], jointDic[i])

#Parent the 2nd group with the first controller. Do this for the whole hierarchy. 
for i in common:
    pm.parent(groupDic[i+1], curveDic[i])

#I'm getting keyError after I put the "+1" in my groupDic and I don't know why, although it still works, I guess.

autoCraneRig()

Upvotes: 1

Views: 1572

Answers (1)

Morten
Morten

Reputation: 497

Here's an example for how to call a specific function/command when a button is clicked, and how to get the value of an int field. The key is in naming the fields, so you can reference the UI control later.

import pymel.core as pm


def ui():
    if (pm.window("myWindow", exists=True)):
        pm.deleteUI("myWindow")

    window = pm.window("myWindow", t="My Window", w=400, h=200)
    pm.columnLayout(adj=True)
    pm.intField("myIntField")
    pm.button("Button", aop=True, command="action()")

    pm.showWindow(window)


def action():
    print("Button clicked!")
    value = pm.intField("myIntField", q=True, v=True)
    print(value)


ui()

If you want to get more into making UI's, I would recommend you watch these two videos:

Upvotes: 1

Related Questions