Exemplo n.º 1
0
    def connectNodeToAttr(self, sourceNode, destinationPlug, force):
        # MObject, MPlug, bool

        sysPrint("testing source type")
        bumpObj = None
        dg = OpenMaya.MDGModifier()
        if sourceNode.hasFn(OpenMaya.MFn.kTexture2d):
            sysPrint("source is a texture2D")
            bumpObj = dg.createNode("bump2d")
        elif sourceNode.hasFn(OpenMaya.MFn.kTexture3d):
            sysPrint("source is a texture3D")
            bumpObj = dg.createNode("bump3d")
        dg.doIt()

        src = OpenMaya.MFnDependencyNode(sourceNode)
        # Get the outAlpha plug (we don't need to check, it must exists)
        outAlpha = src.findPlug("outAlpha", True)

        bump = OpenMaya.MFnDependencyNode(bumpObj)
        sysPrint("bump; %s" % bump.name())
        bumpValue = bump.findPlug("bumpValue", True)
        outNormal = bump.findPlug("outNormal", True)

        dg.connect(outAlpha, bumpValue)
        dg.connect(outNormal, destinationPlug)

        sysPrint("destinationPlug: %s" % destinationPlug.name())

        dg.doIt()
Exemplo n.º 2
0
def connect_nodeplugs(source_mobject, source_mplug, dest_mobject, dest_mplug):
    source_mplug = get_plug(source_mobject, source_mplug)
    dest_mplug = get_plug(dest_mobject, dest_mplug)

    m_DGMod = OpenMaya.MDGModifier()
    m_DGMod.connect(source_mplug, dest_mplug)
    m_DGMod.doIt()
Exemplo n.º 3
0
Arquivo: set.py Projeto: kthulhu/mrv
		def __init__( self, sellist ):
			dgmod = api.MDGModifier( )
			self.setobj = dgmod.createNode( "objectSet" )
			dgmod.doIt( )
			# add members
			mfnset = api.MFnSet( self.setobj )
			mfnset.addMembers( sellist )
Exemplo n.º 4
0
def addSecondaryObjsAttr(node):
    activeList=om.MSelectionList()
    om.MGlobal.getSelectionListByName(node,activeList)
    depNode=om.MObject() 
    iter=om.MItSelectionList(activeList)
    iter.reset()
    iter.getDependNode(depNode)
    
    Mod=om.MDGModifier()
    
    mfnMsgAttr=om.MFnMessageAttribute()
    MsgAttr=mfnMsgAttr.create('secondaryObject','secondaryObject')
    mfnMsgAttr.setConnectable(True)
    mfnMsgAttr.setReadable(True)
    mfnMsgAttr.setWritable(True)
    
    mfnComAttr=om.MFnCompoundAttribute()
    comAttr=mfnComAttr.create('secondaryObjectList','secondaryObjectList')
    mfnComAttr.setReadable(True)
    mfnComAttr.setWritable(True)
    mfnComAttr.setArray(True)
    mfnComAttr.setUsesArrayDataBuilder(True)
    mfnComAttr.addChild(MsgAttr)
    Mod.addAttribute(depNode,comAttr)
    Mod.doIt()
Exemplo n.º 5
0
def remove(mo_node, b_force=False):
    
    """
    !@Brief Remove given node

    @type mo_node: OpenMaya.MObject
    @param mo_node: Maya object node.
    @type b_force: bool
    @param b_force: Delete locked node.
    """

    if isinstance(mo_node, OpenMaya.MObject) is False:
        raise TypeError("Argument must be a MObject not {0}".format(type(mo_node)))

    if mo_node.hasFn(OpenMaya.MFn.kDagNode) is False and mo_node.hasFn(OpenMaya.MFn.kDependencyNode) is False:
        raise TypeError("Object must be a DagNode or DependencyNode not {0}".format(mo_node.apyTypeStr()))

    moh_node = OpenMaya.MObjectHandle(mo_node)
    if mo_node.isNull() or not moh_node.isValid() or not moh_node.isAlive():
        cmds.debug('Node given does not exists !')
        return

    mfn_node = OpenMaya.MFnDependencyNode(mo_node)
    if mfn_node.isLocked() and b_force is False:
        raise TypeError('Node "{0}" is locked. Set b_force to True for remove it'.format(name(mo_node)))

    if b_force:
        mfn_node.setLocked(False)

    mdg_mod = OpenMaya.MDagModifier() if mo_node.hasFn(OpenMaya.MFn.kDagNode) else OpenMaya.MDGModifier()
    mdg_mod.deleteNode(mo_node)
    mdg_mod.doIt()
    del mdg_mod
Exemplo n.º 6
0
    def __undoCacheMesh(self):
        depNodeFn = om.MFnDependencyNode()

        meshNodeShape = self._fDagPath.node()
        dupMeshNodeShape = self._fDuplicateDagPath.node()

        depNodeFn.setObject(meshNodeShape)
        meshNodeName = depNodeFn.name()
        meshNodeDestPlug = depNodeFn.findPlug("inMesh")
        meshNodeOutMeshPlug = depNodeFn.findPlug("outMesh")

        depNodeFn.setObject(dupMeshNodeShape)
        dupMeshNodeSrcPlug = depNodeFn.findPlug("outMesh")

        if self._fHasTweaks:
            dgModifier = om.MDGModifier()
            dgModifier.connect(dupMeshNodeSrcPlug, meshNodeDestPlug)
            dgModifier.doIt()

            cmd = "dgeval {0}.inMesh".format(meshNodeName)
            om.MGlobal.executeCommand(cmd, False, False)
            dgModifier.undoIt()

            # attempt to delete dup mesh node here?

        else:
            meshData = om.MObject(dupMeshNodeSrcPlug.asMObject())
            meshNodeOutMeshPlug.setMObject(meshData)
Exemplo n.º 7
0
    def __init__(self):
        OMMPx.MPxCommand.__init__(self)
        self.__isQueryUsed = True  # initialize to True so command is not added to queue if argument parsing fails
        self.__isEditUsed = False

        self.__ribbonNodeFn = OM.MFnDependencyNode(
        )  # the am_ribbon node selected for edit and query modes

        self.__selectedCurves = OM.MSelectionList(
        )  # selection list containing only nurbs curves in the object list

        self.__baseNameArg = ''  # base name for the newly created ribbon meshes
        self.__widthArg = None  # width of the ribbon in centimeters
        self.__divisionsArg = None  # divisions along the ribbon
        self.__divisionsPerUnitArg = None  # optional parameter to specify a rate of divisions to get similar-sized faces when multiple curves are selected
        self.__taperArg = None  # scale at the end of the ribbon
        self.__twistBaseArg = None  # rotation around the curve at the start of the ribbon
        self.__twistLengthArg = None  # rotation around the curve at the end of the ribbon
        self.__upVectorArg = None  # base up-vector at the start of the ribbon
        self.__uvScaleArg = None  # scale factor of new uvs
        self.__uvScaleGroupArg = None  # scaling method to apply to the whole group of newly-created ribbons--only in create mode
        self.__uvPinArg = None  # uv pinning location

        self.__dagModify = OM.MDagModifier(
        )  # Dag modifier used to create new shapes/transforms
        self.__dgModify = OM.MDGModifier(
        )  # DG modifier used to create and modify new ribbon nodes
Exemplo n.º 8
0
 def createCrowdNode(self):
     dg_modifier = OpenMaya.MDGModifier()
     self.parent = dg_modifier.createNode('container')
     dg_modifier.renameNode(self.parent, self.parent_name)
     crowd_attribute = crowdAttributes.Connect(self.parent)        
     crowd_attribute.createParentAttributes(mobject=dg_modifier)
     dg_modifier.doIt()
Exemplo n.º 9
0
def disconnectAttrApi( attr1, attr2 ):
    
    plug1 = getPlugFromString( attr1 )
    plug2 = getPlugFromString( attr2 )
    
    mode = om.MDGModifier()
    mode.disconnect( plug1, plug2 )
    mode.doIt()
Exemplo n.º 10
0
    def targetConnect(self, target, ctl, base):

        cmds.connectAttr(target + '.wm', base + '.arrow[1].aimMatrix')

        cmds.connectAttr(base + '.wm', base + '.arrow[0].aimMatrix')

        cmds.connectAttr(ctl + '.t', base + '.arrow[1].offset')

        retargetNodes = self.getRetargetNodes(target)

        for retargetNode in retargetNodes:

            fnc.clearArrayElement(retargetNode + '.localData')
            index = fnc.getLastIndex(retargetNode + '.localData') + 1

            cmds.connectAttr(
                ctl + '.wm',
                retargetNode + '.localData[%d].localMatrix' % index)

            if not cmds.attributeQuery('localMult', node=ctl, ex=1):
                selList = om.MSelectionList()
                selList.add(ctl)

                mObj = om.MObject()
                selList.getDependNode(0, mObj)

                nAttr = om.MFnNumericAttribute()

                aAttrX = nAttr.create("localMultX", "localMultX",
                                      om.MFnNumericData.kDouble, 1.0)
                nAttr.setMin(0.0)
                aAttrY = nAttr.create("localMultY", "localMultY",
                                      om.MFnNumericData.kDouble, 1.0)
                nAttr.setMin(0.0)
                aAttrZ = nAttr.create("localMultZ", "localMultZ",
                                      om.MFnNumericData.kDouble, 1.0)
                nAttr.setMin(0.0)
                aAttr = nAttr.create('localMult', 'localMult', aAttrX, aAttrY,
                                     aAttrZ)
                nAttr.setKeyable(True)
                nAttr.setStorable(True)

                modify = om.MDGModifier()
                modify.addAttribute(mObj, aAttr)
                modify.doIt()

            if not cmds.attributeQuery('localMultOrient', node=ctl, ex=1):
                cmds.addAttr(ctl, ln='localMultOrient', min=0, dv=1)
                cmds.setAttr(ctl + '.localMultOrient', e=1, k=1)

            try:
                cmds.connectAttr(
                    ctl + '.localMult',
                    retargetNode + '.localData[%d].localMult' % index)
            except:
                cmds.connectAttr(
                    ctl + '.localMultOrient',
                    retargetNode + '.localData[%d].localMult' % index)
Exemplo n.º 11
0
    def __init__(self):
        super(SplitShape, self).__init__()

        self.baseGeo = None
        self.targetGeo = None
        self.numOfDivision = 2
        self.dgMod = OpenMaya.MDGModifier()
        self.dagMod = OpenMaya.MDagModifier()
        self.createdNodes = OpenMaya.MObjectArray()
Exemplo n.º 12
0
Arquivo: set.py Projeto: kthulhu/mrv
		def __del__( self ):
			"""Delete our own set upon deletion"""
			# assure we release members before - otherwise they might be deleted 
			# as well if it is empty sets !
			mfnset = api.MFnSet( self.setobj )
			mfnset.clear()
			del( mfnset )
			dgmod = api.MDGModifier()
			dgmod.deleteNode( self.setobj )
			dgmod.doIt()
Exemplo n.º 13
0
 def set_connections(self, mobject, data):
     mfn_dependency_node = OpenMaya.MFnDependencyNode(mobject)
     for attribute, contents in data.items():
         input_attribute, input_node = contents['value'].split('@')
         output_mplug = mfn_dependency_node.findPlug(attribute)
         input_mplug = self.get_mplug('%s.%s' %
                                      (input_node, input_attribute))
         dgMod = OpenMaya.MDGModifier()
         dgMod.connect(input_mplug, output_mplug)
         dgMod.doIt()
Exemplo n.º 14
0
def addArrayMessageAttribute( node, attrName ):
    
    msgAttr = om.MFnMessageAttribute()
    
    aMessage = msgAttr.create( attrName, attrName )
    msgAttr.setArray( True )
    
    mdgMode = om.MDGModifier()
    mdgMode.addAttribute( node, aMessage )
    mdgMode.doIt()
Exemplo n.º 15
0
	def plugin_loaded(self, pluginName):
		"""Retrieve plugin information from a plugin named ``pluginName``, which is 
		assumed to be loaded.
		Currently the nodetypes found are added to the node-type tree to make them available.
		The plugin author is free to add specialized types to the tree afterwards, overwriting 
		the default ones.
		
		We loosely determine the inheritance by differentiating them into types suggested
		by MFn::kPlugin<Name>Node"""
		import base		# needs late import, TODO: reorganize modules
		
		self.log.debug("plugin '%s' loaded" % pluginName)
		
		type_names = cmds.pluginInfo(pluginName, q=1, dependNode=1) or list()
		self[pluginName] = type_names
		
		# register types in the system if possible
		dgmod = api.MDGModifier()
		dagmod = api.MDagModifier()
		transobj = None
		
		nt = globals()
		for tn in type_names:
			tnc = capitalize(tn)
			if tnc in nt:
				self.log.debug("Skipped type %s as it did already exist in module" % tnc)
				continue
			# END skip existing node types ( probably user created )
			
			# get the type id- first try depend node, then dag node. Never actually
			# create the nodes in the scene, created MObjects will be discarded
			# once the modifiers go out of scope
			apitype = None
			try:
				apitype = dgmod.createNode(tn).apiType()
			except RuntimeError:
				try:
					# most plugin dag nodes require a transform to be created
					# We create a dummy for the dagmod, otherwise it would create
					# it for us and return the parent transform instead, which 
					# has no child officially yet as its not part of the dag
					# ( so we cannot query the child from there ).
					if transobj is None:
						transobj = dagmod.createNode("transform")
					# END assure we have parent 
					
					apitype = dagmod.createNode(tn, transobj).apiType()
				except RuntimeError:
					self.log.error("Failed to retrieve apitype of node type %s - skipped" % tnc)
					continue
				# END dag exception handling
			# END dg exception handling 
			
			parentclsname = base._plugin_type_to_node_type_name.get(apitype, 'Unknown')
			typ._addCustomType( nt, parentclsname, tnc, force_creation=True )
Exemplo n.º 16
0
    def assignShadingGroup(self, fnDagNode):

        fnSet = self.getShadingGroup()

        if fnSet is not None:
            # Easiest, cleanest way seems to be calling MEL.
            # sets command handles everything, even nested instanced dag paths
            mdgm = OpenMaya.MDGModifier()
            mdgm.commandToExecute("sets -e -nw -fe " + fnSet.name() + " " +
                                  fnDagNode.name())
            mdgm.doIt()
Exemplo n.º 17
0
    def fix(self, report, params):
        node = report.node()
        if node.dg().isFromReferencedFile():
            return False

        if node.dg().isLocked():
            node.dg().setLocked(False)

        mod = OpenMaya.MDGModifier()
        mod.deleteNode(node.object())
        mod.doIt()
Exemplo n.º 18
0
 def create_kshading_engine(self, name, shader_mplug=None, geometries=None):
     shading_engine = self.create_shading_engine(name)
     if shader_mplug:
         output_mplug = self.get_mplug('%s.surfaceShader' %
                                       (shading_engine))
         dgMod = OpenMaya.MDGModifier()
         dgMod.connect(shader_mplug, output_mplug)
         dgMod.doIt()
     if geometries:
         self.assign_to_shading_engine(geometries, shading_engine)
     return self.get_mobject(shading_engine)
Exemplo n.º 19
0
    def __init__(self, **kwargs):
        """Constructor.

        Parameters
        ----------
        kwargs
            Keyword arguments to define additional attributes.
        """
        self.dg = OpenMaya.MDGModifier()
        self.dag = OpenMaya.MDagModifier()
        self.transforms = []
        self.__dict__.update(kwargs)
Exemplo n.º 20
0
def connectAttrApi( attr1, attr2 ):
    
    cons = cmds.listConnections( attr2, s=1, d=0, p=1, c=1 )
    if cons:
        disconnectAttrApi( cons[1], cons[0] )
    
    plug1 = getPlugFromString( attr1 )
    plug2 = getPlugFromString( attr2 )
    
    mode = om.MDGModifier()
    mode.connect( plug1, plug2 )
    mode.doIt()
Exemplo n.º 21
0
def _createTmpNode(nodetype):
    """Return tuple(mobject, modifier) for the nodetype or raise RuntimeError
	doIt has not yet been called on the modifier, hence the mobject is temporary"""
    try:
        mod = api.MDGModifier()
        obj = mod.createNode(nodetype)
        return (obj, mod)
    except RuntimeError:
        mod = api.MDagModifier()
        tmpparent = mod.createNode("transform")
        obj = mod.createNode(nodetype, tmpparent)
        return (obj, mod)
Exemplo n.º 22
0
    def __init__(self):
        OpenMayaMPx.MPxCommand.__init__(self)
        self.dgMod = OpenMaya.MDGModifier()

        self.nodeName = ''
        self.skipX = False
        self.skipY = False
        self.skipZ = False
        self.distanceValue = 0.0
        self.startFrame = 0.0
        self.startVector = OpenMaya.MVector()
        self.sList = OpenMaya.MSelectionList()
Exemplo n.º 23
0
def connect(source_obj, source_plug_name, destination_obj, destination_plug_name):
    """
    Perform the connection process.
    :param source_obj: <MObject> Source object.
    :param destination_obj: <MObject> Destination object.
    :param source_plug_name: <str> The plug name to connect frOpenMaya.
    :param destination_plug_name: <str> The plug name to connect frOpenMaya.
    """
    source_plug = get_m_plug(source_obj, source_plug_name)
    destination_plug = get_m_plug(destination_obj, destination_plug_name)
    mg_mod = OpenMaya.MDGModifier()
    mg_mod.connect(source_plug, destination_plug)
    mg_mod.doIt()
Exemplo n.º 24
0
    def __init__(self):
        OpenMayaMPx.MPxCommand.__init__(self)

        self.sources = []
        self.destination = None

        self.destination_index = 0

        self.keep = False

        self.action = Action.kNothing

        self.dgModifier = OpenMaya.MDGModifier()
        self.sel = OpenMaya.MSelectionList()
Exemplo n.º 25
0
def __connectNodes(modifierNode, meshDagPath):
    class MeshOpHolderData:
        def __init__(self):
            self.meshNodeTransform = OpenMaya.MObject()
            self.meshNodeShape = OpenMaya.MObject()
            self.meshNodeDestPlug = OpenMaya.MPlug()
            self.meshNodeDestAttr = OpenMaya.MObject()

            self.upstreamNodeTransform = OpenMaya.MObject()
            self.upstreamNodeShape = OpenMaya.MObject()
            self.upstreamNodeSrcPlug = OpenMaya.MPlug()
            self.upstreamNodeSrcAttr = OpenMaya.MObject()

            self.modifierNodeSrcAttr = OpenMaya.MObject()
            self.modifierNodeDestAttr = OpenMaya.MObject()

    data = MeshOpHolderData()

    fnDN = OpenMaya.MFnDependencyNode(modifierNode)
    data.modifierNodeSrcAttr = fnDN.attribute("result")
    data.modifierNodeDestAttr = fnDN.attribute("parm_input")

    data.meshNodeShape = meshDagPath.node()
    dagNodeFn = OpenMaya.MFnDagNode(data.meshNodeShape)

    if dagNodeFn.parentCount() == 0:
        raise RuntimeError("Mesh shape has no parent transform")

    data.meshNodeTransform = dagNodeFn.parent(0)
    data.meshNodeDestPlug = dagNodeFn.findPlug("inMesh")
    data.meshNodeDestAttr = data.meshNodeDestPlug.attribute()

    dgModifier = OpenMaya.MDGModifier()
    __processUpstreamNode(data, meshDagPath, dgModifier)

    if __hasTweaks(meshDagPath):
        __processTweaks(data, dgModifier, modifierNode)
    else:
        modifierDestPlug = OpenMaya.MPlug(modifierNode,
                                          data.modifierNodeDestAttr)
        dgModifier.connect(data.upstreamNodeSrcPlug, modifierDestPlug)

    modifierSrcPlug = OpenMaya.MPlug(modifierNode, data.modifierNodeSrcAttr)
    meshDestAttr = OpenMaya.MPlug(data.meshNodeShape, data.meshNodeDestAttr)

    dgModifier.connect(modifierSrcPlug, meshDestAttr)

    dgModifier.doIt()
Exemplo n.º 26
0
 def disconnect_chanelbox(self, mobject):
     dependency_node = OpenMaya.MFnDependencyNode(mobject)
     attributes = [
         'translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY',
         'rotateZ', 'scaleX', 'scaleY', 'scaleZ', 'visibility', 'translate',
         'rotate', 'scale'
     ]
     for attribute in attributes:
         attr_mobject = dependency_node.attribute(attribute)
         output_plug = dependency_node.findPlug(attr_mobject)
         if not output_plug.isConnected():
             continue
         input_plugs = OpenMaya.MPlugArray()
         output_plug.connectedTo(input_plugs, 1, 0)
         dg_modifier = OpenMaya.MDGModifier()
         dg_modifier.disconnect(input_plugs[0], output_plug)
         dg_modifier.doIt()
Exemplo n.º 27
0
    def setAttrs(self, wedge_attr, attr_plug, start_plug, value_plug):
        attr_plug.setString(wedge_attr)
        dest_node_attr = wedge_attr.split('.')
        selectionList = OpenMaya.MSelectionList()
        selectionList.add(dest_node_attr[0])
        dest_node = OpenMaya.MObject()
        selectionList.getDependNode(0, dest_node)
        dest_nodeFn = OpenMaya.MFnDependencyNode(dest_node)
        dest_plug = dest_nodeFn.findPlug(dest_node_attr[1])
        start_value = round(dest_plug.asDouble(), 3)
        start_plug.setDouble(start_value)
        value_plug.setDouble(start_value)

        mdg = OpenMaya.MDGModifier()
        mdg.connect(value_plug, dest_plug)
        mdg.doIt()
        return start_value
Exemplo n.º 28
0
def addArrayMessageAttr(targetName, attrName):

    targetObj = om.MObject()

    selList = om.MSelectionList()
    selList.add(targetName)
    selList.getDependNode(0, targetObj)

    msgAttr = om.MFnMessageAttribute()
    msgAttrObj = msgAttr.create('layerTarget', 'lt')
    msgAttr.setArray(True)

    modify = om.MDGModifier()

    modify.addAttribute(targetObj, msgAttrObj)

    modify.doit()

    return modify
Exemplo n.º 29
0
    def rayCallback(*args):
        callbackType, callbackPlug, _, thisNode = args
        dependNode = om.MFnDependencyNode(thisNode.thisMObject())
        debugPlug = dependNode.findPlug("debugRay", False)

        if callbackPlug != debugPlug:
            return

        if debugPlug.asBool():
            dgMod = om.MDagModifier()
            drawVector = dgMod.createNode("drawVector")
            dgMod.doIt()

            sourcePlug = dependNode.findPlug("sourcePoint", False)
            aimPlug = dependNode.findPlug("hitPoint", False)
            messagePlug = dependNode.findPlug('message', False)

            drawVectorTrnDag = om.MFnDagNode(drawVector)
            drawVectorTrnDag.setLocked(True)
            drawVectorDepend = om.MFnDependencyNode(drawVectorTrnDag.child(0))
            sourceDestPlug = drawVectorDepend.findPlug("sourcePoint", False)
            aimDestPlug = drawVectorDepend.findPlug("aimPoint", False)
            messageDestPlug = drawVectorDepend.findPlug("drawMessage", False)

            dgMod = om.MDGModifier()
            dgMod.connect(sourcePlug, sourceDestPlug)
            dgMod.connect(aimPlug, aimDestPlug)
            dgMod.connect(messagePlug, messageDestPlug)
            dgMod.doIt()

        else:
            #Delete draw vector node connected through message
            sourcePlug = dependNode.findPlug("message", False)
            plugArray = om.MPlugArray()
            sourcePlug.connectedTo(plugArray, False, True)
            drawVectorTrn = om.MFnDagNode(plugArray[0].node()).parent(0)
            drawVectorTrnDag = om.MFnDagNode(drawVectorTrn)
            drawVectorTrnDag.setLocked(0)

            dgMod = om.MDagModifier()
            dgMod.deleteNode(drawVectorTrn)
            dgMod.doIt()
Exemplo n.º 30
0
    def __init__(self):
        super(polyModifierCmd, self).__init__()

        # polymesh
        self._fDagPathInitialized = False
        self._fDagPath = om.MDagPath()
        self._fDuplicateDagPath = om.MDagPath()

        # modifier node type
        self._fModifierNodeTypeInitialized = False
        self._fModifierNodeNameInitialized = False
        self._fModifierNodeType = om.MTypeId()
        self._fModifierNodeName = ""

        # node state

        self._fHasHistory = False
        self._fHasTweaks = False
        self._fHasRecordHistory = False

        # cached tweak data

        self._fTweakIndexArray = om.MIntArray()
        self._fTweakVectorArray = om.MFloatVectorArray()

        # cached mesh data

        self._fMeshData = om.MObject()

        # dg and dag modifier

        self._fDGModifier = om.MDGModifier()
        self._fDagModifier = om.MDagModifier()

        # manual shape management
        self._manual_redo_queue = []

        numDataFn = om.MFnNumericData()
        numDataFn.create(om.MFnNumericData.k3Float)
        numDataFn.setData3Float(0.0, 0.0, 0.0)
        self.__class__.NULL_VECTOR = numDataFn.object()