def addCustomType( newcls, parentClsName=None, **kwargs ): """ Add a custom class to this module - it will be handled like a native type :param newcls: new class object if metaclass is None, otherwise string name of the type name to be created by your metaclass :param parentClsName: if metaclass is set, the parentclass name ( of a class existing in the nodeTypeTree ( see /maya/cache/nodeHierarchy.html ) Otherwise, if unset, the parentclassname will be extracted from the newcls object :param kwargs: * force_creation: if True, default False, the class type will be created immediately. This can be useful if you wish to use the type for comparison, possibly before it is first being queried by the system. The latter case would bind the StandinClass instead of the actual type. :raise KeyError: if the parentClsName does not exist""" newclsname = newcls newclsobj = None parentname = parentClsName if not isinstance( newcls, basestring ): newclsname = newcls.__name__ newclsobj = newcls if not parentClsName: parentname = newcls.__bases__[0].__name__ # add to hierarchy tree typ._addCustomType( globals(), parentname, newclsname, **kwargs ) # add the class to our module if required if newclsobj: setattr( _thismodule, newclsname, newclsobj )
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 )
def plugin_loaded(self, pluginName, _may_spawn_callbacks=True): """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 # HANDLE FILE LOAD SPECIAL CASE ############################### if _may_spawn_callbacks and (api.MFileIO.isOpeningFile() or api.MFileIO.isReadingFile()): messages = list() if api.MFileIO.isOpeningFile(): messages.append(api.MSceneMessage.kAfterOpen) elif api.MFileIO.isReadingFile(): # when reading files (import + ref), the nodes seem to stay (tested in maya 2012) # therefore we delay the update until after the fact # recheck after import or reference messages.extend((api.MSceneMessage.kAfterImport, api.MSceneMessage.kAfterReference)) #end handle messages plugin_info = [pluginName] for message in messages: info = list() info.append(api.MSceneMessage.addCallback(message, self._post_read_or_open_cb, info)) info.append(plugin_info) #end for each message to create return #end if we are allowed to spawn callbacks (because we are not called by one) 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 # NOTE: Actually, this is not true ! During file loading, its clearly visible # that the nodes stay, may it be dg nodes or dag nodes. This of course dumps # quite a lot of data in case the MR plugin gets loaded. 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 )