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_uv(driver_name, mesh_name): """ get the closest point on surface UV values. :param driver_name: <str> the driving object. :param mesh_name: <str> the mesh object. :return: <tuple> U, V, """ shape_fn = object_utils.get_shape_fn(mesh_name)[0] if object_utils.is_shape_nurbs_surface(mesh_name): param_u = object_utils.ScriptUtil(0.0, as_double_ptr=True) param_v = object_utils.ScriptUtil(0.0, as_double_ptr=True) cpos = get_closest_point(driver_name, mesh_name, as_point=True) shape_fn.getParamAtPoint(cpos, param_u.ptr, param_v.ptr, OpenMaya.MSpace.kObject) return param_u.get_double(), param_v.get_double(),
def get_parameter_tangent(driver_name, curve_name): """ for nurbs curves only. get the normal from parameter value. :param driver_name: <str> the driving object. :param curve_name: <str> the mesh object. :return: <tuple> normal value. """ shape_fn = object_utils.get_shape_fn(curve_name)[0] c_param = get_closest_parameter(driver_name, curve_name) tangent = object_utils.ScriptUtil(0.0, as_double_ptr=True) shape_fn.tangent(c_param, tangent.ptr) return tangent.get_double(),
def get_closest_parameter(driver_name, curve_name, normalize=False): """ for nurbs curves only. get the closest parameter value. :param driver_name: <str> the driving object. :param curve_name: <str> the mesh object. :param normalize: <bool> if set True, returns a normalized parameter value. :return: <tuple> parameter value. """ shape_fn = object_utils.get_shape_fn(curve_name)[0] cpoc = get_closest_point(driver_name, curve_name, as_point=True) param_u = object_utils.ScriptUtil(0.0, as_double_ptr=True) shape_fn.getParamAtPoint(cpoc, param_u.ptr) if normalize: return param_u.get_double() / get_param_length(curve_name) else: return param_u.get_double(),
def get_component_data(objects_array=(), uv=False, position=True, as_m_vector=False, world_space=True, object_space=False, rounded=True): """ get the component indices data :param objects_array: <tuple> (optional) array of objects. to iterate over. Else iterates over selected items. :param position: <bool> get X, Y, Z position values from component index selected. :param uv: <bool> get UV data, not implemented correctly. :param as_m_vector: <bool> return as an OpenMaya.MVector object. :param world_space: <bool> return the position in world space co-ordinates. :param object_space: <bool> return the position in object space co-ordinates. :param rounded: <bool> the positional data will be rounded to 4 significant digits. :return: <dict> tuples of indices. """ objects_array = check_and_convert_obj_into_array(objects_array) m_iter = object_utils.get_m_selection_iter(objects_array) items = {} while not m_iter.isDone(): m_dag = OpenMaya.MDagPath() m_component = OpenMaya.MObject() m_iter.getDagPath(m_dag, m_component) if object_utils.get_shapes_len(m_dag): m_shape_dag = object_utils.get_shape_dag(m_dag) sel = OpenMaya.MSelectionList() sel.add(m_shape_dag) m_dag = OpenMaya.MDagPath() m_component = OpenMaya.MObject() sel.getDagPath(0, m_dag, m_component) # if nurbsSurface shape if object_utils.is_shape_nurbs_surface(m_dag): s_iter = OpenMaya.MItSurfaceCV(m_dag, m_component) while not s_iter.isDone(): key_name = s_iter.index() items = init_data_dict(key_name, data_dict=items) if uv: int_u = object_utils.ScriptUtil(as_int_ptr=True) int_v = object_utils.ScriptUtil(as_int_ptr=True) s_iter.getIndex(int_u.ptr, int_v.ptr) items.update( updata_data_dict(key_name, 'uv', (int_u.get_int(), int_v.get_int()), data_dict=items)) if position: m_point = s_iter.position( get_space(world_space, object_space)) if as_m_vector: vector = OpenMaya.MVector(m_point) elif not as_m_vector: vector = round(m_point.x, 4), round(m_point.y, 4), round(m_point.z, 4), items.update( updata_data_dict(key_name, 'position', vector, data_dict=items)) s_iter.next() # if mesh shape if object_utils.is_shape_mesh(m_dag): msh_iter = OpenMaya.MItMeshVertex(m_dag, m_component) while not msh_iter.isDone(): key_name = msh_iter.index() items = init_data_dict(key_name, data_dict=items) if uv: float2 = object_utils.ScriptUtil((0.0, 0.0), as_float2_ptr=True) msh_iter.getUV(float2.ptr, 'map1') items.update( updata_data_dict(key_name, 'uv', float2.get_float2_item(), data_dict=items)) if position: m_point = msh_iter.position( get_space(world_space, object_space)) if as_m_vector: vector = OpenMaya.MVector(m_point) elif not as_m_vector: vector = round(m_point.x, 4), round(m_point.y, 4), round(m_point.z, 4), items.update( updata_data_dict(key_name, 'position', vector, data_dict=items)) msh_iter.next() m_iter.next() return items
def get_data(m_dag, m_component, world_space=True, index=False, uv=False, position=False, as_m_vector=False, object_space=False, uv_map_name="map1"): """ grabs the data from the m_dag and the m_component parameters given. :param m_dag: <OpenMaya.MDagPath> :param m_component: <OpenMaya.MObject> :param world_space: <bool> if True, get the vectors in world space coordinates. :param index: <bool> if True, get the vertex/ CV indices. :param uv: <bool> if True, get the UV indices. :param position: <bool> if True, get the position x y z. :param as_m_vector: <bool> if True, return position in world space. :param object_space: <bool> if True, return position in object space. :param uv_map_name: <str> the UV map name to get coordinates from. :return: <tuple> array of requested items. """ data = () # if nurbsSurface shape if object_utils.is_shape_nurbs_surface(m_dag): s_iter = OpenMaya.MItSurfaceCV(m_dag, m_component) while not s_iter.isDone(): if index: data += s_iter.index(), elif uv: int_u = object_utils.ScriptUtil(as_int_ptr=True) int_v = object_utils.ScriptUtil(as_int_ptr=True) s_iter.getIndex(int_u.ptr, int_v.ptr) data += int_u.get_int(), int_v.get_int(), elif position: m_point = s_iter.position(get_space(world_space, object_space)) if as_m_vector: vector = OpenMaya.MVector(m_point) elif not as_m_vector: vector = m_point.x, m_point.y, m_point.z, data += vector, s_iter.next() # end loop # if mesh shape if object_utils.is_shape_mesh(m_dag): msh_iter = OpenMaya.MItMeshVertex(m_dag, m_component) while not msh_iter.isDone(): if index: data += msh_iter.index(), if uv: float2 = object_utils.ScriptUtil((0.0, 0.0), as_float2_ptr=True) msh_iter.getUV(float2.ptr, uv_map_name) elif position: m_point = msh_iter.position( get_space(world_space, object_space)) if as_m_vector: vector = OpenMaya.MVector(m_point) elif not as_m_vector: vector = m_point.x, m_point.y, m_point.z, data += vector, msh_iter.next() # end loop return data