# Calculating Area of Object as Rendered from the Camera

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[0], center[1], center[2]+d)

A_0 = CalcHullArea(obj, location, 0)
A_1 = CalcHullArea(obj, location, 100)

print(A_0, A_1)


• Feb 11 at 12:17
• in complement, looking at the code here github.com/dfelinto/blender/blob/… you can optimize things a bit Feb 11 at 12:24