def charcoalContrast(): """ Modifies ShaderFX materials to generate contrast from lightness """ materials = cmds.ls(type="ShaderfxShader") for mat in materials: lib.setAttr(mat, "Shade_Override", 0) lib.setAttr(mat, "Diffuse_Factor", 0.8) lib.printInfo("ShaderFX materials changed for charcoal stylization")
def saveScreenshot(self, name, directory): """ Saves screenshot out to disk Args: name: Name of the screenshot directory: Directory to save into """ # get camera, current position and focus object cameraName = cmds.lookThru(q=True) prevPosition = cmds.getAttr("{0}.translate".format(cameraName)) objName = cmds.ls(sl=True, l=True) if objName: objName = objName[0] else: cmds.error("No object has been selected") # frame camera to object cmds.viewFit() # 'f' on keyboard distance = lib.distanceBetween(cameraName, objName) frameDistance = distance * 0.5 cmds.dolly(cameraName, d=-frameDistance) # take screenshot screenshotDir = mnpr_system.renderFrame(os.path.join(directory, name), 100, 100, 1, ".jpg") # bring camera back to normal lib.setAttr(cameraName, "translate", prevPosition) return screenshotDir
def noiseShift(fx, widget): """ Noise shift, will shift the procedural noise of an effect Args: fx (MNPR_FX): MNPR_FX object coming from the caller widget (RelativeSlider): RelativeSlider object that is calling this function """ # get value to enter valueDiff = widget.relValue() valueDiff /= 100.0 # shift between [-1:1] # get node names sfxNodes = getNodeNames(fx, 0) # shift each material materials = getMaterials() for mat in materials: # turn on procedural noise if turned off stateId = getId(mat, sfxNodes.stateNodeName) if not cmds.shaderfx(sfxnode=mat, getPropertyValue=(stateId, "value")): cmds.shaderfx(sfxnode=mat, edit_bool=(stateId, "value", True)) # set attribute prevValue = cmds.getAttr("{0}.{1}".format(mat, sfxNodes.shiftNodeName)) newValue = prevValue + valueDiff lib.setAttr(mat, sfxNodes.shiftNodeName, newValue)
def loadStyle(self, attrs): if cmds.objExists(mnpr_info.configNode): # set attributes for attr in attrs: splitter = attr.split('.') lib.setAttr(splitter[0], splitter[1], attrs[attr], True) lib.printInfo("Style changed and attributes set successfully")
def createMaterial(objs, name="mnprMat_SFX", prototype="shaderFX", graph="mnpr_uber"): """ Create and assign material to all objs Args: name (str): Name of new material objs (list): List of objects to assign new material into prototype (str): "shaderFX" or "prototypeC" Returns: Material name (str) """ logger.debug("Creating new material for {0}".format(objs)) # get shader file shaderFile = os.path.join(mnpr_info.environment, "shaders", "{0}.sfx".format(graph)) if prototype != "shaderFX": if os.name == 'nt' and mnpr_info.backend == 'dx11': shaderFile = os.path.join(mnpr_info.environment, "shaders", "{0}.fx".format(prototype)) if not os.path.isfile(shaderFile): shaderFile = os.path.join(mnpr_info.environment, "shaders", "{0}.fxo".format(prototype)) else: shaderFile = os.path.join(mnpr_info.environment, "shaders", "{0}.ogsfx".format(prototype)) # check if objects are meshes shapes = lib.getShapes(objs) if not len(shapes): cmds.error( "{0} -> All selected objects need to be meshes".format(objs)) # generate name of material newName = "{0}_{1}".format(name, mnpr_info.abbr) shader = "" if prototype == "shaderFX": shader = cmds.shadingNode('ShaderfxShader', asShader=True, name=name) cmds.shaderfx(sfxnode=shader, loadGraph=shaderFile) else: if os.name == 'nt' and mnpr_info.backend == 'dx11': shader = cmds.shadingNode('dx11Shader', asShader=True, n=newName) else: shader = cmds.shadingNode('GLSLShader', asShader=True, n=newName) # assign shader to selected cmds.select(objs, r=True) cmds.hyperShade(assign=shader) if prototype != "shaderFX": lib.setAttr(shader, "shader", shaderFile) lib.setAttr(shader, "xUseControl", False) return shader
def setMaterialAttrs(mat, matAttrs, options={}): """ Sets material attributes found in matAttrs (e.g., settings, procedural settings, attributes and textures) Args: mat (str): name of material matAttrs (dict): dictionary of material attributes options (dict): dictionary of options to set """ if not options: # coming from update, set all to true options["textures"] = True options["noiseFX"] = True # set settings settings = matAttrs['settings'] for setting in settings: nodeId = cmds.shaderfx(sfxnode=mat, getNodeIDByName=setting) if "value" in cmds.shaderfx(sfxnode=mat, listProperties=nodeId): type = cmds.shaderfx(sfxnode=mat, getPropertyType=(nodeId, "value")) eval( "cmds.shaderfx(sfxnode=mat, edit_{0}=(nodeId, 'value', settings[setting]))" .format(type)) else: cmds.shaderfx(sfxnode=mat, edit_stringlist=(nodeId, "options", int(settings[setting]))) # set procedural settings if options["noiseFX"]: procSettings = matAttrs['procSettings'] for setting in procSettings: try: nodeId = cmds.shaderfx(sfxnode=mat, getNodeIDByName=setting) cmds.shaderfx(sfxnode=mat, edit_bool=(nodeId, "value", procSettings[setting])) except RuntimeError: #traceback.print_exc() print "Setting of {0} procedural node has failed".format( setting) continue # set all attributes if mnpr_system.updateAE(): attributes = matAttrs['attributes'] for attr in attributes: lib.setAttr(mat, attr, attributes[attr], True) # set all textures if options["textures"]: textures = matAttrs['textures'] for texture in textures: lib.setAttr(mat, texture, textures[texture], True)
def renderFrame(saveDir, width, height, renderSize=1, imgFormat=".jpg", override=mnpr_info.prototype): """ Renders current frame in the viewport Args: saveDir (str): save directory width (int): width in pixels height (int): height in pixels renderSize (float): render size (factor) imgFormat (str): .jpg, .exr, etc) override (str): name of desired override (if any) """ check() # check that everything is in order renderSize = resolutionCheck( width, height, renderSize) # make sure resolution is reasonable # get working values to be changed workingRenderSize = cmds.getAttr("{0}.renderScale".format( mnpr_info.configNode)) workingColorDepth = cmds.getAttr("{0}.colorDepth".format( mnpr_info.configNode)) # set desired attributes if workingColorDepth != 2: lib.setAttr(mnpr_info.configNode, "colorDepth", 2) if renderSize != workingRenderSize: lib.setAttr(mnpr_info.configNode, "renderScale", renderSize) # prepare renderer cmds.mnpr(g=True) # enable mnprGamma mnprOperations = len(cmds.mnpr(lsO=True)) cmds.mnpr(renderOperation=mnprOperations - 1, s=0) # HUD cmds.mnpr(renderOperation=mnprOperations - 2, s=0) # UI cmds.refresh() # render frame try: screenshotPath = lib.screenshot(saveDir, width, height, format=imgFormat, override=override) # render the frame except WindowsError: print("Screenshot saving has been canceled") except: traceback.print_exc() if screenshotPath: # bring everything back to normal cmds.mnpr(renderOperation=mnprOperations - 1, s=1) # HUD cmds.mnpr(renderOperation=mnprOperations - 2, s=1) # UI lib.setAttr(mnpr_info.configNode, "renderScale", workingRenderSize) lib.setAttr(mnpr_info.configNode, "colorDepth", workingColorDepth) cmds.mnpr(g=False) cmds.refresh() return screenshotPath
def noiseSlide(fx, widget): """ Noise slide, will modify the procedural noise of an effect Args: fx (MNPR_FX): MNPR_FX object coming from the caller widget (LabeledSlider): LabeledSlider object that is calling this function """ # get index of sliding operation idx = 0 # default scale index if widget.label != "scale": idx = fx.procOptions.index(widget.label) # get node names of operation sfxNodes = getNodeNames(fx, idx) # get value to enter valueDiff = widget.slider.relValue() if widget.label == "scale": valueDiff /= 100.0 else: valueDiff /= 5.0 materials = getMaterials() for mat in materials: # turn on procedural noise if turned off stateId = getId(mat, sfxNodes.stateNodeName) if not cmds.shaderfx(sfxnode=mat, getPropertyValue=(stateId, "value")): lib.printInfo("Recompiling material") cmds.shaderfx(sfxnode=mat, edit_bool=(stateId, "value", True)) # get attribute name attr = "" if widget.label != "scale": attr = sfxNodes.intensityNodeName else: attr = sfxNodes.scaleNodeName # set attribute attribute = "{0}.{1}".format(mat, attr) prevValue = cmds.getAttr(attribute) newValue = prevValue + valueDiff lib.setAttr(mat, attr, newValue)
def noiseWorldScale(widget): """ Modify the world scale value of procedural control Args: widget (LabeledSlider): LabeledSlider object calling the function """ materials = getMaterials() # get value to enter valueDiff = widget.slider.relValue() valueDiff /= 100.0 # scale between [-1:1] # get node names worldScale = "World_Scale_MNPR" for mat in materials: prevValue = cmds.getAttr("{0}.{1}".format(mat, worldScale)) newValue = prevValue + valueDiff lib.setAttr(mat, worldScale, newValue)
def load(self, name): """ Loads the specified attribute set Args: name (str): Name of the attribute set to import """ attrs = self[name]['attributes'] # check if substrate is available substrateAttr = "{0}.substrateTexture".format(mnpr_info.configNode) p = lib.Path(lib.getLibDir()).parent().child("textures") textures = os.listdir(p.path) if attrs[substrateAttr] not in textures: # check if substrates have been installed if len(textures) <= 2: result = cmds.confirmDialog(t="Substrates (papers/canvas) not found", m="The required substrate is not available.\nWould you like to download the MNPR substrates?", b=['Yes', 'Load anyway', 'Close'], icn="warning") if result == "Close": return elif result == "Yes": mnpr_runner.downloadSubstrates() return else: cmds.warning("Substrate texture not found, reverting to default substrate (style might not display correctly)") attrs[substrateAttr] = "rough_default_2k.jpg" else: cmds.warning("Substrate texture not found, reverting to default substrate (style might not display correctly)") attrs[substrateAttr] = "rough_default_2k.jpg" # check change of style first styleAttr = "{0}.style".format(mnpr_info.configNode) if styleAttr in attrs: style = attrs[styleAttr] if style != cmds.mnpr(style=True): lib.setAttr(mnpr_info.configNode, "style", style) func = functools.partial(self.loadStyle, attrs) return cmds.scriptJob(runOnce=True, event=["SelectionChanged", func]) else: # set attributes for attr in attrs: splitter = attr.split('.') lib.setAttr(splitter[0], splitter[1], attrs[attr]) else: # for legacy presets (we do not worry about styles here) for attr in attrs: splitter = attr.split('.') if "NPRConfig" in splitter[0]: splitter[0] = "mnprConfig" lib.setAttr(splitter[0], splitter[1], attrs[attr]) lib.printInfo("Attributes set successfully")
def enableVtxCtrl(shapes): """ Enable vertex color control on shapes Args: shapes (list): List of shapes (str) to enable vertex control to """ # enable ctrl in material selected = cmds.ls(sl=True, l=True) cmds.hyperShade(smn=True) mats = cmds.ls(sl=True, l=True, mat=True) for mat in mats: if cmds.nodeType(mat) == "ShaderfxShader": nodeId = getId(mat, "vtxControls") cmds.shaderfx(sfxnode=mat, edit_bool=(nodeId, "value", True)) else: if cmds.attributeQuery("xUseControl", node=mat, ex=True): lib.setAttr(mat, "xUseControl", True) if cmds.attributeQuery("Color0_Source", node=mat, ex=True): lib.setAttr(mat, "Color0_Source", "color:controlSetA") if cmds.attributeQuery("Color1_Source", node=mat, ex=True): lib.setAttr(mat, "Color1_Source", "color:controlSetB") if cmds.attributeQuery("Color2_Source", node=mat, ex=True): lib.setAttr(mat, "Color2_Source", "color:controlSetC") cmds.select(selected, r=True) # create vtx control sets for shape in shapes: colorSets = cmds.polyColorSet(shape, query=True, allColorSets=True) if not colorSets: colorSets = [] if "controlSetC" not in colorSets: logger.debug("Creating control sets for {0}".format(shape)) # create color sets cmds.polyColorSet(shape, cs='controlSetA', create=True) cmds.polyColorSet(shape, cs='controlSetB', create=True) cmds.polyColorSet(shape, cs='controlSetC', create=True) defaultVertexColors(shape)
def playblast(saveDir, width, height, renderCamera, modelPanel, renderSize=1): """ Playblasts the timeslider Args: saveDir (str): save directory with *.mov extension width (int): width in pixels height: height in pixels renderCamera: camera to playblast from modelPanel: modelPanel to playblast from renderSize: render size (factor) """ check() # check that everything is in order renderSize = resolutionCheck( width, height, renderSize) # make sure resolution is reasonable aPlayBackSliderPython = mel.eval('$tmpVar=$gPlayBackSlider') audioNode = cmds.timeControl(aPlayBackSliderPython, q=True, s=True) # get audio node # get working values to be changed workingRenderSize = cmds.getAttr("{0}.renderScale".format( mnpr_info.configNode)) workingColorDepth = cmds.getAttr("{0}.colorDepth".format( mnpr_info.configNode)) workingCamera = cmds.modelEditor(modelPanel, cam=True, q=True) workingCameraShape = cmds.listRelatives(workingCamera, s=True) if workingCameraShape: workingCameraShape = workingCameraShape[0] else: # we already have the shape workingCameraShape = workingCamera # set desired attributes cmds.mnpr(g=True) mnprOperations = len(cmds.mnpr(lsO=True)) cmds.mnpr(renderOperation=mnprOperations - 1, s=0) # HUD cmds.mnpr(renderOperation=mnprOperations - 2, s=0) # UI cmds.modelEditor(modelPanel, cam=renderCamera, e=True) # change modelPanel lib.setAttr(mnpr_info.configNode, "renderScale", renderSize) lib.setAttr(mnpr_info.configNode, "colorDepth", 2) # needs to be 32bit to avoid artefacts cmds.refresh() # try playblasting try: cmds.playblast(f=saveDir, format="qt", w=width, h=height, percent=100, qlt=100, v=True, fo=True, os=True, s=audioNode, compression="PNG") except RuntimeError: try: cmds.playblast(f=saveDir, format="avi", w=width, h=height, percent=100, qlt=100, v=True, fo=True, os=True, s=audioNode) except RuntimeError: cmds.error( "Video cannot be playblasted as qt or avi, please check the installed codecs." ) # bring everything back to normal cmds.mnpr(renderOperation=mnprOperations - 1, s=1) # HUD cmds.mnpr(renderOperation=mnprOperations - 2, s=1) # UI cmds.modelEditor(modelPanel, cam=workingCameraShape, e=True) lib.setAttr(mnpr_info.configNode, "renderScale", workingRenderSize) lib.setAttr(mnpr_info.configNode, "colorDepth", workingColorDepth) cmds.mnpr(g=False) cmds.refresh() lib.printInfo( "Video has been successfully playblasted to: {0}".format(saveDir))
def dx112sfx(graph="mnpr_uber"): """ Converts dx11 materials to shaderFX materials Args: graph (str): ShaderFX graph name (filename) """ check() dx11Shaders = cmds.ls(type="dx11Shader") prototypeCNodes = [] for dx11Shader in dx11Shaders: shaderPath = cmds.getAttr("{0}.shader".format(dx11Shader)) if "rototypeC" not in shaderPath: continue prototypeCNodes.append(dx11Shader) print("Converting {0} shader".format(dx11Shader)) # get all attributes attributes = cmds.listAttr(dx11Shader, ud=True, st="x*", k=True) print(attributes) # get all connected nodes connectedNodes = cmds.listConnections(dx11Shader, t="file", c=True) print(connectedNodes) # get all shapes cmds.select(dx11Shader, r=True) cmds.hyperShade(objects="") shapes = cmds.ls(sl=True) print(shapes) # create shaderFX shader shader = cmds.shadingNode('ShaderfxShader', asShader=True, name="{0}".format( dx11Shader.replace("_WC", "_SFX"))) cmds.select(shapes, r=True) cmds.hyperShade(assign=shader) shaderFile = os.path.join(mnpr_info.environment, "shaders", "{0}.sfx".format(graph)) cmds.shaderfx(sfxnode=shader, loadGraph=shaderFile) print(">>> Shader {0} created".format(shader)) # assign settings vtxControl = bool( cmds.getAttr("{0}.{1}".format(dx11Shader, "xUseControl"))) if vtxControl: nodeId = cmds.shaderfx(sfxnode=shader, getNodeIDByName="vtxControls") cmds.shaderfx(sfxnode=shader, edit_bool=(nodeId, "value", vtxControl)) shadows = bool( cmds.getAttr("{0}.{1}".format(dx11Shader, "xUseShadows"))) if not shadows: nodeId = cmds.shaderfx(sfxnode=shader, getNodeIDByName="Shadow") cmds.shaderfx(sfxnode=shader, edit_bool=(nodeId, "value", shadows)) specularity = bool( cmds.getAttr("{0}.{1}".format(dx11Shader, "xSpecular"))) if specularity: nodeId = cmds.shaderfx(sfxnode=shader, getNodeIDByName="Specularity") cmds.shaderfx(sfxnode=shader, edit_bool=(nodeId, "value", specularity)) # assign attributes print("Setting attributes for {0}".format(shader)) for attr in attributes: value = cmds.getAttr("{0}.{1}".format(dx11Shader, attr)) if attr in dx2sfxAttr: lib.setAttr(shader, dx2sfxAttr[attr], value) # assign textures if connectedNodes: for i in range(0, len(connectedNodes), 2): textureDir = cmds.getAttr("{0}.{1}".format( connectedNodes[i + 1], "fileTextureName")) attr = connectedNodes[i].split(".")[1] lib.setAttr(shader, dx2sfxAttr[attr], textureDir) # delete prototypeC shaders cmds.delete(prototypeCNodes)
def load(self, name, options): """ Loads the specified attribute set Args: name (str): Name of the attribute set to import """ # get data selection = cmds.ls(sl=True, l=True) mat, xform = getMaterial(selection) if not mat: cmds.error("Nothing was selected") # if not the same material type, create new material matType = cmds.objectType(mat) try: graph = self[name]['graph'] except KeyError: graph = "mnpr_uber" prevGraph = "NA" if self[name]['type'] != matType: mat = createMaterial(xform, graph=graph) else: # shaderFX shader, get current graph name try: nodeId = cmds.shaderfx(sfxnode=mat, getNodeIDByName="graphName") prevGraph = cmds.shaderfx(sfxnode=mat, getPropertyValue=(nodeId, "value")) except RuntimeError: pass # if a new material is desired, create anyways if options["newMaterial"]: mat = createMaterial([xform[0]], graph=graph) elif graph != prevGraph: shaderFile = os.path.join(mnpr_info.environment, "shaders", "{0}.sfx".format(graph)) cmds.shaderfx(sfxnode=mat, loadGraph=shaderFile) # default lighting in case there are no lights defaultLighting() shapes = lib.getShapes(xform) # if colorSets are present, enable control to avoid wrong vertex stylization inputs if cmds.polyColorSet(shapes, query=True, allColorSets=True): mnpr_pFX.enableVtxCtrl(shapes) # disable/enable shadows when proxy geometry is involved if graph == "mnpr_geoproxy": for shape in shapes: lib.setAttr(shape, "castsShadows", False) lib.setAttr(shape, "receiveShadows", False) elif prevGraph == "mnpr_geoproxy": for shape in shapes: lib.setAttr(shape, "castsShadows", True) lib.setAttr(shape, "receiveShadows", True) # set material settings and attributes if matType == 'ShaderfxShader': setMaterialAttrs(mat, self[name], options) else: # set attributes in material print "->{0} will be replaced".format(mat) attrs = self[name]['attributes'] for attr in attrs: lib.setAttr(mat, attr, attrs[attr]) cmds.select(mat, r=True)