def jointListerAddRow(self, ctr, tempJoint, name, card, parentCard): index = next(ctr) jointName = pdil.shortName(tempJoint) self.setItem(index, self.JOINT_LISTER_NAME, Cell(jointName)) cb = Cell(checked=tempJoint.isHelper) self.setItem(index, self.JOINT_LISTER_HELPER, cb) self.setItem(index, self.JOINT_LISTER_OUTPUT, Cell(name)) cb = Cell(checked=tempJoint.displayHandle.get()) self.setItem(index, self.JOINT_LISTER_HANDLES, cb) # --- Orient --- orientText = '' if tempJoint.customOrient: if tempJoint.customOrient == tempJoint.card: orientText = '-as card-' elif tempJoint.customOrient == tempJoint: orientText = '-as proxy-' else: orientText = 'custom:' + pdil.shortName(tempJoint.customOrient) elif isinstance(tempJoint.orientTarget, basestring): orientText = tempJoint.orientTarget elif tempJoint.orientTarget: orientText = pdil.shortName(tempJoint.orientTarget) self.setItem(index, self.JOINT_LISTER_ORIENT, Cell(orientText)) # --- parent --- if tempJoint.parent: # Technically this will fail if there is a helper also has a child (which is just fine, just not useful) outputMap = tempJoint.parent.card.getOutputMap(includeHelpers=True) if tempJoint.info.get('options', {}).get('mirroredSide'): parentName = outputMap[tempJoint.parent][1] else: parentName = outputMap[tempJoint.parent][0] if not parentName: # This being empty means the parent is a helper parentName = '!helper! ' + pdil.simpleName(tempJoint.parent) elif tempJoint.extraNode[0]: outputMap = tempJoint.extraNode[0].card.getOutputMap( includeHelpers=False) parentName = outputMap[tempJoint.extraNode[0]][1] else: parentName = '' self.setItem(index, self.JOINT_LISTER_CHILDOF, Cell(parentName))
def baseSpec(cls, obj): spec = OrderedDict() spec['idtype'] = _baseSpecType spec['short'] = pdil.shortName(obj) spec['long'] = obj.longName() spec['ver'] = cls.version return spec
def getSpec(self, obj): spec = self.baseSpec(obj) if pdil.shortName(obj) == 'rootMotion': spec['idtype'] = self.specType return spec return None
def relink(src, dup): ''' When a card has been duplicated, relinks the parenting appropriately. .. todo:: Does the scaling setup duplicate properly? ''' children = dup.listRelatives(type='joint') for i, j in enumerate(src.joints): for child in children: if shortName(child) == shortName(j): child.msg >> dup.attr('joints')[i].jmsg dup.scale >> child.inverseScale for prev, j in zip(dup.joints[:-1], dup.joints[1:]): pointer(prev, j) if src.start().parent: pointer(src.start().parent, dup.start())
def getControlGroup(name): ''' Used to organize controls under the main group. ''' match = re.match('[_a-zA-Z]+[_a-zA-Z0-9_]*', name) if not match or match.group(0) != name: raise Exception("An invalid group name was given") for child in node.mainGroup().listRelatives(): if shortName(child) == name: return child g = group(em=True, name=name, p=node.mainGroup()) pdil.dagObj.lock(g) return g
def getTrueWorld(): ''' Make a node that stays in world space. ''' main = find.mainGroup() if not main: return None for child in main.listRelatives(): if pdil.shortName(child) == 'trueWorld': return child grp = group(em=True, name='trueWorld') for t in 'trs': for a in 'xyz': grp.attr(t + a).setKeyable(False) hide(grp) grp.setParent(main) grp.inheritsTransform.set(False) return grp
def addTwistControls(controlChain, boundChain, boundEnd, influenceDist=3): ''' Put a rotation controller under each child of the controlChain to drive .rz of the boundChain. They must both be the same size. :param Joint controlChain: The first joint of the controlling rig (ideally pruned) :param Joint boundChain: The first joint of joints being controlled by the spline. :param Joint boundEnd: The last joint in the bound chain, used to address possible branching. :param int influenceDist: How many adjacent joints are influenced (total # is 2x since it influences both directions). ''' obj = controlChain[0] target = boundChain #controlJoints = getChain( controlChain, findChild(controlChain, shortName(boundEnd)) ) controlJoints = controlChain boundJoints = util.getChain( boundChain, util.findChild(boundChain, pdil.shortName(boundEnd)) ) assert len(controlJoints) == len(boundJoints), "Failure when adding twist controls, somehow the chains don't match length, contorls {0} != {1}".format( len(controlJoints), len(boundJoints) ) controls = [] groups = [] pointConstraints = [] orientConstraints = [] for i, (obj, target) in enumerate(zip(controlJoints, boundJoints)): c = controllerShape.simpleCircle() c.setParent(obj) c.t.set(0, 0, 0) c.r.set(0, 0, 0) controls.append(c) spinner = group(em=True, name='spinner%i' % i, p=target) spinner.r.set(0, 0, 0) spinner.setParent(obj) spinner.t.set(0, 0, 0) # Aligning the spinners to the bound joint means we don't have to offset # the orientConstraint which means nicer numbers. # spinner.setRotation( target.getRotation(space='world'), space='world' ) groups.append(spinner) pointConstraints.append( pdil.constraints.pointConst( obj, target, maintainOffset=False ) ) orientConstraints.append( pdil.constraints.orientConst( spinner, target, maintainOffset=False ) ) children = obj.listRelatives(type='joint') if children: obj = children[0] else: obj = None break for pSrc, pDest in zip( pointConstraints[:-1], pointConstraints[1:]): pSrc >> pDest for oSrc, oDest in zip( orientConstraints[:-1], orientConstraints[1:]): oSrc >> oDest # &&& This and the i+7 reflect the number of controls that influence bigList = [None] * influenceDist + controls + [None] * influenceDist influenceRange = (influenceDist * 2) + 1 axis = util.identifyAxis(controlChain[0].listRelatives(type='joint')[0]) exp = [] for i, spinner in enumerate(groups): exp.append(driverExpression( spinner, bigList[i: i + influenceRange], axis )) expression( s=';\n'.join(exp) ) return controls, util.ConstraintResults( pointConstraints[0], orientConstraints[0] )
def buildUI(self, card): uiFieldKwargs = self.getUIFieldKwargs(card) if self.type == self.BOOL: field = checkBox(l='', **uiFieldKwargs) # noqa e741 checkBox(field, e=True, cc=pdil.alt.Callback(self.setParam, field)) elif self.type == self.INT: field = intField(**uiFieldKwargs) intField(field, e=True, cc=pdil.alt.Callback(self.setParam, field)) elif self.type == self.FLOAT: field = floatField(**uiFieldKwargs) floatField(field, e=True, cc=pdil.alt.Callback(self.setParam, field)) elif self.type == self.ENUM: field = optionMenu(l='') # noqa e741 optionMenu(field, e=True, cc=pdil.alt.Callback(self.setParam, field)) for i, choice in enumerate(self.enum, 1): menuItem(l=choice) # noqa e741 if self.enum[choice] == uiFieldKwargs['text']: optionMenu(field, e=True, sl=i) elif self.type == self.STR: # &&& Possibly super gross, if the field is "name", use the first joint... if 'text' not in uiFieldKwargs and self.kwargName == 'name': uiFieldKwargs['text'] = pdil.shortName(card.joints[0]) #default = card.n #getDefaultIkName(card) # &&& MAKE THIS so I can use the same logic when building the card. field = textField(**uiFieldKwargs) textField(field, e=True, cc=pdil.alt.Callback(self.setParam, field)) setattr(field, 'getValue', field.getText) # Hack to allow ducktyping. elif self.type == self.NODE_0: def setExtraNode(extraNode): card.extraNode[0] = extraNode temp = ParamInfo.toDict(card.rigParams) temp[self.kwargName] = 'NODE_0' card.rigParams = ParamInfo.toStr(temp) return True def clearExtraNode(extraNode): card.extraNode[0] = None temp = ParamInfo.toDict(card.rigParams) del temp[self.kwargName] card.rigParams = ParamInfo.toStr(temp) return True util.GetNextSelected( setExtraNode, clearExtraNode, l='', # noqa e741 tx=pdil.shortName(card.extraNode[0]) if card.extraNode[0] else '', cw=[(1, 1), (2, 100), (3, 20)])