ソースを参照

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



読み込み中…
キャンセル
保存