0
$\begingroup$

New description : The goal is to capture snapshots of a 3d model. For that, I need to ensure the model fits the Camera view well. The Camera location will be provided by the client, which cannot be changed. The Camera can be positioned anywhere. The model will always be positioned at the Centre. How to determine the scaling factor automatically, for the 3d model?

Previous description : I am new to Blender. The goal is to capture snapshots of a 3d model. For that, I need to scale it down/up according to the camera position(and probably "focal length" too), so that the model fits well in the snapshot. My task is to automate all of this. For determining the scaling factor, I think I would need to know the area captured by a Camera at the origin(since the 3d model will always be centered at origin). Is there a formula to calculate the area ? Then I can use that to scale down the object along all 3 axis.

$\endgroup$
2

2 Answers 2

0
$\begingroup$

You need to write a full script for this, I've made one that iteratively zoom the camera in and out until the object fit the frame by checking for 2D view bounds. Here is the function that helped me achieve this (that I stole from somewhere else):

def camera_view_bounds_2d(obj): #Returns camera space bounding box of mesh object.

scene = bpy.context.scene
cam_ob = scene.camera
mat = cam_ob.matrix_world.normalized().inverted()
depsgraph = bpy.context.evaluated_depsgraph_get()
mesh_eval = obj.evaluated_get(depsgraph)
me = mesh_eval.to_mesh()
me.transform(obj.matrix_world)
me.transform(mat)

camera = cam_ob.data
frame = [-v for v in camera.view_frame(scene=scene)[:3]]
camera_persp = camera.type != 'ORTHO'

lx = []
ly = []

for v in me.vertices:
    co_local = v.co
    z = -co_local.z

    if camera_persp:
        if z == 0.0:
            lx.append(0.5)
            ly.append(0.5)
        else:
            frame = [(v / (v.z / z)) for v in frame]

    min_x, max_x = frame[1].x, frame[2].x
    min_y, max_y = frame[0].y, frame[1].y

    x = (co_local.x - min_x) / (max_x - min_x + .001)
    y = (co_local.y - min_y) / (max_y - min_y + .001)

    lx.append(x)
    ly.append(y)

min_x = clamp(min(lx), 0.0, 1.0)
max_x = clamp(max(lx), 0.0, 1.0)
min_y = clamp(min(ly), 0.0, 1.0)
max_y = clamp(max(ly), 0.0, 1.0)

mesh_eval.to_mesh_clear()

r = scene.render
fac = r.resolution_percentage * 0.01
dim_x = r.resolution_x * fac
dim_y = r.resolution_y * fac
$\endgroup$
2
0
$\begingroup$

Not sure that I completely understand what you're attempting to do but I think you want to recreate the actual scaling that you would see from a real physical imaging configuration. If that's true, try working out the distances and focal lengths according to the simple relationship that the ratio of the focal length to the image size is the same as the ratio of the camera distance to the image footprint at the object in question. f/s = D/S where f is the camera focal length, s is the size of the image, D is the camera Distance and S is the image footprint in scene space. Hope that helps move things along.

Updated comment: So someone is providing you with pictures of a 3 dimensional object (i assume from different angles) and they are telling you how far away the object is but they are not telling the focal length of the camera? I'm guessing that the goal is that you hope to create a Blender model of the object and that the dimensions of that product will be the same as the original object. Even though you have multiple pictures, you either need to know the focal length or at least one dimension of the object (like height) in order to properly set the scale.

$\endgroup$
1
  • $\begingroup$ Thank you for the reply. I have updated the description. Hope its clear now. $\endgroup$ Aug 18, 2021 at 11:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .