Passing variables (inheritance?) between classes

36 views
Skip to first unread message

flaye

unread,
Feb 8, 2014, 4:05:01 PM2/8/14
to python_in...@googlegroups.com

Hi,

I come from a MEL background, and currently exploring the Python OOP world. I'm trying to wrap my head around classes. 

This seems like a very simple issue to resolve, but I can't seem to get the proper syntax to work. As an example, I want to create a module with two classes. I want the second class (Spring) to grab the variable information from the first one (Connector) and use it to build a new set of locators with additional functionality to be attached to them. I've tried a bunch of syntax combinations, but can't seem to get the handle on it. The current Spring class is mangled, and any help would be greatly appreciated.

At the moment, it creates two sets of locators and curves, and gives the following error:

# Error: SetLoc() takes exactly 1 argument (2 given)
# Traceback (most recent call last):
#   File "<maya console>", line 4, in <module>
#   File "C:/Users/.../Documents/maya/2014-x64/prefs/scripts\tgpMechanix.py", line 53, in __init__
#     self.SetSpring(locs)
#   File "C:/Users/.../Documents/maya/2014-x64/prefs/scripts\tgpMechanix.py", line 59, in SetSpring
#     self.basePos=mc.move(0,25,0, locs(self.baseLoc))
# TypeError: SetLoc() takes exactly 1 argument (2 given) #

Here's the current code:

import maya.cmds as mc

class Connector(object):
    '''
    This class will create a curve connector between two locators
    '''
    #initialize the class
    def __init__(self):
      
       
        self.SetLoc()
       
    def SetLoc(self):
       
        print "testing connector class"
        #create locators
        self.baseLoc=mc.spaceLocator(name="baseLoc", p=(0,0,0))[0]
        self.topLoc=mc.spaceLocator(name="topLoc", p=(0,0,0))[0]
       
        #create the connecting curve
        self.conCurve=mc.curve(name="conCurve", d=1, p=[(0,0,0),(0,0,0)])
        mc.setAttr(self.conCurve+".template",1) #template the curve
       
        #create distanceNode
        self.dNode=mc.createNode("distanceBetween")
       
        #position the locators
        self.basePos=mc.move(0,0,0, self.baseLoc) 
        self.topPos=mc.move(0,10,0,self.topLoc)
       
        #connect the curve between the locators
        mc.connectAttr(self.baseLoc+".t",self.conCurve+".cv[0]", force=True)
        mc.connectAttr(self.topLoc+".t",self.conCurve+".cv[1]",force=True)
       
        #attach the distanceNode between the locators
        mc.connectAttr(self.topLoc+".worldMatrix[0]",self.dNode+".inMatrix1",force=True)
        mc.connectAttr(self.baseLoc+".worldMatrix[0]",self.dNode+".inMatrix2",force=True)
       
       
    
#create new class to build spring using the locators from the Connector class     
 
class Spring(Connector):
    def __init__(self, *args):
        super(Spring,self).__init__(*args)
       
        locs=Connector().SetLoc
        self.SetSpring(locs)
   
    def SetSpring(self,locs):
       
        print "testing Spring class"
        #position the locators
        self.basePos=mc.move(0,25,0, locs(self.baseLoc)) 
        self.topPos=mc.move(0,40,0,locs(self.topLoc))
       
       
       
      


 

Justin Israel

unread,
Feb 8, 2014, 5:27:42 PM2/8/14
to python_in...@googlegroups.com
What you have here is a base class, called Connector, and a subclass called Spring. 

When you create a subclass, it inherits all of the superclass functionality. Additionally, when you implement your constructor on the Spring class, and call super(), you are triggering the superclass constructor. In this case, that means SetLoc() is being called (side note: In Python it is idiomatic to use lower-case naming for methods in your class:  set_loc(), set_spring(), ...).

In your Spring constructor, you have a line that reads:

    locs=Connector().SetLoc

What this is actually doing is creating a temporary instance of a Connector, and grabbing a reference to its SetLoc method (it doesn't actually call SetLoc. Just takes a reference to the method). Then you are taking that method object and passing it to your SetSpring(). In SetSpring, you are trying to use it like a function call that takes arguments. But if you look at your definition for SetLoc, it does not take arguments other than the self reference:

    def SetLoc(self):

This where you are getting your error from. When you do:   loc(self.baseLoc), that is effectively the same thing as:  Connector().SetLoc(self.baseLoc)  
and we know method SetLoc() does not take params. 

Here are some comments on your code:

class Connector(object):
    ...        
    def SetLoc(self):
        ...        
        # Thet move() command does not return anything
        # so nothing useful is being set here
        # 
        #self.basePos=mc.move(0,0,0, self.baseLoc)  
        #self.topPos=mc.move(0,10,0,self.topLoc)


class Spring(Connector):
    def __init__(self, *args):
        # When you make this call, the Connector's
        # constructor will do all of its work, which includes
        # calling Connector.SetLoc()
        super(Spring,self).__init__(*args)
        
        # This doesn't really do anything for a number of reasons
        # 1) Its a method reference on a temporary Connector object
        # 2) SetLoc takes no parameters
        # 3) SetLoc returns nothing
        # 
        #locs=Connector().SetLoc
        
        #self.SetSpring(locs)
        self.SetSpring()
    
    # We don't really need to pass locators to
    # this method. Spring is a subclass of Connector, 
    # meaning that is has access to all of the attributes 
    # already established by Connector
    # 
    #def SetSpring(self, locs):
    def SetSpring(self):
        ...
        # If we just want to move the locators, we already
        # have the reference. 
        # 
        #self.basePos=mc.move(0,25,0, locs(self.baseLoc))  
        #self.topPos=mc.move(0,40,0,locs(self.topLoc))
        mc.move(0, 25, 0, self.baseLoc)
        mc.move(0, 40, 0, self.topLoc)


-- justin




--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/88ccabda-2fff-4df6-a1bb-f538bb248b8d%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

flaye

unread,
Feb 8, 2014, 5:47:48 PM2/8/14
to python_in...@googlegroups.com
@Justin...Thank you very much for your detailed and informative reply. It's greatly appreciated.
Cheers!

Justin Israel

unread,
Feb 8, 2014, 6:04:40 PM2/8/14
to python_in...@googlegroups.com

Sure. Feel free to update with more questions as you explore. 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages