浏览代码

Update the Blender add-on

Instead of using the built-in camera fitting function,
which wants to rotate the camera, it now calculates the
local bounding box of the object for each camera angle.
master
Fen Dweller 3 年前
父节点
当前提交
c8a71e5b20
共有 1 个文件被更改,包括 35 次插入18 次删除
  1. +35
    -18
      scripts/blender/addons/macrovision/ops.py

+ 35
- 18
scripts/blender/addons/macrovision/ops.py 查看文件

@@ -1,6 +1,6 @@
import bpy

from mathutils import Vector, Euler, Color
from mathutils import Vector, Euler, Color, Matrix
import json
import pathlib
import os
@@ -20,22 +20,18 @@ VIEW_DATA = {
"BOTTOM_FLIPPED": [2, 2, 1, "Bottom Flipped"],
}

def read_sci(property):
return property.base * pow(10, property.power)

def get_bounds(objects):
def get_bounds(objects, camera_transform):
xl = []
yl = []
zl = []
for obj in objects:
if not obj.hide_render:
for bounds in obj.bound_box:
v = obj.matrix_world @ Vector(bounds)
xl += [v[0] for c in obj.bound_box]
yl += [v[1] for c in obj.bound_box]
zl += [v[2] for c in obj.bound_box]
for vert in obj.data.vertices:
v = camera_transform @ obj.matrix_world @ vert.co
xl += [v[0]]
yl += [v[1]]
zl += [v[2]]
return (
Vector([min(xl), min(yl), min(zl)]),
Vector([min(xl), min(yl), max(zl)]),
@@ -355,7 +351,7 @@ class MVExport(bpy.types.Operator):
if clobber:
all_data["forms"] = list(filter(lambda form: form["name"] != coll.name, all_data["forms"]))

bounds = get_bounds(coll.objects)
bounds = get_bounds(coll.objects, Matrix())
bounds_seq = []
for bound in bounds:
bounds_seq += [bound[0], bound[1], bound[2]]
@@ -364,7 +360,7 @@ class MVExport(bpy.types.Operator):
dimensions = bound_max - bound_min
size = max(dimensions)
global_bbox_center = 0.5 * (bound_min + bound_max)
view_list = []

lineart.grease_pencil_modifiers['Lineart'].source_collection = coll
@@ -376,15 +372,36 @@ class MVExport(bpy.types.Operator):
view_list = default_views

for angles in view_list:
c.location = global_bbox_center
# start the camera in vaguely the right position
point = global_bbox_center
print(global_bbox_center)
c.location = point
c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2])
print(list(bound_min) + list(bound_max))
_, c.data.ortho_scale = c.camera_fit_coords(bpy.context.evaluated_depsgraph_get(), bounds_seq)
c.location = Vector([c.location[0], c.location[1], c.location[2]])
c.data.ortho_scale *= 1.1
rot = c.rotation_euler.to_matrix()
rot.invert()
c.location += Vector([0, 0, size * 2]) @ rot

# Having modified the transform, we need to update everything
bpy.context.view_layer.update()

matrix = c.matrix_world.copy()
matrix.invert()
local_bounds = get_bounds(coll.objects, matrix)

print(local_bounds)
local_bbox_center = (local_bounds[0] + local_bounds[-1]) / 2
print("Center: ", c.matrix_world @ local_bbox_center)

print(local_bounds[0])
print(local_bounds[-1])

delta_x = local_bounds[-1][0] - local_bounds[0][0]
delta_y = local_bounds[-1][1] - local_bounds[0][1]

c.location = c.matrix_world @ local_bbox_center
c.location += Vector([0, 0, size * 2]) @ rot
c.data.ortho_scale = max(delta_x, delta_y)
c.data.ortho_scale *= 1.05
c.data.clip_start = size / 4
c.data.clip_end = size * 8



正在加载...
取消
保存