def get_head_length(self): jnt_head = self.get_head_jnt() if not jnt_head: self.warning("Can't resolve head length!") ref_tm = jnt_head.getMatrix(worldSpace=True) geometries = libRigging.get_affected_geometries(jnt_head) # Resolve the top of the head location bot = pymel.datatypes.Point(ref_tm.translate) #dir = pymel.datatypes.Point(1,0,0) * ref_tm #dir = dir.normal() # This is strange but not pointing to the world sometime don't work... # TODO: FIX ME dir = pymel.datatypes.Point(0,1,0) top = libRigging.ray_cast_farthest(bot, dir, geometries) if not top: self.warning("Can't resolve head top location using raycasts using {0} {1}!".format( bot, dir )) return None return libPymel.distance_between_vectors(bot, top)
def get_head_length(self, jnt_head): """ Resolve a head influence height using raycasts. This is in the Rig class to increase performance using the caching mechanism. :param jnt_head: The head influence to mesure. :return: A float representing the head length. None if unsuccessful. """ ref_tm = jnt_head.getMatrix(worldSpace=True) geometries = libHistory.get_affected_shapes(jnt_head) # Resolve the top of the head location bot = pymel.datatypes.Point(ref_tm.translate) # dir = pymel.datatypes.Point(1,0,0) * ref_tm # dir = dir.normal() # This is strange but not pointing to the world sometime don't work... # TODO: FIX ME dir = pymel.datatypes.Point(0, 1, 0) top = libRigging.ray_cast_farthest(bot, dir, geometries) if not top: self.warning("Can't resolve head top location using raycasts using {0} {1}!".format( bot, dir )) return None return libPymel.distance_between_vectors(bot, top)
def get_head_length(self): jnt_head = self.get_head_jnt() if not jnt_head: self.warning("Can't resolve head length!") ref_tm = jnt_head.getMatrix(worldSpace=True) geometries = libRigging.get_affected_geometries(jnt_head) # Resolve the top of the head location bot = pymel.datatypes.Point(ref_tm.translate) #dir = pymel.datatypes.Point(1,0,0) * ref_tm #dir = dir.normal() # This is strange but not pointing to the world sometime don't work... # TODO: FIX ME dir = pymel.datatypes.Point(0, 1, 0) top = libRigging.ray_cast_farthest(bot, dir, geometries) if not top: self.warning( "Can't resolve head top location using raycasts using {0} {1}!" .format(bot, dir)) return None return libPymel.distance_between_vectors(bot, top)
def get_face_macro_ctrls_distance_from_head(self, multiplier=1.2, default_distance=20): """ :return: The recommended distance between the head middle and the face macro ctrls. """ jnt_head = self.get_head_jnt() if not jnt_head: log.warning( "Cannot resolve desired macro avars distance from head. Using default ({0})" .format(default_distance)) return default_distance ref_tm = jnt_head.getMatrix(worldSpace=True) geometries = libRigging.get_affected_geometries(jnt_head) # Resolve the top of the head location pos = pymel.datatypes.Point(ref_tm.translate) #dir = pymel.datatypes.Point(1,0,0) * ref_tm #dir = dir.normal() # This is strange but not pointing to the world sometime don't work... # TODO: FIX ME dir = pymel.datatypes.Point(0, 1, 0) top = next(iter(libRigging.ray_cast(pos, dir, geometries)), None) if not top: raise Exception("Can't resolve head top location using raycasts!") # Resolve the middle of the head middle = ((top - pos) * 0.5) + pos # Find the front of the face # For now, one raycase seem fine. #dir = pymel.datatypes.Point(0,-1,0) * ref_tm #dir.normalize() dir = pymel.datatypes.Point(0, 0, 1) front = next(iter(libRigging.ray_cast(middle, dir, geometries)), None) if not front: raise Exception( "Can't resolve head front location using raycasts!") distance = libPymel.distance_between_vectors(middle, front) return distance * multiplier
def calibrate_attr_using_translation(attr, ref, step_size=0.1, epsilon=0.01, default=1.0): """ Return the distance that @ref move when @attr is changed. This is used to automatically tweak the ctrl sensibility so the doritos have a more pleasant feel. Note that to compensate non-linear movement, a small value (@step_size) is used. """ attr.set(0) pos_s = ref.getTranslation(space='world') attr.set(-step_size) # HACK: Jaw only deforme the face in the negative direction... pos_e = ref.getTranslation(space='world') attr.set(0) distance = libPymel.distance_between_vectors(pos_s, pos_e) / step_size if distance > epsilon: return distance else: log.warning("Can't detect sensibility for {0}".format(attr)) return default
def get_average_pos_between_nodes(jnts): nearest_jnt = None nearest_distance = None middle = get_average_pos_between_vectors(jnts) middle.y = 0 middle.z = 0 for jnt in jnts: jnt_pos = jnt.getTranslation(space='world') jnt_pos.y = 0 jnt_pos.z = 0 distance = libPymel.distance_between_vectors(jnt_pos, middle) #distance = abs(.x) if nearest_jnt is None or distance < nearest_distance: nearest_jnt = jnt nearest_distance = distance return nearest_jnt
def get_closest_point_on_shapes(meshes, pos): """ Return informations about the closest intersection between a point and multiple mesh polygons. :param mesh: A pymel.nodetypes.Mesh to analyze. :param pos: A pymel.datatypes.Vector world-space position. :return: A 4-sized tuple containing: - A pymel.nodetypes.Mesh instance representing the closest mesh. - A pymel.datatypes.Vector representing the closest intersection between the mesh and the provided position. - The u coordinate of the resulting position. - The v coordinate of the resulting position. If nothing is found, a 4-sized tuple containing all None values are returned. """ shortest_delta = None return_val = (None, None, None, None) for mesh in meshes: closest_pos, closest_u, closest_v = get_closest_point_on_shape(mesh, pos) delta = libPymel.distance_between_vectors(pos, closest_pos) if shortest_delta is None or delta < shortest_delta: shortest_delta = delta return_val = (mesh, closest_pos, closest_u, closest_v) return return_val
def get_face_macro_ctrls_distance_from_head(self, multiplier=1.2, default_distance=20): """ :return: The recommended distance between the head middle and the face macro ctrls. """ jnt_head = self.get_head_jnt() if not jnt_head: log.warning("Cannot resolve desired macro avars distance from head. Using default ({0})".format(default_distance)) return default_distance ref_tm = jnt_head.getMatrix(worldSpace=True) geometries = libRigging.get_affected_geometries(jnt_head) # Resolve the top of the head location pos = pymel.datatypes.Point(ref_tm.translate) #dir = pymel.datatypes.Point(1,0,0) * ref_tm #dir = dir.normal() # This is strange but not pointing to the world sometime don't work... # TODO: FIX ME dir = pymel.datatypes.Point(0,1,0) top = next(iter(libRigging.ray_cast(pos, dir, geometries)), None) if not top: raise Exception("Can't resolve head top location using raycasts!") # Resolve the middle of the head middle = ((top-pos) * 0.5) + pos # Find the front of the face # For now, one raycase seem fine. #dir = pymel.datatypes.Point(0,-1,0) * ref_tm #dir.normalize() dir = pymel.datatypes.Point(0,0,1) front = next(iter(libRigging.ray_cast(middle, dir, geometries)), None) if not front: raise Exception("Can't resolve head front location using raycasts!") distance = libPymel.distance_between_vectors(middle, front) return distance * multiplier
def ray_cast_farthest(pos, *args, **kwargs): results = ray_cast(pos, *args, **kwargs) results = sorted(results, key=lambda x: libPymel.distance_between_vectors(pos, x)) return next(iter(reversed(results)), None)