Laika
Laika

Reputation: 31

Getting the 2D projection from a 3D mesh in python

I am currently trying to get all of the 2d projection of a 3d mesh model of a cat on each face of it 3d bounding box using Python.

You can download the 3d mesh model of a cat here: Cat model

This is my 3d mesh model of a cat with 3d cyan color bounding box: cat model

What i want it to get the 2d projection of my cat onto each faces of the 3d bounding box like how this picture show:

object 2d projection onto bounding box

I have tried the code below but i only manage to get 4 faces of my cat. But the problem is when viewing from azimuth of 90 degrees:

90

and 270 degrees:

270

The image gets stretch because the bounding box is too narrow. I also don't know how to get the top and bottom projection faces of my model.

import trimesh
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Load the 3D mesh file (e.g., STL, OBJ, PLY)
mesh = trimesh.load('/content/12221_Cat_v1_l3.obj')  # Change the path and file type as needed

# Define the angles for the four views
angles = [(azim, 0) for azim in [0, 90, 180 ,270]]  # Set elevation to 0 for a middle view


for i, (azim, elev) in enumerate(angles):
    # Create a new figure for each angle
    fig = plt.figure()

    ax = fig.add_subplot(111, projection='3d')
    ax.set_title(f'View {azim}')

    # Plot the mesh
    ax.plot_trisurf(mesh.vertices[:, 0], mesh.vertices[:, 1], mesh.vertices[:, 2],
                    triangles=mesh.faces, color='cyan', edgecolor='none', alpha=0.5)
    # Set the viewing angle
    ax.view_init(elev=elev, azim=azim)

    # Set limits based on mesh bounds
    max_range = mesh.bounds[1] - mesh.bounds[0]
    mid_x = (mesh.bounds[0][0] + mesh.bounds[1][0]) / 2
    mid_y = (mesh.bounds[0][1] + mesh.bounds[1][1]) / 2
    mid_z = (mesh.bounds[0][2] + mesh.bounds[1][2]) / 2

    ax.set_xlim(mid_x - max_range[0] / 2, mid_x + max_range[0] / 2)
    ax.set_ylim(mid_y - max_range[1] / 2, mid_y + max_range[1] / 2)
    ax.set_zlim(mid_z - max_range[2] / 2, mid_z + max_range[2] / 2)

    # Hide axes
    ax.axis('off')

    # Save the figure as an image without axes
    plt.savefig(f'mesh_view_{i + 1}.png', bbox_inches='tight', pad_inches=0, dpi=300)
    plt.close(fig)  # Close the figure

Upvotes: 3

Views: 138

Answers (0)

Related Questions