def do(): shaderList = list() shadingEngines = cmds.ls(type="shadingEngine") for shadingEngine in shadingEngines: cnx = [x for x in (cmds.listConnections("%s.surfaceShader" % shadingEngine) or []) if x.endswith("_SHD")] if cnx: shaderList.append(cnx[0]) shaderList = list(set(shaderList)) foundShaders = list() for assetCategory in ['environments', 'characters']: currentShaderLibrary = ddConstants.SHADER_DIRECTORIES[assetCategory] categories = [ x for x in (os.listdir(currentShaderLibrary) or []) if os.path.isdir(os.path.join(currentShaderLibrary, x)) and not x.startswith(".") and not x in ["Keyboard", "Materials", "_Materials"] ] # Loop through the shader categories. for category in categories: directory = os.path.join(currentShaderLibrary, category) # Get the list of swatch files on disk for the category. swatchFiles = [x.replace(".png", "") for x in os.listdir(directory) if x.endswith(".png")] for shader in shaderList: # For each category, loop through the shaders, looking for a match. meshList = list() swatch = shader.replace("_SHD", "") if swatch in swatchFiles: # If a match is found, import and connect it. tempGrp = "tempImportedGrp" if cmds.objExists(tempGrp): cmds.delete(tempGrp) foundShaders.append(shader) connectedShadingEngines = cmds.listConnections("%s.outColor" % shader) or [] for connectedShadingEngine in connectedShadingEngines: meshSubList = [x for x in (cmds.listHistory(connectedShadingEngine) or []) if cmds.nodeType(x) == "mesh"] if meshSubList: meshList.extend(meshSubList) cmds.delete(connectedShadingEngine) cmds.delete(shader) deleteNodes = cmds.ls("%s_*DIFF*" % swatch, "%s_*SPEC*" % swatch, "%s_*NRML*" % swatch) try: cmds.delete(deleteNodes) except: pass # Get the path to swatch file. fileName = os.path.join(directory, "%s.ma" % swatch) if os.path.isfile(fileName): # Import swatch file into tempGrp. cmds.file(fileName, i=True, groupReference=True, groupName=tempGrp) if cmds.objExists(tempGrp): # Remove any namespaces from imported nodes. tempGrp = ddRemoveNamespaces.doRemoveNamespaces(tempGrp) # Children consists of one swatch plane. children = cmds.listRelatives(tempGrp, children=True, path=True) if children: # Get the connected shading engine. shadingEngine = getConnectedShadingEngine(children[0]) if shadingEngine: # Assign shader to selected objects. for sel in meshList: selShape = sel if not (cmds.nodeType(sel) == "mesh"): selShape = cmds.listRelatives(sel, shapes=True, path=True) if selShape: selShape = selShape[0] if selShape: cmds.sets(selShape, forceElement=shadingEngine) sys.stdout.write("Shader reconnected: %s\n" % shader) if cmds.objExists(tempGrp): cmds.delete(tempGrp) strayNodes = cmds.ls("tempImportedGrp*") if strayNodes: try: cmds.delete(strayNodes) except: pass # Figure out if any shaders were not reconnected. shaderNotFoundStr = "" for shaderName in shaderList: if not shaderName in foundShaders: shaderNotFoundStr += "%s, " % shaderName if shaderNotFoundStr: sys.stdout.write("Shaders not found for %s\n" % shaderNotFoundStr[:-1]) else: sys.stdout.write("All shaders have been reconnected.\n") # end (do)
def do(nodes=None, replaceWithReference=True, export=True, currentAssetCategory="environments", notify=True): # double check if necessary environment variables exist before continuing print "should we notify? %s" % str(notify) vpe.VP_Environment().test() currentAssetLibrary = ddConstants.ASSET_DIRECTORIES[currentAssetCategory] # Check if assetLibrary folder exists if not os.path.isdir(currentAssetLibrary): confirm = cmds.confirmDialog( title="Warning", messageAlign="center", message="AssetLibrary path does not exist: %s" % currentAssetLibrary, button=["Ok"], defaultButton="Ok", cancelButton="Ok", dismissString="Ok", ) return # Get selection if not nodes: nodes = cmds.ls(selection=True, objectsOnly=True, long=True) if len(nodes) == 0: confirm = cmds.confirmDialog( title="Warning", messageAlign="center", message="Select at least one group object.", button=["Ok"], defaultButton="Ok", cancelButton="Ok", dismissString="Ok", ) return if not isinstance(nodes, list): nodes = [nodes] invalidNodes = list() invalid_textured_nodes = list() override = False resultTopNodes = list() # Clean and export for sel in nodes: sys.stdout.write("\n--> %s\n" % sel.rpartition("|")[2]) currentNode = sel nodeParent = cmds.listRelatives(sel, parent=True, path=True) if cmds.referenceQuery(currentNode, isNodeReferenced=True): currentNode = ddImportFromReference.do(currentNode)[0] invalidNode = ddCheckNames.do(nodes=currentNode, currentAssetCategory=currentAssetCategory) valid_textures = ddCheckTextures.do(node=currentNode)[0] if not invalidNode and valid_textures: publish_details = {} # no need to grab notes from user if not sending email if notify: publish_details["Notes"] = publish_notes.PublishNotes().notes validNode = ddRemoveNamespaces.doRemoveNamespaces(node=currentNode) topGrpLayer = ddRemoveFromLayers.do(nodes=validNode)[0] pos = cmds.xform(validNode, query=True, worldSpace=True, absolute=True, rotatePivot=True) rot = cmds.getAttr("%s.r" % validNode)[0] scl = cmds.getAttr("%s.s" % validNode)[0] ddUnlockGeoTransforms.do(nodes=validNode) returnedNodes = ddRemovePivotOffsets.do( nodes=validNode, returnToPos=False, currentAssetCategory=currentAssetCategory ) if returnedNodes: validNode = returnedNodes[0] ddAddGeoMetadata.do(nodes=validNode) ddLockGeoTransforms.do(nodes=validNode) advancedAssets = cmds.ls(type="container", long=True) if advancedAssets: sys.stdout.write("Deleting advanced assets...\n") cmds.delete(advancedAssets) unknownNodes = cmds.ls(type="unknown", long=True) if unknownNodes: try: sys.stdout.write("Deleting unknown nodes...\n") cmds.delete(unknownNodes) except: cmds.warning("Unable to delete unknown nodes.") if not export: continue if currentAssetLibrary == ddConstants.CHAR_ASSETLIBRARY: exportedNode, exportedPath = exportCharacterAsset(sel) # attempt to collect publish details for character piece charType = {"hero": "hero", "bg": "background", "sec": "secondary"} scene_patt = re.compile("char_(%s)_[A-Z]{3}_[a-z]+" % "|".join(charType.values())) char_patt = re.compile("[A-Z]{3}_[a-zA-Z]+") if scene_patt.search(exportedNode): publish_details["Character"] = char_patt.search(exportedNode).group() publish_details["Template_Category"] = "vad_chesspiece" else: exportedNode, exportedPath, override = exportAsset( node=validNode, override=False, currentAssetCategory=currentAssetCategory ) env_patt = re.compile("[a-z]{3,4}(_[a-z]{3})*(_[a-z]+)*_([a-zA-Z]+[0-9]*[A-Z]v[A-Z])_*") if env_patt.search(exportedNode): publish_details["Enviro_Asset"] = env_patt.search(exportedNode).groups()[-1] publish_details["Template_Category"] = "vad_enviro_asset" if exportedPath: ddScreenBoardGrab.do_boards( nodes=exportedNode.rpartition("|")[2], current_asset_category=currentAssetCategory ) # ddScreenGrab.do(nodes=exportedNode.rpartition("|")[2], currentAssetCategory=currentAssetCategory) else: if currentNode != sel: cmds.delete(currentNode) sys.stdout.write("Export of %s was Canceled..." % exportedNode) return # update publish details with version, file # and file path information version_patt = re.compile("_v([0-9]{2,4})_*") if version_patt.search(exportedNode): publish_details["Version"] = version_patt.search(exportedNode).groups()[0] publish_details["FILEPATH"] = "%s.ma" % exportedPath publish_details["FILE"] = os.path.basename(publish_details["FILEPATH"]) if replaceWithReference and exportedPath: currentSceneFile = cmds.file(query=True, sceneName=True).replace("/", os.sep) exportedFile = "%s.ma" % exportedPath if currentSceneFile == exportedFile: confirm = cmds.confirmDialog( title="Warning", messageAlign="center", message="Scene file is already open. Cannot reference a file into itself.", button=["Ok"], defaultButton="Ok", cancelButton="Ok", dismissString="Ok", ) if confirm == "Ok": continue # Delete original GRP confirm = cmds.confirmDialog( title="Warning", messageAlign="center", message="Delete original GRP?", button=["Ok", "Keep Original"], defaultButton="Ok", cancelButton="Keep Original", dismissString="Keep Original", ) if confirm == "Ok": cmds.delete(exportedNode) else: # Move group back. cmds.xform(exportedNode, worldSpace=True, absolute=True, translation=pos) cmds.setAttr("%s.r" % exportedNode, rot[0], rot[1], rot[2]) cmds.setAttr("%s.s" % exportedNode, scl[0], scl[1], scl[2]) # Reference a copy of the exported file namespace = os.path.split(exportedPath)[1].partition(".")[0] newReferencedNodes = cmds.file( "%s.ma" % exportedPath, reference=True, namespace=namespace, returnNewNodes=True ) referencedTopGrp = "" refTransforms = [x for x in newReferencedNodes if cmds.nodeType(x) == "transform"] for refTransform in refTransforms: refParent = cmds.listRelatives(refTransform, parent=True, fullPath=True) if not refParent or not refParent[0] in refTransforms: referencedTopGrp = refTransform cmds.xform(referencedTopGrp, worldSpace=True, absolute=True, translation=pos) cmds.setAttr("%s.r" % referencedTopGrp, rot[0], rot[1], rot[2]) cmds.setAttr("%s.s" % referencedTopGrp, scl[0], scl[1], scl[2]) if topGrpLayer: cmds.editDisplayLayerMembers(topGrpLayer, referencedTopGrp, noRecurse=True) if nodeParent: referencedTopGrp = cmds.parent(referencedTopGrp, nodeParent[0])[0] resultTopNodes.append(referencedTopGrp.rpartition("|")[2]) else: # Move group back. cmds.xform(exportedNode, worldSpace=True, absolute=True, translation=pos) cmds.setAttr("%s.r" % exportedNode, rot[0], rot[1], rot[2]) cmds.setAttr("%s.s" % exportedNode, scl[0], scl[1], scl[2]) resultTopNodes.append(exportedNode.rpartition("|")[2]) if topGrpLayer: cmds.editDisplayLayerMembers(topGrpLayer, exportedNode, noRecurse=True) if nodeParent: exportedNode = cmds.parent(exportedNode, nodeParent[0])[0] # prep and send publish email publish_details["SHOW"] = os.getenv("SHOW") publish_details["ARTIST"] = os.getenv("ARTIST") if os.getenv("ARTIST") else "Some Artist" # send publish email if user specified notification if notify: sys.stdout.write("Sending email. \n") set_email = pub_mail.PublishEmail(publish_details["Template_Category"]) set_email.publish_details = publish_details set_email.build_email() set_email.send_mail() else: sys.stdout.write("Holding off on sending publish email by request. \n") else: if invalidNode: sys.stdout.write("Invalid name %s. Skipping...\n" % invalidNode[0].rpartition("|")[2]) invalidNodes.append(sel) elif not valid_textures: sys.stdout.write("Invalid texture found on node %s. Skipping...\n" % sel.rpartition("|")[2]) invalid_textured_nodes.append(sel) if invalidNodes: nodeString = "" for invalidNode in invalidNodes: nodeString += "%s, " % invalidNode.rpartition("|")[2] confirm = cmds.confirmDialog( title="Warning", messageAlign="center", message="Please legalize the %s names of the following groups and re-export:\n\n%s" % (currentAssetCategory[:-1], nodeString[:-2]), button=["Ok"], defaultButton="Ok", cancelButton="Ok", dismissString="Ok", ) cmds.select(invalidNodes, replace=True) # report back any nodes found with invalid textures if invalid_textured_nodes: node_string = ", ".join(invalid_textured_nodes) confirm = cmds.confirmDialog( title="Warning", messageAlign="center", message="Please fix the textures of the following groups and re-export:\n\n%s" % (node_string), button=["Ok"], defaultButton="Ok", cancelButton="Ok", dismissString="Ok", ) if invalidNodes: # add to selection of other invalid nodes cmds.select(invalid_textured_nodes, add=True) else: # select only these invalid nodes cmds.select(invalid_textured_nodes, replace=True) if resultTopNodes: try: cmds.select(resultTopNodes, r=1) except: pass
def doImportShaders(arg=None): ''' Button: Import Shader. Imports selected shader from library if does not already exist in file and assigns shader to selected objects. ''' selectedCategory = cmds.textScrollList("shaderCategoriesSL", query=True, selectItem=True) selection = cmds.ls(selection=True, long=True) or [] tempGrp = "tempImportedGrp" if cmds.objExists(tempGrp): cmds.delete(tempGrp) # Get selected swatch. swatch = cmds.textField("currentlySelectedTFD", query=True, text=True) if not swatch: sys.stdout.write("Select a shader\n") return # Get selected category. directory = getCategoryFolder() # Check if selected swatch shader already exists in file. shadingEngine = "%s_SG" % swatch shader = "%s_SHD" % swatch validTexture = False if cmds.objExists(shadingEngine): meshList = [x for x in (cmds.listHistory(shadingEngine) or []) if cmds.nodeType(x) == "mesh"] if meshList: meshTransform = cmds.listRelatives(meshList[0], path=True, parent=True)[0] validTexture = ddCheckTexturePublished.do(nodes=meshTransform, confirm=False, assetCategory=selectedCategory) if cmds.objExists(shadingEngine) and cmds.objExists(shader) and validTexture: if selection: # Apply existing shader to selection. sys.stdout.write('Shader "%s_SG" already exists. Applying to selection... \n' % swatch) for sel in selection: selShape = sel if not (cmds.nodeType(sel) == "mesh"): selShape = cmds.listRelatives(sel, shapes=True, path=True) if selShape: selShape = selShape[0] if selShape: cmds.sets(selShape, forceElement=shadingEngine) else: sys.stdout.write('Shader "%s_SG" already exists. Skipping... \n' % swatch) else: meshList = list() connectedSurfaceShader = None # If shader has been deleted from Hypershade, shading engine and other nodes must also be deleted. if cmds.objExists(shadingEngine): meshList = [x for x in (cmds.listHistory(shadingEngine) or []) if cmds.nodeType(x) == "mesh"] connectedSurfaceShader = cmds.listConnections("%s.surfaceShader" % shadingEngine) cmds.delete(shadingEngine) if cmds.objExists(shader): connectedShadingEngine = cmds.listConnections("%s.outColor" % shader) if connectedShadingEngine: meshList = [x for x in (cmds.listHistory(connectedShadingEngine[0]) or []) if cmds.nodeType(x) == "mesh"] cmds.delete(shader) if connectedSurfaceShader and cmds.objExists(connectedSurfaceShader[0]): cmds.delete(connectedSurfaceShader[0]) deleteNodes = cmds.ls("%s_*DIFF*" % swatch, "%s_*SPEC*" % swatch, "%s_*NRML*" % swatch) try: cmds.delete(deleteNodes) except: pass # Get the path to swatch file. fileName = os.path.join(directory, "%s.ma" % swatch) if os.path.isfile(fileName): # Import swatch file into tempGrp. cmds.file(fileName, i=True, groupReference=True, groupName=tempGrp) if cmds.objExists(tempGrp): # Remove any namespaces from imported nodes. tempGrp = ddRemoveNamespaces.doRemoveNamespaces(tempGrp) # Children consists of one swatch plane. children = cmds.listRelatives(tempGrp, children=True, path=True) if children: # Get the connected shading engine. shadingEngine = getConnectedShadingEngine(children[0]) meshList.extend(selection) if shadingEngine: # Assign shader to selected objects. for sel in meshList: selShape = sel if not (cmds.nodeType(sel) == "mesh"): selShape = cmds.listRelatives(sel, shapes=True, path=True) if selShape: selShape = selShape[0] if selShape: cmds.sets(selShape, forceElement=shadingEngine) else: sys.stdout.write("Swatch shader for %s not found. Skipping...\n" % swatch) # Change the button font to oblique for imported shader. try: cmds.iconTextCheckBox("%sBTN" % swatch, edit=True, font = "obliqueLabelFont") except: pass else: sys.stdout.write("Swatch mesh for %s not found. Skipping...\n" % swatch) cmds.delete(tempGrp) else: sys.stdout.write("Shader did not load properly. \n" % fileName) else: sys.stdout.write("Swatch file %s not found. Skipping... \n" % fileName) # Deselect the shader. deselectAll() # Reselect original selection. if selection: cmds.select(selection, replace=True)