def _is_influence(self, obj): """ Supported influences are joints and nurbsSurface. :return: """ return libPymel.isinstance_of_transform(obj, pymel.nodetypes.Joint) or \ libPymel.isinstance_of_shape(obj, pymel.nodetypes.NurbsSurface)
def build(self, no_subdiv=False, num_ctrl=None, degree=3, create_ctrl=True, constraint=False, rot_fol=True, *args, **kwargs): super(Ribbon, self).build(create_grp_anm=create_ctrl, *args, **kwargs) if num_ctrl is not None: self.num_ctrl = num_ctrl nomenclature_rig = self.get_nomenclature_rig() # Create the plane and align it with the selected bones plane_tran = next( (input for input in self.input if libPymel.isinstance_of_shape(input, pymel.nodetypes.NurbsSurface)), None) if plane_tran is None: plane_name = nomenclature_rig.resolve("ribbonPlane") if no_subdiv: # We don't want any subdivision in the plane, so use only 2 bones to create it no_subdiv_degree = 2 if degree < 2: no_subdiv_degree = degree plane_tran = libRigging.create_nurbs_plane_from_joints([self.chain_jnt[0], self.chain_jnt[-1]], degree=no_subdiv_degree, width=self.width) else: plane_tran = libRigging.create_nurbs_plane_from_joints(self.chain_jnt, degree=degree, width=self.width) plane_tran.rename(plane_name) plane_tran.setParent(self.grp_rig) self._ribbon_shape = plane_tran.getShape() # Create the follicule needed for the system on the skinned bones self.attach_to_plane(rot_fol) # TODO : Support aim constraint for bones instead of follicle rotation? follicles_grp = pymel.createNode("transform") follicle_grp_name = nomenclature_rig.resolve("follicleGrp") follicles_grp.rename(follicle_grp_name) follicles_grp.setParent(self.grp_rig) for n in self._follicles: n.setParent(follicles_grp) # Create the joints that will drive the ribbon. # TODO: Support other shapes than straight lines... self._ribbon_jnts = libRigging.create_chain_between_objects( self.chain_jnt.start, self.chain_jnt.end, self.num_ctrl, parented=False) # Group all the joints ribbon_chain_grp_name = nomenclature_rig.resolve('ribbonChainGrp') self.ribbon_chain_grp = pymel.createNode('transform', name=ribbon_chain_grp_name, parent=self.grp_rig) align_chain = True if len(self.chain_jnt) == len(self._ribbon_jnts) else False for i, jnt in enumerate(self._ribbon_jnts): # Align the ribbon joints with the real joint to have a better rotation ctrl ribbon_jnt_name = nomenclature_rig.resolve('ribbonJnt{0:02d}'.format(i)) jnt.rename(ribbon_jnt_name) jnt.setParent(self.ribbon_chain_grp) if align_chain: matrix = self.chain_jnt[i].getMatrix(worldSpace=True) jnt.setMatrix(matrix, worldSpace=True) # TODO - Improve skinning smoothing by setting manually the skin... pymel.skinCluster(list(self._ribbon_jnts), plane_tran, dr=1.0, mi=2.0, omi=True) try: libSkinning.assign_weights_from_segments(self._ribbon_shape, self._ribbon_jnts, dropoff=1.0) except ZeroDivisionError, e: pass
def build(self, no_subdiv=False, num_ctrl = None, degree=3, create_ctrl=True, constraint=False, rot_fol=True, *args, **kwargs): super(Ribbon, self).build(create_grp_anm=create_ctrl, *args, **kwargs) if num_ctrl is not None: self.num_ctrl = num_ctrl nomenclature_rig = self.get_nomenclature_rig() # Create the plane and align it with the selected bones plane_tran = next((input for input in self.input if libPymel.isinstance_of_shape(input, pymel.nodetypes.NurbsSurface)), None) if plane_tran is None: plane_name = nomenclature_rig.resolve("ribbonPlane") if no_subdiv: # We don't want any subdivision in the plane, so use only 2 bones to create it no_subdiv_degree = 2 if degree < 2: no_subdiv_degree = degree plane_tran = libRigging.create_nurbs_plane_from_joints([self.chain_jnt[0], self.chain_jnt[-1]], degree=no_subdiv_degree, width=self.width) else: plane_tran = libRigging.create_nurbs_plane_from_joints(self.chain_jnt, degree=degree, width=self.width) plane_tran.rename(plane_name) plane_tran.setParent(self.grp_rig) self._ribbon_shape = plane_tran.getShape() # Create the follicule needed for the system on the skinned bones self.attach_to_plane(rot_fol) # TODO : Support aim constraint for bones instead of follicle rotation? follicles_grp = pymel.createNode("transform") follicle_grp_name = nomenclature_rig.resolve("follicleGrp") follicles_grp.rename(follicle_grp_name) follicles_grp.setParent(self.grp_rig) for n in self._follicles: n.setParent(follicles_grp) # Create the joints that will drive the ribbon. # TODO: Support other shapes than straight lines... self._ribbon_jnts = libRigging.create_chain_between_objects( self.chain_jnt.start, self.chain_jnt.end, self.num_ctrl, parented=False) # Group all the joints ribbon_chain_grp_name = nomenclature_rig.resolve('ribbonChainGrp') self.ribbon_chain_grp = pymel.createNode('transform', name=ribbon_chain_grp_name, parent=self.grp_rig) align_chain = True if len(self.chain_jnt) == len(self._ribbon_jnts) else False for i, jnt in enumerate(self._ribbon_jnts): # Align the ribbon joints with the real joint to have a better rotation ctrl ribbon_jnt_name = nomenclature_rig.resolve('ribbonJnt{0:02d}'.format(i)) jnt.rename(ribbon_jnt_name) jnt.setParent(self.ribbon_chain_grp) if align_chain: matrix = self.chain_jnt[i].getMatrix(worldSpace=True) jnt.setMatrix(matrix, worldSpace=True) # TODO - Improve skinning smoothing by setting manually the skin... pymel.skinCluster(list(self._ribbon_jnts), plane_tran, dr=1.0, mi=2.0, omi=True) try: libSkinning.assign_weights_from_segments(self._ribbon_shape, self._ribbon_jnts, dropoff=1.0) except ZeroDivisionError, e: pass
def build(self, rig, num_subdiv = 5, num_ctrl = None, degree=1, create_ctrl=True, constraint=False, rot_fol=False, *args, **kwargs): super(Ribbon, self).build(rig, create_grp_anm=create_ctrl, *args, **kwargs) if num_ctrl is not None: self.num_ctrl = num_ctrl nomenclature_anm = self.get_nomenclature_anm(rig) nomenclature_rig = self.get_nomenclature_rig(rig) #Create the plane and align it with the selected bones plane_tran = next((input for input in self.input if libPymel.isinstance_of_shape(input, pymel.nodetypes.NurbsSurface)), None) if plane_tran is None: plane_name = nomenclature_rig.resolve("ribbonPlane") plane_tran = libRigging.create_nurbs_plane_from_joints(self.chain_jnt, degree=degree, width=self.width) plane_tran.rename(plane_name) plane_tran.setParent(self.grp_rig) self._ribbon_shape = plane_tran.getShape() # TODO: Remove usage of djRivet #Create the follicule needed for the system on the skinned bones for i, jnt in enumerate(self.chain_jnt): pymel.select(jnt, plane_tran) mel.eval("djRivet") #TODO : Support aim constraint for bones instead of follicle rotation? # Apply the skin on the plane and rename follicle from djRivet dj_rivet_grp = pymel.PyNode("djRivetX") follicle_grp_name = nomenclature_rig.resolve("follicle_grp") dj_rivet_grp.rename(follicle_grp_name) dj_rivet_grp.setParent(self.grp_rig) self._follicles = dj_rivet_grp.getChildren() for n in self._follicles: fol_name = nomenclature_rig.resolve("fol") n.rename(fol_name) # Create the joints that will drive the ribbon. # TODO: Support other shapes than straight lines... # TODO: Support ctrl hold/fetch when building/unbuilding. self._ribbon_jnts = libRigging.create_chain_between_objects( self.chain_jnt.start, self.chain_jnt.end, self.num_ctrl, parented=False) # Group all the joints ribbon_chain_grp_name = nomenclature_rig.resolve('ribbonChain' + "_grp") ribbon_chain_grp = pymel.createNode('transform', name=ribbon_chain_grp_name, parent=self.grp_rig) align_chain = True if len(self.chain_jnt) == len(self._ribbon_jnts) else False for i, jnt in enumerate(self._ribbon_jnts): #Align the ribbon joints with the real joint to have a better rotation ctrl if align_chain: matrix = self.chain_jnt[i].getMatrix(worldSpace=True) jnt.setMatrix(matrix, worldSpace=True) jnt.setParent(ribbon_chain_grp) #TODO - Improve skinning smoothing by setting manully the skin... pymel.skinCluster(list(self._ribbon_jnts), plane_tran, dr=1.0, mi=2.0, omi=True) try: libSkinning.assign_weights_from_segments(self._ribbon_shape, self._ribbon_jnts, dropoff=1.0) except ZeroDivisionError, e: pass
def run(self): import pymel.core as pymel from omtk.libs import libPymel mesh = next((obj for obj in pymel.selected() if libPymel.isinstance_of_shape(obj, cls=pymel.nodetypes.Mesh)), None) if not mesh: pymel.warning("Please select a mesh to follow.") return for ctrl_model in self._iter_ictrl(): ctrl_model.swap_mesh(mesh)
def build(self, stretch=True, squash=False, *args, **kwargs): # TODO: Use self.chain_jnt self._joints = [input for input in self.input if libPymel.isinstance_of_transform(input, pymel.nodetypes.Joint)] self._curves = [input for input in self.input if libPymel.isinstance_of_shape(input, pymel.nodetypes.CurveShape)] if len(self._joints) < 2: raise Exception("Can't build SplineIK. Expected at least two joints, got {0}".format(self._joints)) if len(self._curves) < 1: raise Exception("Can't build SplineIK. Expected at least one nurbsCurve, got {0}".format(self._curves)) super(SplineIK, self).build(*args, **kwargs) nomenclature_rig = self.get_nomenclature_rig() # todo: handle multiple curves? curve = next(iter(self._curves), None) curve_shape = next((shape for shape in curve.getShapes() if isinstance(shape, pymel.nodetypes.NurbsCurve)), None) # Create ik solver handle_name = nomenclature_rig.resolve('ikHandle') eff_name = nomenclature_rig.resolve('ikEffector') self.ikHandle, self.ikEffector = pymel.ikHandle( solver="ikSplineSolver", curve=curve, startJoint=self._joints[0], endEffector=self._joints[-1], createCurve=False, name=handle_name, parentCurve=False, snapCurve=False) self.ikHandle.setParent(self.grp_rig) self.ikEffector.rename(eff_name) # Create stretch # Todo: use shape instead of transform as curve input? if stretch: stretch_attr = libRigging.create_strech_attr_from_curve(curve_shape) for jnt in self._joints: pymel.connectAttr(stretch_attr, jnt.sx, force=True) # Create squash if squash: num_joints = len(self._joints) squash_attrs = libRigging.create_squash_atts(stretch_attr, num_joints) # Todo: Find correct axis orient for jnt, squash in zip(self._joints, squash_attrs): pymel.connectAttr(squash, jnt.sy, force=True) pymel.connectAttr(squash, jnt.sz, force=True)
def handle_surface(self): """ Create the surface that the follicle will slide on if necessary. :return: """ # Hack: Provide backward compatibility for when surface was provided as an input. if self.surface is None: fn_is_nurbsSurface = lambda obj: libPymel.isinstance_of_shape(obj, pymel.nodetypes.NurbsSurface) surface = next(iter(filter(fn_is_nurbsSurface, self.input)), None) if surface: self.input.remove(surface) self.surface = surface if self.surface is None: self.warning("Can't find surface for {0}, creating one...".format(self)) self.surface = self.create_surface()
def handle_surface(self): """ Create the surface that the follicle will slide on if necessary. :return: """ # Hack: Provide backward compatibility for when surface was provided as an input. if self.surface is None: fn_is_nurbsSurface = lambda obj: libPymel.isinstance_of_shape( obj, pymel.nodetypes.NurbsSurface) surface = next(iter(filter(fn_is_nurbsSurface, self.input)), None) if surface: self.input.remove(surface) self.surface = surface if self.surface is None: self.warning( "Can't find surface for {0}, creating one...".format(self)) self.surface = self.create_surface()
def get_surfaces(self): """ :return: All meshes under the mesh group of type mesh. If found nothing, scan the whole scene. """ return filter(lambda x: libPymel.isinstance_of_shape(x, pymel.nodetypes.NurbsSurface), self.get_shapes())
def build(self, stretch=True, squash=False, *args, **kwargs): # TODO: Use self.chain_jnt self._joints = [ input for input in self.input if libPymel.isinstance_of_transform(input, pymel.nodetypes.Joint) ] self._curves = [ input for input in self.input if libPymel.isinstance_of_shape(input, pymel.nodetypes.CurveShape) ] if len(self._joints) < 2: raise Exception( "Can't build SplineIK. Expected at least two joints, got {0}". format(self._joints)) if len(self._curves) < 1: raise Exception( "Can't build SplineIK. Expected at least one nurbsCurve, got {0}" .format(self._curves)) super(SplineIK, self).build(*args, **kwargs) nomenclature_rig = self.get_nomenclature_rig() # todo: handle multiple curves? curve = next(iter(self._curves), None) curve_shape = next((shape for shape in curve.getShapes() if isinstance(shape, pymel.nodetypes.NurbsCurve)), None) # Create ik solver handle_name = nomenclature_rig.resolve('ikHandle') eff_name = nomenclature_rig.resolve('ikEffector') self.ikHandle, self.ikEffector = pymel.ikHandle( solver="ikSplineSolver", curve=curve, startJoint=self._joints[0], endEffector=self._joints[-1], createCurve=False, name=handle_name, parentCurve=False, snapCurve=False) self.ikHandle.setParent(self.grp_rig) self.ikEffector.rename(eff_name) # Create stretch # Todo: use shape instead of transform as curve input? if stretch: stretch_attr = libRigging.create_strech_attr_from_curve( curve_shape) for jnt in self._joints: pymel.connectAttr(stretch_attr, jnt.sx, force=True) # Create squash if squash: num_joints = len(self._joints) squash_attrs = libRigging.create_squash_atts( stretch_attr, num_joints) # Todo: Find correct axis orient for jnt, squash in zip(self._joints, squash_attrs): pymel.connectAttr(squash, jnt.sy, force=True) pymel.connectAttr(squash, jnt.sz, force=True)
def _post_setattr_inputs(self): super(SplineIK, self)._post_setattr_inputs() self._joints = [input for input in self.input if libPymel.isinstance_of_transform(input, pymel.nodetypes.Joint)] self._curves = [input for input in self.input if libPymel.isinstance_of_shape(input, pymel.nodetypes.CurveShape)]
def get_surfaces(self): """ :return: A list of all inputs of type pymel.nodetypes.NurbsSurface. """ return [obj for obj in self.input if libPymel.isinstance_of_shape(obj, pymel.nodetypes.NurbsSurface)]
def get_surface(obj): if libPymel.isinstance_of_shape(obj, pymel.nodetypes.NurbsSurface): return obj