def copy_attr(self, attr_cls, non_zero=False, match_world_space=False): """ copy the non-default attributes of one attribute class to another. :param non_zero: <bool> match only the non-zero attributes. :param match_world_space: <bool> copy the transforms if worldspace positions are not the same. :return: <True> for success. """ target_tfm = transform_utils.Transform(attr_cls.MAYA_STR_OBJECT) source_tfm = transform_utils.Transform(self.MAYA_STR_OBJECT) if match_world_space: if source_tfm.world_matrix_list() != target_tfm.world_matrix_list( ): cmds.xform(self.MAYA_STR_OBJECT, m=target_tfm.world_matrix_list(), ws=1) return target_tfm.world_matrix_list(), # if the world spaces match, perform the operation to copy attributes. else: if non_zero: attrs = attr_cls.non_zero_attributes() else: attrs = attr_cls for attr, val in attrs.items(): if attr in self.__dict__(): if self.is_attr_connected(attr) or self.is_attr_locked( attr): continue self.set_attributes(attr, val) return True
def get_vector_positon_2_objects(object_1, object_2, divisions=2): """ calculates the world space vector between the two points. :return: <tuple> vector positions. """ vector_1 = transform_utils.Transform(object_1).translate_values(world=True) vector_2 = transform_utils.Transform(object_2).translate_values(world=True) return get_vector_position_2_points(vector_1, vector_2, divisions)
def look_at(source, target, up_vector=(0, 1, 0), as_vector=True): """ allows the transform object to look at another target vector object. :return: <tuple> rotational vector. """ source_world = transform_utils.Transform(source).world_matrix_list() target_world = transform_utils.Transform(target).world_matrix_list() source_parent_name = object_utils.get_parent_name(source)[0] if source_parent_name == 'world': source_parent_name = None else: parent_world = transform_utils.Transform(source_parent_name).world_matrix_list() # build normalized vector from the translations from matrix data z = MVector(target_world[12] - source_world[12], target_world[13] - source_world[13], target_world[14] - source_world[14]) z *= -1 z.normalize() # get normalized cross product of the z against the up vector at origin # x = z ^ MVector(-up_vector[0], -up_vector[1], -up_vector[2]) x = z ^ MVector(up_vector[0], up_vector[1], up_vector[2]) x.normalize() # get the normalized y vector y = x ^ z y.normalize() # build the aim matrix local_matrix_list = ( x.x, x.y, x.z, 0, y.x, y.y, y.z, 0, z.x, z.y, z.z, 0, 0, 0, 0, 1.0) matrix = object_utils.ScriptUtil(local_matrix_list, matrix_from_list=True).matrix if source_parent_name: # transform the matrix in the local space of the parent object parent_matrix = object_utils.ScriptUtil(parent_world, matrix_from_list=True) matrix *= parent_matrix.matrix.inverse() # retrieve the desired rotation for "source" to aim at "target", in degrees if as_vector: rotation = MTransformationMatrix(matrix).eulerRotation() * RADIANS_2_DEGREES vector = rotation.asVector() return vector.x, vector.y, vector.z, else: return local_matrix_list
def get_closest_point(driver_name, mesh_name, as_point=False, tree_based=False): """ uses the Function set Shape to get the closestPoint positions. :param driver_name: <str> the driving object. :param mesh_name: <str> the mesh object. :param as_point: <bool> if True, return as a <OpenMaya.MPoint> object. Else return as a tuple(x, y, z). :param tree_based: <bool> get the closest point on nurbsSurface using treeBased algorithm. :return: <tuple> x, y, z. <OpenMaya.MPoint>. """ shape_fn = object_utils.get_shape_fn(mesh_name)[0] # the get_shape_obj function returns a tuple of children items, so we only need one. shape_obj = object_utils.convert_list_to_str(object_utils.get_shape_obj(mesh_name)) mesh_dag = object_utils.get_dag(mesh_name) try: driver_vector = transform_utils.Transform(driver_name).translate_values(as_m_vector=True, world=True) except RuntimeError: # object is incompatible with this method driver_vector = mesh_utils.get_component_position(driver_name, as_m_vector=True, world_space=True) # get the parent inverse matrix m_matrix = mesh_dag.inclusiveMatrixInverse() if object_utils.is_shape_nurbs_surface(mesh_name): m_point = OpenMaya.MPoint(driver_vector) if tree_based: m_nurb_intersect = OpenMaya.MNurbsIntersector() m_nurb_intersect.create(shape_obj, m_matrix) point_nurb = OpenMaya.MPointOnNurbs() m_nurb_intersect.getClosestPoint(m_point, point_nurb) result_point = point_nurb.getPoint() else: m_point *= m_matrix result_point = shape_fn.closestPoint(m_point) if as_point: return result_point return unpack_vector(result_point * mesh_dag.inclusiveMatrix()) elif object_utils.is_shape_mesh(mesh_name): m_point = OpenMaya.MPoint(driver_vector) result_m_point = OpenMaya.MPoint() shape_fn.getClosestPoint(m_point, result_m_point) if as_point: return result_m_point return unpack_vector(result_m_point) elif object_utils.is_shape_nurbs_curve(mesh_name): m_point = OpenMaya.MPoint(driver_vector) m_point *= m_matrix result_point = shape_fn.closestPoint(m_point) if as_point: return result_point return unpack_vector(result_point * mesh_dag.inclusiveMatrix()) else: OpenMaya.MGlobal.displayError("[ClosestPoint] :: Invalid object.") return False
def reflection_vector(object_name, as_array=True): """ calculates the reflection vector from the origin. R = 2(N * L) * N - L :return: """ array_1 = transform_utils.Transform(object_name).translate_values(world=True) vector_1 = MVector(*array_1) normal = MVector(0.0, 1.0, 0.0) vector = normal * (2 * (normal * vector_1)) vector -= vector_1 if not as_array: return vector else: return vector.x, vector.y, vector.z
from maya import OpenMaya from maya import cmds # import local modules import object_utils import math_utils import transform_utils # define local variables __shape_name__ = 'nurbsCurve' connect_attr = object_utils.connect_attr create_node = object_utils.create_node attr_name = object_utils.attr_name attr_set = object_utils.attr_set world_transform = lambda x: transform_utils.Transform( x).get_world_translation_list() def get_all_nurb_objs(): """ traverses the scene to get all nurbsCurve objects. :return: <tuple> array of nurbsCurve objects. """ return object_utils.get_scene_objects(node_type=__shape_name__) def get_all_nurb_fn(): """ traverses the scene to get all nurbsCurve function objects. :return: <tuple> array of nurbsCurve function objects. """