pythonopen3dtrimesh

rotate a mesh in python to be parallel to a vector


I have two meshes (call them A and B) which I am interacting within python using the open3d library (happy to use import trimesh or something else if it works better). Mesh A is a curved structure and mesh B approximates to a flatter surface.

I need to rotate the meshes so that the surface I am interested in is facing the camera. To identify the surfaces that I need I have written functions to turn the meshes into point clouds and create the best fit sphere for mesh A and a best-fit plane for mesh B. These work really well and match the objects nicely.

I need to rotate the meshes and have gotten stuck with how to perform the rotation.

The input data that I have:

for mesh A: centroid of mesh A coords and coords of its best fit sphere (+ its radius) - I want to rotate the mesh so that is perpendicular to the vector described by the above data?

for mesh B: centroid of mesh B coords and vector of the normal of the best fit plane - I want to rotate the mesh so that is perpendicular to the vector described by the above data


Solution

  • Solved it! created two vectors as numpy arrays, vector 1 and vector2 and found the open3d commands to center the mesh and apply the rotation matrix between the two vectors. Think this is susceptible to gimbal lock but I cant get my head around quaternions and it works well enough for my usage scenario.

    #this function to create a rotation matrix was taken from https://stackoverflow.com/q/63525482/6010071
    def rotation_matrix_from_vectors(vec1, vec2):
    
        a, b = (vec1 / np.linalg.norm(vec1)).reshape(3), (vec2 / np.linalg.norm(vec2)).reshape(3)
        v = np.cross(a, b)
        c = np.dot(a, b)
        s = np.linalg.norm(v)
        kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])
        rotation_matrix = np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2))
        return rotation_matrix
    #to move the mesh to 0,0,0 (using open3d library)
    mesh.translate(-mesh.get_center())
    # to rotate the mesh to variable vector2, i set it to np.array([0,0,1]) = in line with z axis again using open3d library
    mesh.rotate(rotation_matrix_from_vectors(vector1,vector2),center=(0,0,0))