Cycles: support for multiple render layers. It currently renders each layer
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 21 Dec 2011 20:51:55 +0000 (20:51 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 21 Dec 2011 20:51:55 +0000 (20:51 +0000)
entirely before moving on to the next.

intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_mesh.cpp
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_session.cpp
intern/cycles/blender/blender_session.h
intern/cycles/blender/blender_sync.cpp
intern/cycles/blender/blender_sync.h

index d631158f5eba29c1aa15f9b9615b4cf6ae6c4ecc..24f3de6e8590d542428dc8a67a8b9ca1485a637a 100644 (file)
@@ -160,18 +160,17 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
         scene = context.scene
         rd = scene.render
 
-        row = layout.row()
-        row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
+        row = layout.row()
+        row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
 
-        col = row.column(align=True)
-        col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
-        col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="")
+        col = row.column(align=True)
+        col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
+        col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="")
 
         row = layout.row()
-        # rl = rd.layers.active
-        rl = rd.layers[0]
+        rl = rd.layers.active
         row.prop(rl, "name")
-        #row.prop(rd, "use_single_layer", text="", icon_only=True)
+        row.prop(rd, "use_single_layer", text="", icon_only=True)
 
         split = layout.split()
 
@@ -183,6 +182,7 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
 
         layout.separator()
 
+        rl = rd.layers[0]
         layout.prop(rl, "material_override", text="Material")
 
 
index 4b7651dba4c62690bc00768c98eeff4b50a1fade..72b8cfa23552ca6a208bb0128e2ab18e581d843a 100644 (file)
@@ -232,8 +232,10 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
 
        BL::Object::material_slots_iterator slot;
        for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
-               if(render_layer.material_override)
-                       find_shader(render_layer.material_override, used_shaders, scene->default_surface);
+               BL::Material material_override = render_layers.front().material_override;
+
+               if(material_override)
+                       find_shader(material_override, used_shaders, scene->default_surface);
                else
                        find_shader(slot->material(), used_shaders, scene->default_surface);
        }
index db8ea5fbf1e57aee9db4631dc61d3069021d93b8..608c5fda5ac356cc15dfba80e053fda4f2e3f815 100644 (file)
@@ -203,7 +203,7 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob,
 void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
 {
        /* layer data */
-       uint scene_layer = render_layer.scene_layer;
+       uint scene_layer = render_layers.front().scene_layer;
        
        /* prepare for sync */
        light_map.pre_sync();
index 1803dd36beb43a650a548578be3c75137c19edb2..d8c65c7a607d0020e4e1ca5257de5b7e7c558c39 100644 (file)
@@ -40,7 +40,8 @@
 CCL_NAMESPACE_BEGIN
 
 BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_)
-: b_engine(b_engine_), b_data(b_data_), b_scene(b_scene_), b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL)
+: b_engine(b_engine_), b_data(b_data_), b_scene(b_scene_), b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL),
+  b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL)
 {
        /* offline render */
        BL::RenderSettings r = b_scene.render();
@@ -55,7 +56,8 @@ BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_
 
 BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_,
        BL::SpaceView3D b_v3d_, BL::RegionView3D b_rv3d_, int width_, int height_)
-: b_engine(b_engine_), b_data(b_data_), b_scene(b_scene_), b_v3d(b_v3d_), b_rv3d(b_rv3d_)
+: b_engine(b_engine_), b_data(b_data_), b_scene(b_scene_), b_v3d(b_v3d_), b_rv3d(b_rv3d_),
+  b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL)
 {
        /* 3d view render */
        width = width_;
@@ -64,6 +66,7 @@ BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_
        last_redraw_time = 0.0f;
 
        create_session();
+       session->start();
 }
 
 BlenderSession::~BlenderSession()
@@ -99,11 +102,9 @@ void BlenderSession::create_session()
        session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this));
        session->set_pause(BlenderSync::get_session_pause(b_scene, background));
 
-       /* start rendering */
+       /* set buffer parameters */
        BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
-
        session->reset(buffer_params, session_params.samples);
-       session->start();
 }
 
 void BlenderSession::free_session()
@@ -114,42 +115,67 @@ void BlenderSession::free_session()
 
 void BlenderSession::render()
 {
-       session->wait();
+       /* get buffer parameters */
+       BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
+       int w = buffer_params.width, h = buffer_params.height;
 
-       if(session->progress.get_cancel())
-               return;
+       /* create render result */
+       RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, w, h);
+       PointerRNA rrptr;
+       RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr);
+       b_rr = BL::RenderResult(rrptr);
+
+       BL::RenderSettings r = b_scene.render();
+       BL::RenderResult::layers_iterator b_iter;
+       BL::RenderLayers b_rr_layers(r.ptr);
+       
+       int active = 0;
+
+       /* render each layer */
+       for(b_rr.layers.begin(b_iter); b_iter != b_rr.layers.end(); ++b_iter, ++active) {
+               /* single layer render */
+               if(r.use_single_layer())
+                       active = b_rr_layers.active_index();
+
+               /* set layer */
+               b_rlay = *b_iter;
 
-       /* write result */
-       write_render_result();
+               /* update scene */
+               sync->sync_data(b_v3d, active);
+
+               /* render */
+               session->start();
+               session->wait();
+
+               if(session->progress.get_cancel())
+                       break;
+
+               /* write result */
+               write_render_result();
+       }
+
+       /* delete render result */
+       RE_engine_end_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data);
 }
 
 void BlenderSession::write_render_result()
 {
-       /* get result */
+       /* get state */
        RenderBuffers *buffers = session->buffers;
        float exposure = scene->film->exposure;
        double total_time, sample_time;
        int sample;
        session->progress.get_sample(sample, total_time, sample_time);
 
+       /* get pixels */
        float4 *pixels = buffers->copy_from_device(exposure, sample);
 
        if(!pixels)
                return;
 
-       BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
-       int w = buffer_params.width, h = buffer_params.height;
-
-       struct RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, w, h);
-       PointerRNA rrptr;
-       RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr);
-       BL::RenderResult rr(rrptr);
-
-       BL::RenderResult::layers_iterator layer;
-       rr.layers.begin(layer);
-       rna_RenderLayer_rect_set(&layer->ptr, (float*)pixels);
-
-       RE_engine_end_result((RenderEngine*)b_engine.ptr.data, rrp);
+       /* write pixels */
+       rna_RenderLayer_rect_set(&b_rlay.ptr, (float*)pixels);
+       RE_engine_update_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data);
 
        delete [] pixels;
 }
@@ -164,6 +190,7 @@ void BlenderSession::synchronize()
           scene->params.modified(scene_params)) {
                free_session();
                create_session();
+               session->start();
                return;
        }
 
index e30b60c3d637bedf5d95dc39c90b7ad4343bfbb3..26fffcf3aff9a20603fdd3f8dffe2a212b8f43fb 100644 (file)
@@ -69,6 +69,8 @@ public:
        BL::Scene b_scene;
        BL::SpaceView3D b_v3d;
        BL::RegionView3D b_rv3d;
+       BL::RenderResult b_rr;
+       BL::RenderLayer b_rlay;
 
        string last_status;
        float last_progress;
index 52555fadefb8e34508c38cd300991c516e0bce2c..3443f76b1ce58cd846de66093cb8382fa41135b0 100644 (file)
@@ -48,7 +48,8 @@ BlenderSync::BlenderSync(BL::BlendData b_data_, BL::Scene b_scene_, Scene *scene
   light_map(&scene_->lights),
   world_map(NULL),
   world_recalc(false),
-  experimental(false)
+  experimental(false),
+  active_layer(0)
 {
        scene = scene_;
        preview = preview_;
@@ -120,10 +121,10 @@ bool BlenderSync::sync_recalc()
        return recalc;
 }
 
-void BlenderSync::sync_data(BL::SpaceView3D b_v3d)
+void BlenderSync::sync_data(BL::SpaceView3D b_v3d, int layer)
 {
-       sync_render_layer(b_v3d);
-       sync_integrator();
+       sync_render_layers(b_v3d);
+       sync_integrator(layer);
        sync_film();
        sync_shaders();
        sync_objects(b_v3d);
@@ -131,7 +132,7 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d)
 
 /* Integrator */
 
-void BlenderSync::sync_integrator()
+void BlenderSync::sync_integrator(int layer)
 {
        PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
 
@@ -153,7 +154,7 @@ void BlenderSync::sync_integrator()
 
        integrator->no_caustics = get_boolean(cscene, "no_caustics");
        integrator->seed = get_int(cscene, "seed");
-       integrator->layer_flag = render_layer.layer;
+       integrator->layer_flag = render_layers[layer].layer;
 
        if(integrator->modified(previntegrator))
                integrator->tag_update(scene);
@@ -185,27 +186,32 @@ void BlenderSync::sync_film()
 
 /* Render Layer */
 
-void BlenderSync::sync_render_layer(BL::SpaceView3D b_v3d)
+void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d)
 {
+       render_layers.clear();
+
        if(b_v3d) {
-               render_layer.scene_layer = get_layer(b_v3d.layers());
-               render_layer.layer = render_layer.scene_layer;
-               render_layer.material_override = PointerRNA_NULL;
+               RenderLayerInfo rlay;
+
+               rlay.scene_layer = get_layer(b_v3d.layers());
+               rlay.layer = rlay.scene_layer;
+               rlay.material_override = PointerRNA_NULL;
+
+               render_layers.push_back(rlay);
        }
        else {
                BL::RenderSettings r = b_scene.render();
                BL::RenderSettings::layers_iterator b_rlay;
-               bool first = true;
 
                for(r.layers.begin(b_rlay); b_rlay != r.layers.end(); ++b_rlay) {
                        /* single layer for now */
-                       if(first) {
-                               render_layer.scene_layer = get_layer(b_scene.layers());
-                               render_layer.layer = get_layer(b_rlay->layers());
-                               render_layer.material_override = b_rlay->material_override();
+                       RenderLayerInfo rlay;
 
-                               first = false;
-                       }
+                       rlay.scene_layer = get_layer(b_scene.layers());
+                       rlay.layer = get_layer(b_rlay->layers());
+                       rlay.material_override = b_rlay->material_override();
+
+                       render_layers.push_back(rlay);
                }
        }
 }
index cd667205854be08f222899117757ced14267d289..60fdd7c386b143c48afabc9e43fce40dd392c5d2 100644 (file)
@@ -54,7 +54,7 @@ public:
 
        /* sync */
        bool sync_recalc();
-       void sync_data(BL::SpaceView3D b_v3d);
+       void sync_data(BL::SpaceView3D b_v3d, int layer = 0);
        void sync_camera(int width, int height);
        void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height);
 
@@ -70,10 +70,10 @@ private:
        void sync_materials();
        void sync_objects(BL::SpaceView3D b_v3d);
        void sync_film();
-       void sync_integrator();
+       void sync_integrator(int layer);
        void sync_view();
        void sync_world();
-       void sync_render_layer(BL::SpaceView3D b_v3d);
+       void sync_render_layers(BL::SpaceView3D b_v3d);
        void sync_shaders();
 
        void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
@@ -112,7 +112,10 @@ private:
                uint scene_layer;
                uint layer;
                BL::Material material_override;
-       } render_layer;
+       };
+
+       vector<RenderLayerInfo> render_layers;
+       int active_layer;
 };
 
 CCL_NAMESPACE_END