[Bf-blender-cvs] [5144dca] asset-experiments: Add previews to scenes, and enhance batch preview generation.

Bastien Montagne noreply at git.blender.org
Thu Feb 12 18:01:28 CET 2015


Commit: 5144dcaeabea2777e972ae3f8ce73f84698c1a02
Author: Bastien Montagne
Date:   Wed Feb 11 21:52:15 2015 +0100
Branches: asset-experiments
https://developer.blender.org/rB5144dcaeabea2777e972ae3f8ce73f84698c1a02

Add previews to scenes, and enhance batch preview generation.

Batch preview generation can now also generate 'internal' previews (materials, textures etc.),
as well as scene ones. Also, some basic Cycles handling is there now.
You can now chose which kind of data to generate previews for, and whether the files are
trusted or not (for py autorun and drivers).
And rendering happens in background again, issue was actually a bug in creator.c, fixed in master.
Main TODOs reamining here: OpenGL rendering, and find a way to prevent '.blend1' when
saving over (either as a new option of save op, or simply by removing those files in script?).

Added a batch cleanup of previews too.

Also, added path of files as their tooltip 'image' button in main filebrowser view,
quite useful with the 'recursive' option...

===================================================================

M	release/scripts/modules/bl_previews_utils/bl_previews_render.py
M	release/scripts/startup/bl_operators/wm.py
M	release/scripts/startup/bl_ui/space_info.py
M	source/blender/blenkernel/intern/icons.c
M	source/blender/blenkernel/intern/scene.c
M	source/blender/blenloader/intern/readblenentry.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/editors/interface/interface_icons.c
M	source/blender/editors/space_file/file_draw.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/windowmanager/intern/wm_files.c
M	source/blender/windowmanager/intern/wm_operators.c

===================================================================

diff --git a/release/scripts/modules/bl_previews_utils/bl_previews_render.py b/release/scripts/modules/bl_previews_utils/bl_previews_render.py
index d1551c8..b27ce99 100644
--- a/release/scripts/modules/bl_previews_utils/bl_previews_render.py
+++ b/release/scripts/modules/bl_previews_utils/bl_previews_render.py
@@ -35,72 +35,254 @@ import sys
 import bpy
 from mathutils import Vector, Euler
 
-##### Utils #####
 
-def object_children_recursive(ob):
-    for child in ob.children:
-        yield child
-        yield from object_children_recursive(child)
-
-def object_merge_bbox(bbox, ob, ob_space):
-    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)
-        if bbox[0].x > v.x:
-            bbox[0].x = v.x
-        if bbox[0].y > v.y:
-            bbox[0].y = v.y
-        if bbox[0].z > v.z:
-            bbox[0].z = v.z
-        if bbox[1].x < v.x:
-            bbox[1].x = v.x
-        if bbox[1].y < v.y:
-            bbox[1].y = v.y
-        if bbox[1].z < v.z:
-            bbox[1].z = v.z
-
-
-def do_previews_bi(do_objects, do_groups):
-    render_scene = bpy.data.scenes.new("TEMP_preview_render_scene")
-    render_world = bpy.data.worlds.new("TEMP_preview_render_world")
-    render_camera_data = bpy.data.cameras.new("TEMP_preview_render_camera")
-    render_camera = bpy.data.objects.new("TEMP_preview_render_camera", render_camera_data)
-    render_lamp_data = bpy.data.lamps.new("TEMP_preview_render_lamp", 'SPOT')
-    render_lamp = bpy.data.objects.new("TEMP_preview_render_lamp", render_lamp_data)
-    render_image = None
-
-    objects_ignored = {render_camera, render_lamp}
-    groups_ignored = {}
-
-    render_world.use_sky_blend = True
-    render_world.horizon_color = 0.9, 0.9, 0.9
-    render_world.zenith_color = 0.5, 0.5, 0.5
-    render_world.ambient_color = 0.1, 0.1, 0.1
-    render_world.light_settings.use_environment_light = True
-    render_world.light_settings.environment_energy = 1.0
-    render_world.light_settings.environment_color = 'SKY_COLOR'
-    render_scene.world = render_world
-
-    render_camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ')  # (66.67, 0.0, 45.0)
-    render_scene.camera = render_camera
-    render_scene.objects.link(render_camera)
-
-    render_lamp.rotation_euler = Euler((0.7853981852531433, 0.0, 1.7453292608261108), 'XYZ')  # (45.0, 0.0, 100.0)
-    render_lamp_data.falloff_type = 'CONSTANT'
-    render_lamp_data.spot_size = 1.0471975803375244  # 60
-    render_scene.objects.link(render_lamp)
-
-    render_scene.render.resolution_x = 128
-    render_scene.render.resolution_y = 128
-    render_scene.render.resolution_percentage = 100
-    render_scene.render.alpha_mode = 'TRANSPARENT'
-    render_scene.render.filepath = '/tmp/TEMP_preview_render.png'  # XXX To be done properly!!!!
-
-    prev_scene = bpy.context.screen.scene
-    bpy.context.screen.scene = render_scene
+INTERN_PREVIEW_TYPES = {'MATERIAL', 'LAMP', 'WORLD', 'TEXTURE', 'IMAGE'}
+OBJECT_TYPES_RENDER = {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'}
+
+
+def rna_backup_gen(data, include_props=None, exclude_props=None, root=()):
+    # only writable properties...
+    for p in data.bl_rna.properties:
+        pid = p.identifier
+        if pid in {'rna_type',}:
+            continue
+        path = root + (pid,)
+        if include_props is not None and path not in include_props:
+            continue
+        if exclude_props is not None and path in exclude_props:
+            continue
+        val = getattr(data, pid)
+        if val is not None and p.type == 'POINTER':
+            # recurse!
+            yield from rna_backup_gen(val, include_props, exclude_props, root=path)
+        elif data.is_property_readonly(pid):
+            continue
+        else:
+            yield path, val
+
+
+def rna_backup_restore(data, backup):
+    for path, val in backup:
+        dt = data
+        for pid in path[:-1]:
+            dt = getattr(dt, pid)
+        setattr(dt, path[-1], val)
+
+
+def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
+    # Helpers.
+    RenderContext = collections.namedtuple("RenderContext", (
+        "scene", "world", "camera", "lamp", "camera_data", "lamp_data", "image",
+        "backup_scene", "backup_world", "backup_camera", "backup_lamp", "backup_camera_data", "backup_lamp_data",
+    ))
+
+    def render_context_create(engine, objects_ignored):
+        if engine == '__SCENE':
+            backup_scene, backup_world, backup_camera, backup_lamp, backup_camera_data, backup_lamp_data = [()] * 6
+            scene = bpy.context.screen.scene
+            exclude_props = {('world',), ('camera',), ('tool_settings',), ('preview',)}
+            backup_scene = tuple(rna_backup_gen(scene, exclude_props=exclude_props))
+            world = scene.world
+            camera = scene.camera
+            if camera:
+                camera_data = camera.data
+            else:
+                backup_camera, backup_camera_data = [None] * 2
+                camera_data = bpy.data.cameras.new("TEMP_preview_render_camera")
+                camera = bpy.data.objects.new("TEMP_preview_render_camera", camera_data)
+                camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ')  # (66.67, 0.0, 45.0)
+                scene.camera = camera
+                scene.objects.link(camera)
+            # TODO: add lamp if none found in scene?
+            lamp = None
+            lamp_data = None
+        else:
+            backup_scene, backup_world, backup_camera, backup_lamp, backup_camera_data, backup_lamp_data = [None] * 6
+
+            scene = bpy.data.scenes.new("TEMP_preview_render_scene")
+            world = bpy.data.worlds.new("TEMP_preview_render_world")
+            camera_data = bpy.data.cameras.new("TEMP_preview_render_camera")
+            camera = bpy.data.objects.new("TEMP_preview_render_camera", camera_data)
+            lamp_data = bpy.data.lamps.new("TEMP_preview_render_lamp", 'SPOT')
+            lamp = bpy.data.objects.new("TEMP_preview_render_lamp", lamp_data)
+
+            objects_ignored.add((camera.name, lamp.name))
+
+            scene.world = world
+
+            camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ')  # (66.67, 0.0, 45.0)
+            scene.camera = camera
+            scene.objects.link(camera)
+
+            lamp.rotation_euler = Euler((0.7853981852531433, 0.0, 1.7453292608261108), 'XYZ')  # (45.0, 0.0, 100.0)
+            lamp_data.falloff_type = 'CONSTANT'
+            lamp_data.spot_size = 1.0471975803375244  # 60
+            scene.objects.link(lamp)
+
+            if engine == 'BLENDER_RENDER':
+                scene.render.engine = 'BLENDER_RENDER'
+                scene.render.alpha_mode = 'TRANSPARENT'
+
+                world.use_sky_blend = True
+                world.horizon_color = 0.9, 0.9, 0.9
+                world.zenith_color = 0.5, 0.5, 0.5
+                world.ambient_color = 0.1, 0.1, 0.1
+                world.light_settings.use_environment_light = True
+                world.light_settings.environment_energy = 1.0
+                world.light_settings.environment_color = 'SKY_COLOR'
+            elif engine == 'CYCLES':
+                scene.render.engine = 'CYCLES'
+                scene.cycles.film_transparent = True
+                # TODO: define Cycles world?
+
+        scene.render.image_settings.file_format = 'PNG'
+        scene.render.image_settings.color_depth = '8'
+        scene.render.image_settings.color_mode = 'RGBA'
+        scene.render.image_settings.compression = 25
+        scene.render.resolution_x = 128
+        scene.render.resolution_y = 128
+        scene.render.resolution_percentage = 100
+        scene.render.filepath = '/tmp/TEMP_preview_render.png'  # XXX To be done properly!!!!
+        scene.render.use_overwrite = True
+        scene.render.use_stamp = False
+
+        image = bpy.data.images.new("TEMP_render_image", 128, 128, alpha=True)
+        image.source = 'FILE'
+        image.filepath = scene.render.filepath
+
+        return RenderContext(
+            scene, world, camera, lamp, camera_data, lamp_data, image,
+            backup_scene, backup_world, backup_camera, backup_lamp, backup_camera_data, backup_lamp_data,
+        )
+
+    def render_context_delete(render_context):
+        # Do not crash here, too much things can go wrong...
+        try:
+            scene = render_context.scene
+            if render_context.backup_scene is None:
+                scene.world = None
+                scene.camera = None
+                if render_context.camera:
+                    scene.objects.unlink(render_context.camera)
+                if render_context.lamp:
+                    scene.objects.unlink(render_context.lamp)
+                bpy.data.scenes.remove(scene)
+                scene = None
+            else:
+                rna_backup_restore(scene, render_context.backup_scene)
+            if render_context.backup_world is None:
+                if scene is not None:
+                    scene.world = None
+                bpy.data.worlds.remove(render_context.world)
+            else:
+                rna_backup_restore(render_context.world, render_context.backup_world)
+            if render_context.camera:
+                if render_context.backup_camera is None:
+                    if scene is not None:
+                        scene.camera = None
+                    bpy.data.objects.remove(render_context.camera)
+                    bpy.data.cameras.remove(render_context.camera_data)
+                else:
+                    rna_backup_restore(render_context.camera, render_context.backup_camera)
+                    rna_backup_restore(render_context.camera_data, render_context.backup_camera_data)
+            if render_context.lamp:
+                if render_context.backup_lamp is None:
+                    bpy.data.objects.remove(render_context.lamp)
+                    bpy.data.lamps.remove(re

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list