I am trying to build a program to optimise the position of a camera such that the object in question fills the render. The bounding box is inadequate for renders from 45 degree angles, for instance.
I am attempting to achieve this by projecting the vertices to their 2D representation from the camera perspective and finding the convex hull. This I can compare to the area of the viewport.
However, the program outputs the same vertices regardless of my transformation matrix. I am new to Blender and therefore am a bit lost.
Can someone suggest what might be wrong here? I am using Blender 3.4.1.
import numpy as np from scipy.spatial import ConvexHull def CalcHullArea(obj, location, distance): scene = bpy.context.scene camera = scene.camera m_0 = np.asarray(camera.matrix_world.copy()) camera.location = location(distance) camera.update_tag() bpy.context.view_layer.update() m_1 = np.asarray(camera.matrix_world.copy()) ## Check m_0 and m_1 are different. assert (!np.allclose(m_0, m_1)) # Get the world matrix of the object world_matrix = obj.matrix_world # Get the inverse of the camera matrix camera_matrix = camera.matrix_world.inverted() # Get the projection matrix of the camera projection_matrix = camera.calc_matrix_camera( bpy.context.evaluated_depsgraph_get(), x=scene.render.resolution_x, y=scene.render.resolution_y ) # Combine the world space matrix, camera inverse matrix, and projection matrix combined_matrix = projection_matrix @ camera_matrix @ world_matrix # Project the vertices of the object to 2D screen space verts_2D = np.array([np.array((vert.co @ combined_matrix))[:2] for vert in obj.data.vertices]) # Compute the convex hull of the 2D screen space vertices hull = ConvexHull(verts_2D) # Calculate the area of the convex hull area = hull.volume return area # Example usage obj = bpy.context.active_object center = obj.location location = lambda d: (center, center, center+d) A_0 = CalcHullArea(obj, location, 0) A_1 = CalcHullArea(obj, location, 100) print(A_0, A_1)