.. toctree:: ******************** Metaclasses ******************** Last Updated: 08.19.2020 **Common Flags** There's some general flags to be aware of: * ``asMeta`` | Most queries that can be have the ``asMeta`` kw which returns the data as meta nodes -------- **Name Tagging** One of the things that is tedious beyond belief is naming all the little things created in a coherent manner. We got tired of doing this and so decided to do something about it. This system utilized the NameFactory which resides in cgmMeta. Some bits about this: * In order to do this, we have something we call name tags that are tagged to any object * These tags can be strings, messages, or whatever * Objects generate a name dict from their own data and that of their parents * Some name tags can be inheritted * Most often inheritance is from parent to child * In the case of an un-type tagged group, it will inherit from it's child * Some tags check against a settings file for short hand names for tags – for example ``joint`` to ``jnt`` * Our current tags are as follows: ``cgmDirection``, ``cgmDirectionModifier``, ``cgmPosition``, ``cgmName``, ``cgmType``, ``cgmTypeModifier`` -------- cgmNode =============== This is our root metaClass which almost all other cgmMetaClasses are descendants of. It itself is a subclass of r9Meta.MetaClass and thus inherits all functions added to the core Red9 metaclass * Superclass | ``r9Meta.MetaClass`` * Location | ``cgmc.core.cgm_Meta.cgmNode`` **Arguments** * ``node`` | ``string`` | Node to initialize * ``name`` | ``string`` | Name for the node * ``nodeType`` | ``string`` | type of node to create if it doesn't exist * ``setClass`` | ``bool`` | whether to set the mClass attribute on initialization What are the differences between a cgmMeta.cgmNode and a r9Meta.MetaClass * Many added functions * msgList handling * connectChild/Children/Parent nodes - we wanted a different connection type than the one red9 used. Ours is ``objChild.msgHook`` >> ``objHolder.msgAttr``. If memory serves, red9s is ``objChild.msgAttr`` >> ``objHolder.msgAttr``. * Component mode ability - ability to say metaClass a vertice or ep * Message handling in general - we allow for message like storage of attributes and not just nodes * Access to the insanity of the NameFactory and all the wonders therein. ----------- Attributes ------------------ ------------------ ``isAttrKeyed()`` | ... * **parameters** : * **attr** ``string`` (None) | Attribute to query ('tx' for example) * **returns** : status ``bool`` * **relates to** : ``ATTR.is_keyed`` ------------------ ``isAttrConnected()`` | ... * **parameters** : * **attr** ``string`` (None) | Attribute to query ('tx' for example) * **returns** : status ``bool`` * **relates to** : ``ATTR.is_keyed`` ------------------ * ``doStore`` | ``ATTR.store_info`` | Supported: message,doubleArray,json dicts and much more * ``copyAttrTo`` | ``ATTR.copy_to`` | Copy attributes from one object to another as well as other options. If the attribute already exists, it'll copy the values. If it doesn't, it'll make it. If it needs to convert, it can. It will not make toast * ``getMayaAttr`` | ``ATTR.get`` * ``setMayaAttr`` | ``ATTR.set`` * ``getMayaAttrString`` | "{0}.{1}".format(getattr(NAMES,nameCall)(self.mNode), attr) * ``getEnumValueString`` | Get the string value of an enum | ``ATTR.get_enumValueString`` * ``getAttrs`` | ``mc.listAttr`` * ``doRemove`` | Remove an attribute * ``resetAttrs`` | Reset all or filtered attributes * ``verifyAttrDict`` | Verify a dictionary of attributes by type * ``doOverrideColor`` | ``RIGGING.override_color`` * ``doConnectIn`` | Wiring call inbound * ``doConnectOut`` | Wiring call outbound .. code-block:: python mLoc = cgmMeta.asMeta(mc.spaceLocator()[0]) mLoc2 = cgmMeta.asMeta(mc.spaceLocator()[0]) mLoc.doConnectOut('ty',"{0}.ty".format(mLoc2.mNode)) mLoc.doConnectIn('tx',"{0}.tx".format(mLoc2.mNode)) ----------- Names ------------------ * ``uiPrompt_rename`` | Provides ui prompt to rename a node and renames it if ``OK``. * ``getNameShort`` | short name * ``getNameLong`` | long name * ``getNameBase`` | shortest name option stripped of all pomp and circumstance * ``asAttrString`` | Returns name with an arg attr as 'Node.attr' * ``getNameMatches`` | Find name matches for a given object. ``report`` arg if you want a report * ``getReferencePrefix`` | ... * ``doName`` | Name a given node based on cgmNameTags * ``doGetNameDictame`` | Get a dict of the name tags * ``doTagAndName`` | Apply a dict of name tags and then name the node * ``getNameAlias`` | Get name alias for ui functions or other stuff we do * ``doCopyNameTagsFromObject`` | Grab name tags from another node ----------- Overloads ------------------ Super class functions we overload * ``__setMessageAttr__`` | Overload for red9's message handling to follow ours * ``addAttr`` | Added initialValue kw as well as few other items * ``connectChildNode`` | Replacing Mark's connect child with our own which connects to .message connections. * ``connectParentNode`` | Replacing Mark's connect child with our own which connects to .message connections. * ``connectChildrenNodes`` | Replacing Mark's connect child with our own which connects to .message connections. * ``__repr__`` | "(node: '{0}' | mClass: {1} | class: {2})" ----------- Properties ------------------ * ``p_referencePrefix`` | ( getReferencePrefix ) - get the reference prefix * ``p_nameBase`` | clean name string * ``p_nameLong`` | node long name * ``p_nameShort`` | node short name * ``p_parent`` | get/set parent of an object (set only currently on cgmObject) ----------- Query ------------------ * ``getMayaType`` | ``VALID.get_mayaType`` * ``getPositionOutPlug`` | Look for an outplug on a given node * ``getMessage`` | This maybe odd to some, but we treat traditional nodes as regular message connections. However, sometimes, you want a message like connection to an attribute. To do this, we devised a method of creating a compaptble attr on the object to recieve the message, connecting the attribute you want to connect to that attribute and then when you call an attribute as getMessage, if it is not a message attr it tries to trace back that connection to an attribute. simple MUST be True by default * ``getMessageAsMeta`` | ... but return ``asMeta`` ----------- Relational ------------------ * ``getParent`` | ... * ``getSiblings`` | ... * ``getComponent`` | Only if this is a component node * ``isComponent`` | bool check * ``getComponents`` | By arg type ----------- Transform ------------------ * ``getPosition`` | ``TRANS.position_get`` * ``doDuplicate`` | Node duplication with some options like breaking connections * ``getDag`` | Get the dag of a node if this node isn't one ----------- Special ------------------ Very specialized stuff or tech we do. mgList/datList ^^^^^^^^^^^^^^^^ This is our answer to the frustration with how multiMessage attrs work in maya when you need lists to be intact. The following should work for msgList or datList. A msgList assumes node connections. A datList can be strings or whatever kind of data you want. * ``x_connect`` | Wire * ``x_get`` | Query * ``x_append`` | ... * ``x_index`` | Get index of arg if in list * ``x_remove`` | By index * ``x_purge`` | Purge the datList from the node which means deleting all the sequential attributes * ``x_clean`` | Remove empty entries in the series and reconnect * ``x_exists`` | Is it there? * ``getSequentialAttrDict`` | Get a sequential attr dict. Our attr should be listed without the tail '_' ex: {0: u'back_to_back_0', 1: u'back_to_back_1'} .. code-block:: python #>>msgList ==================================================================================== #Let's look at the concept of the msgList mi_catcherObj = cgmMeta.cgmObject(name = 'msgListCather') #First we're gonna make some objects to deal with, say 5 md_msgListObjs = {} ml_msgListObjs = [] for i in range(5): try:mObj= cgmMeta.cgmObject('msgListObj_%i'%i) except:mObj= cgmMeta.cgmObject(name = 'msgListObj_%i'%i) md_msgListObjs[i] = mObj ml_msgListObjs.append(mObj) #Connect the first two objects, you can pass metaclass or string objects mi_catcherObj.msgList_connect([ml_msgListObjs[0],ml_msgListObjs[1].mNode],'msgAttr','connectBack') ml_msgListObjs[0].connectBack#what do you know, we connected back to our holder we can also dance a little with that... ml_msgListObjs[0].connectBack.msgAttr_0.connectBack.msgAttr_1#The mind truly spins....:) #Let's query it mi_catcherObj.msgList_get('msgAttr')#Query our list, it's going to default to do it as meta #Say we wanted just the objlist mi_catcherObj.msgList_get('msgAttr',asMeta=False) #We can also do a getMessage call which offers a few more options mi_catcherObj.msgList_getMessage('msgAttr',longNames = True) #Appending is supported mi_catcherObj.msgList_append(ml_msgListObjs[2],'msgAttr') mi_catcherObj.msgList_get('msgAttr',False) #What do you know, we have the new on there... #Indexing is supported mi_catcherObj.msgList_index(ml_msgListObjs[2],'msgAttr') #As is checking if we have a msgList on an attr name mi_catcherObj.msgList_exists('msgAttr') mi_catcherObj.msgList_exists('isAnyoneThere')#Nope... #Let's remove the first mi_catcherObj.msgList_remove(ml_msgListObjs[0],'msgAttr') mi_catcherObj.msgList_get('msgAttr',False) #We Removed the first #Let's store em all mi_catcherObj.msgList_connect(ml_msgListObjs,'msgAttr','connectBack') #Let's delete number 2.... ml_msgListObjs[2].delete() mi_catcherObj.msgList_get('msgAttr',asMeta=False,cull = False)#That entry is empty now...When cull is off, on by default #What if we want to clean this list without the empty mi_catcherObj.msgList_clean('msgAttr') #And we have a clean list again... #Say we wanna purge this data... mi_catcherObj.msgList_purge('msgAttr')#Our attrs are gone... so sad.... #============================================================================================== ----------- stringModuleCall ^^^^^^^^^^^^^^^^^ ``(self, module = None, func = '', *args,**kws)`` Function to call from a given module a function by string name with args and kws. The general idea is to call any function with the node as it's first arg. ----------- doLoc ^^^^^^^^^^^^^^^^^ Create a locator at a node or component's position. -------- Examples ------------------ ------------------ Message treatment ^^^^^^^^^^^^^^^^^^^^ .. code-block:: python #>>message Treatment ========================================================================= #We have made several changes to r9's stuff in how we do messages, it is however compatible with r9's stuff #One of our calls to store info is doStore #First we're gonna make a catcher node mi_catchMeObj = cgmMeta.cgmObject(name = 'catchMe') mi_catcherObj = cgmMeta.cgmObject(name = 'msgCather') #One of our calls to store info is doStore mi_catcherObj.doStore('objNoMessage',mi_catchMeObj.mNode,overideMessageCheck = True)#It's gonna just store a string, no message.... mi_catcherObj.doStore('objNoMessage',mi_catchMeObj.mNode,overideMessageCheck = False)#Now it's a message...woot! #So maya can do that, what if you wanted to do something neater like say, store an attribute mi_catcherObj.doStore('objTX',"%s.tx"%mi_catchMeObj.mNode)#It's gonna just store a string, no message.... mi_catchMeObj.tx = 4#our attribute changed. That's because, this storage method stores on a compatible attribute format #That's great and all, but we were talking about messages... mi_catcherObj.getMessage('objTX')# we get the attribute, neato... mi_catcherObj.getMessageAsMeta('objTX')# we get the attribute, neato...cgmAttr for the win #implementing attr setup to msgLists is on the ToDO list #============================================================================================== ------------------ Component Use ^^^^^^^^^^^^^^^^^^^^ One of the areas, where we differ is with component use. We can wrap cv's,vertices, etc. .. code-block:: python #>>Component use ============================================================================== #We'll make a shphere and buffer that... l_sphereReturn = mc.sphere(nsp = 4, name = 'MySphere') mi_sphere = cgmMeta.cgmNode(l_sphereReturn[0])#We'll meta the sphere object mi_sphere.mNode#Just like an mNode, but what if we wanna instance a component... mi_cv = cgmMeta.cgmNode("%s.cv[3][0]"%mi_sphere.mNode)#metaNode a cv mi_cv.mNode#We get the shape back mi_cv.getComponent()#We get the component mi_cv.isComponent()#Yup mi_sphere.isComponent()#Nope...it's a sphere mi_sphere.getComponents('cv')#List of cv's mi_sphere.getPosition()#Get our position,arg is world space or not, default is worldspace(True) mi_cv.getPosition()#Get the position of the cv mi_cv.getTransform()#Ger the transform of the component #============================================================================================== ------------------ Properties ^^^^^^^^^^^^^^^^^^^^ We've added some properties to our metaclass for easy call/set ability. .. code-block:: python #>>Properties ================================================================================= mi_sphere.p_nameBase#name string along mi_sphere.p_nameLong#long name form mi_sphere.p_nameShort#short name form mi_sphere.p_referencePrefix#Gonna be false as we're not referenced mi_sphere.p_parent#returns our parent, on cgmObject, you can set as well, we'll get more into it there #============================================================================================== ------------------ Other ^^^^^^^^^^^^^^^^^^^^ .. code-block:: python :linenos: #>>Other Calls ================================================================================ mi_cv.getMayaType()#Because maya's type return thing isn't so hot.... mi_sphere.getMayaType() mi_sphere.doDuplicate()#its gonna give us a duplicate, but only a null?.... mi_dup = mi_sphere.doDuplicate(parentOnly=False)#Now it works mi_loc = mi_sphere.doLoc()#We can loc items with the same maker cgmLocinator uses mi_cvLoc = mi_cv.doLoc()#We can loc components too... #We're gonna add an enum to look at something... mi_sphere.addAttr('testEnum',attrType = 'enum') mi_sphere.testEnum#nice, but what if we want as a string mi_sphere.getEnumValueString('testEnum') mi_loc.returnPositionOutPlug()#This is a wip one but it works for most necessary things, handy for nodal work #============================================================================================== ---------- cgmObject =============== If the object has a dag, this is what we generally use * Superclass | ``MetaClass|cgmNode`` * Location | ``cgmc.core.cgm_Meta.cgmObject`` **Arguments** * ``node`` | ``string`` | Node to initialize * ``name`` | ``string`` | Name for the node * ``nodeType`` | ``string`` | type of node to create if it doesn't exist * ``setClass`` | ``bool`` | whether to set the mClass attribute on initialization ----------- Attributes ------------------ ``dagLock()`` | For locking/unlocking nodes. * **parameters** : * **state** ``bool`` (True) * **ignore** ``list`` (None) | Don't do these attributes * **visibility** ``bool`` (True) * **keyable** ``bool`` (False) * **returns** : None ----------- ``isVisible()`` | If this node is visible. * **parameters** : * **checkShapes** ``bool`` (False) * **returns** : status ``bool`` ----------- Constraints ------------------ * ``getConstraintsTo`` | Get constraints to this dag * ``getConstraintsFrom`` | Get constraints from this dag * ``getConstrainingObjects`` | What's driving this * ``select`` | bool | Select result * ``getConstraintsByDrivingObject`` | Connection walking * ``isConstrainedBy`` | Am I constrained by the arg ----------- Properties ------------------ * ``p_parent`` | get/set parent of an object (set only currently on cgmObject) * ``p_position`` | get/set * ``p_positionEuclid`` | get/set * ``p_orient`` | get/set * ``p_rotateAxis`` | get/set * ``p_rotatePivot`` | get/set * ``p_scalePivot`` | get/set ----------- Query ------------------ * ``getPositionOutPlug`` | Get an out plug for a given node. as the ability to ``autoLoc`` as well for mNodes that don't have outPlugs * ``getDeformers`` | Get connected deformers * ``deformerTypes`` | What kind of deformes you want ``'all'``, list args acceptable as well ----------- Relational ------------------ * ``getParent`` | ... * ``setParent`` | ... * ``getParents`` | ... * ``getSiblings`` | ... * ``getDescendents|getAllChildren`` | ... * ``getChildren`` | ... * ``getShapes`` | ... * ``getListPathTo`` | Get the list path from one node to another in a given heirarchy **Queries** * ``isParentTo`` | bool * ``isChildTo`` | bool ----------- Rigging ------------------ * ``doCopyPivot`` | ``RIGGING.copy_pivot`` | .... * ``doMatchTransform`` | ``RIGGING.match_transform`` | .... * ``doGroup`` | General dag grouping * ``maintain`` | bool | Maintain heirarchal place * ``parentTo`` | bool | Parent this to the new group or not * ``asMeta`` | bool | ... * ``typeModifier`` | bool | Tags the group name with a modifier and connects to the node as ``[typeModifier]Group`` * ``setClass`` | bool | Set mClass on creation if ``asMeta`` * ``doCreateAt`` | Create another object at this one * ``create`` | string | null,joint,locator, etc * ``copyAttrs`` | list | List of attributes to copy. When we use it's usually for a cgmNameTag or something * ``asMeta`` | bool | ... .. code-block:: python #>>Parenting ==================================================================================== #First we're gonna make some objects to deal with, say 5 ml_cgmObjects = [] for i in range(5): mObj= cgmMeta.cgmObject(mc.joint(p = [0,0,2*i],name = 'generatedCGMObject_%i'%i)) ml_cgmObjects.append(mObj) #Neat,now we have a few joints to play with...let's play ml_cgmObjects[1].p_parent = False #We're gonna parent the idx 1 joint to the world by passing it false for mObj in ml_cgmObjects:mObj.p_parent = False #Let's parent them all to the world for i,mObj in enumerate(ml_cgmObjects[1:]):mObj.p_parent = ml_cgmObjects[i] #Parent em back #What if we wanted to parent idx 2 and 3 both to 1? ml_cgmObjects[2].p_parent = ml_cgmObjects[0]#We can pass the mClass ml_cgmObjects[2].tx = 2#just to be a little clearer ml_cgmObjects[4].p_parent = ml_cgmObjects[1].mNode#We can pass the string mNode ml_cgmObjects[1].tx = -2 #and a little more clear ml_cgmObjects[4].tx = 0 #and a little more clear ml_cgmObjects[4].p_parent #returns just the parent ml_cgmObjects[4].getParent(asMeta = 1) #what if we want as a parent. the property uses this command with the default asMeta of False ml_cgmObjects[4].getParent(asMeta = 1).p_nameShort #daisy chain the calls #============================================================================================== #>>Family ==================================================================================== ml_cgmObjects[4].getAllParents()#we can get all the parents of an object as well as the imediate ml_cgmObjects[4].getAllParents(fullPath = True)#We can get full paths ml_cgmObjects[4].getAllParents(asMeta = 1)#We can get those as meta too ml_cgmObjects[0].getChildren()#We can get immediate children ml_cgmObjects[0].getChildren(asMeta = True)#as meta or full path too ml_cgmObjects[0].getAllChildren()#We can get all dag children ml_cgmObjects[0].getAllChildren(asMeta = True)#as meta or full path too ml_cgmObjects[0].getShapes()# Hmm...no shapes, let's try something with shapes mi_sphere = cgmMeta.cgmObject(mc.sphere()[0]) #let's wrap a sphere mi_sphere.getShapes() #Get some shapes mi_sphere.getShapes(asMeta = 1) #as meta too #What about some other relative checks... ml_cgmObjects[1].getSiblings() #What is a sibling? A sibling is a definition of our own... #It is an object at the same heirarchal level as another object of matching type to our source ml_cgmObjects[1].getSiblings(asMeta = 1) #Can do the asMeta call as well ml_cgmObjects[1].getFamilyDict()#Another way to get a few bits of data... ml_cgmObjects[4].isChildOf(ml_cgmObjects[0]) #We can check up the dag tree for a logic check.. ml_cgmObjects[4].isChildOf(ml_cgmObjects[2]) #This one is not a child of that joint ml_cgmObjects[0].isParentOf(ml_cgmObjects[1]) #Can check the other relationship as well ml_cgmObjects[4].isParentOf(ml_cgmObjects[2]) ml_cgmObjects[4].getListPathTo(ml_cgmObjects[0])#Another way to get some data ml_cgmObjects[0].getListPathTo(ml_cgmObjects[4])#front or back #============================================================================================== #>>Name Stuff ==================================================================================== #Let's start by tagging our root joint ml_cgmObjects[0].addAttr('cgmName','testing') #This is our main tag ml_cgmObjects[0].doName()#Our object has been renamed with this name tag and it autotyped #Let's add some direction tags to idx 1/2 ml_cgmObjects[1].addAttr('cgmDirection','left') #Direction tag of left ml_cgmObjects[2].addAttr('cgmDirection','right') #...and right for idx in [1,2]:ml_cgmObjects[idx].doName() #Now our two joints are prefixed with their directions, note they have inherited their parent's name, note the children are not named... for idx in [1,2]:ml_cgmObjects[idx].doName(nameChildren = True)# Neat, now the children are named for idx in [1,2]:ml_cgmObjects[idx].doName(fastIterate = False, nameChildren = True) #The most thorough name tag is turning off fastIterate, it is slower so we don't use very often. If you're just doing manual stuff if's fine. #If you're running large processes, you'll wanna avoid #Another thing nametags can be are messages, let's try that. mi_locToName = cgmMeta.cgmObject(mc.spaceLocator()[0]) mi_locToName.addAttr('cgmName',ml_cgmObjects[0].mNode,attrType = 'messageSimple')#we're gonna store the first joint to the locators, cgmName tag mi_locToName.doName() #You'll see it's taken the name of the name linked object and named with that #So what's going on with this stuff? When objects are named, they generate a name dictionary and build a name from that... ml_cgmObjects[4].getNameDict() #Even though this object has none of these cgmNameTag attributes, it nonethless, inherits those names ml_cgmObjects[4].parent = False ml_cgmObjects[4].getNameDict()#Now the only thing the name dict contains is it's type which all objects have ml_cgmObjects[4].parent = ml_cgmObjects[1]#Parent back for now #Let's add another tag to our root ml_cgmObjects[0].addAttr('cgmTypeModifier','skin') ml_cgmObjects[0].doName(nameChildren = True)#Hmmm...so there are some tags which aren't inherited, type modifiers are not but types are del(ml_cgmObjects[0].cgmTypeModifier) ml_cgmObjects[0].addAttr('cgmPosition','front') ml_cgmObjects[0].doName(nameChildren = True)#Positons are inheritable #============================================================================================== #>>Rigging functions ========================================================================== ml_cgmObjects[1].doGroup(maintain = True)#You'll see we get a new group maintaining our objects's position ml_cgmObjects[1].doGroup(maintain = False)#This will not maintain our heirarchy and generate a new group #Copy pivot this is for objects with shapes mi_copyPivotToMe = cgmMeta.cgmObject(mc.sphere(name = 'copyPivotToMe')[0]) mi_copyPivotFromMe = cgmMeta.cgmObject(mc.sphere(name = 'copyPivotFromMe')[0]) mi_copyPivotFromMe.ty = 5 mi_copyPivotToMe.doCopyPivot(mi_copyPivotFromMe) mi_copyPivotToMe.select()#Look at it's pivot #Contraints #Let's start by contrainting a couple of joints mc.pointConstraint(ml_cgmObjects[4].mNode,ml_cgmObjects[3].mNode,maintainOffset = False) mc.orientConstraint(ml_cgmObjects[2].mNode,ml_cgmObjects[3].mNode,maintainOffset = False) #Great, now what.... ml_cgmObjects[3].getConstraintsTo()#Get the constraint to ml_cgmObjects[3].getConstraintsTo(asMeta = True) ml_cgmObjects[4].getConstraintsFrom()#Get the constraint from ml_cgmObjects[4].getConstraintsFrom(asMeta = True) ml_cgmObjects[3].isConstrainedBy(ml_cgmObjects[2])#Get a constraint from one object to another #============================================================================================== ----------- Transform ------------------ * ``doSnapTo`` | ``TRANS.snap`` | .... * ``doAim`` | ``TRANS.aim`` | .... * ``doAimAtPoint`` | ``TRANS.aim_atPoint`` | .... **Positions** * ``setPosition`` | ``TRANS.position_set`` | .... * ``getPositionAsEuclid`` | ``TRANS.getPosition`` | with ``asEuclid`` on **Rotation** * ``getOrient`` | ``TRANS.orient_get`` | .... * ``setOrient`` | ``TRANS.orient_set`` | .... * ``getRotateAxis`` | ``TRANS.rotateAxis_get`` | .... * ``setRotateAxis`` | ``TRANS.rotateAxis_set`` | .... **Scale** * ``getScaleLossy`` | ``TRANS.scaleLossy_get`` | .... **Pivots** * ``getRotatePivot`` | ``TRANS.rotatePivot_get`` | .... * ``setRotatePivot`` | ``TRANS.rotatePivot_set`` | .... * ``getScalePivot`` | ``TRANS.scalePivot_get`` | .... * ``setScalePivot`` | ``TRANS.scalePivot_set`` | .... * ``p_rotatePivot`` | .... * ``p_scalePivot`` | .... * ``doPivotsRecenter`` | ``TRANS.pivots_recenter`` | .... * ``doPivotsZeroTransform`` | ``TRANS.pivots_zeroTransform`` | .... * ``getBBSize`` | ``POS.get_bb_size`` | .... * ``getBBCenter`` | ``POS.get_bb_center`` | .... **Vectors** * ``getAxisVector`` | ``TRANS.vector_byAxis`` | .... * ``createVectorLine`` | ``TRANS.create_vectorCurveFromObj`` | .... * ``getPositionByAxisDistance`` | ``TRANS.position_getByAxisDistance`` | .... * ``getWorldMatrix`` | ``TRANS.worldMatrix`` | .... * ``p_worldMatrix`` | .... **Transform Data** * ``getTransformDirection`` | ``TRANS.transformDirection`` | .... * ``getTransformPoint`` | ``TRANS.transformPoint`` | .... * ``getTransformInverseDirection`` | ``TRANS.transformInverseDirection`` | .... * ``getTransformInversePoint`` | ``TRANS.transformInversePoint`` | .... * ``xxx`` | ``xxx.xxx`` | .... ---------- cgmControl =============== General animation control metaclass * Superclass | ``MetaClass.cgmNode.cgmObject`` * Location | ``cgmc.core.cgm_Meta.cgmControl`` **Arguments** * ``node`` | ``string`` | Node to initialize * ``name`` | ``string`` | Name for the node ----------- Mirror ------------------ * ``_verifyMirrorable`` | Make sure the node is wired with r9Meta mirror attributes * ``isMirrorable`` | ... * ``doMirrorMe`` | ... * ``mode`` | string | red9 pass through * ``doPushToMirrorObject`` | ... * ``mode`` | string | red9 pass through ----------- Transform ------------------ * ``_setControlGroupLocks`` | Sets locks on control groups ``masterGroup``, ``zeroGroup`` * ``lock`` | bool | state of the lock * ``constraintGroup`` | bool | whether to do a constraint group as well. Can probably depreciate this * ``controller_get`` | Gets a maya controller tag for this node and wires them to one another **Aim** * ``_isAimable`` | If control has aim attributes * ``_verifyAimable`` | Ensures the object has aiming attributes ``SNAP.verify_aimAttrs`` * ``doAim`` | Aim it * ``target`` | node to aim at ---------- cgmObjectSet =============== * Superclass | ``MetaClass.cgmNode`` * Location | ``cgmc.core.cgm_Meta.cgmObjectSet`` **Arguments** * ``setName`` | ``string`` | Name for the set * ``setType`` | ``bool`` | * ``qssState`` | ``bool`` | If this node should be a qss set * ``value`` | (x) | Value to set on call * ``nameOnCall`` | ``bool`` | If on, will add generate a uiPrompt to set name on creation ----------- **Set Types** These are our own thing to help organize sets. * Animation * layout * modeling * td * fx * lighting ----------- General ------------------ * ``isQss`` | ... * ``makeQss`` | Set the qss flag state * ``getSetType`` | ... * ``doSetType`` | ... * ``setType`` | What type to set to * ``getMetaList`` | Only works with string data * ``getList`` | ... * ``doSetList`` | Reset the list with the objects provided in ``objectList`` arg * ``log`` | Print a report of the objectSet dat to the script editor * ``deleteSet`` | Completely delete set ----------- Data ------------------ * ``contains|doesContain`` | Returns if contains ``obj`` arg * ``getParents`` | Get parent Set * ``extend`` | ... * ``append|add`` | ... * ``addSelected`` | Add object or attribute if channelbox selection active * ``remove|removeObj`` | ... * ``removeSelected`` | ... * ``purge`` | ... * ``copy`` | Copy the set to a new one * ``select`` | Select set contents if possible * ``selectSelf`` | Select actual set node **Anim** * ``key`` | Ket set contents * ``reset`` | reset ... * ``deleteKey`` | Selects then ``cutKey(*a,**kw)`` pass through * ``deleteCurrentKey`` | ... ----------- Properties ------------------ * ``value`` | ``getList``, ``doSetList``, ``deleteSet``