global name 'newparent' is not defined ?

global name 'newparent' is not defined ?

dg3duy
Collaborator Collaborator
714 Views
9 Replies
Message 1 of 10

global name 'newparent' is not defined ?

dg3duy
Collaborator
Collaborator

It is a script that I am designing to align a camera to another, at the time of eliminating the locator and the pairing does not happen.

 

  • Creates a locator in the pivot of the selected camera
  • Once the locator created and the camera root are selected, I link them with parent constraint
  • Once the locator and the target camera "proxy" have been selected, I link the locator to the target camera.

    At the end of all the steps I cannot delete the locator created nor the relationship.
    It does not find them by name apparently.

 

cmds.delete(newparent)
cmds.delete(newLoc)​

The example on the screen is 2 cameras, there is nothing special.
delete locator.gif

import maya.cmds as cmds


class MatchCamScript():
    
    def __init__(self):

        myWin = cmds.window(minimizeButton=0,maximizeButton=0,title="Match Cam", widthHeight=(150, 80))
        cmds.columnLayout("mainColumn")
        cmds.rowLayout( numberOfColumns=2, columnAttach=(1, "right", 10), columnWidth=[(1,143),(2,245)] )
        self.button = cmds.button(p = "mainColumn",label="Camera Rig",width=148,align='center', command= lambda x: self.makelocator())
        cmds.separator(p = "mainColumn")  
        self.button = cmds.button(p = "mainColumn",label="Root Camera Rig Selected",width=148,align='center', command=lambda x: self.selroot())
        cmds.separator(p = "mainColumn")  
        self.button = cmds.button(p = "mainColumn",label="Camera Proxy Selected",width=148,align='center', command=lambda x: self.selproxy())


        cmds.showWindow(myWin)
    
    def execute():
        pass
    
    def makelocator(args,):
    	sel = cmds.ls(sl = 1)

	for obj in sel:
	    newLoc = cmds.spaceLocator( n='LocatorCameraPivot' )
	    newCon = cmds.parentConstraint(obj, newLoc, mo = 0)
	    cmds.delete(newCon)
	    
    def selroot(args,):
    		
		nodes = cmds.ls(sl=True)
		myParent = nodes[-1]
		nodes.pop()
		for node in nodes:
			newparent = cmds.parentConstraint(nodes[-1], myParent, mo=True, weight=1)

    def selproxy(args,):

		nodes = cmds.ls(sl=True)
		myParent = nodes[-1]
		nodes.pop()
		for node in nodes:
			newparentX = cmds.parentConstraint(myParent, nodes[-1], mo=False)
			cmds.delete(newparentX)
			cmds.delete(newparent)
			cmds.delete(newLoc)
			
MatchCamScript()​

 

0 Likes
Accepted solutions (2)
715 Views
9 Replies
Replies (9)
Message 2 of 10

Kahylan
Advisor
Advisor

Hi!

 

Your variable "newparent" is only defined in the function "selroot", so your function "selproxy" doesn't know it. You could make it global, but that is generally quite risky and should be avoided. I would instead just use the selectionslist to find your locator and delete it, the constraint will be deleted automatically.

import maya.cmds as cmds


class MatchCamScript:


    def __init__(self):

        myWin = cmds.window(minimizeButton=0,maximizeButton=0,title="Match Cam", widthHeight=(150, 80))
        cmds.columnLayout("mainColumn")
        cmds.rowLayout( numberOfColumns=2, columnAttach=(1, "right", 10), columnWidth=[(1,143),(2,245)] )
        self.button = cmds.button(p = "mainColumn",label="Camera Rig",width=148,align='center', command= lambda x: self.makelocator())
        cmds.separator(p = "mainColumn")  
        self.button = cmds.button(p = "mainColumn",label="Root Camera Rig Selected",width=148,align='center', command=lambda x: self.selroot())
        cmds.separator(p = "mainColumn")  
        self.button = cmds.button(p = "mainColumn",label="Camera Proxy Selected",width=148,align='center', command=lambda x: self.selproxy())
        
        
        cmds.showWindow(myWin)
    
    def execute():
        pass
    
    def makelocator(args,):
        sel = cmds.ls(sl = 1)

        for obj in sel:
            newLoc = cmds.spaceLocator( n='LocatorCameraPivot' )
            newCon = cmds.parentConstraint(obj, newLoc, mo = 0)
            cmds.delete(newCon)
    
    def selroot(args,):
    		
        nodes = cmds.ls(sl=True)
        myParent = nodes[-1]
        nodes.pop()
        for node in nodes:
            newparent = cmds.parentConstraint(nodes[-1], myParent, mo=True, weight=1)

    def selproxy(args,):
        
        nodes = cmds.ls(sl=True)
        myParent = nodes[-1]

        nodes.pop()
        for node in nodes:
            newparentX = cmds.parentConstraint(myParent, nodes[-1], mo=False)
            cmds.delete(newparentX)
            cmds.delete(nodes[-1])

            
        
MatchCamScript()     

 

But no offense, your script seems quite cluncky. Like, you need to click 3 buttons and change the selection 3 times to simply match one camera to another. Wouldn't it be easier to just select both cams and then match the camera selected first to the camera selected second?

import maya.cmds as cmds


class MatchCamScript:


    def __init__(self):

        myWin = cmds.window(minimizeButton=0,maximizeButton=0,title="Match Cam", widthHeight=(150, 80))
        cmds.columnLayout("mainColumn")
        cmds.rowLayout( numberOfColumns=2, columnAttach=(1, "right", 10), columnWidth=[(1,143),(2,245)] )
        self.button = cmds.button(p = "mainColumn",label="Match Cameras",width=148,align='center', command= lambda x: self.matchCams())
        
        
        cmds.showWindow(myWin)
    
    def execute():
        pass
    
    def matchCams(args,):
        sel = cmds.ls(sl = 1)
        matchTo = sel.pop(-1)
        mat = cmds.xform(matchTo, m= True, ws= True, q = True)

        for obj in sel:
            cmds.xform(obj, m = mat, ws=True)

            
        
MatchCamScript()     

 

I hope it helps!

Message 3 of 10

dg3duy
Collaborator
Collaborator

@Kahylan 
It happens that it is necessary to delete first the constraint and finally the locator object created, so that the rig camera is located in its position and orientation.
I cannot use your suggestion because it deletes the locator object without first deleting the constraint.
I can not use your simplified code because the pivots of the cameras are totally different, one is in the root of the rig at its base and the other in the camera at its pivot.
delete locator and constraint.gif

0 Likes
Message 4 of 10

Kahylan
Advisor
Advisor

Ok, if you need to move the entire rig with the camera, it makes a bit more sense.

Still, your problem is, that you have a local variable in one function, that you are trying to call in another function.

A simple solution to this is, to just store the important objects you need for your script first in the UI, so you can just call upon the UI Element:

 

This would be the Code for that:

import maya.cmds as cmds


class MatchCamScript:
    

    def __init__(self):


        myWin = cmds.window("Match Cam", minimizeButton=0,maximizeButton=0,title="Match Cam", widthHeight=(400, 400), s = True)
        cmds.columnLayout("mainColumn")
        self.textFieldGrp1 = cmds.textFieldButtonGrp("TxGrp1",p = "mainColumn",label="Camera in Rig", bl = "Load", bc=lambda field = "TxGrp1": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")  
        self.textFieldGrp2 = cmds.textFieldButtonGrp("TxGrp2",p = "mainColumn",label="Snap Camera", bl = "Load", bc=lambda field = "TxGrp2": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")  
        self.textFieldGrp3 = cmds.textFieldButtonGrp("TxGrp3",p = "mainColumn",label="Rig Main", bl = "Load", bc=lambda field = "TxGrp3": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")
        cmds.columnLayout("secondaryColumn")
        self.button = cmds.button(p = "secondaryColumn",l = "execute", c= self.execute)
        
        
        
        cmds.showWindow(myWin)
    
    def execute(*args):
        cam1 = cmds.textFieldButtonGrp("TxGrp1", tx = True, q = True)
        cam2 = cmds.textFieldButtonGrp("TxGrp2", tx = True, q = True)
        main = cmds.textFieldButtonGrp("TxGrp3", tx = True, q = True)
        
        
        mat = cmds.xform(cam1, m= True, ws= True, q= True)
        loc = cmds.spaceLocator(n = "tempLoc")[0]
        cmds.xform(loc, m= mat, ws= True)
        const1 = cmds.parentConstraint(loc, main, mo = True)
        mat= cmds.xform(cam2, m= True, ws= True, q= True)
        cmds.xform(loc,m= mat, ws= True)
        cmds.delete(const1,loc)

    
    def loadSelection(*args, field = None):
        
        sel = cmds.ls(sl= True)[0]
        cmds.textFieldButtonGrp(field, tx = sel, e = True)
              
MatchCamScript()

 

Or you could just go over selection order:

import maya.cmds as cmds


class MatchCamScript:
    

    def __init__(self):


        myWin = cmds.window("Match Cam", minimizeButton=0,maximizeButton=0,title="Match Cam", widthHeight=(400, 400), s = True)
        cmds.columnLayout("mainColumn")
        cmds.text("Please select the following Items in Order:")
        cmds.text("1) Camera in Rig")
        cmds.text("2) Camera you want to Snap to")
        cmds.text("3) Rig Main CTRL")
        self.button = cmds.button(p = "mainColumn",l = "execute", c= self.execute)
        
        
        
        cmds.showWindow(myWin)
    
    def execute(*args):
        
        sel= cmds.ls(sl= True)
        cam1 = sel[0]
        cam2 = sel[1]
        main = sel[2]
        
        
        mat = cmds.xform(cam1, m= True, ws= True, q= True)
        loc = cmds.spaceLocator(n = "tempLoc")[0]
        cmds.xform(loc, m= mat, ws= True)
        const1 = cmds.parentConstraint(loc, main, mo = True)
        mat= cmds.xform(cam2, m= True, ws= True, q= True)
        cmds.xform(loc,m= mat, ws= True)
        cmds.delete(const1,loc)

    
    def loadSelection(*args, field = None):
        
        sel = cmds.ls(sl= True)[0]
        cmds.textFieldButtonGrp(field, tx = sel, e = True)
              
MatchCamScript()

 

I hope it helps!

Message 5 of 10

dg3duy
Collaborator
Collaborator

The video you made is the solution I was looking for, it is exactly what I need. 😍
When I run any of the 2 scripts you posted I get the following error.

MatchCamScript()
# Error: invalid syntax
#   File "<maya console>", line 40
#     def loadSelection(*args, field = None):
#                                  ^
# SyntaxError: invalid syntax # 

 

0 Likes
Message 6 of 10

Kahylan
Advisor
Advisor
Accepted solution

I see. I'm guessing you are on an earlier version of Maya than 2022.

This script should be python 2.7 compadible:

import maya.cmds as cmds


class MatchCamScript:
    

    def __init__(self):


        myWin = cmds.window("Match Cam", minimizeButton=0,maximizeButton=0,title="Match Cam", widthHeight=(400, 400), s = True)
        cmds.columnLayout("mainColumn")
        self.textFieldGrp1 = cmds.textFieldButtonGrp("TxGrp1",p = "mainColumn",label="Camera in Rig", bl = "Load", bc=lambda field = "TxGrp1": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")  
        self.textFieldGrp2 = cmds.textFieldButtonGrp("TxGrp2",p = "mainColumn",label="Snap Camera", bl = "Load", bc=lambda field = "TxGrp2": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")  
        self.textFieldGrp3 = cmds.textFieldButtonGrp("TxGrp3",p = "mainColumn",label="Rig Main", bl = "Load", bc=lambda field = "TxGrp3": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")
        cmds.columnLayout("secondaryColumn")
        self.button = cmds.button(p = "secondaryColumn",l = "execute", c= self.execute)
        
        
        
        cmds.showWindow(myWin)
    
    def execute(self, *args):
        cam1 = cmds.textFieldButtonGrp("TxGrp1", tx = True, q = True)
        cam2 = cmds.textFieldButtonGrp("TxGrp2", tx = True, q = True)
        main = cmds.textFieldButtonGrp("TxGrp3", tx = True, q = True)
        
        
        mat = cmds.xform(cam1, m= True, ws= True, q= True)
        loc = cmds.spaceLocator(n = "tempLoc")[0]
        cmds.xform(loc, m= mat, ws= True)
        const1 = cmds.parentConstraint(loc, main, mo = True)
        mat= cmds.xform(cam2, m= True, ws= True, q= True)
        cmds.xform(loc,m= mat, ws= True)
        cmds.delete(const1,loc)


    def loadSelection(self,field = None, *args):
        sel = cmds.ls(sl= True)[0]
        cmds.textFieldButtonGrp(field, tx = sel, e = True)
     
MatchCamScript()
Message 7 of 10

dg3duy
Collaborator
Collaborator

@Kahylan I am indeed using the 2020 version.
A genius! it works like a charm, thank you very much.

0 Likes
Message 8 of 10

dg3duy
Collaborator
Collaborator

@Kahylan 

proc defaultButtonPush2()
{

//Camara in Rig
string $selCtrl[] = `ls -sl`;

float $srchfa = `getAttr ($selCtrl[1] + ".hfa")`;
float $srcvfa = `getAttr ($selCtrl[1] + ".vfa")`;
float $srcfl = `getAttr ($selCtrl[1] + ".fl")`;
float $srclsr = `getAttr ($selCtrl[1] + ".lsr")`;
float $srcfs = `getAttr ($selCtrl[1] + ".fs")`;
float $srcfd = `getAttr ($selCtrl[1] + ".fd")`;
float $srcsa = `getAttr ($selCtrl[1] + ".sa")`;
float $srccoi = `getAttr ($selCtrl[1] + ".coi")`;


//Camera Snap
setAttr ($selCtrl[0] + ".hfa") $srchfa;
setAttr ($selCtrl[0] + ".vfa") $srcvfa;
setAttr ($selCtrl[0] + ".fl") $srcfl;
setAttr ($selCtrl[0] + ".lsr") $srclsr;
setAttr ($selCtrl[0] + ".fs") $srcfs;
setAttr ($selCtrl[0] + ".fd") $srcfd;
setAttr ($selCtrl[0] + ".sa") $srcsa;
setAttr ($selCtrl[0] + ".coi") $srccoi;
;
}

In mel code this was the way I used to copy the information from the snap camera to the in rig camera.
I totally lost how to do it in phyton and use it in the script you posted. If you can give me some more help on the subject is welcome.🤗
 

0 Likes
Message 9 of 10

Kahylan
Advisor
Advisor
Accepted solution

If you want to only transfer this list of attributes, it would be something like this:

import maya.cmds as cmds


class MatchCamScript:
    

    def __init__(self):


        myWin = cmds.window("Match Cam", minimizeButton=0,maximizeButton=0,title="Match Cam", widthHeight=(400, 400), s = True)
        cmds.columnLayout("mainColumn")
        self.textFieldGrp1 = cmds.textFieldButtonGrp("TxGrp1",p = "mainColumn",label="Camera in Rig", bl = "Load", bc=lambda field = "TxGrp1": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")  
        self.textFieldGrp2 = cmds.textFieldButtonGrp("TxGrp2",p = "mainColumn",label="Snap Camera", bl = "Load", bc=lambda field = "TxGrp2": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")  
        self.textFieldGrp3 = cmds.textFieldButtonGrp("TxGrp3",p = "mainColumn",label="Rig Main", bl = "Load", bc=lambda field = "TxGrp3": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")
        cmds.columnLayout("secondaryColumn")
        cmds.rowLayout("buttonRow", nc = 2)
        self.button = cmds.button(p = "buttonRow",l = "execute", c= self.execute)
        self.button = cmds.button(p = "buttonRow",l = "match attributes", c= self.matchAttrs)
        
        
        
        cmds.showWindow(myWin)
    
    def execute(self, *args):
        cam1 = cmds.textFieldButtonGrp("TxGrp1", tx = True, q = True)
        cam2 = cmds.textFieldButtonGrp("TxGrp2", tx = True, q = True)
        main = cmds.textFieldButtonGrp("TxGrp3", tx = True, q = True)
        
        
        mat = cmds.xform(cam1, m= True, ws= True, q= True)
        loc = cmds.spaceLocator(n = "tempLoc")[0]
        cmds.xform(loc, m= mat, ws= True)
        const1 = cmds.parentConstraint(loc, main, mo = True)
        mat= cmds.xform(cam2, m= True, ws= True, q= True)
        cmds.xform(loc,m= mat, ws= True)
        cmds.delete(const1,loc)


    def loadSelection(self,field = None, *args):
        sel = cmds.ls(sl= True)[0]
        cmds.textFieldButtonGrp(field, tx = sel, e = True)
        
    def matchAttrs(self, *args):
        cam1 = cmds.textFieldButtonGrp("TxGrp1", tx = True, q = True)
        cam2 = cmds.textFieldButtonGrp("TxGrp2", tx = True, q = True)
        
        attrList = ["hfa","vfa","fl","lsr","fs","fd","sa","coi"]
        
        
        for a in attrList:
           
            v = cmds.getAttr("{0}.{1}".format(cam2,a))
                      
            cmds.setAttr("{0}.{1}".format(cam1,a),v)

     
MatchCamScript()

 

If you wanted a more complete list of attributes, I would probably use listAttr to do so:

import maya.cmds as cmds


class MatchCamScript:
    

    def __init__(self):


        myWin = cmds.window("Match Cam", minimizeButton=0,maximizeButton=0,title="Match Cam", widthHeight=(400, 400), s = True)
        cmds.columnLayout("mainColumn")
        self.textFieldGrp1 = cmds.textFieldButtonGrp("TxGrp1",p = "mainColumn",label="Camera in Rig", bl = "Load", bc=lambda field = "TxGrp1": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")  
        self.textFieldGrp2 = cmds.textFieldButtonGrp("TxGrp2",p = "mainColumn",label="Snap Camera", bl = "Load", bc=lambda field = "TxGrp2": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")  
        self.textFieldGrp3 = cmds.textFieldButtonGrp("TxGrp3",p = "mainColumn",label="Rig Main", bl = "Load", bc=lambda field = "TxGrp3": self.loadSelection(field = field))
        cmds.separator(p = "mainColumn")
        cmds.columnLayout("secondaryColumn")
        cmds.rowLayout("buttonRow", nc = 2)
        self.button = cmds.button(p = "buttonRow",l = "execute", c= self.execute)
        self.button = cmds.button(p = "buttonRow",l = "match attributes", c= self.matchAttrs)
        
        
        
        cmds.showWindow(myWin)
    
    def execute(self, *args):
        cam1 = cmds.textFieldButtonGrp("TxGrp1", tx = True, q = True)
        cam2 = cmds.textFieldButtonGrp("TxGrp2", tx = True, q = True)
        main = cmds.textFieldButtonGrp("TxGrp3", tx = True, q = True)
        
        
        mat = cmds.xform(cam1, m= True, ws= True, q= True)
        loc = cmds.spaceLocator(n = "tempLoc")[0]
        cmds.xform(loc, m= mat, ws= True)
        const1 = cmds.parentConstraint(loc, main, mo = True)
        mat= cmds.xform(cam2, m= True, ws= True, q= True)
        cmds.xform(loc,m= mat, ws= True)
        cmds.delete(const1,loc)


    def loadSelection(self,field = None, *args):
        sel = cmds.ls(sl= True)[0]
        cmds.textFieldButtonGrp(field, tx = sel, e = True)
        
    def matchAttrs(self, *args):
        cam1 = cmds.textFieldButtonGrp("TxGrp1", tx = True, q = True)
        cam2 = cmds.textFieldButtonGrp("TxGrp2", tx = True, q = True)
        
        transforms = ['translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ', 'scaleX', 'scaleY', 'scaleZ']
        shape = cmds.listRelatives(cam2, c= True, s= True)[0]
        shapeC1 = cmds.listRelatives(cam1, c= True, s= True)[0]
        
        attrs = cmds.listAttr(cam2,hd= True, k= True)
        attrsNT = [x for x in attrs if x not in transforms]
        attrsShape = cmds.listAttr(shape,hd=True, k = True)
        attrs = attrsShape + attrsNT
        
        for a in attrs:
            print(a)
            v = cmds.getAttr("{0}.{1}".format(cam2,a))
            
            if cmds.attributeQuery(a, n= cam1, ex= True) or cmds.attributeQuery(a, n= shapeC1, ex= True):
                cmds.setAttr("{0}.{1}".format(cam1,a),v)

                
     
MatchCamScript()

 

I hope it helps!

Message 10 of 10

dg3duy
Collaborator
Collaborator

@Kahylan A perfection! Thank you very much, there is no doubt that we learn a lot from you.

0 Likes