Ejemplo n.º 1
0
    def objectSet(self, dataID, setIndex, autoCreate=True):
        """Get an object set identified with setIndex at the given dataId
		
		:param dataID: id identifying the storage plug on this node
		:param setIndex: logical index at which the set will be connected to our message plug array
		:param autoCreate: if True, a set will be created if it does not yet exist
		:raises ValueError: if a set does not exist at setIndex and autoCreate is False
		:raises AttributeError: if the plug did not exist ( and autocreate is False )
		:note: method is implicitly undoable if autoCreate is True, this also means that you cannot
			explicitly undo this operation as you do not know if undo has been queued or not
		:note: newly created sets will automatically use partitions if one of the sets does"""
        mp = self.storagePlug(dataID, self.kMessage, autoCreate=autoCreate)
        # array plug having our sets
        setplug = mp.elementByLogicalIndex(setIndex)
        inputplug = setplug.minput()
        if inputplug.isNull():
            if not autoCreate:
                raise AttributeError(
                    "Set at %s[%i] did not exist on %r" %
                    (self._attrprefix + dataID, setIndex, self))
            su = undo.StartUndo()  # make the following operations atomic
            objset = createNode(dataID + "Set", "objectSet", forceNewLeaf=True)
            inputplug = objset.message
            inputplug.mconnectTo(setplug)

            # hook it up to the partition
            if self.partition(dataID):
                self.setPartition(dataID, True)
        # END create set as needed

        # return actual object set
        return inputplug.mwrappedNode()
Ejemplo n.º 2
0
	def setPartition( self, dataID, state ):
		"""Make all sets in dataID use a partition or not
		
		:param dataID: id identifying the storage plug
		:param state: if True, a partition will be used, if False, it will be disabled
		:note: this method makes sure that all sets are hooked up to the partition
		:raise ValueError: If we did not have a single set to which to add to the partition
		:raise AttributeError: If the dataID has never had sets
		:return: if state is True, the name of the possibly created ( or existing ) partition"""
		sets = self.setsByID( dataID )
		partition = self.partition( dataID )

		if state:
			if partition is None:
				if not sets:
					raise ValueError("Cannot create partition as data %r did not have any connected sets" % dataID)
				# END check sets exist
				# create partition
				partition = createNode( "storagePartition", "partition", forceNewLeaf=True )

				tattr = api.MFnTypedAttribute( )
				attr = tattr.create( self._partitionIdAttr, "pid", api.MFnData.kString )
				partition.addAttribute( attr )
			# END create partition

			# make sure all sets are members of our partition
			partition.addSets( sets )
			return partition
		else:
			if partition:
				# delete partition
				# have to clear partition as, for some reason, or own node will be killed as well !
				partition.clear()
				delete( partition )
Ejemplo n.º 3
0
	def objectSet( self, dataID, setIndex, autoCreate = True ):
		"""Get an object set identified with setIndex at the given dataId
		
		:param dataID: id identifying the storage plug on this node
		:param setIndex: logical index at which the set will be connected to our message plug array
		:param autoCreate: if True, a set will be created if it does not yet exist
		:raises ValueError: if a set does not exist at setIndex and autoCreate is False
		:raises AttributeError: if the plug did not exist ( and autocreate is False )
		:note: method is implicitly undoable if autoCreate is True, this also means that you cannot
			explicitly undo this operation as you do not know if undo has been queued or not
		:note: newly created sets will automatically use partitions if one of the sets does"""
		mp = self.storagePlug( dataID, self.kMessage, autoCreate = autoCreate )
		# array plug having our sets
		setplug = mp.elementByLogicalIndex( setIndex )
		inputplug = setplug.minput()
		if inputplug.isNull():
			if not autoCreate:
				raise AttributeError( "Set at %s[%i] did not exist on %r" % ( self._attrprefix + dataID, setIndex, self ) )
			su = undo.StartUndo()			# make the following operations atomic
			objset = createNode( dataID + "Set", "objectSet", forceNewLeaf = True )
			inputplug = objset.message
			inputplug.mconnectTo(setplug)

			# hook it up to the partition
			if self.partition( dataID ):
				self.setPartition( dataID, True )
		# END create set as needed


		# return actual object set
		return inputplug.mwrappedNode()
Ejemplo n.º 4
0
def setPartition(mdplug, state):
    """Make all sets of the given data message plug use a partition or not
    :param state: if True, a partition will be used, if False, it will be disabled
    :note: this method makes sure that all sets are hooked up to the partition
    :raise ValueError: If we did not have a single set to which to add to the partition
    :raise AttributeError: If the dataID has never had sets
    :return: if state is True, the name of the possibly created (or existing) partition"""
    sets = setsByPlug(mdplug)
    pt = partition(mdplug)

    if state:
        if pt is None:
            if not sets:
                raise ValueError("Cannot create partition as plug %s did not have any connected sets" % mdplug)
            # END check sets exist
            # create partition
            pt = createNode("storagePartition", "partition", forceNewLeaf=True)

            tattr = api.MFnTypedAttribute()
            attr = tattr.create(StorageBase.kPartitionIdAttr, "pid", api.MFnData.kString)
            pt.addAttribute(attr)
        # END create partition

        # make sure all sets are members of our partition
        pt.addSets(sets)
        return pt
    else:
        if pt:
            # delete partition
            # have to clear partition as, for some reason, or own node will be killed as well !
            pt.clear()
            delete(pt)
Ejemplo n.º 5
0
def objectSet(mdplug, setIndex, autoCreate=True, setPrefix=''):
    """Get an object set identified with setIndex at the given dataId
    
    :param mdplug: data message plug whose object set to handle
    :param setIndex: logical index at which the set will be connected to our message plug array
    :param autoCreate: if True, a set will be created if it does not yet exist
    :param setPrefix: if given, the string will be used as prefix for the name of newly created
        object sets
    :raises ValueError: if a set does not exist at setIndex and autoCreate is False
    :raises AttributeError: if the plug did not exist (and autocreate is False)
    :note: method is implicitly undoable if autoCreate is True, this also means that you cannot
        explicitly undo this operation as you do not know if undo has been queued or not
    :note: newly created sets will automatically use partitions if one of the sets does"""
    mp = mdplug
    
    # array plug having our sets
    setplug = mp.elementByLogicalIndex(setIndex)
    inputplug = setplug.minput()
    if inputplug.isNull():
        if not autoCreate:
            raise AttributeError("Set at %s[%i] did not exist" % (mp.name(), setIndex))
        su = undo.StartUndo()           # make the following operations atomic
        objset = createNode(setPrefix + "Set", "objectSet", forceNewLeaf = True)
        inputplug = objset.message
        inputplug.mconnectTo(setplug)

        # hook it up to the partition
        if partition(mdplug):
            setPartition(mdplug, True)
    # END create set as needed

    # return actual object set
    return inputplug.mwrappedNode()
Ejemplo n.º 6
0
    def setPartition(self, dataID, state):
        """Make all sets in dataID use a partition or not
		
		:param dataID: id identifying the storage plug
		:param state: if True, a partition will be used, if False, it will be disabled
		:note: this method makes sure that all sets are hooked up to the partition
		:raise ValueError: If we did not have a single set to which to add to the partition
		:raise AttributeError: If the dataID has never had sets
		:return: if state is True, the name of the possibly created ( or existing ) partition"""
        sets = self.setsByID(dataID)
        partition = self.partition(dataID)

        if state:
            if partition is None:
                if not sets:
                    raise ValueError(
                        "Cannot create partition as data %r did not have any connected sets"
                        % dataID)
                # END check sets exist
                # create partition
                partition = createNode("storagePartition",
                                       "partition",
                                       forceNewLeaf=True)

                tattr = api.MFnTypedAttribute()
                attr = tattr.create(self._partitionIdAttr, "pid",
                                    api.MFnData.kString)
                partition.addAttribute(attr)
            # END create partition

            # make sure all sets are members of our partition
            partition.addSets(sets)
            return partition
        else:
            if partition:
                # delete partition
                # have to clear partition as, for some reason, or own node will be killed as well !
                partition.clear()
                delete(partition)
Ejemplo n.º 7
0
    def resetTweaks(self,
                    tweak_type=eComponentType.vertex,
                    keep_tweak_result=False):
        """Reset the tweaks on the given mesh shape
		
		:param tweak_type: the component type(s) whose tweaks are to be removed,
			valid values are 'vertex' and 'uv' members of the eComponentType enumeration. 
			Pass in a scalar value or a list of tweak types
		:param keep_tweak_result: if True, the effect of the tweak will be kept. If False,
			it will be removed. What actually happens depends on the context
			
			* [referenced] mesh *without* history:
				copy outMesh to inMesh, resetTweaks
				
				if referenced, plenty of reference edits are generated, ideally one operates
				on non-referenced geomtry
			   
			* [referenced] mesh *with* history:
			 	put tweakNode into mesh history, copy tweaks onto tweak node
		:note: currently vertex and uv tweaks will be removed if keep is enabled, thus they must
			both be specified"""
        check_types = (isinstance(tweak_type, (list, tuple))
                       and tweak_type) or [tweak_type]
        type_map = {
            self.eComponentType.vertex:
            ("pnts", api.MFnNumericData.k3Float, "polyTweak",
             api.MFn.kPolyTweak, "tweak"),
            self.eComponentType.uv:
            ("uvpt", api.MFnNumericData.k2Float, "polyTweakUV",
             api.MFn.kPolyTweakUV, "uvTweak")
        }

        mia = api.MIntArray()
        for reset_this_type in check_types:
            try:
                attrname, datatype, tweak_node_type, tweak_node_type_API, tweakattr = type_map[
                    reset_this_type]
            except KeyError:
                raise ValueError("Tweak type %s is not supported" %
                                 reset_this_type)

            # KEEP MODE
            #############
            if keep_tweak_result:
                input_plug = self.inMesh.minput()

                # history check
                if input_plug.isNull():
                    # assert as we had to make the handling much more complex to allow this to work right as we copy the whole mesh here
                    # containing all tweaks , not only one type
                    if not (self.eComponentType.vertex in check_types
                            and self.eComponentType.uv in check_types):
                        log.warn(
                            "Currently vertex AND uv tweaks will be removed if a mesh has no history and a reset is requested"
                        )
                    # END print warning

                    # take the output mesh, and stuff it into the input, then proceed
                    # with the reset. This implies that all tweaks have to be removed
                    out_mesh = self.outMesh.asMObject()
                    self.inMesh.msetMObject(out_mesh)
                    self.cachedInMesh.msetMObject(out_mesh)

                    # finally reset all tweeaks
                    return self.resetTweaks(check_types,
                                            keep_tweak_result=False)
                else:
                    # create node of valid type
                    tweak_node = input_plug.mwrappedNode()

                    # create node if there is none as direct input
                    if not tweak_node.hasFn(tweak_node_type_API):
                        tweak_node = base.createNode("polyTweak",
                                                     tweak_node_type,
                                                     forceNewLeaf=1)

                        # hook the node into the history
                        input_plug.mconnectTo(tweak_node.inputPolymesh)
                        tweak_node.output.mconnectTo(self.inMesh)

                        # setup uvset tweak location to tell uvset where to get tweaks from
                        if tweak_node_type_API == api.MFn.kPolyTweakUV:
                            names = list()
                            self.getUVSetNames(names)
                            index = names.index(self.currentUVSetName())

                            own_tweak_location_plug = self.uvSet.elementByLogicalIndex(
                                index).mchildByName('uvSetTweakLocation')
                            tweak_node.uvTweak.elementByLogicalIndex(
                                index).mconnectTo(own_tweak_location_plug)
                        # END uv special setup
                    # END create tweak node

                    dtweak_plug = tweak_node.findPlug(tweakattr)
                    stweak_plug = self.findPlug(attrname)

                    # copy the tweak values - iterate manually as the plug tends to
                    # report incorrect values if history is present - its odd
                    stweak_plug.evaluateNumElements()

                    mia.clear()
                    stweak_plug.getExistingArrayAttributeIndices(mia)
                    for i in mia:
                        try:
                            tplug = stweak_plug.elementByLogicalIndex(i)
                        except RuntimeError:
                            continue
                        else:
                            dtweak_plug.elementByLogicalIndex(i).msetMObject(
                                tplug.asMObject())
                        # END exception handling
                    # END for each tweak plug

                    # proceed with reset of tweaks
                    pass
                # END history handling
            # END keep tweak result handling

            arrayplug = self.findPlug(attrname)
            dataobj = api.MFnNumericData().create(datatype)

            # reset values, do it for all components at once using a data object
            try:
                for p in arrayplug:
                    p.msetMObject(dataobj)
            except RuntimeError:
                # especially uvtweak array plugs return incorrect lengths, thus we may
                # fail once we reach the end of the iteration.
                # uvpt appears to display a lenght equalling the number of uvpoints in the mesh
                # possibly only for the current uvset
                pass
Ejemplo n.º 8
0
    def resetTweaks( self, tweak_type = eComponentType.vertex, keep_tweak_result = False ):
        """Reset the tweaks on the given mesh shape
        
        :param tweak_type: the component type(s) whose tweaks are to be removed,
            valid values are 'vertex' and 'uv' members of the eComponentType enumeration. 
            Pass in a scalar value or a list of tweak types
        :param keep_tweak_result: if True, the effect of the tweak will be kept. If False,
            it will be removed. What actually happens depends on the context
            
            * [referenced] mesh *without* history:
                copy outMesh to inMesh, resetTweaks
                
                if referenced, plenty of reference edits are generated, ideally one operates
                on non-referenced geomtry
               
            * [referenced] mesh *with* history:
                put tweakNode into mesh history, copy tweaks onto tweak node
        :note: currently vertex and uv tweaks will be removed if keep is enabled, thus they must
            both be specified"""
        check_types = ( isinstance( tweak_type, ( list, tuple ) ) and tweak_type ) or [ tweak_type ]
        type_map = {
                            self.eComponentType.vertex : ( "pnts", api.MFnNumericData.k3Float, "polyTweak", api.MFn.kPolyTweak, "tweak" ),
                            self.eComponentType.uv : ( "uvpt", api.MFnNumericData.k2Float, "polyTweakUV", api.MFn.kPolyTweakUV, "uvTweak" )
                    }

        mia = api.MIntArray()
        for reset_this_type in check_types:
            try:
                attrname, datatype, tweak_node_type, tweak_node_type_API, tweakattr = type_map[ reset_this_type ]
            except KeyError:
                raise ValueError( "Tweak type %s is not supported" % reset_this_type )

            # KEEP MODE
            #############
            if keep_tweak_result:
                input_plug = self.inMesh.minput()

                # history check
                if input_plug.isNull():
                    # assert as we had to make the handling much more complex to allow this to work right as we copy the whole mesh here
                    # containing all tweaks , not only one type
                    if not ( self.eComponentType.vertex in check_types and self.eComponentType.uv in check_types ):
                        log.warn("Currently vertex AND uv tweaks will be removed if a mesh has no history and a reset is requested")
                    # END print warning

                    # take the output mesh, and stuff it into the input, then proceed
                    # with the reset. This implies that all tweaks have to be removed
                    out_mesh = self.outMesh.asMObject()
                    self.inMesh.msetMObject( out_mesh )
                    self.cachedInMesh.msetMObject( out_mesh )

                    # finally reset all tweeaks
                    return self.resetTweaks( check_types, keep_tweak_result = False )
                else:
                    # create node of valid type
                    tweak_node = input_plug.mwrappedNode()

                    # create node if there is none as direct input
                    if not tweak_node.hasFn( tweak_node_type_API ):
                        tweak_node = base.createNode( "polyTweak", tweak_node_type, forceNewLeaf = 1  )

                        # hook the node into the history
                        input_plug.mconnectTo(tweak_node.inputPolymesh)
                        tweak_node.output.mconnectTo(self.inMesh)

                        # setup uvset tweak location to tell uvset where to get tweaks from
                        if tweak_node_type_API == api.MFn.kPolyTweakUV:
                            names = list()
                            self.getUVSetNames( names )
                            index = names.index( self.currentUVSetName( ) )

                            own_tweak_location_plug = self.uvSet.elementByLogicalIndex( index ).mchildByName('uvSetTweakLocation')
                            tweak_node.uvTweak.elementByLogicalIndex( index ).mconnectTo(own_tweak_location_plug)
                        # END uv special setup
                    # END create tweak node

                    dtweak_plug = tweak_node.findPlug(tweakattr)
                    stweak_plug = self.findPlug(attrname)

                    # copy the tweak values - iterate manually as the plug tends to
                    # report incorrect values if history is present - its odd
                    stweak_plug.evaluateNumElements()
                    
                    mia.clear()
                    stweak_plug.getExistingArrayAttributeIndices(mia)
                    for i in mia:
                        try:
                            tplug = stweak_plug.elementByLogicalIndex(i)
                        except RuntimeError:
                            continue
                        else:
                            dtweak_plug.elementByLogicalIndex(i).msetMObject(tplug.asMObject())
                        # END exception handling
                    # END for each tweak plug

                    # proceed with reset of tweaks
                    pass
                # END history handling
            # END keep tweak result handling

            arrayplug = self.findPlug(attrname)
            dataobj = api.MFnNumericData().create( datatype )

            # reset values, do it for all components at once using a data object
            try:
                for p in arrayplug:
                    p.msetMObject( dataobj )
            except RuntimeError:
                # especially uvtweak array plugs return incorrect lengths, thus we may
                # fail once we reach the end of the iteration.
                # uvpt appears to display a lenght equalling the number of uvpoints in the mesh
                # possibly only for the current uvset
                pass