You could try something like pyrender.
For documentation purposes here’s one of their example:
import numpy as np import trimesh import pyrender import matplotlib.pyplot as plt fuze_trimesh = trimesh.load('examples/models/fuze.obj') mesh = pyrender.Mesh.from_trimesh(fuze_trimesh) scene = pyrender.Scene() scene.add(mesh) camera = pyrender.PerspectiveCamera(yfov=np.pi / 3.0, aspectRatio=1.0) s = np.sqrt(2)/2 camera_pose = np.array([ [0.0, -s, s, 0.3], [1.0, 0.0, 0.0, 0.0], [0.0, s, s, 0.35], [0.0, 0.0, 0.0, 1.0], ]) scene.add(camera, pose=camera_pose) light = pyrender.SpotLight(color=np.ones(3), intensity=3.0, innerConeAngle=np.pi/16.0, outerConeAngle=np.pi/6.0) scene.add(light, pose=camera_pose) r = pyrender.OffscreenRenderer(400, 400) color, depth = r.render(scene) plt.figure() plt.subplot(1,2,1) plt.axis('off') plt.imshow(color) plt.subplot(1,2,2) plt.axis('off') plt.imshow(depth, cmap=plt.cm.gray_r) plt.show()
or Open3D.
Again, one of the library supplied examples:
pcd = o3d.io.read_point_cloud("../../TestData/fragment.ply") o3d.visualization.draw_geometries([pcd], zoom=0.3412, front=[0.4257, -0.2125, -0.8795], lookat=[2.6172, 2.0475, 1.532], up=[-0.0694, -0.9768, 0.2024])