def doPublishMayaExport(self, fileName, operands): ''' we override doPublishMaya just to force meshPrimitives to be the default nodes! ''' vdb = m.listConnections(m.ls(sl=1, dag=1, type='OpenVDBVisualize', l=1), type='OpenVDBRead') if vdb: self.data['extraFiles'] = [] self.data['publishedVDB'] = {} for node in vdb: p = str(m.getAttr('%s.VdbFilePath' % node)).strip() if p: pattern = p[p.index('$'):p.index('$') + p[p.index('$'):].index('.')] # python_pattern = pattern.replace('$','%').replace('F','0')+'d' pp = p.replace(pattern, '*') files = glob(pp) if files and '/sam/animation/' not in p: self.data['extraFiles'] += files self.data['publishedVDB'][node] = [ "%s/%s" % (self.data['publishPath'], os.path.basename(x)) for x in files ] m.setAttr( '%s.VdbFilePath' % node, "%s/%s" % (self.data['publishPath'], os.path.basename(p)), type='string') ret = genericAsset.maya.doPublishMayaExport(self, fileName, operands) return ret
def doImportMaya(self, filename, nodeName): ''' called by SAM when import an asset in maya ''' if not m.pluginInfo("shaveNode", q=1, l=1): m.loadPlugin('shaveNode') # cleanup shading leftovers cleanup = m.ls('|%s*' % ('_'.join(nodeName.split('_')[:4]))) for each in cleanup: if m.objExists("%s.visibility" % each): m.setAttr("%s.visibility" % each, 0) maya.cleanNodes(cleanup) genericAsset.maya.cleanUnusedShadingNodes() ret = genericAsset.maya.doImportMaya(self, filename, nodeName) # cleanup useless nodes allNodes = [x for x in m.ls(nodeName, dag=1, l=1)] # remove namespaces, if any! for x in [x for x in allNodes if ':' in x]: try: m.rename(x.split('|')[-1], x.split(':')[-1]) except: pass # refresh allNodes with the new cleaned names allNodes = [x for x in m.ls(nodeName, dag=1)] # get the shave nodes and the connected nodes shaveNodes = m.ls(nodeName, dag=1, type='shaveHair') nonDeletable = [] for x in shaveNodes: for n in m.listConnections(x): node = m.ls(n, dag=1, l=1) if not node: node = [n] nonDeletable += node # delete everything that is not connected to the shave nodes!! for x in allNodes: if x not in nonDeletable and 'SAM_SHAVE' not in x: nodeType = m.ls(x, showType=1) if nodeType and nodeType[1] not in ['shaveHair', 'transform']: m.delete(x) # delNodes = [x for x in allNodes if x not in nonDeletable and 'SAM_SHAVE' not in x and m.ls(x,showType=1)[1] not in ['shaveHair','transform'] ] # if ret is True, onRefreshCallback will be called after we return return ret
def doImportMaya( self, filename, nodeName ): ''' called by SAM when import an asset in maya ''' # cleanup shading leftovers # cleanup = m.ls("SAM_SHADER_%s_%s*" % ( # self.data['assetType'].replace('/','_'), # self.data['assetName'].split('.')[-1] # )) # maya.cleanNodes( cleanup ) ret = True if 'RLF' in self.data: import samPrman node = m.createNode("transform", n=nodeName) m.addAttr( node, ln="SAM_RLF_FILE", dt="string" ) m.setAttr( node + '.SAM_RLF_FILE', str(self.data['RLF']), type="string" ) samPrman.setRenderScripts() else: genericAsset.maya.cleanUnusedShadingNodes(force=True) ret = genericAsset.maya.doImportMaya( self, filename, nodeName ) if ret: shadingMap, shadingGroups, shadingNodes, displacementNodes, textures = genericAsset.maya.getShadingMap( m.ls("SAM_SHADER_*", type='transform') ) # for node in textures: # texture = os.path.basename( textures[node] ) # publishedText = "%s/%s" % ( self.data['publishPath'], texture ) # if os.path.exists( '%s.tex' % publishedText ): # publishedText = '%s.tex' % publishedText # # # print texture, '%s.tex' % publishedText , os.path.exists( '%s.tex' % publishedText ) # maya.setFileTexture( node, publishedText ) genericAsset.maya.cleanUnusedShadingNodes() # delete any mesh that may get into the exported scene. maya.cleanNodes( [ x for x in m.ls("SAM_shaders*", dag=1,type='mesh', l=1) if 'SAM' not in x.split('|')[-1] ] ) # for shader in m.ls("SAM_SHADER_*", type='transform'): # nodeToAttach = m.getAttr( shader + '.SAM_ORIGINAL_NODE' ).split('|')[-1] # nodesToAttach = m.ls("*"+nodeToAttach) # print nodesToAttach # # # atach to nodes matching naming map # n = m.ls(shader, dag=1, visible=1, ni=1, type='mesh') # for sg in m.listConnections(n, type="shadingEngine"): # m.sets( nodesToAttach, e=True, forceElement=sg ) return ret
def postPublish(self, operands, finishedSuscessfuly=False): # cleanup sudo = pipe.admin.sudo() for f in self.data['multipleFiles']: sudo.rm(self.data['assetPath'] % f) sudo.run() if finishedSuscessfuly: if m: for each in self.data['meshPrimitives']: if not m.objExists("%s.pipe_asset" % each): m.addAttr(each, ln="pipe_asset", dt="string") m.setAttr("%s.pipe_asset" % each, self.data['publishPath'], type='string')
def gather(self, operands): ''' gather op calls this method to gather the asset!''' assetVersion = '.'.join( map(lambda x: '%02d' % int(x), str(operands['Asset']['info']['version']).split())) path = "%s/%s/%s" % (operands["Asset"]["type"], operands["Asset"]["info"]["name"], assetVersion) data = Asset.AssetParameter(path).getData() if m: x = IECoreMaya.FnProceduralHolder.create("modelAsset", "read", 1) m.setAttr("%s.parm_files_name" % x.fullPathName(), (data['publishFile'] % 0).replace('0000', '####'), type='string') return IECore.StringData('done')
def doPublishMayaExport(self, fileName, operands): ''' create mapping nodes before publishing ''' # find all shave nodes shaveNodes = m.ls(self.data['meshPrimitives'], dag=1, l=1, type='shaveHair') connectionsToRestore = [] createOnlyOne = {} for snode in shaveNodes: placeholder = "SAM_SHAVE_%s_%s_%02d_%02d_%02d_%s" % ( self.data['assetType'].replace( '/', '_'), self.data['assetName'].split('.')[-1], self.data['assetInfo']['version'].value.x, self.data['assetInfo']['version'].value.y, self.data['assetInfo']['version'].value.z, '') # duplicate the shave origin mesh so we can publish a clean scene # TODO: disconect all shaders from mesh to avoid exporting shaders!! c = m.listConnections("%s.inputMesh" % snode, p=1, c=1) for n in range(0, len(c), 2): newNode = c[n + 1].split('.')[0] if newNode not in createOnlyOne: m.setAttr("%s.visibility" % newNode, l=0) createOnlyOne[newNode] = m.duplicate(newNode, n=placeholder + newNode) createOnlyOne[newNode] = m.parent(createOnlyOne[newNode], w=1)[0] # self.data['meshPrimitives'] += m.ls(createOnlyOne[newNode],l=1) m.setAttr("%s.visibility" % createOnlyOne[newNode], 0) m.disconnectAttr(c[n + 1], c[n]) m.connectAttr( "%s.%s" % (createOnlyOne[newNode], c[n + 1].split('.')[-1]), c[n]) connectionsToRestore += c # m.connectAttr( '%s.%s' % ( m.listRelatives(snode, c=1)[0], c[1].split('.')[-1] ), c[0], f=1) if not m.objExists(snode + '.SAM_ORIGINAL_NODE'): m.addAttr(snode, ln="SAM_ORIGINAL_NODE", dt="string") m.setAttr(snode + '.SAM_ORIGINAL_NODE', str(c), type="string") c = m.listConnections(snode, type='file', p=1, c=1) if c: for n in range(0, len(c), 2): m.disconnectAttr(c[n + 1], c[n]) connectionsToRestore += c # use the generic maya export to write scene genericAsset.maya.doPublishMayaExport(self, fileName, operands) for n in range(0, len(connectionsToRestore), 2): print connectionsToRestore[n + 1], connectionsToRestore[n] m.connectAttr(connectionsToRestore[n + 1], connectionsToRestore[n], f=1) for node in createOnlyOne: if m.objExists(createOnlyOne[node]): m.delete(createOnlyOne[node])
def publishMayaShadersAndTextures(self, shadingFile, operands): from threading import Thread import math # loop over all meshs and gather shading mapping! shadingMap, shadingGroups, shadingNodes, displacementNodes, textures = maya.getShadingMap( self.data['meshPrimitives'] ) self.data['shadingMap'] = shadingMap self.data['shadingGroups'] = shadingGroups self.data['shadingNodes'] = shadingNodes self.data['displacementNodes'] = displacementNodes self.data['textures'] = textures # mayaExt = os.path.splitext(operands['%sDependency' % self.prefix].value)[-1].lower() # shadingFile = "%s/data/shaders%s" % (m.workspace(q=1, rd=1), mayaExt) self.data['extraFiles'] = [] self.data['publishedTextures'] = {} tmpFolder = '%s/renderman/sam' % m.workspace(q=1, rd=1) if not os.path.exists(tmpFolder): os.makedirs(tmpFolder) def cleanFileName(file): clean = [ ' ', '!', '&', '(', ')', '[', ']', ] ret = file for each in clean: ret = ret.replace(each,'_') return ret def processTextures(n1, n2, cores, pb, tmpFolder): # tmpFolder = '%s/renderman/sam' % m.workspace(q=1, rd=1) for node in self.data['textures'].keys()[n1:n2+1]: if not os.path.exists(self.data['textures'][node]) and os.path.exists(os.path.splitext(self.data['textures'][node])[0]): self.data['textures'][node] = os.path.splitext(self.data['textures'][node])[0] # fileName = '%s/sourceimages/%s' % ( m.workspace(q=1, rd=1), os.path.basename( self.data['textures'][text] ) ) ext = os.path.splitext( self.data['textures'][node] )[-1].lower() if '/sam/' not in self.data['textures'][node] or ext != '.tex': publishedText = "%s/%s" % ( self.data['publishPath'], os.path.basename( self.data['textures'][node] ) ) tex = '%s.tex' % os.path.basename( cleanFileName(self.data['textures'][node]) ) # by adding to extraFiles, the texture will be published to the asset folder self.data['extraFiles'].append( self.data['textures'][node] ) # convert to tex file # if m.nodeType(node) in ['file', 'PxrTexture']: if ext != '.tex': cmd ='LD_LIBRARY_PATH=$RMANTREE/lib/ $RMANTREE/bin/txmake -newer -resize down -t:%s -mode periodic "%s" %s/%s' % ( cores, self.data['textures'][node], tmpFolder, tex ) print cmd os.popen( cmd ).readlines() self.data['extraFiles'].append( '%s/%s' % (tmpFolder, tex) ) publishedText = "%s/%s" % ( self.data['publishPath'], tex ) else: self.data['extraFiles'].append( self.data['textures'][node] ) self.data['publishedTextures'][node] = publishedText # now we set maya texture node to use the published texture! # print '===>', publishedText # maya.setFileTexture( text, publishedText ) # convert textures to tex using multiple threads threads = [] cores = cpu_count()#*1.5 batches = len( self.data['textures'].keys() ) / cores batches = int( math.ceil(batches) ) # + math.ceil( 1.0 / batches-int(batches) ) # progress bar pb = genericAsset.progressBar( len(self.data['textures'].keys())+int(math.ceil(cores))+1, "Pre-converting textures for publishing...") for n in range( int(math.ceil(cores)) ): n *= batches+1 # print n, n+batches threads.append( Thread( target=processTextures, args=(n,n+batches,cores,pb,tmpFolder,) ) ) threads[-1].start() # wait for the convertion to finish pb.step() for thread in threads: pb.step() thread.join() # make file texture nodes use the published shaders for node in self.data['publishedTextures']: pb.step() maya.setFileTexture( node, self.data['publishedTextures'][node] ) pb.close() # cleanup shading leftovers cleanup = m.ls("SAM_SHADER_%s_%s*" % ( self.data['assetType'].replace('/','_'), self.data['assetName'].split('.')[-1] )) maya.cleanNodes( cleanup ) maya.cleanUnusedShadingNodes() newNodes = [] for node in self.data['shadingMap']: placeholder = "SAM_SHADER_%s_%s_%02d_%02d_%02d_%s" % ( self.data['assetType'].replace('/','_'), self.data['assetName'].split('.')[-1], self.data['assetInfo']['version'].value.x, self.data['assetInfo']['version'].value.y, self.data['assetInfo']['version'].value.z, node ) n=m.createNode('mesh') snode = m.rename(m.listRelatives(n, p=1), placeholder) m.addAttr( snode, ln="SAM_ORIGINAL_NODE", dt="string" ) m.setAttr( snode + '.SAM_ORIGINAL_NODE', str(node), type="string" ) m.sets( snode, e=True, forceElement=self.data['shadingMap'][node].keys()[0] ) newNodes.append( snode ) m.select( self.data['shadingGroups'].keys() + self.data['shadingNodes'].keys() + self.data['displacementNodes'].keys() ,r=1, noExpand=1) m.select(newNodes) mayaExt = os.path.splitext(shadingFile)[-1] m.file(shadingFile, force=1, pr=1, es=1, typ=("mayaBinary" if mayaExt=='.mb'else 'mayaAscii')) # print shadingFile cleanup = m.ls("SAM_SHADER_%s_%s*" % ( self.data['assetType'].replace('/','_'), self.data['assetName'].split('.')[-1] )) maya.cleanNodes( cleanup ) # export RLF data for prman if m.pluginInfo('RenderMan_for_Maya.so', query=1, loaded=1): self.exportRLF()
def onRefreshCallback( assetType, nodeNamePrefix ): import samPrman samPrman.setRenderScripts() m.setAttr( "defaultRenderGlobals.preMel", "python(\"import genericAsset;genericAsset.maya._attachShaders()\")", type="string" ) genericAsset.maya.cleanUnusedShadingNodes() genericAsset.maya.attachShadersLazy()