def addEnumAttribute(node, longName, defaultValue, enum, niceName=None, shortName=None, keyable=True, readable=True, storable=True, writable=True): if node.hasAttr(longName): mgear.log("Attribute already exists", mgear.error) return data = {} # data["longName"] = longName if shortName is not None: data["shortName"] = shortName if niceName is not None: data["niceName"] = niceName data["attributeType"] = "enum" data["en"] = ":".join(enum) data["keyable"] = keyable data["readable"] = readable data["storable"] = storable data["writable"] = writable node.addAttr(longName, **data) node.setAttr(longName, defaultValue) return node.attr(longName)
def processComponents(self): # Init self.components_infos = {} for guide in self.guides.values(): mgear.log("Init : "+ guide.fullName + " ("+guide.type+")") module_name = "mgear.maya.rig.component."+guide.type module = __import__(module_name, globals(), locals(), ["*"], -1) Component = getattr(module , "Component") component = Component(self, guide) if component.fullName not in self.componentsIndex: self.components[component.fullName] = component self.componentsIndex.append(component.fullName) self.components_infos[component.fullName] = [guide.compType, guide.getVersion(), guide.author] # Creation steps self.steps = MainComponent.steps for i, name in enumerate(self.steps): for count, compName in enumerate(self.componentsIndex): component = self.components[compName] mgear.log(name+" : "+ component.fullName + " ("+component.type+")") component.stepMethods[i]() if self.options["step"] >= 1 and i >= self.options["step"]-1: break
def addAttribute(node, longName, attributeType, defaultValue, niceName=None, shortName=None, minValue=None, maxValue=None, keyable=True, readable=True, storable=True, writable=True): if node.hasAttr(longName): mgear.log("Attribute already exists", mgear.error) return data = {} # data["longName"] = longName if shortName is not None: data["shortName"] = shortName if niceName is not None: data["niceName"] = niceName if attributeType == "string": data["dataType"] = attributeType else: data["attributeType"] = attributeType if minValue is not None: data["minValue"] = minValue if maxValue is not None: data["maxValue"] = maxValue data["keyable"] = keyable data["readable"] = readable data["storable"] = storable data["writable"] = writable node.addAttr(longName, **data) node.setAttr(longName, defaultValue) return node.attr(longName)
def create(parent=None, name="icon", m=dt.Matrix(), color=[0,0,0], icon="cube", **kwargs): if "w" not in kwargs.keys(): kwargs["w"] = 1 if "h" not in kwargs.keys(): kwargs["h"] = 1 if "d" not in kwargs.keys(): kwargs["d"] = 1 if "po" not in kwargs.keys(): kwargs["po"] = None if "ro" not in kwargs.keys(): kwargs["ro"] = None if icon == "cube": ctl = cube(parent, name, kwargs["w"], kwargs["h"], kwargs["d"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "pyramid": ctl = pyramid(parent, name, kwargs["w"], kwargs["h"], kwargs["d"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "square": ctl = square(parent, name, kwargs["w"], kwargs["d"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "flower": ctl = flower(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "circle": ctl = circle(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "cylinder": ctl = cylinder(parent, name, kwargs["w"], kwargs["h"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "compas": ctl = compas(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "diamond": ctl = diamond(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "cubewithpeak": ctl = cubewithpeak(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "sphere": ctl = sphere(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "arrow": ctl = arrow(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "crossarrow": ctl = crossarrow(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "cross": ctl = cross(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "null": ctl = null(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) else: mgear.log("invalid type of ico", mgear.sev_error) return return ctl
def setFromSelection(self): selection = ls(selection=True) if not selection: mgear.log("Select one or more guide root or a guide model", mgear.sev_error) self.valid = False return False for node in selection: self.setFromHierarchy(node, node.hasAttr("ismodel")) return True
def keyObj(model, object_names): nodes = [] for name in object_names: node = dag.findChild(model, name) if not node: mgear.log("Can't find object : %s.%s"%(model.name(), name), mgear.sev_error) nodes.append(node) if not nodes: return setKeyframe(*nodes)
def build(self): self.options = self.guide.values self.guides = self.guide.components mgear.log("= GEAR RIG SYSTEM ==============================================") self.initialHierarchy() self.processComponents() self.finalize() mgear.log("= GEAR BUILD RIG DONE ================ [ " + "Not Yet Implemented" + " ] ======") return self.model
def setParamDefValuesFromProperty(self, node): for scriptName, paramDef in self.paramDefs.items(): if not attributeQuery(scriptName, node=node, exists=True): mgear.log("Can't find parameter '%s' in %s"%(scriptName, node), mgear.sev_warning) self.valid = False else: cnx = listConnections(node+"."+scriptName, destination=False, source=True) if cnx: paramDef.value = None self.values[scriptName] = cnx[0] else: paramDef.value = getAttr(node+"."+scriptName) self.values[scriptName] = getAttr(node+"."+scriptName)
def getComponentGuide(self, comp_type): # Check component type path = os.path.join(COMPONENT_PATH, comp_type, "guide.py") if not os.path.exists(path): mgear.log("Can't find guide definition for : " + comp_type + ".\n"+ path, mgear.sev_error) return False # Import module and get class module_name = "mgear.maya.rig.component."+comp_type+".guide" module = __import__(module_name, globals(), locals(), ["*"], -1) ComponentGuide = getattr(module , "Guide") return ComponentGuide()
def setRotOrder(node, s="XYZ"): a = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] if s not in a: mgear.log("Invalid Rotorder : "+s, mgear.siError) return False # Unless Softimage there is no event on the rotorder parameter to automatically adapt the angle values # So let's do it manually using the EulerRotation class er = dt.EulerRotation([getAttr(node+".rx"),getAttr(node+".ry"),getAttr(node+".rz")], unit="degrees") er.reorderIt(s) node.setAttr("ro", a.index(s)) node.setAttr("rotate", er.x, er.y, er.z)
def findComponentRecursive(self, node, branch=True): if node.hasAttr("comp_type"): comp_type = node.getAttr("comp_type") comp_guide = self.getComponentGuide(comp_type) if comp_guide: comp_guide.setFromHierarchy(node) mgear.log(comp_guide.fullName+" ("+comp_type+")") if not comp_guide.valid: self.valid = False self.componentsIndex.append(comp_guide.fullName) self.components[comp_guide.fullName] = comp_guide if branch: for child in node.getChildren(): self.findComponentRecursive(child)
def getModel(widget): syn_widget = getSynopticWidget(widget, max_iter=20) model_name = syn_widget.model_list.currentText() if not pm.ls(model_name): return None try: model = pm.PyNode(model_name) except pm.general.MayaNodeError: mes = traceback.format_exc() mes = "Can't find model {0} for widget: {1}\n{2}".format( model_name, widget, mes) mgear.log(mes, mgear.sev_error) return None return model
def initialHierarchy(self): mgear.log("Initial Hierarchy") # -------------------------------------------------- # Model self.model = pri.addTransformFromPos(None, self.options["rig_name"]) att.lockAttribute(self.model) # -------------------------------------------------- # Global Ctl self.global_ctl = self.addCtl(self.model, "global_C0_ctl", dt.Matrix(), self.options["C_color_fk"], "crossarrow", w=10) # -------------------------------------------------- # INFOS self.isRig_att = att.addAttribute(self.model, "is_rig", "bool", True) self.rigName_att = att.addAttribute(self.model, "rig_name", "string", self.options["rig_name"]) self.user_att = att.addAttribute(self.model, "user", "string", getpass.getuser()) self.isWip_att = att.addAttribute(self.model, "wip", "bool", self.options["mode"] != 0) self.date_att = att.addAttribute(self.model, "date", "string", str(datetime.datetime.now())) self.mayaVersion_att = att.addAttribute(self.model, "maya_version", "string", str(mel.eval("getApplicationVersionAsFloat"))) self.gearVersion_att = att.addAttribute(self.model, "gear_version", "string", mgear.getVersion()) self.synoptic_att = att.addAttribute(self.model, "synoptic", "string", str(self.options["synoptic"])) self.comments_att = att.addAttribute(self.model, "comments", "string", str(self.options["comments"])) self.ctlVis_att = att.addAttribute(self.model, "ctl_vis", "bool", True) self.shdVis_att = att.addAttribute(self.model, "shd_vis", "bool", False) self.qsA_att = att.addAttribute(self.model, "quickselA", "string", "") self.qsB_att = att.addAttribute(self.model, "quickselB", "string", "") self.qsC_att = att.addAttribute(self.model, "quickselC", "string", "") self.qsD_att = att.addAttribute(self.model, "quickselD", "string", "") self.qsE_att = att.addAttribute(self.model, "quickselE", "string", "") self.qsF_att = att.addAttribute(self.model, "quickselF", "string", "") # -------------------------------------------------- # UI SETUP AND ANIM self.oglLevel_att = att.addAttribute(self.model, "ogl_level", "long", 0, None, None, 0, 3) # -------------------------------------------------- # Basic set of null if self.options["shadow_rig"]: self.shd_org = pri.addTransformFromPos(self.model, "shd_org") connectAttr(self.shdVis_att, self.shd_org.attr("visibility"))
def symmetrize(self): """ Inverse the transform of each element of the guide. """ if self.values["comp_side"] not in ["R", "L"]: mgear.log("Can't symmetrize central component", mgear.sev_error) return False for name, paramDef in self.paramDefs.items(): if paramDef.valueType == "string": self.setParamDefValue( name, mgear.string.convertRLName(self.values[name])) for name, t in self.tra.items(): self.tra[name] = tra.getSymmetricalTransform(t) for name, blade in self.blades.items(): self.blades[name] = vec.Blade( tra.getSymmetricalTransform(blade.transform)) return True
def addLocMulti(self, name, parent, updateParent=True): """Add multiple loc objects to the guide. This method can initialize the object or draw it. Loc object is a simple null to define a position or a tranformation in the guide. Args: name (str): Local name of the element. parent (dagNode): The parent of the element. minimum (int): The minimum number of loc. maximum (int): The maximum number of loc. updateParent (bool): if True update the parent reference. False, keep the same for all loc. Returns: list of dagNode: The created loc objects in a list. """ if "#" not in name: mgear.log( "You need to put a '#' in the name of multiple location.", mgear.sev_error) return False locs = [] i = 0 while True: localName = string.replaceSharpWithPadding(name, i) if localName not in self.tra.keys(): break loc = icon.guideLocatorIcon(parent, self.getName(localName), color=17, m=self.tra[localName]) locs.append(loc) if updateParent: parent = loc i += 1 return locs
def setRotOrder(node, s="XYZ"): a = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] if s not in a: mgear.log("Invalid Rotorder : " + s, mgear.siError) return False # Unless Softimage there is no event on the rotorder parameter to automatically adapt the angle values # So let's do it manually using the EulerRotation class er = dt.EulerRotation( [getAttr(node + ".rx"), getAttr(node + ".ry"), getAttr(node + ".rz")], unit="degrees") er.reorderIt(s) node.setAttr("ro", a.index(s)) node.setAttr("rotate", er.x, er.y, er.z)
def applyMirror(nameSpace, mirrorEntry): """Apply mirro pose Args: nameSpace (str): Namespace mirrorEntry (list): List witht the mirror entry template """ node = mirrorEntry["target"] attr = mirrorEntry["attr"] val = mirrorEntry["val"] try: if (pm.attributeQuery(attr, node=node, shortName=True, exists=True) and not node.attr(attr).isLocked()): node.attr(attr).set(val) except RuntimeError as e: mgear.log( "applyMirror failed: {0} {1}: {2}".format(node.name(), attr, e), mgear.sev_error)
def getModuleBasePath(directories, moduleName): """search component path""" if PY2: dic_items = directories.iteritems else: dic_items = directories.items for basepath, modules in dic_items(): if moduleName in modules: # moduleBasePath = os.path.basename(basepath) moduleBasePath = basepath break else: moduleBasePath = "" message = "= GEAR RIG SYSTEM ======" message += "component base directory not found " \ " for {}".format(moduleName) mgear.log(message, mgear.sev_error) return moduleBasePath
def buildFromSelection(self): """Build the rig from selected guides.""" startTime = datetime.datetime.now() mgear.log("\n" + "= SHIFTER RIG SYSTEM " + "=" * 46) self.stopBuild = False selection = pm.ls(selection=True) if not selection: mgear.log("Select one or more guide root or a guide model", mgear.sev_error) return # check if is partial build or full guide build ismodel = False if selection[0].hasAttr("ismodel"): self.preCustomStep(selection) ismodel = True if not self.stopBuild: mgear.log("\n" + "= GUIDE VALIDATION " + "=" * 46) # Check guide is valid self.guide.setFromSelection() if not self.guide.valid: return # Build mgear.log("\n" + "= BUILDING RIG " + "=" * 46) self.build() if ismodel: self.postCustomStep() endTime = datetime.datetime.now() finalTime = endTime - startTime pm.flushUndo() pm.displayInfo("Undo history have been flushed to avoid " "possible crash after rig is build. \n" "More info: " "https://github.com/miquelcampos/mgear/issues/72") mgear.log("\n" + "= SHIFTER BUILD RIG DONE {} [ {} ] {}".format( "=" * 16, finalTime, "=" * 7))
def drawFromUI(self, parent, showUI=True): """Draw the guide in the scene from the UI command. Args: parent (dagNode): the parent of the component. """ if not self.modalPositions(): mgear.log("aborded", mgear.sev_warning) return False self.draw(parent) transform.resetTransform(self.root, r=False, s=False) # reset size self.root.scale.set(1, 1, 1) if showUI: guide_manager.inspect_settings() return True
def processComponents(self): """ Process the components of the rig, following the creation steps. """ # Init self.components_infos = {} for comp in self.guide.componentsIndex: guide_ = self.guides[comp] mgear.log("Init : " + guide_.fullName + " (" + guide_.type + ")") module = importComponent(guide_.type) Component = getattr(module, "Component") comp = Component(self, guide_) if comp.fullName not in self.componentsIndex: self.components[comp.fullName] = comp self.componentsIndex.append(comp.fullName) self.components_infos[comp.fullName] = [ guide_.compType, guide_.getVersion(), guide_.author, ] # Creation steps self.steps = component.Main.steps for i, name in enumerate(self.steps): # for count, compName in enumerate(self.componentsIndex): for compName in self.componentsIndex: comp = self.components[compName] mgear.log( name + " : " + comp.fullName + " (" + comp.type + ")" ) comp.stepMethods[i]() if self.options["step"] >= 1 and i >= self.options["step"] - 1: break
def buildFromSelection(self): """ Build the rig from selected guides. """ startTime = datetime.datetime.now() mgear.log("= GEAR RIG SYSTEM ==============================================") # Get the option first otherwise the change wight might do won't be taken sel = pm.ls(selection=True) # Check guide is valid self.guide.setFromSelection() if not self.guide.valid: return # Build self.build() endTime = datetime.datetime.now() finalTime = endTime - startTime mgear.log("= GEAR BUILD RIG DONE ================ [ " + str(finalTime) + " ] ======")
def __selectChanged(self, *args): sels = [] [sels.append(x.name()) for x in pm.ls(sl=True)] oModel = utils.getModel(self) if not oModel: mes = "model not found for synoptic {}".format(self.name) mgear.log(mes, mgear.sev_info) # self.close() syn_widget = utils.getSynopticWidget(self) syn_widget.updateModelList() return nameSpace = utils.getNamespace(oModel.name()) selButtons = self.findChildren(widgets.SelectButton) selButtonsStyled = self.findChildren(widgets.SelectButtonStyleSheet) buttons = [] buttons.extend(selButtons) buttons.extend(selButtonsStyled) for selB in buttons: obj = str(selB.property("object")).split(",") if len(obj) == 1: if nameSpace: checkName = ":".join([nameSpace, obj[0]]) else: checkName = obj[0] if checkName in sels: selB.paintSelected(True) else: selB.paintSelected(False)
def finalize(self): # Properties -------------------------------------- mgear.log("Finalize") # Groups ------------------------------------------ mgear.log("Creating groups") # Retrieve group content from components for name in self.componentsIndex: component = self.components[name] for name, objects in component.groups.items(): self.addToGroup(objects, name) # Creating all groups select(cl=True) for name, objects in self.groups.items(): s = sets(n=self.model.name()+"_"+name+"_grp") s.union( objects ) # Bind pose --------------------------------------- print self.groups["controlers"] select(self.groups["controlers"]) node = dagPose(save=True, selection=True) print node
def applyMirror(nameSpace, mirrorEntry): """Apply mirro pose Args: nameSpace (str): Namespace mirrorEntry (list): List witht the mirror entry template """ node = mirrorEntry.target attr = mirrorEntry.attr val = mirrorEntry.val try: if (pm.attributeQuery( attr, node=node, shortName=True, exists=True, keyable=True) and not node.attr(attr).isLocked()): if isinstance(val, str) or isinstance(val, unicode): return node.attr(attr).set(val) except RuntimeError: mgear.log( "applyMirror failed: {0} {1}: {2}".format(node.name(), attr, val), mgear.sev_error)
def setInvertMirror(node, invList=None): """Set invert mirror pose values Arguments: node (dagNode): The object to set invert mirror Values """ aDic = {"tx": "invTx", "ty": "invTy", "tz": "invTz", "rx": "invRx", "ry": "invRy", "rz": "invRz", "sx": "invSx", "sy": "invSy", "sz": "invSz"} for axis in invList: if axis not in aDic: mgear.log("Invalid Invert Axis : " + axis, mgear.siError) return False node.setAttr(aDic[axis], True)
def selectObj(model, object_names, mouse_button, key_modifier): if mouse_button == Qt.RightButton: return nodes = [] for name in object_names: node = dag.findChild(model, name) if not node: mgear.log("Can't find object : %s.%s"%(model.name(), name), mgear.sev_error) nodes.append(node) if not nodes: return # Key pressed if key_modifier is None: select(nodes) elif key_modifier == Qt.NoModifier:# No Key select(nodes) elif key_modifier == Qt.ControlModifier: # ctrl select(nodes, add=True) elif key_modifier == Qt.ShiftModifier: # shift select(nodes, toggle=True) elif int(key_modifier) == Qt.ControlModifier + Qt.ShiftModifier: # ctrl + shift select(nodes, deselect=True) elif key_modifier == Qt.AltModifier: # alt select(nodes) elif int(key_modifier) == Qt.ControlModifier + Qt.AltModifier: # ctrl + alt select(nodes, add=True) elif int(key_modifier) == Qt.ShiftModifier + Qt.AltModifier: # shift + alt select(nodes, toggle=True) elif int(key_modifier) == Qt.ControlModifier + Qt.AltModifier + Qt.ShiftModifier: # Ctrl + alt + shift select(nodes, deselect=True) else: select(nodes)
def extractControls(self, *args): oSel = pm.selected() try: cGrp = pm.PyNode("controllers_org") except: cGrp = False mgear.log("Not controller group in the scene or the group is not unique", mgear.sev_error ) for x in oSel: try: old = pm.PyNode(cGrp.name() + "|" + x.name().split("|")[-1]) pm.delete(old) except: pass new = pm.duplicate(x)[0] pm.parent(new, cGrp, a=True) pm.rename(new, x.name()) toDel = new.getChildren(type="transform") pm.delete(toDel) try: pm.sets( "rig_controllers_grp", remove=new ) except: pass
def finalize(self): # Properties -------------------------------------- mgear.log("Finalize") # Groups ------------------------------------------ mgear.log("Creating groups") # Retrieve group content from components for name in self.componentsIndex: component = self.components[name] for name, objects in component.groups.items(): self.addToGroup(objects, name) # Creating all groups select(cl=True) for name, objects in self.groups.items(): s = sets(n=self.model.name() + "_" + name + "_grp") s.union(objects) # Bind pose --------------------------------------- print self.groups["controlers"] select(self.groups["controlers"]) node = dagPose(save=True, selection=True) print node
def buildFromDict(self, conf_dict): log_window() startTime = datetime.datetime.now() mgear.log("\n" + "= SHIFTER RIG SYSTEM " + "=" * 46) self.stopBuild = False self.guide.set_from_dict(conf_dict) endTime = datetime.datetime.now() finalTime = endTime - startTime mgear.log( "\n" + "= SHIFTER FILE READ {} [ {} ] {}".format( "=" * 16, finalTime, "=" * 7 ) ) # Build mgear.log("\n" + "= BUILDING RIG " + "=" * 46) self.from_dict_custom_step(conf_dict, pre=True) self.build() self.from_dict_custom_step(conf_dict, pre=False) # Collect post-build data build_data = self.collect_build_data() endTime = datetime.datetime.now() finalTime = endTime - startTime pm.flushUndo() pm.displayInfo( "Undo history have been flushed to avoid " "possible crash after rig is build. \n" "More info: " "https://github.com/miquelcampos/mgear/issues/72" ) mgear.log( "\n" + "= SHIFTER BUILD RIG DONE {} [ {} ] {}".format( "=" * 16, finalTime, "=" * 7 ) ) return build_data
def setFromHierarchy(self, root): """Set the component guide from given hierarchy. Args: root (dagNode): The root of the hierarchy to parse. """ self.root = root self.model = self.root.getParent(generations=-1) # --------------------------------------------------- # First check and set the settings if not self.root.hasAttr("comp_type"): mgear.log("%s is not a proper guide." % self.root.longName(), mgear.sev_error) self.valid = False return self.setParamDefValuesFromProperty(self.root) # --------------------------------------------------- # Then get the objects for name in self.save_transform: if "#" in name: i = 0 while not self.minmax[name].max > 0 or i < \ self.minmax[name].max: localName = string.replaceSharpWithPadding(name, i) node = dag.findChild(self.model, self.getName(localName)) if not node: break self.tra[localName] = node.getMatrix(worldSpace=True) self.atra.append(node.getMatrix(worldSpace=True)) self.pos[localName] = node.getTranslation(space="world") self.apos.append(node.getTranslation(space="world")) i += 1 if i < self.minmax[name].min: mgear.log( "Minimum of object requiered for " + name + " hasn't been reached!!", mgear.sev_warning) self.valid = False continue else: node = dag.findChild(self.model, self.getName(name)) if not node: mgear.log("Object missing : %s" % (self.getName(name)), mgear.sev_warning) self.valid = False continue self.tra[name] = node.getMatrix(worldSpace=True) self.atra.append(node.getMatrix(worldSpace=True)) self.pos[name] = node.getTranslation(space="world") self.apos.append(node.getTranslation(space="world")) for name in self.save_blade: node = dag.findChild(self.model, self.getName(name)) if not node: mgear.log("Object missing : %s" % (self.getName(name)), mgear.sev_warning) self.valid = False continue self.blades[name] = vector.Blade(node.getMatrix(worldSpace=True)) self.size = self.getSize()
def slice(parent=False, oSel=False, *args): """ Create a proxy geometry from a skinned object. """ startTime = datetime.datetime.now() print oSel if not oSel: oSel = pm.selected()[0] print "----" print oSel oColl = pm.skinCluster(oSel, query=True, influence=True) oFaces = oSel.faces nFaces = oSel.numFaces() faceGroups = [] for x in oColl: faceGroups.append([]) sCluster = pm.listConnections(oSel.getShape(), type="skinCluster") print sCluster sCName = sCluster[0].name() for iFace in range(nFaces): faceVtx = oFaces[iFace].getVertices() oSum = False for iVtx in faceVtx: values = pm.skinPercent(sCName, oSel.vtx[iVtx], q=True, v=True) if oSum: oSum = [L + l for L, l in zip(oSum, values)] else: oSum = values print "adding face: " + str(iFace) + " to group in: " + str( oColl[oSum.index(max(oSum))]) faceGroups[oSum.index(max(oSum))].append(iFace) original = oSel if not parent: try: parentGroup = pm.PyNode("ProxyGeo") except: parentGroup = pm.createNode("transform", n="ProxyGeo") try: proxySet = pm.PyNode("rig_proxyGeo_grp") except: proxySet = pm.sets(name="rig_proxyGeo_grp", em=True) for boneList in faceGroups: if len(boneList): newObj = pm.duplicate(original, rr=True, name=oColl[faceGroups.index(boneList)] + "_Proxy") for trans in [ "tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz" ]: pm.setAttr(newObj[0].name() + "." + trans, lock=0) c = list(newObj[0].faces) for index in reversed(boneList): c.pop(index) pm.delete(c) if parent: pm.parent(newObj, pm.PyNode(oColl[faceGroups.index(boneList)]), a=True) else: pm.parent(newObj, parentGroup, a=True) dummyCopy = pm.duplicate(newObj[0])[0] pm.delete(newObj[0].listRelatives(c=True)) tra.matchWorldTransform( pm.PyNode(oColl[faceGroups.index(boneList)]), newObj[0]) pm.parent(dummyCopy.listRelatives(c=True)[0], newObj[0], shape=True) pm.delete(dummyCopy) pm.rename(newObj[0].listRelatives(c=True)[0], newObj[0].name() + "_offset") mulmat_node = aop.gear_mulmatrix_op( pm.PyNode(oColl[faceGroups.index(boneList)]).name() + ".worldMatrix", newObj[0].name() + ".parentInverseMatrix") dm_node = nod.createDecomposeMatrixNode(mulmat_node + ".output") pm.connectAttr(dm_node + ".outputTranslate", newObj[0].name() + ".t") pm.connectAttr(dm_node + ".outputRotate", newObj[0].name() + ".r") pm.connectAttr(dm_node + ".outputScale", newObj[0].name() + ".s") print "Creating proxy for: " + str( oColl[faceGroups.index(boneList)]) pm.sets(proxySet, add=newObj) endTime = datetime.datetime.now() finalTime = endTime - startTime mgear.log("=============== Slicing for: %s finish ======= [ %s ] ======" % (oSel.name(), str(finalTime)))
def addColorAttribute(node, longName, value=False, keyable=True, readable=True, storable=True, writable=True, niceName=None, shortName=None): """ Add a color attribute to a node Arguments: node (dagNode): The object to add the new attribute. longName (str): The attribute name. value (list of flotat): The default value in a list for RGB. exp [1.0, 0.99, 0.13]. keyable (bool): Set if the attribute is keyable or not. (optional) readable (bool): Set if the attribute is readable or not. (optional) storable (bool): Set if the attribute is storable or not. (optional) writable (bool): Set if the attribute is writable or not. (optional) niceName (str): The attribute nice name. (optional) shortName (str): The attribute short name. (optional) Returns: str: The long name of the new attribute """ if node.hasAttr(longName): mgear.log("Attribute already exists", mgear.error) return data = {} data["attributeType"] = "float3" if shortName is not None: data["shortName"] = shortName if niceName is not None: data["niceName"] = niceName data["usedAsColor"] = True data["keyable"] = keyable data["readable"] = readable data["storable"] = storable data["writable"] = writable # child nested attr dataChild = {} dataChild["attributeType"] = 'float' dataChild["parent"] = longName node.addAttr(longName, **data) node.addAttr(longName + "_r", **dataChild) node.addAttr(longName + "_g", **dataChild) node.addAttr(longName + "_b", **dataChild) if value: node.setAttr(longName + "_r", value[0]) node.setAttr(longName + "_g", value[1]) node.setAttr(longName + "_b", value[2]) return node.attr(longName)
def create(parent=None, name="icon", m=datatypes.Matrix(), color=[0, 0, 0], icon="cube", **kwargs): """Icon master function **Create icon master function.** This function centralize all the icons creation Arguments: parent (dagNode): The parent for the new icon name (str): Name of the Icon. m (matrix): Transformation matrix of the icon color (int or list of float): The color in index base or RGB. icon (str): Icon type. Options: "cube", "pyramid", "square", "flower", "circle", "cylinder", "compas", "diamond", "cubewithpeak", "sphere", "arrow", "crossarrow", "cross", "null" kwargs: The keyword arguments can vary depending of the icon type. Please refear to the specific icon method for more info. Returns: dagNode: The newly created icon. """ if "w" not in kwargs.keys(): kwargs["w"] = 1 if "h" not in kwargs.keys(): kwargs["h"] = 1 if "d" not in kwargs.keys(): kwargs["d"] = 1 if "po" not in kwargs.keys(): kwargs["po"] = None if "ro" not in kwargs.keys(): kwargs["ro"] = None if "degree" not in kwargs.keys(): kwargs["degree"] = 3 if icon == "cube": ctl = cube(parent, name, kwargs["w"], kwargs["h"], kwargs["d"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "pyramid": ctl = pyramid(parent, name, kwargs["w"], kwargs["h"], kwargs["d"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "square": ctl = square(parent, name, kwargs["w"], kwargs["d"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "flower": ctl = flower(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"], kwargs["degree"]) elif icon == "circle": ctl = circle(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"], kwargs["degree"]) elif icon == "cylinder": ctl = cylinder(parent, name, kwargs["w"], kwargs["h"], color, m, kwargs["po"], kwargs["ro"], kwargs["degree"]) elif icon == "compas": ctl = compas(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"], kwargs["degree"]) elif icon == "diamond": ctl = diamond(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "cubewithpeak": ctl = cubewithpeak(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "sphere": ctl = sphere(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"], kwargs["degree"]) elif icon == "arrow": ctl = arrow(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "crossarrow": ctl = crossarrow(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "cross": ctl = cross(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) elif icon == "null": ctl = null(parent, name, kwargs["w"], color, m, kwargs["po"], kwargs["ro"]) else: mgear.log("invalid type of ico", mgear.sev_error) return return ctl
def connect_with_exprespy(self): if not cmds.pluginInfo("exprespy", q=True, loaded=True): cmds.loadPlugin("exprespy.mll", quiet=True) mgear.log("load plugin exprespy.mll") exprespy_template = textwrap.dedent(""" import maya.api.OpenMaya as om neck_ref = {self.neckref_att} # 0: self, 1: head head_ref = {self.headref_att} # 0: self, (1: body, 2: local etc...) neck_base_pos = {self.neck_cns}.translate # FIXME: CONSTANT head_ref_pos = {self.head_pos_ref}.translate # FIXME: CONSTANT res_head_rot = om.MEulerRotation() res_neck_rot = om.MEulerRotation() res_head_pos = head_ref_pos if head_ref == 0: res_head_rot.setValue({self.neck_ctl}.rotate, {self.neck_ctl}.rotateOrder) m = api.MMatrix() """.format(**locals())) exprespy_head_ref_switch_template = textwrap.dedent(""" elif head_ref == {i}: # {ref_name} m = {mat_formula} res_head_rot = api.MTransformationMatrix(m).rotation(False) """) exprespy_head_result_assignment_template = textwrap.dedent(""" if neck_ref == 0: tmp = om.MTransformationMatrix() tmp.setTranslation(neck_base_pos, om.MSpace.kObject) tmp2 = om.MTransformationMatrix(tmp.asMatrixInverse() * {self.neck_npo}.inverseMatrix * {self.neck_ctl}.inverseMatrix * {self.head_pos_ref}.inverseMatrix ) res_head_pos = tmp2.translation(om.MSpace.kObject) * -1. else: neck_quat = api.MTransformationMatrix({self.head_ctl}.matrix * m).rotation(True) identity = api.MQuaternion() res_neck_rot = api.MQuaternion.slerp(identity, neck_quat, {self.neckrate_att}).asEulerRotation() tmp = om.MTransformationMatrix() tmp.setTranslation(neck_base_pos, om.MSpace.kObject) tmp.setRotation(res_neck_rot) tmp2 = om.MTransformationMatrix(tmp.asMatrixInverse() * {self.neck_npo}.inverseMatrix * {self.neck_ctl}.inverseMatrix * {self.head_pos_ref}.inverseMatrix ) res_head_pos = tmp2.translation(om.MSpace.kObject) * -1. res_head_rot.reorderIt({self.head_cns}.rotateOrder) {self.neck_cns}.rotate = res_neck_rot {self.head_cns}.translate = res_head_pos {self.head_cns}.rotate = res_head_rot """) exprespy_code = exprespy_template if self.settings["headrefarray"]: ref_names = self.settings["headrefarray"].split(",") for i, ref_name in enumerate(ref_names): src = self.rig.findRelative(ref_name) down, _, up = findPathAtoB(src, self.root) down_mat = " * ".join( ["{}.matrix".format(x.name()) for x in down]) up_mat = " * ".join( ["{}.inverseMatrix".format(x.name()) for x in up]) if down: mat = "{} * {}".format(down_mat, up_mat) else: mat = "{}".format(up_mat) interpoleted = exprespy_head_ref_switch_template.format( **{ "i": i + 1, "ref_name": ref_name, "mat_formula": mat, }) exprespy_code += interpoleted exprespy_code += exprespy_head_result_assignment_template.format( **locals()) exprespy_node = om2.MFnDependencyNode() name = self.getName("exprespy_node") exprespy_node = exprespy_node.create(EXPRESPY_NODE_ID, name) exprespy_node = om2.MFnDependencyNode(exprespy_node) self.exprespy_node_name = exprespy_node.name() cmds.setAttr("{}.code".format(self.exprespy_node_name), exprespy_code, type="string") import exprespy.cmd exprespy.cmd.setCode(self.exprespy_node_name, exprespy_code, raw=False)
def addAttribute(node, longName, attributeType, value=None, niceName=None, shortName=None, minValue=None, maxValue=None, keyable=True, readable=True, storable=True, writable=True, channelBox=False): """Add attribute to a node Arguments: node (dagNode): The object to add the new attribute. longName (str): The attribute name. attributeType (str): The Attribute Type. Exp: 'string', 'bool', 'long', etc.. value (float or int): The default value. niceName (str): The attribute nice name. (optional) shortName (str): The attribute short name. (optional) minValue (float or int): minimum value. (optional) maxValue (float or int): maximum value. (optional) keyable (bool): Set if the attribute is keyable or not. (optional) readable (bool): Set if the attribute is readable or not. (optional) storable (bool): Set if the attribute is storable or not. (optional) writable (bool): Set if the attribute is writable or not. (optional) channelBox (bool): Set if the attribute is in the channelBox or not, when the attribute is not keyable. (optional) Returns: str: The long name of the new attribute """ if node.hasAttr(longName): mgear.log("Attribute already exists", mgear.error) return data = {} if shortName is not None: data["shortName"] = shortName if niceName is not None: data["niceName"] = niceName if attributeType == "string": data["dataType"] = attributeType else: data["attributeType"] = attributeType if minValue is not None and minValue is not False: data["minValue"] = minValue if maxValue is not None and maxValue is not False: data["maxValue"] = maxValue data["keyable"] = keyable data["readable"] = readable data["storable"] = storable data["writable"] = writable if value is not None and attributeType not in ["string"]: data["defaultValue"] = value node.addAttr(longName, **data) if value is not None: node.setAttr(longName, value) if channelBox: node.attr(longName).set(channelBox=True) return node.attr(longName)
def getRelation(self, name): if name not in self.relatives.keys(): mgear.log("Can't find reference for object : " + self.fullName + "." + name, mgear.sev_error) return False return self.relatives[name]
def setFromHierarchy(self, root, branch=True): # Start mgear.log("Checking guide") # Get the model and the root self.model = root.getParent(generations=-1) while True: if root.hasAttr("comp_type") or self.model == root: break root = root.getParent() # --------------------------------------------------- # First check and set the options mgear.log("Get options") if not root.hasAttr("rig_name"): mgear.log("%s is not a proper rig guide."%self.model, mgear.sev_error) self.valid = False return self.setParamDefValuesFromProperty(self.model) # --------------------------------------------------- # Get the controlers mgear.log("Get controlers") self.controlers_org = dag.findChild(self.model, "controlers_org") if self.controlers_org: for child in self.controlers_org.getChildren(): self.controlers[child.name().split("|")[-1]] = child # --------------------------------------------------- # Components mgear.log("Get components") self.findComponentRecursive(root, branch) # Parenting if self.valid: mgear.log("Get parenting") for name in self.componentsIndex: compChild = self.components[name] compChild_parent = compChild.root.getParent() for name in self.componentsIndex: compParent = self.components[name] for localName, element in compParent.getObjects(self.model).items(): if element is not None and element == compChild_parent: compChild.parentComponent = compParent compChild.parentLocalName = localName break # More option values self.addOptionsValues() # End if not self.valid: mgear.log("The guide doesn't seem to be up to date. Check logged messages and update the guide.", mgear.sev_warning) mgear.log("Guide loaded from hierarchy in [ " + "Not Yet Implemented" + " ]")
def inspectProperties(self, *args): modeSet = ["FK", "IK", "IK/FK"] rotOrderSet = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] guideModeSet = ["Final", "WIP"] # apply changes def applyCloseGuide(root, *args): if pm.attributeQuery("mode", node=root, ex=True): root.attr("mode").set(guideModeSet.index(pMode.getValue())) pm.select(root, r=True) pm.deleteUI(window, window=True) def skinLoad(root, *args): startDir = root.attr("skin").get() filePath = pm.fileDialog2(dialogStyle=2, fileMode=1, startingDirectory=startDir, fileFilter='mGear skin (*%s)' % skin.FILE_EXT) if not filePath: return if not isinstance(filePath, basestring): filePath = filePath[0] root.attr("skin").set(filePath) def applyCloseComp(root, *args): newName = pName.getText() newSide = pSide.getValue() newIndex = pIndex.getValue1() if pm.attributeQuery("mode", node=root, ex=True): root.attr("mode").set(modeSet.index(pMode.getValue())) if pm.attributeQuery("default_rotorder", node=root, ex=True): root.attr("default_rotorder").set( rotOrderSet.index(pRotOrder.getValue())) guide = shifter.RigGuide() guide.updateProperties(root, newName, newSide, newIndex) pm.select(root, r=True) pm.deleteUI(window, window=True) if pm.window("compProperties", exists=True): pm.deleteUI("compProperties") oSel = pm.selected() if oSel: root = oSel[0] else: mgear.log("Select one root Guide or component to edit properties", mgear.sev_error) return if pm.attributeQuery("comp_type", node=root, ex=True): #property window constructor customAttr = pm.listAttr(root, ud=True) window = pm.window(title=root.name()) pm.columnLayout(adjustableColumn=True, cal="right") for attr in customAttr: if attr == "comp_name": fl = pm.formLayout() oriVal = root.attr("comp_name").get() pName = pm.textFieldGrp(l="comp_name") pm.setParent('..') pm.formLayout(fl, e=True, af=(pName, "left", 0)) pName.setText(oriVal) elif attr == "comp_side": sideSet = ["C", "L", "R"] fl = pm.formLayout() pSide = pm.optionMenu(l="comp_side") pSide.addMenuItems(sideSet) pSide.setWidth(120) pm.setParent('..') pm.formLayout(fl, e=1, af=(pSide, "left", 90)) oriVal = root.attr("comp_side").get() pSide.setValue(oriVal) elif attr == "mode": fl = pm.formLayout() pMode = pm.optionMenu(l="mode") pMode.addMenuItems(modeSet) pMode.setWidth(120) pm.setParent('..') pm.formLayout(fl, e=1, af=(pMode, "left", 115)) oriVal = root.attr("mode").get() pMode.setValue(modeSet[oriVal]) elif attr == "default_rotorder": fl = pm.formLayout() pRotOrder = pm.optionMenu(l="default_rotorder") pRotOrder.addMenuItems(rotOrderSet) pRotOrder.setWidth(140) pm.setParent('..') pm.formLayout(fl, e=1, af=(pRotOrder, "left", 60)) oriVal = root.attr("default_rotorder").get() pRotOrder.setValue(rotOrderSet[oriVal]) elif attr == "comp_index": fl = pm.formLayout() oriVal = root.attr("comp_index").get() pIndex = pm.intFieldGrp(v1=oriVal, l="comp_index") pm.setParent('..') pm.formLayout(fl, e=True, af=(pIndex, "left", 0)) else: editable = True if attr == "comp_type": editable = False pm.columnLayout(cal="right") pm.attrControlGrp(attribute=root.attr(attr), po=True, en=editable) pm.setParent('..') pm.button(label='Apply', command=partial(applyCloseComp, root), h=100) pm.setParent('..') pm.showWindow(window) elif pm.attributeQuery("ismodel", node=root, ex=True): #property window constructor customAttr = pm.listAttr(root, ud=True) window = pm.window(title=root.name()) pm.columnLayout(adjustableColumn=True, cal="right") for attr in customAttr: if attr.split("_")[-1] not in ["r", "g", "b"]: if attr == "mode": fl = pm.formLayout() pMode = pm.optionMenu(l="mode") pMode.addMenuItems(guideModeSet) pMode.setWidth(120) pm.setParent('..') pm.formLayout(fl, e=1, af=(pMode, "left", 115)) oriVal = root.attr("mode").get() pMode.setValue(guideModeSet[oriVal]) elif attr == "skin": pm.columnLayout(cal="right") pm.attrControlGrp(attribute=root.attr(attr), po=True) pm.setParent('..') pm.button(label='Load Skin ', command=partial(skinLoad, root)) else: pm.columnLayout(cal="right") pm.attrControlGrp(attribute=root.attr(attr), po=True) pm.setParent('..') pm.button(label='Apply', command=partial(applyCloseGuide, root), h=50) pm.setParent('..') pm.showWindow(window) else: mgear.log("Select a root Guide or component to edit properties", mgear.sev_error) return
def getBiNormalFromPos(self, pos): if len(pos) < 3: mgear.log("%s : Not enough references to define binormal"%self.fullName, mgear.sev_error) return vec.getPlaneBiNormal(pos[0], pos[1], pos[2])
def addMinMax(self, name, minimum=1, maximum=-1): if "#" not in name: mgear.log( "Invalid definition for min/max. You should have a '#' in the name", mgear.sev_error) self.minmax[name] = MinMax(minimum, maximum)
def initialHierarchy(self): """Build the initial hierarchy of the rig. Create the rig model, the main properties, and a couple of base organisation nulls. Get the global size of the rig. """ mgear.log("Initial Hierarchy") # -------------------------------------------------- # Model self.model = primitive.addTransformFromPos(None, self.options["rig_name"]) attribute.lockAttribute(self.model) # -------------------------------------------------- # INFOS self.isRig_att = attribute.addAttribute(self.model, "is_rig", "bool", True) self.rigName_att = attribute.addAttribute(self.model, "rig_name", "string", self.options["rig_name"]) self.user_att = attribute.addAttribute(self.model, "user", "string", getpass.getuser()) self.isWip_att = attribute.addAttribute(self.model, "wip", "bool", self.options["mode"] != 0) self.date_att = attribute.addAttribute(self.model, "date", "string", str(datetime.datetime.now())) self.mayaVersion_att = attribute.addAttribute( self.model, "maya_version", "string", str(pm.mel.eval("getApplicationVersionAsFloat"))) self.gearVersion_att = attribute.addAttribute(self.model, "gear_version", "string", mgear.getVersion()) self.synoptic_att = attribute.addAttribute( self.model, "synoptic", "string", str(self.options["synoptic"])) self.comments_att = attribute.addAttribute( self.model, "comments", "string", str(self.options["comments"])) self.ctlVis_att = attribute.addAttribute(self.model, "ctl_vis", "bool", True) if versions.current() >= 201650: self.ctlVisPlayback_att = attribute.addAttribute( self.model, "ctl_vis_on_playback", "bool", True) self.jntVis_att = attribute.addAttribute(self.model, "jnt_vis", "bool", True) self.qsA_att = attribute.addAttribute(self.model, "quickselA", "string", "") self.qsB_att = attribute.addAttribute(self.model, "quickselB", "string", "") self.qsC_att = attribute.addAttribute(self.model, "quickselC", "string", "") self.qsD_att = attribute.addAttribute(self.model, "quickselD", "string", "") self.qsE_att = attribute.addAttribute(self.model, "quickselE", "string", "") self.qsF_att = attribute.addAttribute(self.model, "quickselF", "string", "") self.rigGroups = self.model.addAttr("rigGroups", at='message', m=1) self.rigPoses = self.model.addAttr("rigPoses", at='message', m=1) self.rigCtlTags = self.model.addAttr("rigCtlTags", at='message', m=1) # ------------------------- ------------------------- # Global Ctl if self.options["worldCtl"]: self.global_ctl = self.addCtl(self.model, "world_ctl", datatypes.Matrix(), self.options["C_color_fk"], "circle", w=10) else: self.global_ctl = self.addCtl(self.model, "global_C0_ctl", datatypes.Matrix(), self.options["C_color_fk"], "crossarrow", w=10) attribute.setRotOrder(self.global_ctl, "ZXY") # Connect global visibility pm.connectAttr(self.ctlVis_att, self.global_ctl.attr("visibility")) if versions.current() >= 201650: pm.connectAttr(self.ctlVisPlayback_att, self.global_ctl.attr("hideOnPlayback")) attribute.lockAttribute(self.global_ctl, ['v']) # -------------------------------------------------- # Setup in world Space self.setupWS = primitive.addTransformFromPos(self.model, "setup") attribute.lockAttribute(self.setupWS) # -------------------------------------------------- # Basic set of null if self.options["joint_rig"]: self.jnt_org = primitive.addTransformFromPos(self.model, "jnt_org") pm.connectAttr(self.jntVis_att, self.jnt_org.attr("visibility"))
def selectObj(model, object_names, mouse_button, key_modifier): """Select an object Args: model (PyNode): The rig top node object_names (list): The names of the objects to select mouse_button (QtSignal): Clicked mouse button signal key_modifier (QtSignal): Modifier button signal Returns: None """ if not model: return nameSpace = getNamespace(model) with pm.UndoChunk(): nodes = [] for name in object_names: if nameSpace: node = getNode(nameSpace + ":" + name) else: node = getNode(name) if not node: continue if not node and nameSpace: mgear.log("Can't find object : %s:%s" % (nameSpace, name), mgear.sev_error) elif not node: mgear.log("Can't find object : %s" % (name), mgear.sev_error) nodes.append(node) if not nodes: return if mouse_button == QtCore.Qt.RightButton: mirrorPose(False, nodes) return if mouse_button == QtCore.Qt.MiddleButton: mirrorPose(True, nodes) return # Key pressed if key_modifier is None: pm.select(nodes) elif key_modifier == QtCore.Qt.NoModifier: # No Key pm.select(nodes) elif key_modifier == QtCore.Qt.ControlModifier: # ctrl pm.select(nodes, deselect=True) elif key_modifier == QtCore.Qt.ShiftModifier: # shift pm.select(nodes, toggle=True) elif int(key_modifier) == (QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier): # ctrl + shift pm.select(nodes, add=True) elif key_modifier == QtCore.Qt.AltModifier: # alt pm.select(nodes) elif int(key_modifier) == (QtCore.Qt.ControlModifier | QtCore.Qt.AltModifier): # ctrl + alt pm.select(nodes, deselect=True) elif int(key_modifier) == (QtCore.Qt.ShiftModifier | QtCore.Qt.AltModifier): # shift + alt pm.select(nodes, toggle=True) # Ctrl + alt + shift elif int(key_modifier) == (QtCore.Qt.ControlModifier | QtCore.Qt.AltModifier | QtCore.Qt.ShiftModifier): pm.select(nodes, add=True) else: pm.select(nodes)
def postCustomStep(self): customSteps = self.stepsList("doPostCustomStep", "postCustomStep") if customSteps: mgear.log("\n" + "= POST CUSTOM STEPS " + "=" * 46) self.customStep(customSteps)
def addMinMax(self, name, minimum=1, maximum=-1): if "#" not in name: mgear.log("Invalid definition for min/max. You should have a '#' in the name", mgear.sev_error) self.minmax[name] = MinMax(minimum, maximum)
def finalize(self): """Finalize the rig.""" groupIdx = 0 # Properties -------------------------------------- mgear.log("Finalize") # clean jnt_org -------------------------------------- if self.options["joint_rig"]: mgear.log("Cleaning jnt org") for jOrg in dag.findChildrenPartial(self.jnt_org, "org"): if not jOrg.listRelatives(c=True): pm.delete(jOrg) # Groups ------------------------------------------ mgear.log("Creating groups") # Retrieve group content from components for name in self.componentsIndex: component_ = self.components[name] for name, objects in component_.groups.items(): self.addToGroup(objects, name) for name, objects in component_.subGroups.items(): self.addToSubGroup(objects, name) # Create master set to group all the groups masterSet = pm.sets(n=self.model.name() + "_sets_grp", em=True) pm.connectAttr(masterSet.message, self.model.rigGroups[groupIdx]) groupIdx += 1 # Creating all groups pm.select(cl=True) for name, objects in self.groups.items(): s = pm.sets(n=self.model.name() + "_" + name + "_grp") s.union(objects) pm.connectAttr(s.message, self.model.rigGroups[groupIdx]) groupIdx += 1 masterSet.add(s) for parentGroup, subgroups in self.subGroups.items(): pg = pm.PyNode(self.model.name() + "_" + parentGroup + "_grp") for sg in subgroups: sub = pm.PyNode(self.model.name() + "_" + sg + "_grp") if sub in masterSet.members(): masterSet.remove(sub) pg.add(sub) # Bind pose --------------------------------------- # controls_grp = self.groups["controllers"] # pprint(controls_grp, stream=None, indent=1, width=100) ctl_master_grp = pm.PyNode(self.model.name() + "_controllers_grp") pm.select(ctl_master_grp, replace=True) dag_node = pm.dagPose(save=True, selection=True) pm.connectAttr(dag_node.message, self.model.rigPoses[0]) print dag_node # Bind skin re-apply if self.options["importSkin"]: try: pm.displayInfo("Importing Skin") skin.importSkin(self.options["skin"]) except RuntimeError: pm.displayWarning("Skin doesn't exist or is not correct. " + self.options["skin"] + " Skipped!")
def setFromHierarchy(self, root): self.root = root self.model = self.root.getParent(generations=-1) # --------------------------------------------------- # First check and set the settings if not self.root.hasAttr("comp_type"): mgear.log("%s is not a proper guide."%self.root.longName(), mgear.sev_error) self.valid = False return self.setParamDefValuesFromProperty(self.root) # --------------------------------------------------- # Then get the objects for name in self.save_transform: if "#" in name: i = 0 while not self.minmax[name].max > 0 or i < self.minmax[name].max: localName = string.replaceSharpWithPadding(name, i) node = dag.findChild(self.model, self.getName(localName)) if not node: break self.tra[localName] = node.getMatrix(worldSpace=True) self.atra.append(node.getMatrix(worldSpace=True)) self.pos[localName] = node.getTranslation(space="world") self.apos.append(node.getTranslation(space="world")) i += 1 if i < self.minmax[name].min: mgear.log("Minimum of object requiered for "+name+" hasn't been reached", mgear.sev_warning) self.valid = False continue else: node = dag.findChild(self.model, self.getName(name)) if not node: mgear.log("Object missing : %s"%name, mgear.sev_warning) self.valid = False continue self.tra[name] = node.getMatrix(worldSpace=True) self.atra.append(node.getMatrix(worldSpace=True)) self.pos[name] = node.getTranslation(space="world") self.apos.append(node.getTranslation(space="world")) for name in self.save_blade: node = dag.findChild(self.model, self.getName(name)) if not node: mgear.log("Object missing : %s"%name, mgear.sev_warning) self.valid = False continue self.blades[name] = vec.Blade(node.getMatrix(worldSpace=True)) self.size = self.getSize()