Fix T47314: Misaligned DataBlock Previews for groups with custom center coordinates
authorBastien Montagne <montagne29@wanadoo.fr>
Thu, 11 Feb 2016 16:32:21 +0000 (17:32 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 11 Feb 2016 16:34:08 +0000 (17:34 +0100)
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...).

release/scripts/modules/bl_previews_utils/bl_previews_render.py

index 627a6ab2d3d26c1c9772b551a71f5a0757f6149f..beee78b3ce03a6d7a19ce599ca41950d521d38fe 100644 (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])