def create_fk_ik_sn(controls, **kwargs): fk, ik = get_fk_ik_joints(controls) # Add the FkIkMode attribute to both controls and identify # which control is the fk control and which is the ik control. for c in controls: addAttr(c, longName='FkIkMode', niceName='FKIK Mode', attributeType='enum', enumName='FK:IK', keyable=True, defaultValue=1) sn = scriptNode(scriptType=2, sourceType='python', beforeScript=';'.join(['import pymel.core.nodetypes as nt', 'import %s as x' % __name__, "x.create_fk_ik_sj(%s)" % controls]), afterScript=';'.join(['import pymel.core.nodetypes as nt', "[c.attr('FkIkMode').delete() for c in %s]" % controls]), **kwargs) # Make the appropriate connections to toggle both visibility and # orient constraints. rev = shadingNode('reverse', asUtility=True) ik['ctrl'].attr('FkIkMode').connect(ik['ctrl'].attr('visibility')) fk['ctrl'].attr('FkIkMode').connect(rev.attr('inputX')) rev.attr('outputX').connect(fk['ctrl'].attr('visibility')) ik['ctrl'].attr('FkIkMode').connect(ik['sj'].attr('visibility')) fk['ctrl'].attr('FkIkMode').connect(rev.attr('inputY')) rev.attr('outputY').connect(fk['sj'].attr('visibility')) for jtype in ('shoulder', 'elbow', 'hand'): kwargs = jtype == 'elbow' and dict(skip=('x', 'z')) or {} oc = orientConstraint(ik[jtype], fk[jtype], **kwargs) ik['ctrl'].attr('FkIkMode').connect( \ oc.attr(ik[jtype].nodeName() + 'W0')) create_fk_ik_sj(controls)
def on_orientJointsButton_clicked(self): undoInfo(openChunk=True) sel = selected() kwargs = {} if self.zeroScaleOrientCB.isChecked(): kwargs.update({'zeroScaleOrient': True}) if self.aimAxisNoneRadio.isChecked(): val = 'none' else: for i, radio in enumerate( (self.aimAxisXRadio, self.aimAxisYRadio, self.aimAxisZRadio)): if radio.isChecked(): xyz = 'xyz' if self.upAxisNoneRadio.isChecked(): val = xyz[i:] + xyz[:i] else: val = str(radio.text()).lower() for up_radio in (self.upAxisXRadio, self.upAxisYRadio, self.upAxisZRadio): if up_radio.isChecked(): val += str(up_radio.text()).lower() break for c in xyz: if c not in val: val += c break sao = self.worldUpYRadio.isChecked() and 'y' \ or self.worldUpZRadio.isChecked() and 'z' \ or upAxis(query=True, axis=True) sao += self.worldUpReverseCB.isChecked() \ and 'down' or 'up' kwargs.update({'secondaryAxisOrient': sao}) break reverse_aim = self.aimAxisReverseCB.isChecked() \ and Vector([val[1] == c for c in 'xyz']) * 180 or None reverse_up = self.upAxisReverseCB.isChecked() \ and Vector([val[0] == c for c in 'xyz']) * 180 or None for j in self.get_affected_joints(): if j.numChildren(): j.orientJoint(val, **kwargs) else: p = j.getParent() if p: delete(orientConstraint(p, j)) else: self.freeze(j, jointOrient=True) if self.zeroScaleOrientCB.isChecked(): j.zeroScaleOrient() if reverse_aim: self.tweak_joint_orientation(1, rotateAxis=reverse_aim) if reverse_up: self.tweak_joint_orientation(1, rotateAxis=reverse_up) select(sel) undoInfo(closeChunk=True)
def on_orientJointsButton_clicked(self): undoInfo(openChunk=True) sel = selected() kwargs = {} if self.zeroScaleOrientCB.isChecked(): kwargs.update({'zeroScaleOrient': True}) if self.aimAxisNoneRadio.isChecked(): val = 'none' else: for i, radio in enumerate((self.aimAxisXRadio, self.aimAxisYRadio, self.aimAxisZRadio)): if radio.isChecked(): xyz = 'xyz' if self.upAxisNoneRadio.isChecked(): val = xyz[i:] + xyz[:i] else: val = str(radio.text()).lower() for up_radio in (self.upAxisXRadio, self.upAxisYRadio, self.upAxisZRadio): if up_radio.isChecked(): val += str(up_radio.text()).lower() break for c in xyz: if c not in val: val += c break sao = self.worldUpYRadio.isChecked() and 'y' \ or self.worldUpZRadio.isChecked() and 'z' \ or upAxis(query=True, axis=True) sao += self.worldUpReverseCB.isChecked() \ and 'down' or 'up' kwargs.update({'secondaryAxisOrient': sao}) break reverse_aim = self.aimAxisReverseCB.isChecked() \ and Vector([val[1] == c for c in 'xyz']) * 180 or None reverse_up = self.upAxisReverseCB.isChecked() \ and Vector([val[0] == c for c in 'xyz']) * 180 or None for j in self.get_affected_joints(): if j.numChildren(): j.orientJoint(val, **kwargs) else: p = j.getParent() if p: delete(orientConstraint(p, j)) else: self.freeze(j, jointOrient=True) if self.zeroScaleOrientCB.isChecked(): j.zeroScaleOrient() if reverse_aim: self.tweak_joint_orientation(1, rotateAxis=reverse_aim) if reverse_up: self.tweak_joint_orientation(1, rotateAxis=reverse_up) select(sel) undoInfo(closeChunk=True)
def create_fk_ik_sn(controls, **kwargs): fk, ik = get_fk_ik_joints(controls) # Add the FkIkMode attribute to both controls and identify # which control is the fk control and which is the ik control. for c in controls: addAttr(c, longName='FkIkMode', niceName='FKIK Mode', attributeType='enum', enumName='FK:IK', keyable=True, defaultValue=1) sn = scriptNode(scriptType=2, sourceType='python', beforeScript=';'.join([ 'import pymel.core.nodetypes as nt', 'import %s as x' % __name__, "x.create_fk_ik_sj(%s)" % controls ]), afterScript=';'.join([ 'import pymel.core.nodetypes as nt', "[c.attr('FkIkMode').delete() for c in %s]" % controls ]), **kwargs) # Make the appropriate connections to toggle both visibility and # orient constraints. rev = shadingNode('reverse', asUtility=True) ik['ctrl'].attr('FkIkMode').connect(ik['ctrl'].attr('visibility')) fk['ctrl'].attr('FkIkMode').connect(rev.attr('inputX')) rev.attr('outputX').connect(fk['ctrl'].attr('visibility')) ik['ctrl'].attr('FkIkMode').connect(ik['sj'].attr('visibility')) fk['ctrl'].attr('FkIkMode').connect(rev.attr('inputY')) rev.attr('outputY').connect(fk['sj'].attr('visibility')) for jtype in ('shoulder', 'elbow', 'hand'): kwargs = jtype == 'elbow' and dict(skip=('x', 'z')) or {} oc = orientConstraint(ik[jtype], fk[jtype], **kwargs) ik['ctrl'].attr('FkIkMode').connect( \ oc.attr(ik[jtype].nodeName() + 'W0')) create_fk_ik_sj(controls)
def __init__(self, driver=shapes.Plus, driven=None, **kwargs): # Driver if not isinstance(driver, shapes.Shape) and issubclass(driver, shapes.Shape): driver = driver() assert isinstance(driver, shapes.Shape), \ ("Parameter 'driver' must be an instance or subclass of %s." % shapes.Shape.__name__) self._driver = driver self._transform = driver.get_transform() self._shapes = self._transform.getShapes() # Driven if not driven: driven = ls(selection=True, transforms=True) assert len(driven) == 1, "Parameter 'driven' requires exactly one transform." driven = driven[0] self._driven = driven # Face Axis face_x = kwargs.pop('fx', kwargs.pop('faceX', False)) face_y = kwargs.pop('fy', kwargs.pop('faceY', False)) face_z = kwargs.pop('fz', kwargs.pop('faceZ', False)) face_sum = sum([face_x, face_y, face_z]) if not face_sum: face_x = True face_sum = 1 else: assert face_sum == 1, "Rig control can only face one axis." rotate(self._transform, [face_z and 90 or 0, 0, face_x and -90 or 0]) select(self._transform) FreezeTransformations() # Constraints do_parent_constraint = kwargs.pop('pc', kwargs.pop('parentConstraint', False)) do_point_constraint = kwargs.pop('xc', kwargs.pop('pointConstraint', False)) do_orient_constraint = kwargs.pop('oc', kwargs.pop('orientConstraint', False)) do_scale_constraint = kwargs.pop('sc', kwargs.pop('scaleConstraint', False)) if do_parent_constraint or do_point_constraint or do_orient_constraint or \ do_scale_constraint: self._buffer = Transform() snap(self._buffer, self._driven, scale=True) select(self._buffer) parent(self._transform, self._buffer) if do_parent_constraint: parentConstraint(self._transform, self._driven) else: if do_point_constraint: pointConstraint(self._transform, self._driven) if do_orient_constraint: orientConstraint(self._transform, self._driven) if do_scale_constraint: scaleConstraint(self._transform, self._driven) elif isinstance(self._driven, Joint): # Parent the drivers directly underneath the driven joint. parent(self._driver, self._driven, relative=True, shape=True) delete(self._transform) self._transform = self._driven elif isinstance(self._driven, IkHandle): self._buffer = self._transform self._transform = self._driven snap(self._ebuffer, self._transform) parent(self._transform, self._buffer) parent(self._driver, self._transform, relative=True, shape=True) else: # Parent the drivers underneath a new buffered transform. self._buffer = self._driven parent(self._transform, self._buffer) parent(self._buffer.getShapes(), self._transform, relative=True, shape=True) # Pop the shape nodes out and back in to reorder the driven shape(s) to # the top. This way, the Outliner icons for this transform will reflect the # appropriate first-child shape node. parent(self._driver, self._buffer, relative=True, shape=True) parent(self._driver, self._transform, relative=True, shape=True) if self._buffer: select(self._transform) ResetTransformations() for trs in 'trs': for xyz in 'xyz': self._buffer.attr(trs + xyz).lock() if isinstance(self._driven, IkHandle): self.__class__ = IkRigControl self.__init__()
def __init__(self, driver=shapes.Plus, driven=None, **kwargs): # Driver if not isinstance(driver, shapes.Shape) and issubclass( driver, shapes.Shape): driver = driver() assert isinstance(driver, shapes.Shape), \ ("Parameter 'driver' must be an instance or subclass of %s." % shapes.Shape.__name__) self._driver = driver self._transform = driver.get_transform() self._shapes = self._transform.getShapes() # Driven if not driven: driven = ls(selection=True, transforms=True) assert len( driven ) == 1, "Parameter 'driven' requires exactly one transform." driven = driven[0] self._driven = driven # Face Axis face_x = kwargs.pop('fx', kwargs.pop('faceX', False)) face_y = kwargs.pop('fy', kwargs.pop('faceY', False)) face_z = kwargs.pop('fz', kwargs.pop('faceZ', False)) face_sum = sum([face_x, face_y, face_z]) if not face_sum: face_x = True face_sum = 1 else: assert face_sum == 1, "Rig control can only face one axis." rotate(self._transform, [face_z and 90 or 0, 0, face_x and -90 or 0]) select(self._transform) FreezeTransformations() # Constraints do_parent_constraint = kwargs.pop( 'pc', kwargs.pop('parentConstraint', False)) do_point_constraint = kwargs.pop('xc', kwargs.pop('pointConstraint', False)) do_orient_constraint = kwargs.pop( 'oc', kwargs.pop('orientConstraint', False)) do_scale_constraint = kwargs.pop('sc', kwargs.pop('scaleConstraint', False)) if do_parent_constraint or do_point_constraint or do_orient_constraint or \ do_scale_constraint: self._buffer = Transform() snap(self._buffer, self._driven, scale=True) select(self._buffer) parent(self._transform, self._buffer) if do_parent_constraint: parentConstraint(self._transform, self._driven) else: if do_point_constraint: pointConstraint(self._transform, self._driven) if do_orient_constraint: orientConstraint(self._transform, self._driven) if do_scale_constraint: scaleConstraint(self._transform, self._driven) elif isinstance(self._driven, Joint): # Parent the drivers directly underneath the driven joint. parent(self._driver, self._driven, relative=True, shape=True) delete(self._transform) self._transform = self._driven elif isinstance(self._driven, IkHandle): self._buffer = self._transform self._transform = self._driven snap(self._ebuffer, self._transform) parent(self._transform, self._buffer) parent(self._driver, self._transform, relative=True, shape=True) else: # Parent the drivers underneath a new buffered transform. self._buffer = self._driven parent(self._transform, self._buffer) parent(self._buffer.getShapes(), self._transform, relative=True, shape=True) # Pop the shape nodes out and back in to reorder the driven shape(s) to # the top. This way, the Outliner icons for this transform will reflect the # appropriate first-child shape node. parent(self._driver, self._buffer, relative=True, shape=True) parent(self._driver, self._transform, relative=True, shape=True) if self._buffer: select(self._transform) ResetTransformations() for trs in 'trs': for xyz in 'xyz': self._buffer.attr(trs + xyz).lock() if isinstance(self._driven, IkHandle): self.__class__ = IkRigControl self.__init__()