Fix T47314: Misaligned DataBlock Previews for groups with custom center coordinates

Now take into account `dupli_offset` of groups.

Also fixed another issue related to objects renderability, previous code was giving
bad results due to added temp objects to generate previews (camera, lamp...).
This commit is contained in:
Bastien Montagne 2016-02-11 17:32:21 +01:00
parent 1d0e084834
commit 7428ccfd6d
Notes: blender-bot 2023-04-14 09:18:04 +02:00
Referenced by issue #47314, Misaligned DataBlock Previews for groups with custom center coordinates
1 changed files with 17 additions and 12 deletions

View File

@ -26,7 +26,7 @@ import os
import sys
import bpy
from mathutils import Vector, Euler
from mathutils import Vector, Euler, Matrix
INTERN_PREVIEW_TYPES = {'MATERIAL', 'LAMP', 'WORLD', 'TEXTURE', 'IMAGE'}
@ -246,13 +246,14 @@ def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
return 'CYCLES'
return 'BLENDER_RENDER'
def object_bbox_merge(bbox, ob, ob_space):
def object_bbox_merge(bbox, ob, ob_space, offset_matrix):
if ob.bound_box:
ob_bbox = ob.bound_box
else:
ob_bbox = ((-ob.scale.x, -ob.scale.y, -ob.scale.z), (ob.scale.x, ob.scale.y, ob.scale.z))
for v in ob.bound_box:
v = ob_space.matrix_world.inverted() * ob.matrix_world * Vector(v)
for v in ob_bbox:
v = offset_matrix * Vector(v) if offset_matrix is not None else Vector(v)
v = ob_space.matrix_world.inverted() * ob.matrix_world * v
if bbox[0].x > v.x:
bbox[0].x = v.x
if bbox[0].y > v.y:
@ -266,11 +267,11 @@ def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
if bbox[1].z < v.z:
bbox[1].z = v.z
def objects_bbox_calc(camera, objects):
def objects_bbox_calc(camera, objects, offset_matrix):
bbox = (Vector((1e9, 1e9, 1e9)), Vector((-1e9, -1e9, -1e9)))
for obname in objects:
ob = bpy.data.objects[obname, None]
object_bbox_merge(bbox, ob, camera)
object_bbox_merge(bbox, ob, camera, offset_matrix)
# Our bbox has been generated in camera local space, bring it back in world one
bbox[0][:] = camera.matrix_world * bbox[0]
bbox[1][:] = camera.matrix_world * bbox[1]
@ -286,12 +287,12 @@ def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
)
return cos
def preview_render_do(render_context, item_container, item_name, objects):
def preview_render_do(render_context, item_container, item_name, objects, offset_matrix=None):
scene = bpy.data.scenes[render_context.scene, None]
if objects is not None:
camera = bpy.data.objects[render_context.camera, None]
lamp = bpy.data.objects[render_context.lamp, None] if render_context.lamp is not None else None
cos = objects_bbox_calc(camera, objects)
cos = objects_bbox_calc(camera, objects, offset_matrix)
loc, ortho_scale = camera.camera_fit_coords(scene, cos)
camera.location = loc
if lamp:
@ -322,7 +323,7 @@ def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
prev_scenename = bpy.context.screen.scene.name
if do_objects:
prev_shown = tuple(ob.hide_render for ob in ids_nolib(bpy.data.objects))
prev_shown = {ob.name: ob.hide_render for ob in ids_nolib(bpy.data.objects)}
for ob in ids_nolib(bpy.data.objects):
if ob in objects_ignored:
continue
@ -368,8 +369,10 @@ def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
scene.objects.unlink(ob)
ob.hide_render = True
for ob, is_rendered in zip(tuple(ids_nolib(bpy.data.objects)), prev_shown):
ob.hide_render = is_rendered
for ob in ids_nolib(bpy.data.objects):
is_rendered = prev_shown.get(ob.name, ...)
if is_rendered is not ...:
ob.hide_render = is_rendered
if do_groups:
for grp in ids_nolib(bpy.data.groups):
@ -391,7 +394,9 @@ def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
grp_obname = grp_ob.name
scene.update()
preview_render_do(render_context, 'groups', grp.name, objects)
offset_matrix = Matrix.Translation(grp.dupli_offset).inverted()
preview_render_do(render_context, 'groups', grp.name, objects, offset_matrix)
scene = bpy.data.scenes[render_context.scene, None]
scene.objects.unlink(bpy.data.objects[grp_obname, None])