Render API/Cycles: Identify Render Passes by their name instead of a type flag
authorLukas Stockner <lukas.stockner@freenet.de>
Tue, 2 May 2017 22:21:18 +0000 (00:21 +0200)
committerLukas Stockner <lukas.stockner@freenet.de>
Wed, 3 May 2017 14:44:52 +0000 (16:44 +0200)
Previously, every RenderPass would have a bitfield that specified its type. That limits the number of passes to 32, which was reached a while ago.
However, most of the code already supported arbitrary RenderPasses since they were also used to store Multilayer EXR images.
Therefore, this commit completely removes the passflag from RenderPass and changes all code to use the unique pass name for identification.
Since Blender Internal relies on hardcoded passes and to preserve compatibility, 32 pass names are reserved for the old hardcoded passes.

To support these arbitrary passes, the Render Result compositor node now adds dynamic sockets. For compatibility, the old hardcoded sockets are always stored and just hidden when the corresponding pass isn't available.

To use these changes, the Render Engine API now includes a function that allows render engines to add arbitrary passes to the render result. To be able to add options for these passes, addons can now add their own properties to SceneRenderLayers.
To keep the compositor input node updated, render engine plugins have to implement a callback that registers all the passes that will be generated.

From a user perspective, nothing should change with this commit.

Differential Revision: https://developer.blender.org/D2443

Differential Revision: https://developer.blender.org/D2444

50 files changed:
intern/cycles/blender/addon/__init__.py
intern/cycles/blender/addon/engine.py
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_python.cpp
intern/cycles/blender/blender_session.cpp
intern/cycles/blender/blender_sync.cpp
intern/cycles/blender/blender_sync.h
source/blender/blenkernel/BKE_blender_version.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/versioning_270.c
source/blender/blenloader/intern/writefile.c
source/blender/compositor/CMakeLists.txt
source/blender/compositor/intern/COM_NodeGraph.cpp
source/blender/compositor/nodes/COM_ImageNode.cpp
source/blender/compositor/nodes/COM_RenderLayersNode.cpp
source/blender/compositor/nodes/COM_RenderLayersNode.h
source/blender/compositor/operations/COM_RenderLayersProg.cpp
source/blender/compositor/operations/COM_RenderLayersProg.h
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_update.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_edit.c
source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
source/blender/makesdna/DNA_node_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_scene.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_composite.h
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/render/CMakeLists.txt
source/blender/render/extern/include/RE_engine.h
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/include/render_result.h
source/blender/render/intern/include/rendercore.h
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/external_engine.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/render_result.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/zbuf.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index eb792af7264277868763b4ae3bee12c54a2815cf..a2d6262fb2083a3af0dc4f34b70edcc3bcaba27d 100644 (file)
@@ -102,6 +102,9 @@ class CyclesRender(bpy.types.RenderEngine):
         else:
             self.report({'ERROR'}, "OSL support disabled in this build.")
 
+    def update_render_passes(self, scene, srl):
+        engine.register_passes(self, scene, srl)
+
 
 def engine_exit():
     engine.exit()
index ab57dd44bdb670152425efcbf5bbf63b20a152cc..affeef994d417ff2e425831768341247b4171efe 100644 (file)
@@ -205,3 +205,36 @@ def with_network():
 def system_info():
     import _cycles
     return _cycles.system_info()
+
+def register_passes(engine, scene, srl):
+    engine.register_pass(scene, srl, "Combined", 4, "RGBA", 'COLOR')
+
+    if srl.use_pass_z:                     engine.register_pass(scene, srl, "Depth",         1, "Z",    'VALUE')
+    if srl.use_pass_mist:                  engine.register_pass(scene, srl, "Mist",          1, "Z",    'VALUE')
+    if srl.use_pass_normal:                engine.register_pass(scene, srl, "Normal",        3, "XYZ",  'VECTOR')
+    if srl.use_pass_vector:                engine.register_pass(scene, srl, "Vector",        4, "XYZW", 'VECTOR')
+    if srl.use_pass_uv:                    engine.register_pass(scene, srl, "UV",            3, "UVA",  'VECTOR')
+    if srl.use_pass_object_index:          engine.register_pass(scene, srl, "IndexOB",       1, "X",    'VALUE')
+    if srl.use_pass_material_index:        engine.register_pass(scene, srl, "IndexMA",       1, "X",    'VALUE')
+    if srl.use_pass_shadow:                engine.register_pass(scene, srl, "Shadow",        3, "RGB",  'COLOR')
+    if srl.use_pass_ambient_occlusion:     engine.register_pass(scene, srl, "AO",            3, "RGB",  'COLOR')
+    if srl.use_pass_diffuse_direct:        engine.register_pass(scene, srl, "DiffDir",       3, "RGB",  'COLOR')
+    if srl.use_pass_diffuse_indirect:      engine.register_pass(scene, srl, "DiffInd",       3, "RGB",  'COLOR')
+    if srl.use_pass_diffuse_color:         engine.register_pass(scene, srl, "DiffCol",       3, "RGB",  'COLOR')
+    if srl.use_pass_glossy_direct:         engine.register_pass(scene, srl, "GlossDir",      3, "RGB",  'COLOR')
+    if srl.use_pass_glossy_indirect:       engine.register_pass(scene, srl, "GlossInd",      3, "RGB",  'COLOR')
+    if srl.use_pass_glossy_color:          engine.register_pass(scene, srl, "GlossCol",      3, "RGB",  'COLOR')
+    if srl.use_pass_transmission_direct:   engine.register_pass(scene, srl, "TransDir",      3, "RGB",  'COLOR')
+    if srl.use_pass_transmission_indirect: engine.register_pass(scene, srl, "TransInd",      3, "RGB",  'COLOR')
+    if srl.use_pass_transmission_color:    engine.register_pass(scene, srl, "TransCol",      3, "RGB",  'COLOR')
+    if srl.use_pass_subsurface_direct:     engine.register_pass(scene, srl, "SubsurfaceDir", 3, "RGB",  'COLOR')
+    if srl.use_pass_subsurface_indirect:   engine.register_pass(scene, srl, "SubsurfaceInd", 3, "RGB",  'COLOR')
+    if srl.use_pass_subsurface_color:      engine.register_pass(scene, srl, "SubsurfaceCol", 3, "RGB",  'COLOR')
+    if srl.use_pass_emit:                  engine.register_pass(scene, srl, "Emit",          3, "RGB",  'COLOR')
+    if srl.use_pass_environment:           engine.register_pass(scene, srl, "Env",           3, "RGB",  'COLOR')
+
+    crl = srl.cycles
+    if crl.pass_debug_bvh_traversed_nodes:     engine.register_pass(scene, srl, "Debug BVH Traversed Nodes",     1, "X", 'VALUE')
+    if crl.pass_debug_bvh_traversed_instances: engine.register_pass(scene, srl, "Debug BVH Traversed Instances", 1, "X", 'VALUE')
+    if crl.pass_debug_bvh_intersections:       engine.register_pass(scene, srl, "Debug BVH Intersections",       1, "X", 'VALUE')
+    if crl.pass_debug_ray_bounces:             engine.register_pass(scene, srl, "Debug Ray Bounces",             1, "X", 'VALUE')
index 53740efb62734cabf8e1c83905fb156d3cbc5371..a8a0f0bfc70d523393d1135d485da9f17bc5e388 100644 (file)
@@ -1166,6 +1166,39 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
     def unregister(cls):
         del bpy.types.Scene.cycles_curves
 
+class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
+    @classmethod
+    def register(cls):
+        bpy.types.SceneRenderLayer.cycles = PointerProperty(
+                name="Cycles SceneRenderLayer Settings",
+                description="Cycles SceneRenderLayer Settings",
+                type=cls,
+                )
+        cls.pass_debug_bvh_traversed_nodes = BoolProperty(
+                name="Debug BVH Traversed Nodes",
+                description="Store Debug BVH Traversed Nodes pass",
+                default=False,
+                )
+        cls.pass_debug_bvh_traversed_instances = BoolProperty(
+                name="Debug BVH Traversed Instances",
+                description="Store Debug BVH Traversed Instances pass",
+                default=False,
+                )
+        cls.pass_debug_bvh_intersections = BoolProperty(
+                name="Debug BVH Intersections",
+                description="Store Debug BVH Intersections",
+                default=False,
+                )
+        cls.pass_debug_ray_bounces = BoolProperty(
+                name="Debug Ray Bounces",
+                description="Store Debug Ray Bounces pass",
+                default=False,
+                )
+
+    @classmethod
+    def unregister(cls):
+        del bpy.types.SceneRenderLayer.cycles
+
 
 class CyclesCurveSettings(bpy.types.PropertyGroup):
     @classmethod
@@ -1324,6 +1357,7 @@ def register():
     bpy.utils.register_class(CyclesCurveSettings)
     bpy.utils.register_class(CyclesDeviceSettings)
     bpy.utils.register_class(CyclesPreferences)
+    bpy.utils.register_class(CyclesRenderLayerSettings)
 
 
 def unregister():
@@ -1339,3 +1373,4 @@ def unregister():
     bpy.utils.unregister_class(CyclesCurveSettings)
     bpy.utils.unregister_class(CyclesDeviceSettings)
     bpy.utils.unregister_class(CyclesPreferences)
+    bpy.utils.unregister_class(CyclesRenderLayerSettings)
index ab1fe8924bc1d234f830fe20c81e19b5b6175d29..ea5bc8979c010c9668ac96032544e02a1b1bc05a 100644 (file)
@@ -476,11 +476,14 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel):
     bl_options = {'DEFAULT_CLOSED'}
 
     def draw(self, context):
+        import _cycles
+
         layout = self.layout
 
         scene = context.scene
         rd = scene.render
         rl = rd.layers.active
+        crl = rl.cycles
 
         split = layout.split()
 
@@ -527,8 +530,12 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel):
         col.prop(rl, "use_pass_emit", text="Emission")
         col.prop(rl, "use_pass_environment")
 
-        if hasattr(rd, "debug_pass_type"):
-            layout.prop(rd, "debug_pass_type")
+        if _cycles.with_cycles_debug:
+          col = layout.column()
+          col.prop(crl, "pass_debug_bvh_traversed_nodes")
+          col.prop(crl, "pass_debug_bvh_traversed_instances")
+          col.prop(crl, "pass_debug_bvh_intersections")
+          col.prop(crl, "pass_debug_ray_bounces")
 
 
 class CyclesRender_PT_views(CyclesButtonsPanel, Panel):
index d509e9de981d487406f5b35be5d7b39f6cc3d9a8..01570b1e3f99581c6bff40d4f891c35811162b26 100644 (file)
@@ -811,6 +811,14 @@ void *CCL_python_module_init()
        PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
 #endif
 
+#ifdef WITH_CYCLES_DEBUG
+       PyModule_AddObject(mod, "with_cycles_debug", Py_True);
+       Py_INCREF(Py_True);
+#else
+       PyModule_AddObject(mod, "with_cycles_debug", Py_False);
+       Py_INCREF(Py_False);
+#endif
+
 #ifdef WITH_NETWORK
        PyModule_AddObject(mod, "with_network", Py_True);
        Py_INCREF(Py_True);
index 26f9bccd95d647fd60a74eccb43043052e7c75d9..dfd6dc8db348ac0e9e975e2a5176643f096bee9a 100644 (file)
@@ -243,90 +243,6 @@ void BlenderSession::free_session()
        delete session;
 }
 
-static PassType get_pass_type(BL::RenderPass& b_pass)
-{
-       switch(b_pass.type()) {
-               case BL::RenderPass::type_COMBINED:
-                       return PASS_COMBINED;
-
-               case BL::RenderPass::type_Z:
-                       return PASS_DEPTH;
-               case BL::RenderPass::type_MIST:
-                       return PASS_MIST;
-               case BL::RenderPass::type_NORMAL:
-                       return PASS_NORMAL;
-               case BL::RenderPass::type_OBJECT_INDEX:
-                       return PASS_OBJECT_ID;
-               case BL::RenderPass::type_UV:
-                       return PASS_UV;
-               case BL::RenderPass::type_VECTOR:
-                       return PASS_MOTION;
-               case BL::RenderPass::type_MATERIAL_INDEX:
-                       return PASS_MATERIAL_ID;
-
-               case BL::RenderPass::type_DIFFUSE_DIRECT:
-                       return PASS_DIFFUSE_DIRECT;
-               case BL::RenderPass::type_GLOSSY_DIRECT:
-                       return PASS_GLOSSY_DIRECT;
-               case BL::RenderPass::type_TRANSMISSION_DIRECT:
-                       return PASS_TRANSMISSION_DIRECT;
-               case BL::RenderPass::type_SUBSURFACE_DIRECT:
-                       return PASS_SUBSURFACE_DIRECT;
-
-               case BL::RenderPass::type_DIFFUSE_INDIRECT:
-                       return PASS_DIFFUSE_INDIRECT;
-               case BL::RenderPass::type_GLOSSY_INDIRECT:
-                       return PASS_GLOSSY_INDIRECT;
-               case BL::RenderPass::type_TRANSMISSION_INDIRECT:
-                       return PASS_TRANSMISSION_INDIRECT;
-               case BL::RenderPass::type_SUBSURFACE_INDIRECT:
-                       return PASS_SUBSURFACE_INDIRECT;
-
-               case BL::RenderPass::type_DIFFUSE_COLOR:
-                       return PASS_DIFFUSE_COLOR;
-               case BL::RenderPass::type_GLOSSY_COLOR:
-                       return PASS_GLOSSY_COLOR;
-               case BL::RenderPass::type_TRANSMISSION_COLOR:
-                       return PASS_TRANSMISSION_COLOR;
-               case BL::RenderPass::type_SUBSURFACE_COLOR:
-                       return PASS_SUBSURFACE_COLOR;
-
-               case BL::RenderPass::type_EMIT:
-                       return PASS_EMISSION;
-               case BL::RenderPass::type_ENVIRONMENT:
-                       return PASS_BACKGROUND;
-               case BL::RenderPass::type_AO:
-                       return PASS_AO;
-               case BL::RenderPass::type_SHADOW:
-                       return PASS_SHADOW;
-
-               case BL::RenderPass::type_DIFFUSE:
-               case BL::RenderPass::type_COLOR:
-               case BL::RenderPass::type_REFRACTION:
-               case BL::RenderPass::type_SPECULAR:
-               case BL::RenderPass::type_REFLECTION:
-                       return PASS_NONE;
-#ifdef WITH_CYCLES_DEBUG
-               case BL::RenderPass::type_DEBUG:
-               {
-                       switch(b_pass.debug_type()) {
-                               case BL::RenderPass::debug_type_BVH_TRAVERSED_NODES:
-                                       return PASS_BVH_TRAVERSED_NODES;
-                               case BL::RenderPass::debug_type_BVH_TRAVERSED_INSTANCES:
-                                       return PASS_BVH_TRAVERSED_INSTANCES;
-                               case BL::RenderPass::debug_type_BVH_INTERSECTIONS:
-                                       return PASS_BVH_INTERSECTIONS;
-                               case BL::RenderPass::debug_type_RAY_BOUNCES:
-                                       return PASS_RAY_BOUNCES;
-                       }
-                       break;
-               }
-#endif
-       }
-       
-       return PASS_NONE;
-}
-
 static ShaderEvalType get_shader_type(const string& pass_type)
 {
        const char *shader_type = pass_type.c_str();
@@ -483,22 +399,11 @@ void BlenderSession::render()
 
                /* add passes */
                array<Pass> passes;
-               Pass::add(PASS_COMBINED, passes);
-
                if(session_params.device.advanced_shading) {
-
-                       /* loop over passes */
-                       BL::RenderLayer::passes_iterator b_pass_iter;
-
-                       for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
-                               BL::RenderPass b_pass(*b_pass_iter);
-                               PassType pass_type = get_pass_type(b_pass);
-
-                               if(pass_type == PASS_MOTION && scene->integrator->motion_blur)
-                                       continue;
-                               if(pass_type != PASS_NONE)
-                                       Pass::add(pass_type, passes);
-                       }
+                       passes = sync->sync_render_passes(b_rlay, *b_layer_iter);
+               }
+               else {
+                       Pass::add(PASS_COMBINED, passes);
                }
 
                buffer_params.passes = passes;
@@ -753,19 +658,25 @@ void BlenderSession::do_write_update_render_result(BL::RenderResult& b_rr,
                        BL::RenderPass b_pass(*b_iter);
 
                        /* find matching pass type */
-                       PassType pass_type = get_pass_type(b_pass);
+                       PassType pass_type = BlenderSync::get_pass_type(b_pass);
                        int components = b_pass.channels();
 
-                       /* copy pixels */
-                       if(!buffers->get_pass_rect(pass_type, exposure, sample, components, &pixels[0]))
+                       bool read = false;
+                       if(pass_type != PASS_NONE) {
+                               /* copy pixels */
+                               read = buffers->get_pass_rect(pass_type, exposure, sample, components, &pixels[0]);
+                       }
+
+                       if(!read) {
                                memset(&pixels[0], 0, pixels.size()*sizeof(float));
+                       }
 
                        b_pass.rect(&pixels[0]);
                }
        }
        else {
                /* copy combined pass */
-               BL::RenderPass b_combined_pass(b_rlay.passes.find_by_type(BL::RenderPass::type_COMBINED, b_rview_name.c_str()));
+               BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str()));
                if(buffers->get_pass_rect(PASS_COMBINED, exposure, sample, 4, &pixels[0]))
                        b_combined_pass.rect(&pixels[0]);
        }
index ff6c749b99dfc5c6512178e5bc6aa37feccc14cf..17d2378b7ab131f940cc20827a2e706013c5e2ba 100644 (file)
@@ -479,6 +479,94 @@ void BlenderSync::sync_images()
        }
 }
 
+/* Passes */
+PassType BlenderSync::get_pass_type(BL::RenderPass& b_pass)
+{
+       string name = b_pass.name();
+#define MAP_PASS(passname, passtype) if(name == passname) return passtype;
+       /* NOTE: Keep in sync with defined names from DNA_scene_types.h */
+       MAP_PASS("Combined", PASS_COMBINED);
+       MAP_PASS("Depth", PASS_DEPTH);
+       MAP_PASS("Mist", PASS_MIST);
+       MAP_PASS("Normal", PASS_NORMAL);
+       MAP_PASS("IndexOB", PASS_OBJECT_ID);
+       MAP_PASS("UV", PASS_UV);
+       MAP_PASS("Vector", PASS_MOTION);
+       MAP_PASS("IndexMA", PASS_MATERIAL_ID);
+
+       MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT);
+       MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT);
+       MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT);
+       MAP_PASS("SubsurfaceDir", PASS_SUBSURFACE_DIRECT);
+
+       MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT);
+       MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT);
+       MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT);
+       MAP_PASS("SubsurfaceInd", PASS_SUBSURFACE_INDIRECT);
+
+       MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR);
+       MAP_PASS("GlossCol", PASS_GLOSSY_COLOR);
+       MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR);
+       MAP_PASS("SubsurfaceCol", PASS_SUBSURFACE_COLOR);
+
+       MAP_PASS("Emit", PASS_EMISSION);
+       MAP_PASS("Env", PASS_BACKGROUND);
+       MAP_PASS("AO", PASS_AO);
+       MAP_PASS("Shadow", PASS_SHADOW);
+
+#ifdef __KERNEL_DEBUG__
+       MAP_PASS("Debug BVH Traversed Nodes", PASS_BVH_TRAVERSED_NODES);
+       MAP_PASS("Debug BVH Traversed Instances", PASS_BVH_TRAVERSED_INSTANCES);
+       MAP_PASS("Debug BVH Intersections", PASS_BVH_INTERSECTIONS);
+       MAP_PASS("Debug Ray Bounces", PASS_RAY_BOUNCES);
+#endif
+#undef MAP_PASS
+
+       return PASS_NONE;
+}
+
+array<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
+                                               BL::SceneRenderLayer& b_srlay)
+{
+       array<Pass> passes;
+       Pass::add(PASS_COMBINED, passes);
+
+       /* loop over passes */
+       BL::RenderLayer::passes_iterator b_pass_iter;
+
+       for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
+               BL::RenderPass b_pass(*b_pass_iter);
+               PassType pass_type = get_pass_type(b_pass);
+
+               if(pass_type == PASS_MOTION && scene->integrator->motion_blur)
+                       continue;
+               if(pass_type != PASS_NONE)
+                       Pass::add(pass_type, passes);
+       }
+
+#ifdef __KERNEL_DEBUG__
+       PointerRNA crp = RNA_pointer_get(&b_srlay.ptr, "cycles");
+       if(get_boolean(crp, "pass_debug_bvh_traversed_nodes")) {
+               b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_srlay.name().c_str());
+               Pass::add(PASS_BVH_TRAVERSED_NODES, passes);
+       }
+       if(get_boolean(crp, "pass_debug_bvh_traversed_instances")) {
+               b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_srlay.name().c_str());
+               Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes);
+       }
+       if(get_boolean(crp, "pass_debug_bvh_intersections")) {
+               b_engine.add_pass("Debug BVH Intersections", 1, "X", b_srlay.name().c_str());
+               Pass::add(PASS_BVH_INTERSECTIONS, passes);
+       }
+       if(get_boolean(crp, "pass_debug_ray_bounces")) {
+               b_engine.add_pass("Debug Ray Bounces", 1, "X", b_srlay.name().c_str());
+               Pass::add(PASS_RAY_BOUNCES, passes);
+       }
+#endif
+
+       return passes;
+}
+
 /* Scene Parameters */
 
 SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
index 70a20400fa96d7d4713c3d6364fc84f8d55e911f..aee39a5652ab82df78eb9a19440d595a7ffd362a 100644 (file)
@@ -67,6 +67,8 @@ public:
                       void **python_thread_state,
                       const char *layer = 0);
        void sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer);
+       array<Pass> sync_render_passes(BL::RenderLayer& b_rlay,
+                                      BL::SceneRenderLayer& b_srlay);
        void sync_integrator();
        void sync_camera(BL::RenderSettings& b_render,
                         BL::Object& b_override,
@@ -93,6 +95,8 @@ public:
                                              Camera *cam,
                                              int width, int height);
 
+       static PassType get_pass_type(BL::RenderPass& b_pass);
+
 private:
        /* sync */
        void sync_lamps(bool update_all);
index 4f4787f9da59d49fd8df358ef988f24c93e7e072..207631d36bd98ca7f618522b143c01175a62914f 100644 (file)
@@ -28,7 +28,7 @@
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         278
-#define BLENDER_SUBVERSION      4
+#define BLENDER_SUBVERSION      5
 /* Several breakages with 270, e.g. constraint deg vs rad */
 #define BLENDER_MINVERSION      270
 #define BLENDER_MINSUBVERSION   6
index 7544e8f5b3e7cef6852ec6baae58a996e007f007..41028c730140fc80f2c534158b7621f5ae2ec457 100644 (file)
@@ -973,7 +973,8 @@ void ntreeCompositExecTree(struct Scene *scene, struct bNodeTree *ntree, struct
 void ntreeCompositTagRender(struct Scene *sce);
 int ntreeCompositTagAnimated(struct bNodeTree *ntree);
 void ntreeCompositTagGenerators(struct bNodeTree *ntree);
-void ntreeCompositForceHidden(struct bNodeTree *ntree);
+void ntreeCompositUpdateRLayers(struct bNodeTree *ntree);
+void ntreeCompositRegisterPass(struct bNodeTree *ntree, struct Scene *scene, struct SceneRenderLayer *srl, const char *name, int type);
 void ntreeCompositClearTags(struct bNodeTree *ntree);
 
 struct bNodeSocket *ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree, struct bNode *node,
index 8a01e120d6d78944a0ffed20dca36b15f861134a..2db13f9c7787619db1931f481cfacf8a751febfb 100644 (file)
@@ -2739,7 +2739,6 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
        }
 }
 
-#define PASSTYPE_UNSET -1
 /* return renderpass for a given pass index and active view */
 /* fallback to available if there are missing passes for active view */
 static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const int view, int *r_passindex)
@@ -2748,7 +2747,7 @@ static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const
        RenderPass *rpass;
 
        int rp_index = 0;
-       int rp_passtype = PASSTYPE_UNSET;
+       const char *rp_name = "";
 
        for (rpass = rl->passes.first; rpass; rpass = rpass->next, rp_index++) {
                if (rp_index == pass) {
@@ -2758,12 +2757,12 @@ static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const
                                break;
                        }
                        else {
-                               rp_passtype = rpass->passtype;
+                               rp_name = rpass->name;
                        }
                }
                /* multiview */
-               else if ((rp_passtype != PASSTYPE_UNSET) &&
-                        (rpass->passtype == rp_passtype) &&
+               else if (rp_name[0] &&
+                        STREQ(rpass->name, rp_name) &&
                         (rpass->view_id == view))
                {
                        rpass_ret = rpass;
@@ -2783,7 +2782,6 @@ static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const
 
        return rpass_ret;
 }
-#undef PASSTYPE_UNSET
 
 /* if layer or pass changes, we need an index for the imbufs list */
 /* note it is called for rendered results, but it doesnt use the index! */
@@ -3753,7 +3751,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
                        }
 
                        for (rpass = rl->passes.first; rpass; rpass = rpass->next)
-                               if (rpass->passtype == SCE_PASS_Z)
+                               if (STREQ(rpass->name, RE_PASSNAME_Z) && rpass->view_id == actview)
                                        rectz = rpass->rect;
                }
        }
index 906fa0134a02bca8c6a88ed2836635e416328ab2..559531a3d8a72353493bd3051c80ed13a8de87d6 100644 (file)
@@ -2063,6 +2063,11 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
 
        BKE_freestyle_config_free(&srl->freestyleConfig);
 
+       if (srl->prop) {
+               IDP_FreeProperty(srl->prop);
+               MEM_freeN(srl->prop);
+       }
+
        BLI_remlink(&scene->r.layers, srl);
        MEM_freeN(srl);
 
index c55b426c0259277f8f828bcd1621b8d8c9bc6797..eabe2feb4d79dcfd01c63d2caf4456633712f617 100644 (file)
@@ -3109,7 +3109,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                        else if (ntree->type==NTREE_COMPOSIT) {
                                if (ELEM(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT))
                                        direct_link_curvemapping(fd, node->storage);
-                               else if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+                               else if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
                                        ((ImageUser *)node->storage)->ok = 1;
                        }
                        else if ( ntree->type==NTREE_TEXTURE) {
@@ -6162,6 +6162,11 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        link_list(fd, &(sce->r.layers));
        link_list(fd, &(sce->r.views));
 
+
+       for (srl = sce->r.layers.first; srl; srl = srl->next) {
+               srl->prop = newdataadr(fd, srl->prop);
+               IDP_DirectLinkGroup_OrFree(&srl->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+       }
        for (srl = sce->r.layers.first; srl; srl = srl->next) {
                link_list(fd, &(srl->freestyleConfig.modules));
        }
index bc88bbb899783b4eb39e2215d1b493e34dc36ec1..c187766b5862718427a07491a89193129e831091 100644 (file)
@@ -80,6 +80,7 @@
 
 #include "NOD_common.h"
 #include "NOD_socket.h"
+#include "NOD_composite.h"
 
 #include "readfile.h"
 
@@ -1559,8 +1560,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
                }
        }
 
-       /* To be added to next subversion bump! */
-       {
+       if (!MAIN_VERSION_ATLEAST(main, 278, 5)) {
                /* Mask primitive adding code was not initializing correctly id_type of its points' parent. */
                for (Mask *mask = main->mask.first; mask; mask = mask->id.next) {
                        for (MaskLayer *mlayer = mask->masklayers.first; mlayer; mlayer = mlayer->next) {
@@ -1609,6 +1609,30 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
                                }
                        }
                }
+
+               FOREACH_NODETREE(main, ntree, id) {
+                       if (ntree->type == NTREE_COMPOSIT) {
+                               bNode *node;
+                               for (node = ntree->nodes.first; node; node = node->next) {
+                                       if (node->type == CMP_NODE_R_LAYERS) {
+                                               int pass_index = 0;
+                                               const char *sockname;
+                                               for (bNodeSocket *sock = node->outputs.first; sock && pass_index < 31; sock = sock->next, pass_index++) {
+                                                       if (sock->storage == NULL) {
+                                                               NodeImageLayer *sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
+                                                               sock->storage = sockdata;
+                                                               BLI_strncpy(sockdata->pass_name, node_cmp_rlayers_sock_to_pass(pass_index), sizeof(sockdata->pass_name));
+
+                                                               if (pass_index == 0) sockname = "Image";
+                                                               else if (pass_index == 1) sockname = "Alpha";
+                                                               else sockname = node_cmp_rlayers_sock_to_pass(pass_index);
+                                                               BLI_strncpy(sock->name, sockname, sizeof(sock->name));
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               } FOREACH_NODETREE_END
        }
 }
 
index 723b7929667d335d9568948892c756f06023c2f3..ef9062298a0cfaccedaf588945047d50c7358a7a 100644 (file)
@@ -1052,7 +1052,7 @@ static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree)
                                writestruct(wd, DATA, NodeImageMultiFileSocket, 1, sock->storage);
                        }
                }
-               if (node->type == CMP_NODE_IMAGE) {
+               if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS)) {
                        /* write extra socket info */
                        for (sock = node->outputs.first; sock; sock = sock->next) {
                                writestruct(wd, DATA, NodeImageLayer, 1, sock->storage);
@@ -2710,6 +2710,9 @@ static void write_scene(WriteData *wd, Scene *sce)
 
        for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) {
                writestruct(wd, DATA, SceneRenderLayer, 1, srl);
+               if (srl->prop) {
+                       IDP_WriteProperty(srl->prop, wd);
+               }
                for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
                        writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc);
                }
index 3180e7e41540bfac24a58376cf2bb8cbebdb02fb..3e1dd83112a95ce2bf29d5017257079f4b83e2a8 100644 (file)
@@ -551,8 +551,4 @@ if(WITH_INTERNATIONAL)
        add_definitions(-DWITH_INTERNATIONAL)
 endif()
 
-if(WITH_CYCLES AND WITH_CYCLES_DEBUG)
-       add_definitions(-DWITH_CYCLES_DEBUG)
-endif()
-
 blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}")
index c5096a6b35278362043e3b15bd86af23242c41ef..891e64ed12b3a75c2a8282a3c23c674f1c7f42ce 100644 (file)
@@ -179,7 +179,8 @@ void NodeGraph::add_bNodeLink(const NodeRange &node_range, bNodeLink *b_nodelink
        /// @note: ignore invalid links
        if (!(b_nodelink->flag & NODE_LINK_VALID))
                return;
-       if ((b_nodelink->fromsock->flag & SOCK_UNAVAIL) || (b_nodelink->tosock->flag & SOCK_UNAVAIL))
+       const int unavail_mask = SOCK_UNAVAIL | SOCK_VIRTUAL;
+       if ((b_nodelink->fromsock->flag & unavail_mask) || (b_nodelink->tosock->flag & unavail_mask))
                return;
        
        /* Note: a DNA input socket can have multiple NodeInput in the compositor tree! (proxies)
index facd422c21732b0f134c1ea42e08e62cef6c98d6..462947f32a36629e09086fc5f09e5d65b28a24e0 100644 (file)
@@ -95,18 +95,10 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
                                        NodeOperation *operation = NULL;
                                        socket = this->getOutputSocket(index);
                                        bNodeSocket *bnodeSocket = socket->getbNodeSocket();
-                                       RenderPass *rpass = (RenderPass *)BLI_findstring(&rl->passes, bnodeSocket->identifier, offsetof(RenderPass, internal_name));
+                                       NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;
+                                       RenderPass *rpass = (RenderPass *)BLI_findstring(&rl->passes, storage->pass_name, offsetof(RenderPass, name));
                                        int view = 0;
 
-                                       /* Passes in the file can differ from passes stored in sockets (#36755).
-                                        * Look up the correct file pass using the socket identifier instead.
-                                        */
-#if 0
-                                       NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;*/
-                                       int passindex = storage->pass_index;*/
-                                       RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex);
-#endif
-
                                        /* returns the image view to use for the current active view */
                                        if (BLI_listbase_count_ex(&image->rr->views, 2) > 1) {
                                                const int view_image = imageuser->view;
@@ -147,7 +139,7 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
                                                if (index == 0 && operation) {
                                                        converter.addPreview(operation->getOutputSocket());
                                                }
-                                               if (rpass->passtype == SCE_PASS_COMBINED) {
+                                               if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
                                                        BLI_assert(operation != NULL);
                                                        BLI_assert(index < numberOfOutputs - 1);
                                                        NodeOutput *outputSocket = this->getOutputSocket(index + 1);
index 842edcf35c904b90597acaf55d98d2ff9393e983..75128de2d846bc8777ca11512f27817805bd8bd8 100644 (file)
 #include "COM_ScaleOperation.h"
 #include "COM_SetValueOperation.h"
 
-#ifdef WITH_CYCLES_DEBUG
-#  include "RE_pipeline.h"
-#endif
-
 RenderLayersNode::RenderLayersNode(bNode *editorNode) : Node(editorNode)
 {
        /* pass */
 }
 
 void RenderLayersNode::testSocketLink(NodeConverter &converter, const CompositorContext &context,
-                                            int outputSocketNumber, RenderLayersBaseProg *operation) const
+                                      NodeOutput *output, RenderLayersProg *operation,
+                                      Scene *scene, int layerId, bool is_preview) const
 {
-       NodeOutput *outputSocket = this->getOutputSocket(outputSocketNumber);
-       Scene *scene = (Scene *)this->getbNode()->id;
-       short layerId = this->getbNode()->custom1;
-
        operation->setScene(scene);
        operation->setLayerId(layerId);
        operation->setRenderData(context.getRenderData());
        operation->setViewName(context.getViewName());
 
-       converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
+       converter.mapOutputSocket(output, operation->getOutputSocket());
        converter.addOperation(operation);
        
-       if (outputSocketNumber == 0) /* only for image socket */
+       if (is_preview) /* only for image socket */
                converter.addPreview(operation->getOutputSocket());
 }
 
 void RenderLayersNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
 {
-       testSocketLink(converter, context, 0, new RenderLayersColorProg());
-       testSocketLink(converter, context, 1, new RenderLayersAlphaProg());
-       testSocketLink(converter, context, 2, new RenderLayersDepthProg());
-       testSocketLink(converter, context, 3, new RenderLayersNormalOperation());
-       testSocketLink(converter, context, 4, new RenderLayersUVOperation());
-       testSocketLink(converter, context, 5, new RenderLayersSpeedOperation());
-       testSocketLink(converter, context, 6, new RenderLayersColorOperation());
-       testSocketLink(converter, context, 7, new RenderLayersDiffuseOperation());
-       testSocketLink(converter, context, 8, new RenderLayersSpecularOperation());
-       testSocketLink(converter, context, 9, new RenderLayersShadowOperation());
-       testSocketLink(converter, context, 10, new RenderLayersAOOperation());
-       testSocketLink(converter, context, 11, new RenderLayersReflectionOperation());
-       testSocketLink(converter, context, 12, new RenderLayersRefractionOperation());
-       testSocketLink(converter, context, 13, new RenderLayersIndirectOperation());
-       testSocketLink(converter, context, 14, new RenderLayersObjectIndexOperation());
-       testSocketLink(converter, context, 15, new RenderLayersMaterialIndexOperation());
-       testSocketLink(converter, context, 16, new RenderLayersMistOperation());
-       testSocketLink(converter, context, 17, new RenderLayersEmitOperation());
-       testSocketLink(converter, context, 18, new RenderLayersEnvironmentOperation());
+       Scene *scene = (Scene *)this->getbNode()->id;
+       short layerId = this->getbNode()->custom1;
+       Render *re = (scene) ? RE_GetRender(scene->id.name) : NULL;
+       int numberOfOutputs = this->getNumberOfOutputSockets();
        
-       // cycles passes
-       testSocketLink(converter, context, 19, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_DIRECT));
-       testSocketLink(converter, context, 20, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_INDIRECT));
-       testSocketLink(converter, context, 21, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_COLOR));
-       testSocketLink(converter, context, 22, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_DIRECT));
-       testSocketLink(converter, context, 23, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_INDIRECT));
-       testSocketLink(converter, context, 24, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_COLOR));
-       testSocketLink(converter, context, 25, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_DIRECT));
-       testSocketLink(converter, context, 26, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_INDIRECT));
-       testSocketLink(converter, context, 27, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_COLOR));
-       testSocketLink(converter, context, 28, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_DIRECT));
-       testSocketLink(converter, context, 29, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_INDIRECT));
-       testSocketLink(converter, context, 30, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_COLOR));
-
-#ifdef WITH_CYCLES_DEBUG
-       {
-               Scene *scene = (Scene *)this->getbNode()->id;
-               Render *re = RE_GetRender(scene->id.name);
-               int debug_pass_type = ((re != NULL) ? RE_debug_pass_type_get(re) : scene->r.debug_pass_type);
-               testSocketLink(converter, context, 31, new RenderLayersCyclesDebugOperation(SCE_PASS_DEBUG, debug_pass_type));
+       if (re) {
+               RenderResult *rr = RE_AcquireResultRead(re);
+               if (rr) {
+                       SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&scene->r.layers, layerId);
+                       if (srl) {
+                               RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
+                               if (rl) {
+                                       for (int i = 0; i < numberOfOutputs; i++) {
+                                               NodeOutput *output = this->getOutputSocket(i);
+                                               NodeImageLayer *storage = (NodeImageLayer*) output->getbNodeSocket()->storage;
+                                               RenderPass *rpass = (RenderPass*) BLI_findstring(&rl->passes, storage->pass_name, offsetof(RenderPass, name));
+                                               if (rpass) {
+                                                       if (STREQ(rpass->name, RE_PASSNAME_COMBINED) && STREQ(output->getbNodeSocket()->name, "Alpha")) {
+                                                               testSocketLink(converter, context, output, new RenderLayersAlphaProg(rpass->name, COM_DT_VALUE, rpass->channels), scene, layerId, false);
+                                                       }
+                                                       else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+                                                               testSocketLink(converter, context, output, new RenderLayersDepthProg(rpass->name, COM_DT_VALUE, rpass->channels), scene, layerId, false);
+                                                       }
+                                                       else {
+                                                               DataType type = ((rpass->channels == 4)? COM_DT_COLOR : ((rpass->channels == 3)? COM_DT_VECTOR : COM_DT_VALUE));
+                                                               testSocketLink(converter, context, output, new RenderLayersProg(rpass->name, type, rpass->channels), scene, layerId, STREQ(output->getbNodeSocket()->name, "Image"));
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               RE_ReleaseResult(re);
        }
-#endif
 }
index 5863cbb390cd9088212b2746bfc697f4c974ece0..1f733a9f4bb3f00ef30658c210e18dca37074f7f 100644 (file)
@@ -33,5 +33,11 @@ public:
        RenderLayersNode(bNode *editorNode);
        void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
 private:
-       void testSocketLink(NodeConverter &converter, const CompositorContext &context, int outputSocketNumber, RenderLayersBaseProg *operation) const;
+       void testSocketLink(NodeConverter &converter,
+                           const CompositorContext &context,
+                           NodeOutput *output,
+                           RenderLayersProg *operation,
+                           Scene *scene,
+                           int layerId,
+                           bool is_preview) const;
 };
index 099208ce6005116c216b8b41ef13b44bcee7e07e..f2f1b211a976fa43876cbf76170a4085c84e719c 100644 (file)
@@ -34,17 +34,18 @@ extern "C" {
 
 /* ******** Render Layers Base Prog ******** */
 
-RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize) : NodeOperation()
+RenderLayersProg::RenderLayersProg(const char *passName, DataType type, int elementsize) : NodeOperation(), m_passName(passName)
 {
-       this->m_renderpass = renderpass;
        this->setScene(NULL);
        this->m_inputBuffer = NULL;
        this->m_elementsize = elementsize;
        this->m_rd = NULL;
+
+       this->addOutputSocket(type);
 }
 
 
-void RenderLayersBaseProg::initExecution()
+void RenderLayersProg::initExecution()
 {
        Scene *scene = this->getScene();
        Render *re = (scene) ? RE_GetRender(scene->id.name) : NULL;
@@ -59,10 +60,7 @@ void RenderLayersBaseProg::initExecution()
 
                        RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
                        if (rl) {
-                               this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass, this->m_viewName);
-                               if (this->m_inputBuffer == NULL && this->m_renderpass == SCE_PASS_COMBINED) {
-                                       this->m_inputBuffer = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, this->m_viewName);
-                               }
+                               this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_passName.c_str(), this->m_viewName);
                        }
                }
        }
@@ -72,7 +70,7 @@ void RenderLayersBaseProg::initExecution()
        }
 }
 
-void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, PixelSampler sampler)
+void RenderLayersProg::doInterpolation(float output[4], float x, float y, PixelSampler sampler)
 {
        unsigned int offset;
        int width = this->getWidth(), height = this->getHeight();
@@ -111,7 +109,7 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
        }
 }
 
-void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+void RenderLayersProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
 {
 #if 0
        const RenderData *rd = this->m_rd;
@@ -173,12 +171,12 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y
        }
 }
 
-void RenderLayersBaseProg::deinitExecution()
+void RenderLayersProg::deinitExecution()
 {
        this->m_inputBuffer = NULL;
 }
 
-void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2])
+void RenderLayersProg::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2])
 {
        Scene *sce = this->getScene();
        Render *re = (sce) ? RE_GetRender(sce->id.name) : NULL;
@@ -207,13 +205,6 @@ void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsig
 }
 
 /* ******** Render Layers AO Operation ******** */
-
-RenderLayersAOOperation::RenderLayersAOOperation() : RenderLayersBaseProg(SCE_PASS_AO, 3)
-{
-       this->addOutputSocket(COM_DT_COLOR);
-}
-
-
 void RenderLayersAOOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
 {
        float *inputBuffer = this->getInputBuffer();
@@ -227,12 +218,6 @@ void RenderLayersAOOperation::executePixelSampled(float output[4], float x, floa
 }
 
 /* ******** Render Layers Alpha Operation ******** */
-
-RenderLayersAlphaProg::RenderLayersAlphaProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4)
-{
-       this->addOutputSocket(COM_DT_VALUE);
-}
-
 void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
 {
        float *inputBuffer = this->getInputBuffer();
@@ -247,27 +232,7 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float
        }
 }
 
-/* ******** Render Layers Color Operation ******** */
-
-RenderLayersColorOperation::RenderLayersColorOperation() : RenderLayersBaseProg(SCE_PASS_RGBA, 4)
-{
-       this->addOutputSocket(COM_DT_COLOR);
-}
-
-/* ******** Render Layers Cycles Operation ******** */
-
-RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) : RenderLayersBaseProg(pass, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
 /* ******** Render Layers Depth Operation ******** */
-
-RenderLayersDepthProg::RenderLayersDepthProg() : RenderLayersBaseProg(SCE_PASS_Z, 1)
-{
-       this->addOutputSocket(COM_DT_VALUE);
-}
-
 void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/)
 {
        int ix = x;
@@ -281,135 +246,4 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float
                unsigned int offset = (iy * this->getWidth() + ix);
                output[0] = inputBuffer[offset];
        }
-}
-
-/* ******** Render Layers Diffuse Operation ******** */
-
-RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() : RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Emit Operation ******** */
-
-RenderLayersEmitOperation::RenderLayersEmitOperation() : RenderLayersBaseProg(SCE_PASS_EMIT, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Environment Operation ******** */
-
-RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() : RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Image Operation ******** */
-
-RenderLayersColorProg::RenderLayersColorProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4)
-{
-       this->addOutputSocket(COM_DT_COLOR);
-}
-
-/* ******** Render Layers Indirect Operation ******** */
-
-RenderLayersIndirectOperation::RenderLayersIndirectOperation() : RenderLayersBaseProg(SCE_PASS_INDIRECT, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Material Index Operation ******** */
-
-RenderLayersMaterialIndexOperation::RenderLayersMaterialIndexOperation() : RenderLayersBaseProg(SCE_PASS_INDEXMA, 1)
-{
-       this->addOutputSocket(COM_DT_VALUE);
-}
-
-/* ******** Render Layers Mist Operation ******** */
-
-RenderLayersMistOperation::RenderLayersMistOperation() : RenderLayersBaseProg(SCE_PASS_MIST, 1)
-{
-       this->addOutputSocket(COM_DT_VALUE);
-}
-
-/* ******** Render Layers Normal Operation ******** */
-
-RenderLayersNormalOperation::RenderLayersNormalOperation() : RenderLayersBaseProg(SCE_PASS_NORMAL, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Object Index Operation ******** */
-
-RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() : RenderLayersBaseProg(SCE_PASS_INDEXOB, 1)
-{
-       this->addOutputSocket(COM_DT_VALUE);
-}
-
-/* ******** Render Layers Reflection Operation ******** */
-
-RenderLayersReflectionOperation::RenderLayersReflectionOperation() : RenderLayersBaseProg(SCE_PASS_REFLECT, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Refraction Operation ******** */
-
-RenderLayersRefractionOperation::RenderLayersRefractionOperation() : RenderLayersBaseProg(SCE_PASS_REFRACT, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Shadow Operation ******** */
-
-RenderLayersShadowOperation::RenderLayersShadowOperation() : RenderLayersBaseProg(SCE_PASS_SHADOW, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Specular Operation ******** */
-
-RenderLayersSpecularOperation::RenderLayersSpecularOperation() : RenderLayersBaseProg(SCE_PASS_SPEC, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Speed Operation ******** */
-
-RenderLayersSpeedOperation::RenderLayersSpeedOperation() : RenderLayersBaseProg(SCE_PASS_VECTOR, 4)
-{
-       this->addOutputSocket(COM_DT_COLOR);
-}
-
-/* ******** Render Layers UV Operation ******** */
-
-RenderLayersUVOperation::RenderLayersUVOperation() : RenderLayersBaseProg(SCE_PASS_UV, 3)
-{
-       this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Debug Render Layers Cycles Operation ******** */
-
-#ifdef WITH_CYCLES_DEBUG
-
-RenderLayersCyclesDebugOperation::RenderLayersCyclesDebugOperation(
-        int pass,
-        int debug_pass_type)
-       : RenderLayersBaseProg(pass, RE_debug_pass_num_channels_get(debug_pass_type))
-{
-       switch (m_elementsize) {
-               case 1:
-                       this->addOutputSocket(COM_DT_VALUE);
-                       break;
-               case 3:
-                       this->addOutputSocket(COM_DT_VECTOR);
-                       break;
-               case 4:
-                       this->addOutputSocket(COM_DT_COLOR);
-                       break;
-               default:
-                       BLI_assert(!"Unkown debug pass type element size.");
-       }
-}
-
-#endif
+}
\ No newline at end of file
index 89eb2a6954dc9cd417375c41ae531d10b37d0be2..1be159067701fa872d2b4d9d6d9b948b4bffd94c 100644 (file)
@@ -40,7 +40,7 @@ extern "C" {
  *
  * @todo: rename to operation.
  */
-class RenderLayersBaseProg : public NodeOperation {
+class RenderLayersProg : public NodeOperation {
 protected:
        /**
         * Reference to the scene object.
@@ -65,7 +65,7 @@ protected:
        /**
         * renderpass where this operation needs to get its data from
         */
-       int m_renderpass;
+       std::string m_passName;
        
        int m_elementsize;
 
@@ -73,11 +73,6 @@ protected:
         * @brief render data used for active rendering
         */
        const RenderData *m_rd;
-
-       /**
-        * Constructor
-        */
-       RenderLayersBaseProg(int renderpass, int elementsize);
        
        /**
         * Determine the output resolution. The resolution is retrieved from the Renderer
@@ -91,6 +86,10 @@ protected:
 
        void doInterpolation(float output[4], float x, float y, PixelSampler sampler);
 public:
+       /**
+        * Constructor
+        */
+       RenderLayersProg(const char *passName, DataType type, int elementsize);
        /**
         * setter for the scene field. Will be called from
         * @see RenderLayerNode to set the actual scene where
@@ -108,116 +107,25 @@ public:
        void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
 };
 
-class RenderLayersAOOperation : public RenderLayersBaseProg {
+class RenderLayersAOOperation : public RenderLayersProg {
 public:
-       RenderLayersAOOperation();
+       RenderLayersAOOperation(const char *passName, DataType type, int elementsize)
+        : RenderLayersProg(passName, type, elementsize) {}
        void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
 };
 
-class RenderLayersAlphaProg : public RenderLayersBaseProg {
+class RenderLayersAlphaProg : public RenderLayersProg {
 public:
-       RenderLayersAlphaProg();
+       RenderLayersAlphaProg(const char *passName, DataType type, int elementsize)
+        : RenderLayersProg(passName, type, elementsize) {}
        void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
 };
 
-class RenderLayersColorOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersColorOperation();
-};
-
-class RenderLayersCyclesOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersCyclesOperation(int pass);
-};
-
-class RenderLayersDepthProg : public RenderLayersBaseProg {
+class RenderLayersDepthProg : public RenderLayersProg {
 public:
-       RenderLayersDepthProg();
+       RenderLayersDepthProg(const char *passName, DataType type, int elementsize)
+        : RenderLayersProg(passName, type, elementsize) {}
        void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
 };
 
-class RenderLayersDiffuseOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersDiffuseOperation();
-};
-
-class RenderLayersEmitOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersEmitOperation();
-};
-
-class RenderLayersEnvironmentOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersEnvironmentOperation();
-};
-
-/// @todo rename to image operation
-class RenderLayersColorProg : public RenderLayersBaseProg {
-public:
-       RenderLayersColorProg();
-};
-
-class RenderLayersIndirectOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersIndirectOperation();
-};
-
-class RenderLayersMaterialIndexOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersMaterialIndexOperation();
-};
-
-class RenderLayersMistOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersMistOperation();
-};
-
-class RenderLayersNormalOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersNormalOperation();
-};
-
-class RenderLayersObjectIndexOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersObjectIndexOperation();
-};
-
-class RenderLayersReflectionOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersReflectionOperation();
-};
-
-class RenderLayersRefractionOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersRefractionOperation();
-};
-
-class RenderLayersShadowOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersShadowOperation();
-};
-
-class RenderLayersSpecularOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersSpecularOperation();
-};
-
-class RenderLayersSpeedOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersSpeedOperation();
-};
-
-class RenderLayersUVOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersUVOperation();
-};
-
-#ifdef WITH_CYCLES_DEBUG
-class RenderLayersCyclesDebugOperation : public RenderLayersBaseProg {
-public:
-       RenderLayersCyclesDebugOperation(int pass,
-                                        int debug_pass_type);
-};
-#endif
-
 #endif
index 8c5d25ad44d162454cc433272aa75f63bda54f79..7c580bbd8967340cfe9867f4379c780fe10b036d 100644 (file)
@@ -210,7 +210,7 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
                        }
                        else {
                                if (rr->renlay == NULL) return;
-                               rectf = RE_RenderLayerGetPass(rr->renlay, SCE_PASS_COMBINED, viewname);
+                               rectf = RE_RenderLayerGetPass(rr->renlay, RE_PASSNAME_COMBINED, viewname);
                        }
                }
                if (rectf == NULL) return;
index f11a8177bf83aff1f28ac886a390bbd0d1ab0db3..4e02ff77a3175fb7faec95abd43887e14768d2b4 100644 (file)
@@ -189,8 +189,12 @@ void ED_render_engine_changed(Main *bmain)
 
        RE_FreePersistentData();
 
-       for (scene = bmain->scene.first; scene; scene = scene->id.next)
+       for (scene = bmain->scene.first; scene; scene = scene->id.next) {
                ED_render_id_flush_update(bmain, &scene->id);
+               if (scene->nodetree) {
+                       ntreeCompositUpdateRLayers(scene->nodetree);
+               }
+       }
 }
 
 /***************************** Updates ***********************************
index b9d98dfe79446b721db7b4220be01cfbd6f58999..db917b0cdf5307c1ce3952850ac6ad44d3ea076c 100644 (file)
@@ -428,7 +428,6 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
        RenderPass *rpass;
        const char *fake_name;
        int nr;
-       int passflag = 0;
 
        /* may have been freed since drawing */
        rr = BKE_image_acquire_renderresult(scene, image);
@@ -450,30 +449,31 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
        fake_name = ui_imageuser_pass_fake_name(rl);
 
        if (fake_name) {
-               BLI_strncpy(rpass_fake.internal_name, fake_name, sizeof(rpass_fake.internal_name));
+               BLI_strncpy(rpass_fake.name, fake_name, sizeof(rpass_fake.name));
                nr += 1;
        }
 
+       ListBase added_passes;
+       BLI_listbase_clear(&added_passes);
+
        /* rendered results don't have a Combined pass */
        /* multiview: the ordering must be ascending, so the left-most pass is always the one picked */
        for (rpass = rl ? rl->passes.first : NULL; rpass; rpass = rpass->next, nr++) {
-
                /* just show one pass of each kind */
-               if (passflag & rpass->passtype)
+               if (BLI_findstring_ptr(&added_passes, rpass->name, offsetof(LinkData, data))) {
                        continue;
+               }
+               BLI_addtail(&added_passes, BLI_genericNodeN(rpass->name));
 
-               passflag |= rpass->passtype;
-
-final:
-               uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->internal_name), 0, 0,
+               uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->name), 0, 0,
                          UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, (float) nr, 0.0, 0, -1, "");
        }
 
+       BLI_freelistN(&added_passes);
+
        if (fake_name) {
-               fake_name = NULL;
-               rpass = &rpass_fake;
-               nr = 0;
-               goto final;
+               uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass_fake.name), 0, 0,
+                         UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, 0.0f, 0.0, 0, -1, "");
        }
 
        BKE_image_release_renderresult(scene, image);
@@ -633,7 +633,7 @@ static bool ui_imageuser_pass_menu_step(bContext *C, int direction, void *rnd_pt
                int rp_index = iuser->pass + 1;
 
                for (rp = rpass->next; rp; rp = rp->next, rp_index++) {
-                       if (rp->passtype != rpass->passtype) {
+                       if (!STREQ(rp->name, rpass->name)) {
                                iuser->pass = rp_index;
                                changed = true;
                                break;
@@ -650,7 +650,7 @@ static bool ui_imageuser_pass_menu_step(bContext *C, int direction, void *rnd_pt
                }
 
                for (rp = rl->passes.first; rp; rp = rp->next, rp_index++) {
-                       if (rp->passtype == rpass->passtype) {
+                       if (STREQ(rp->name, rpass->name)) {
                                iuser->pass = rp_index - 1;
                                changed = true;
                                break;
@@ -769,7 +769,7 @@ static void uiblock_layer_pass_buttons(
                fake_name = ui_imageuser_pass_fake_name(rl);
                rpass = (rl ? BLI_findlink(&rl->passes, iuser->pass  - (fake_name ? 1 : 0)) : NULL);
 
-               display_name = rpass ? rpass->internal_name : (fake_name ? fake_name : "");
+               display_name = rpass ? rpass->name : (fake_name ? fake_name : "");
                rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
                but = uiDefMenuBut(
                        block, ui_imageuser_pass_menu, rnd_pt, IFACE_(display_name),
index 2a63d09411690d0064c16bc93f861f00f2c55a9b..b7c41f0487987c9fcf4ae248d76380f93edf2b0b 100644 (file)
@@ -3069,6 +3069,7 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr,
        bNode *node = node_ptr->data;
        bNodeSocket *sock = ptr->data;
        int type = sock->typeinfo->type;
+       bool connected_to_virtual = (sock->link && (sock->link->fromsock->flag & SOCK_VIRTUAL));
        /*int subtype = sock->typeinfo->subtype;*/
        
        /* XXX not nice, eventually give this node its own socket type ... */
@@ -3076,8 +3077,8 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr,
                node_file_output_socket_draw(C, layout, ptr, node_ptr);
                return;
        }
-       
-       if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) {
+
+       if ((sock->in_out == SOCK_OUT) || ((sock->flag & SOCK_IN_USE) && !connected_to_virtual) || (sock->flag & SOCK_HIDE_VALUE)) {
                node_socket_button_label(C, layout, ptr, node_ptr, text);
                return;
        }
@@ -3590,6 +3591,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
 {
        bool do_shaded = false;
        bool do_triple = false;
+       bool do_dashed = false;
        int th_col1 = TH_WIRE_INNER, th_col2 = TH_WIRE_INNER, th_col3 = TH_WIRE;
        
        if (link->fromsock == NULL && link->tosock == NULL)
@@ -3606,7 +3608,9 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
                        return;
                if (link->fromsock->flag & SOCK_UNAVAIL)
                        return;
-               
+               if ((link->fromsock->flag & SOCK_VIRTUAL) || (link->fromsock->flag & SOCK_VIRTUAL))
+                       do_dashed = true;
+
                if (link->flag & NODE_LINK_VALID) {
                        /* special indicated link, on drop-node */
                        if (link->flag & NODE_LINKFLAG_HILITE) {
@@ -3626,8 +3630,10 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
                        th_col1 = TH_REDALERT;
                }
        }
-       
+
+       if (do_dashed) setlinestyle(3);
        node_draw_link_bezier(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3);
+       if (do_dashed) setlinestyle(0);
 //     node_draw_link_straight(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3);
 }
 
index fdfe316f5edf8d994856537ddb879906275e9cbd..da28c55fb04dd084ea45ed23323c23c9d29e10e2 100644 (file)
@@ -505,8 +505,6 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce)
        nodeAddLink(sce->nodetree, in, fromsock, out, tosock);
        
        ntreeUpdateTree(CTX_data_main(C), sce->nodetree);
-       
-       // XXX ntreeCompositForceHidden(sce->nodetree);
 }
 
 /* assumes nothing being done in ntree yet, sets the default in/out node */
@@ -585,14 +583,6 @@ void snode_set_context(const bContext *C)
        if (snode->nodetree != ntree || snode->id != id || snode->from != from || snode->treepath.last == NULL) {
                ED_node_tree_start(snode, ntree, id, from);
        }
-       
-       /* XXX Legacy hack to update render layer node outputs.
-        * This should be handled by the depsgraph eventually ...
-        */
-       if (ED_node_is_compositor(snode) && snode->nodetree) {
-               /* update output sockets based on available layers */
-               ntreeCompositForceHidden(snode->nodetree);
-       }
 }
 
 void snode_update(SpaceNode *snode, bNode *node)
index 223bc607e213dc6de64046446c0999e69c91bf2f..ea22633c50e3d3c63e6fb2201fe7c9d5940d2d37 100644 (file)
@@ -448,15 +448,13 @@ static void prepare(Render *re, SceneRenderLayer *srl)
        RenderLayer *rl = RE_GetRenderLayer(re->result, srl->name);
        bool diffuse = false, z = false;
        for (RenderPass *rpass = (RenderPass *)rl->passes.first; rpass; rpass = rpass->next) {
-               switch (rpass->passtype) {
-               case SCE_PASS_DIFFUSE:
+               if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
                        controller->setPassDiffuse(rpass->rect, rpass->rectx, rpass->recty);
                        diffuse = true;
-                       break;
-               case SCE_PASS_Z:
+               }
+               if (STREQ(rpass->name, RE_PASSNAME_Z)) {
                        controller->setPassZ(rpass->rect, rpass->rectx, rpass->recty);
                        z = true;
-                       break;
                }
        }
        if (G.debug & G_DEBUG_FREESTYLE) {
@@ -492,7 +490,7 @@ void FRS_composite_result(Render *re, SceneRenderLayer *srl, Render *freestyle_r
                return;
        }
 
-       src = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, freestyle_render->viewname);
+       src = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, freestyle_render->viewname);
        if (!src) {
                if (G.debug & G_DEBUG_FREESTYLE) {
                        cout << "No source result image to composite" << endl;
@@ -512,7 +510,7 @@ void FRS_composite_result(Render *re, SceneRenderLayer *srl, Render *freestyle_r
                }
                return;
        }
-       dest = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, re->viewname);
+       dest = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname);
        if (!dest) {
                if (G.debug & G_DEBUG_FREESTYLE) {
                        cout << "No destination result image to composite to" << endl;
index 47677e50451ef550b0a43ccdbaa4f6ca6398e4ef..0ba3e013c237e13406ded580b725f7194d7d6129 100644 (file)
@@ -159,7 +159,8 @@ typedef enum eNodeSocketFlag {
        SOCK_COLLAPSED = 64,                            /* socket collapsed in UI */
        SOCK_HIDE_VALUE = 128,                          /* hide socket value, if it gets auto default */
        SOCK_AUTO_HIDDEN__DEPRECATED = 256,     /* socket hidden automatically, to distinguish from manually hidden */
-       SOCK_NO_INTERNAL_LINK = 512
+       SOCK_NO_INTERNAL_LINK = 512,
+       SOCK_VIRTUAL = 1024                     /* socket behaves like SOCK_UNAVAIL, but is drawn with dashed links */
 } eNodeSocketFlag;
 
 /* limit data in bNode to what we want to see saved? */
@@ -569,9 +570,9 @@ typedef struct NodeEllipseMask {
 /* layer info for image node outputs */
 typedef struct NodeImageLayer {
        /* index in the Image->layers->passes lists */
-       int pass_index;
-       /* render pass flag, in case this is an original render pass */
-       int pass_flag;
+       int pass_index  DNA_DEPRECATED;
+       /* render pass name */
+       char pass_name[64]; /* amount defined in openexr_multi.h */
 } NodeImageLayer;
 
 typedef struct NodeBlurData {
index 918d0f000409f16a84b7aae6aef8b7b74ba11053..c2711c465e1eb8a7b3c6a98d26334669a5ba9a8a 100644 (file)
@@ -229,7 +229,9 @@ typedef struct SceneRenderLayer {
 
        int samples;
        float pass_alpha_threshold;
-       
+
+       IDProperty *prop;
+
        struct FreestyleConfig freestyleConfig;
 } SceneRenderLayer;
 
@@ -283,9 +285,43 @@ typedef enum ScenePassType {
        SCE_PASS_SUBSURFACE_DIRECT        = (1 << 28),
        SCE_PASS_SUBSURFACE_INDIRECT      = (1 << 29),
        SCE_PASS_SUBSURFACE_COLOR         = (1 << 30),
-       SCE_PASS_DEBUG                    = (1 << 31),  /* This is a virtual pass. */
 } ScenePassType;
 
+#define RE_PASSNAME_COMBINED "Combined"
+#define RE_PASSNAME_Z "Depth"
+#define RE_PASSNAME_VECTOR "Vector"
+#define RE_PASSNAME_NORMAL "Normal"
+#define RE_PASSNAME_UV "UV"
+#define RE_PASSNAME_RGBA "Color"
+#define RE_PASSNAME_EMIT "Emit"
+#define RE_PASSNAME_DIFFUSE "Diffuse"
+#define RE_PASSNAME_SPEC "Spec"
+#define RE_PASSNAME_SHADOW "Shadow"
+
+#define RE_PASSNAME_AO "AO"
+#define RE_PASSNAME_ENVIRONMENT "Env"
+#define RE_PASSNAME_INDIRECT "Indirect"
+#define RE_PASSNAME_REFLECT "Reflect"
+#define RE_PASSNAME_REFRACT "Refract"
+#define RE_PASSNAME_INDEXOB "IndexOB"
+#define RE_PASSNAME_INDEXMA "IndexMA"
+#define RE_PASSNAME_MIST "Mist"
+
+#define RE_PASSNAME_RAYHITS "RayHits"
+#define RE_PASSNAME_DIFFUSE_DIRECT "DiffDir"
+#define RE_PASSNAME_DIFFUSE_INDIRECT "DiffInd"
+#define RE_PASSNAME_DIFFUSE_COLOR "DiffCol"
+#define RE_PASSNAME_GLOSSY_DIRECT "GlossDir"
+#define RE_PASSNAME_GLOSSY_INDIRECT "GlossInd"
+#define RE_PASSNAME_GLOSSY_COLOR "GlossCol"
+#define RE_PASSNAME_TRANSM_DIRECT "TransDir"
+#define RE_PASSNAME_TRANSM_INDIRECT "TransInd"
+#define RE_PASSNAME_TRANSM_COLOR "TransCol"
+
+#define RE_PASSNAME_SUBSURFACE_DIRECT "SubsurfaceDir"
+#define RE_PASSNAME_SUBSURFACE_INDIRECT "SubsurfaceInd"
+#define RE_PASSNAME_SUBSURFACE_COLOR "SubsurfaceCol"
+
 /* note, srl->passflag is treestore element 'nr' in outliner, short still... */
 
 /* View - MultiView */
index 0f3ea27a7f9d2aefc70a6391c7062f8134c8846c..6a08d762920a62e4c7df5a935113a6c1280d2ae2 100644 (file)
@@ -176,9 +176,6 @@ set(INC_SYS
 
 if(WITH_CYCLES)
        add_definitions(-DWITH_CYCLES)
-       if(WITH_CYCLES_DEBUG)
-               add_definitions(-DWITH_CYCLES_DEBUG)
-       endif()
 endif()
 
 if(WITH_PYTHON)
index c3477644979ef85c6665b4e845fed9cf583f592e..dfdd2ff293a9e96a41ddd335de652b9700979708 100644 (file)
@@ -64,6 +64,8 @@
 
 #include "RE_render_ext.h"
 
+#include "NOD_composite.h"
+
 EnumPropertyItem rna_enum_node_socket_in_out_items[] = {
        { SOCK_IN, "IN", 0, "Input", "" },
        { SOCK_OUT, "OUT", 0, "Output", "" },
@@ -2608,7 +2610,7 @@ static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *p
        rna_Node_update(bmain, scene, ptr);
 
        if (scene->nodetree != NULL) {
-               ntreeCompositForceHidden(scene->nodetree);
+               ntreeCompositUpdateRLayers(scene->nodetree);
        }
 }
 
@@ -2747,7 +2749,7 @@ static void rna_Node_scene_layer_update(Main *bmain, Scene *scene, PointerRNA *p
 {
        rna_Node_update(bmain, scene, ptr);
        if (scene->nodetree != NULL) {
-               ntreeCompositForceHidden(scene->nodetree);
+               ntreeCompositUpdateRLayers(scene->nodetree);
        }
 }
 
@@ -4796,7 +4798,7 @@ static void def_cmp_render_layers(StructRNA *srna)
        RNA_def_property_struct_type(prop, "Scene");
        RNA_def_property_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Scene", "");
-       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_scene_layer_update");
        
        prop = RNA_def_property(srna, "layer", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "custom1");
@@ -6922,6 +6924,11 @@ static void rna_def_node_socket(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Enabled", "Enable the socket");
        RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
 
+       prop = RNA_def_property(srna, "is_virtual", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_VIRTUAL);
+       RNA_def_property_ui_text(prop, "Virtual", "Socket is Virtual");
+       RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
+
        prop = RNA_def_property(srna, "link_limit", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "limit");
        RNA_def_property_int_funcs(prop, NULL, "rna_NodeSocket_link_limit_set", NULL);
index 518c7efd9157f3e21d1c0675cc08e1dc473cd4fa..129cc591d9f0de41b4ae6434cb462f0ac656c55e 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <stdlib.h>
 
+#include "DNA_node_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_object_types.h"
 
@@ -41,6 +42,7 @@
 #include "RE_pipeline.h"
 
 
+/* Deprecated, only provided for API compatibility. */
 EnumPropertyItem rna_enum_render_pass_type_items[] = {
        {SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
        {SCE_PASS_Z, "Z", 0, "Z", ""},
@@ -77,18 +79,6 @@ EnumPropertyItem rna_enum_render_pass_type_items[] = {
        {0, NULL, 0, NULL, NULL}
 };
 
-EnumPropertyItem rna_enum_render_pass_debug_type_items[] = {
-       {RENDER_PASS_DEBUG_BVH_TRAVERSED_NODES, "BVH_TRAVERSED_NODES", 0, "BVH Traversed Nodes",
-        "Number of nodes traversed in BVH for the camera rays"},
-       {RENDER_PASS_DEBUG_BVH_TRAVERSED_INSTANCES, "BVH_TRAVERSED_INSTANCES", 0, "BVH Traversed Instances",
-        "Number of BVH instances traversed by camera rays"},
-       {RENDER_PASS_DEBUG_BVH_INTERSECTIONS, "BVH_INTERSECTIONS", 0, "BVH Intersections",
-        "Number of primitive intersections performed by the camera rays"},
-       {RENDER_PASS_DEBUG_RAY_BOUNCES, "RAY_BOUNCES", 0, "Ray Steps",
-        "Number of bounces done by the main integration loop"},
-       {0, NULL, 0, NULL, NULL}
-};
-
 EnumPropertyItem rna_enum_bake_pass_type_items[] = {
        {SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
        {SCE_PASS_AO, "AO", 0, "AO", ""},
@@ -261,6 +251,24 @@ static void engine_update_script_node(RenderEngine *engine, struct bNodeTree *nt
        RNA_parameter_list_free(&list);
 }
 
+static void engine_update_render_passes(RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl)
+{
+       extern FunctionRNA rna_RenderEngine_update_render_passes_func;
+       PointerRNA ptr;
+       ParameterList list;
+       FunctionRNA *func;
+
+       RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+       func = &rna_RenderEngine_update_render_passes_func;
+
+       RNA_parameter_list_create(&list, &ptr, func);
+       RNA_parameter_set_lookup(&list, "scene", &scene);
+       RNA_parameter_set_lookup(&list, "renderlayer", &srl);
+       engine->type->ext.call(NULL, &ptr, func, &list);
+
+       RNA_parameter_list_free(&list);
+}
+
 /* RenderEngine registration */
 
 static void rna_RenderEngine_unregister(Main *UNUSED(bmain), StructRNA *type)
@@ -281,7 +289,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
        RenderEngineType *et, dummyet = {NULL};
        RenderEngine dummyengine = {NULL};
        PointerRNA dummyptr;
-       int have_function[6];
+       int have_function[7];
 
        /* setup dummy engine & engine type to store static properties in */
        dummyengine.type = &dummyet;
@@ -323,6 +331,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
        et->view_update = (have_function[3]) ? engine_view_update : NULL;
        et->view_draw = (have_function[4]) ? engine_view_draw : NULL;
        et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL;
+       et->update_render_passes = (have_function[6]) ? engine_update_render_passes : NULL;
 
        BLI_addtail(&R_engines, et);
 
@@ -419,6 +428,11 @@ static RenderPass *rna_RenderPass_find_by_type(RenderLayer *rl, int passtype, co
        return RE_pass_find_by_type(rl, passtype, view);
 }
 
+static RenderPass *rna_RenderPass_find_by_name(RenderLayer *rl, const char *name, const char *view)
+{
+       return RE_pass_find_by_name(rl, name, view);
+}
+
 #else /* RNA_RUNTIME */
 
 static void rna_def_render_engine(BlenderRNA *brna)
@@ -429,6 +443,13 @@ static void rna_def_render_engine(BlenderRNA *brna)
        FunctionRNA *func;
        PropertyRNA *parm;
 
+       static EnumPropertyItem render_pass_type_items[] = {
+               {SOCK_FLOAT,   "VALUE",     0,    "Value",     ""},
+               {SOCK_VECTOR,  "VECTOR",    0,    "Vector",    ""},
+               {SOCK_RGBA,    "COLOR",     0,    "Color",     ""},
+               {0, NULL, 0, NULL, NULL}
+       };
+
        srna = RNA_def_struct(brna, "RenderEngine", NULL);
        RNA_def_struct_sdna(srna, "RenderEngine");
        RNA_def_struct_ui_text(srna, "Render Engine", "Render engine");
@@ -497,6 +518,12 @@ static void rna_def_render_engine(BlenderRNA *brna)
        func = RNA_def_function(srna, "tag_update", "engine_tag_update");
        RNA_def_function_ui_description(func, "Request update call for viewport rendering");
 
+       func = RNA_def_function(srna, "update_render_passes", NULL);
+       RNA_def_function_ui_description(func, "Update the render passes that will be generated");
+       RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+       parm = RNA_def_pointer(func, "scene", "Scene", "", "");
+       parm = RNA_def_pointer(func, "renderlayer", "SceneRenderLayer", "", "");
+
        func = RNA_def_function(srna, "begin_result", "RE_engine_begin_result");
        RNA_def_function_ui_description(func, "Create render result to write linear floating point render layers and passes");
        parm = RNA_def_int(func, "x", 0, 0, INT_MAX, "X", "", 0, INT_MAX);
@@ -524,6 +551,17 @@ static void rna_def_render_engine(BlenderRNA *brna)
        RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't mark tile as done, don't merge results unless forced");
        RNA_def_boolean(func, "do_merge_results", 0, "Merge Results", "Merge results even if cancel=true");
 
+       func = RNA_def_function(srna, "add_pass", "RE_engine_add_pass");
+       RNA_def_function_ui_description(func, "Add a pass to the render layer");
+       parm = RNA_def_string(func, "name", NULL, 0, "Name", "Name of the Pass, without view or channel tag");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_int(func, "channels", 0, 0, INT_MAX, "Channels", "", 0, INT_MAX);
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_string(func, "chan_id", NULL, 0, "Channel IDs", "Channel names, one character per channel");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       RNA_def_string(func, "layer", NULL, 0, "Layer", "Single layer to add render pass to");  /* NULL ok here */
+
+
        func = RNA_def_function(srna, "test_break", "RE_engine_test_break");
        RNA_def_function_ui_description(func, "Test if the render operation should been canceled, this is a fast call that should be used regularly for responsiveness");
        parm = RNA_def_boolean(func, "do_break", 0, "Break", "");
@@ -646,6 +684,21 @@ static void rna_def_render_engine(BlenderRNA *brna)
        prop = RNA_def_property(srna, "use_highlight_tiles", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_HIGHLIGHT_TILES);
 
+       func = RNA_def_function(srna, "register_pass", "RE_engine_register_pass");
+       RNA_def_function_ui_description(func, "Register a render pass that will be part of the render with the current settings");
+       prop = RNA_def_pointer(func, "scene", "Scene", "", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       prop = RNA_def_pointer(func, "srl", "SceneRenderLayer", "", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       prop = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       prop = RNA_def_int(func, "channels", 1, 1, 8, "Channels", "", 1, 4);
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       prop = RNA_def_string(func, "chanid", NULL, 8, "Channel IDs", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       prop = RNA_def_enum(func, "type", render_pass_type_items, SOCK_FLOAT, "Type", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
        /* registration */
 
        prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
@@ -774,6 +827,15 @@ static void rna_def_render_passes(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
        parm = RNA_def_pointer(func, "render_pass", "RenderPass", "", "The matching render pass");
        RNA_def_function_return(func, parm);
+
+       func = RNA_def_function(srna, "find_by_name", "rna_RenderPass_find_by_name");
+       RNA_def_function_ui_description(func, "Get the render pass for a given name and view");
+       parm = RNA_def_string(func, "name", RE_PASSNAME_COMBINED, 0, "Pass", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_string(func, "view", NULL, 0, "View", "Render view to get pass from");  /* NULL ok here */
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_pointer(func, "render_pass", "RenderPass", "", "The matching render pass");
+       RNA_def_function_return(func, parm);
 }
 
 static void rna_def_render_layer(BlenderRNA *brna)
@@ -822,6 +884,11 @@ static void rna_def_render_pass(BlenderRNA *brna)
 
        RNA_define_verify_sdna(0);
 
+       prop = RNA_def_property(srna, "fullname", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "fullname");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_struct_name_property(srna, prop);
+
        prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "name");
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -835,11 +902,6 @@ static void rna_def_render_pass(BlenderRNA *brna)
        RNA_def_property_int_sdna(prop, NULL, "channels");
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 
-       prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_sdna(prop, NULL, "passtype");
-       RNA_def_property_enum_items(prop, rna_enum_render_pass_type_items);
-       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
        prop = RNA_def_property(srna, "rect", PROP_FLOAT, PROP_NONE);
        RNA_def_property_flag(prop, PROP_DYNAMIC);
        RNA_def_property_multi_array(prop, 2, NULL);
@@ -850,11 +912,6 @@ static void rna_def_render_pass(BlenderRNA *brna)
        RNA_def_property_int_sdna(prop, NULL, "view_id");
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 
-       prop = RNA_def_property(srna, "debug_type", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_sdna(prop, NULL, "debug_type");
-       RNA_def_property_enum_items(prop, rna_enum_render_pass_debug_type_items);
-       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
        RNA_define_verify_sdna(1);
 }
 
index 899466f05dfac73d9ab5850b38f077c25b878068..dd30cb0d03f3a9fe55bab77da16ef25ee3121f38 100644 (file)
@@ -448,6 +448,7 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
 #include "BKE_colortools.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
+#include "BKE_idprop.h"
 #include "BKE_image.h"
 #include "BKE_main.h"
 #include "BKE_node.h"
@@ -1608,6 +1609,18 @@ static void rna_Scene_use_view_map_cache_update(Main *UNUSED(bmain), Scene *UNUS
 #endif
 }
 
+static IDProperty *rna_SceneRenderLayer_idprops(PointerRNA *ptr, bool create)
+{
+       SceneRenderLayer *srl = (SceneRenderLayer *)ptr->data;
+
+       if (create && !srl->prop) {
+               IDPropertyTemplate val = {0};
+               srl->prop = IDP_New(IDP_GROUP, &val, "SceneRenderLayer ID properties");
+       }
+
+       return srl->prop;
+}
+
 static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
 {
        Scene *scene = (Scene *)ptr->id.data;
@@ -1712,11 +1725,18 @@ static void rna_SceneRenderLayer_pass_update(Main *bmain, Scene *activescene, Po
        Scene *scene = (Scene *)ptr->id.data;
 
        if (scene->nodetree)
-               ntreeCompositForceHidden(scene->nodetree);
-       
+               ntreeCompositUpdateRLayers(scene->nodetree);
+
        rna_Scene_glsl_update(bmain, activescene, ptr);
 }
 
+static void rna_SceneRenderLayer_update_render_passes(ID *id)
+{
+       Scene *scene = (Scene*) id;
+       if (scene->nodetree)
+               ntreeCompositUpdateRLayers(scene->nodetree);
+}
+
 static void rna_Scene_use_nodes_update(bContext *C, PointerRNA *ptr)
 {
        Scene *scene = (Scene *)ptr->data;
@@ -5072,14 +5092,20 @@ static void rna_def_scene_render_layer(BlenderRNA *brna)
 {
        StructRNA *srna;
        PropertyRNA *prop;
+       FunctionRNA *func;
 
        srna = RNA_def_struct(brna, "SceneRenderLayer", NULL);
        RNA_def_struct_ui_text(srna, "Scene Render Layer", "Render layer");
        RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
        RNA_def_struct_path_func(srna, "rna_SceneRenderLayer_path");
+       RNA_def_struct_idprops_func(srna, "rna_SceneRenderLayer_idprops");
 
        rna_def_render_layer_common(srna, 1);
 
+       func = RNA_def_function(srna, "update_render_passes", "rna_SceneRenderLayer_update_render_passes");
+       RNA_def_function_ui_description(func, "Requery the enabled render passes from the render engine");
+       RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF);
+
        /* Freestyle */
        rna_def_freestyle_settings(brna);
 
@@ -6742,14 +6768,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
        RNA_def_property_struct_type(prop, "BakeSettings");
        RNA_def_property_ui_text(prop, "Bake Data", "");
 
-       /* Debugging settings. */
-#ifdef WITH_CYCLES_DEBUG
-       prop = RNA_def_property(srna, "debug_pass_type", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_items(prop, rna_enum_render_pass_debug_type_items);
-       RNA_def_property_ui_text(prop, "Debug Pass Type", "Type of the debug pass to use");
-       RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-#endif
-
        /* Nestled Data  */
        /* *** Non-Animated *** */
        RNA_define_animate_sdna(false);
index 3596a2aa12dd53ecdd94ce988646d0f503d35567..c5a3c70100ba7b0fa432bf375157399aa801c60f 100644 (file)
@@ -289,8 +289,4 @@ if(WITH_FREESTYLE)
        add_definitions(-DWITH_FREESTYLE)
 endif()
 
-if(WITH_CYCLES AND WITH_CYCLES_DEBUG)
-       add_definitions(-DWITH_CYCLES_DEBUG)
-endif()
-
 blender_add_lib(bf_nodes "${SRC}" "${INC}" "${INC_SYS}")
index 0215db1dd5555d0881e87be314936b1067bcbd39..a5c2e604f46e9e557368206c7a52edd31b489307 100644 (file)
@@ -139,6 +139,8 @@ void register_node_type_cmp_trackpos(void);
 void register_node_type_cmp_planetrackdeform(void);
 void register_node_type_cmp_cornerpin(void);
 
-void node_cmp_rlayers_force_hidden_passes(struct bNode *node);
+void node_cmp_rlayers_outputs(struct bNodeTree *ntree, struct bNode *node);
+void node_cmp_rlayers_register_pass(struct bNodeTree *ntree, struct bNode *node, struct Scene *scene, struct SceneRenderLayer *srl, const char *name, int type);
+const char *node_cmp_rlayers_sock_to_pass(int sock_index);
 
 #endif
index cb565bd5491bc15560317621b3152f810c359067..36778a18f777acb6ded5ddfa642dc3065e403d03 100644 (file)
@@ -240,8 +240,15 @@ void ntreeCompositExecTree(Scene *scene, bNodeTree *ntree, RenderData *rd, int r
 
 /* *********************************************** */
 
-/* based on rules, force sockets hidden always */
-void ntreeCompositForceHidden(bNodeTree *ntree)
+/* Update the outputs of the render layer nodes.
+ * Since the outputs depend on the render engine, this part is a bit complex:
+ * - ntreeCompositUpdateRLayers is called and loops over all render layer nodes
+ * - Each render layer node calls the update function of the render engine that's used for its scene
+ * - The render engine calls RE_engine_register_pass for each pass
+ * - RE_engine_register_pass calls ntreeCompositRegisterPass,
+ *   which calls node_cmp_rlayers_register_pass for every render layer node
+ */
+void ntreeCompositUpdateRLayers(bNodeTree *ntree)
 {
        bNode *node;
 
@@ -249,16 +256,20 @@ void ntreeCompositForceHidden(bNodeTree *ntree)
 
        for (node = ntree->nodes.first; node; node = node->next) {
                if (node->type == CMP_NODE_R_LAYERS)
-                       node_cmp_rlayers_force_hidden_passes(node);
-               
-               /* XXX this stuff is called all the time, don't want that.
-                * Updates should only happen when actually necessary.
-                */
-#if 0
-               else if (node->type == CMP_NODE_IMAGE) {
-                       nodeUpdate(ntree, node);
-               }
-#endif
+                       node_cmp_rlayers_outputs(ntree, node);
+       }
+
+}
+
+void ntreeCompositRegisterPass(bNodeTree *ntree, Scene *scene, SceneRenderLayer *srl, const char *name, int type)
+{
+       bNode *node;
+
+       if (ntree == NULL) return;
+
+       for (node = ntree->nodes.first; node; node = node->next) {
+               if (node->type == CMP_NODE_R_LAYERS)
+                       node_cmp_rlayers_register_pass(ntree, node, scene, srl, name, type);
        }
 
 }
index 4f02c1065694066d088c37a29427ce55e9311c7d..510e24554f06bb234c5aae4698782f472585a605 100644 (file)
 #include "node_composite_util.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_linklist.h"
 
 #include "DNA_scene_types.h"
 
+#include "RE_engine.h"
+
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 
-#ifdef WITH_CYCLES_DEBUG
-#  include "RE_pipeline.h"
-#endif
-
 /* **************** IMAGE (and RenderResult, multilayer image) ******************** */
 
 static bNodeSocketTemplate cmp_node_rlayers_out[] = {
-       {       SOCK_RGBA, 0, N_("Image"),                                      0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_FLOAT, 0, N_("Alpha"),                                     1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_FLOAT, 0, N_("Z"),                                         1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_VECTOR, 0, N_("Normal"),                           0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_VECTOR, 0, N_("UV"),                                       1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_VECTOR, 0, N_("Speed"),                            1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Color"),                                      0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Diffuse"),                            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Specular"),                           0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Shadow"),                                     0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("AO"),                                         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Reflect"),                            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Refract"),                            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Indirect"),                           0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_FLOAT, 0, N_("IndexOB"),                           0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_FLOAT, 0, N_("IndexMA"),                           0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_FLOAT, 0, N_("Mist"),                                      0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Emit"),                                       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Environment"),                        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Diffuse Direct"),                     0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Diffuse Indirect"),           0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Diffuse Color"),                      0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Glossy Direct"),                      0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Glossy Indirect"),            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Glossy Color"),                       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Transmission Direct"),        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Transmission Indirect"),      0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Transmission Color"),         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Subsurface Direct"),          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Subsurface Indirect"),        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 0, N_("Subsurface Color"),           0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-#ifdef WITH_CYCLES_DEBUG
-       {       SOCK_RGBA, 0, N_("Debug"),                                      0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-#endif
+       {       SOCK_RGBA,   0, N_("Image"),                                                    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_FLOAT,  0, N_("Alpha"),                                                    1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_FLOAT,  0, N_(RE_PASSNAME_Z),                                              1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VECTOR, 0, N_(RE_PASSNAME_NORMAL),                                 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VECTOR, 0, N_(RE_PASSNAME_UV),                                             1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VECTOR, 0, N_(RE_PASSNAME_VECTOR),                                 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_RGBA),                                   0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_DIFFUSE),                                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_SPEC),                                   0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_SHADOW),                                 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_AO),                                             0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_REFLECT),                                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_REFRACT),                                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_INDIRECT),                               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_FLOAT,  0, N_(RE_PASSNAME_INDEXOB),                                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_FLOAT,  0, N_(RE_PASSNAME_INDEXMA),                                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_FLOAT,  0, N_(RE_PASSNAME_MIST),                                   0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_EMIT),                                   0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_ENVIRONMENT),                    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_DIFFUSE_DIRECT),                 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_DIFFUSE_INDIRECT),               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_DIFFUSE_COLOR),                  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_GLOSSY_DIRECT),                  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_GLOSSY_INDIRECT),                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_GLOSSY_COLOR),                   0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_TRANSM_DIRECT),                  0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_TRANSM_INDIRECT),                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_TRANSM_COLOR),                   0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_SUBSURFACE_DIRECT),              0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_SUBSURFACE_INDIRECT),    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA,   0, N_(RE_PASSNAME_SUBSURFACE_COLOR),               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       -1, 0, ""       }
 };
 
-static bNodeSocket *cmp_node_image_add_render_pass_output(bNodeTree *ntree, bNode *node, int pass, int rres_index)
+static void cmp_node_image_add_pass_output(bNodeTree *ntree, bNode *node,
+                                           const char *name, const char *passname,
+                                           int rres_index, int type, int is_rlayers,
+                                           LinkNodePair *available_sockets, int *prev_index)
 {
        bNodeSocket *sock;
-       NodeImageLayer *sockdata;
-       
-       sock = node_add_socket_from_template(ntree, node, &cmp_node_rlayers_out[rres_index], SOCK_OUT);
-       /* extra socket info */
-       sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
-       sock->storage = sockdata;
-       
-       sockdata->pass_flag = pass;
-       
-       return sock;
-}
-
-static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node, int passflag)
-{
-       if (passflag & SCE_PASS_COMBINED) {
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMBINED, RRES_OUT_IMAGE);
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMBINED, RRES_OUT_ALPHA);
-       }
-       
-       if (passflag & SCE_PASS_Z)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_Z, RRES_OUT_Z);
-       if (passflag & SCE_PASS_NORMAL)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_NORMAL, RRES_OUT_NORMAL);
-       if (passflag & SCE_PASS_VECTOR)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_VECTOR, RRES_OUT_VEC);
-       if (passflag & SCE_PASS_UV)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_UV, RRES_OUT_UV);
-       if (passflag & SCE_PASS_RGBA)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_RGBA, RRES_OUT_RGBA);
-       if (passflag & SCE_PASS_DIFFUSE)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE, RRES_OUT_DIFF);
-       if (passflag & SCE_PASS_SPEC)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SPEC, RRES_OUT_SPEC);
-       if (passflag & SCE_PASS_SHADOW)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SHADOW, RRES_OUT_SHADOW);
-       if (passflag & SCE_PASS_AO)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_AO, RRES_OUT_AO);
-       if (passflag & SCE_PASS_REFLECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFLECT, RRES_OUT_REFLECT);
-       if (passflag & SCE_PASS_REFRACT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFRACT, RRES_OUT_REFRACT);
-       if (passflag & SCE_PASS_INDIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDIRECT, RRES_OUT_INDIRECT);
-       if (passflag & SCE_PASS_INDEXOB)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDEXOB, RRES_OUT_INDEXOB);
-       if (passflag & SCE_PASS_INDEXMA)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDEXMA, RRES_OUT_INDEXMA);
-       if (passflag & SCE_PASS_MIST)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_MIST, RRES_OUT_MIST);
-       if (passflag & SCE_PASS_EMIT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_EMIT, RRES_OUT_EMIT);
-       if (passflag & SCE_PASS_ENVIRONMENT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_ENVIRONMENT, RRES_OUT_ENV);
-       
-       if (passflag & SCE_PASS_DIFFUSE_DIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_DIRECT, RRES_OUT_DIFF_DIRECT);
-       if (passflag & SCE_PASS_DIFFUSE_INDIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_INDIRECT, RRES_OUT_DIFF_INDIRECT);
-       if (passflag & SCE_PASS_DIFFUSE_COLOR)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_COLOR, RRES_OUT_DIFF_COLOR);
-       
-       if (passflag & SCE_PASS_GLOSSY_DIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_DIRECT, RRES_OUT_GLOSSY_DIRECT);
-       if (passflag & SCE_PASS_GLOSSY_INDIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_INDIRECT, RRES_OUT_GLOSSY_INDIRECT);
-       if (passflag & SCE_PASS_GLOSSY_COLOR)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_COLOR, RRES_OUT_GLOSSY_COLOR);
-       
-       if (passflag & SCE_PASS_TRANSM_DIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_DIRECT, RRES_OUT_TRANSM_DIRECT);
-       if (passflag & SCE_PASS_TRANSM_INDIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_INDIRECT, RRES_OUT_TRANSM_INDIRECT);
-       if (passflag & SCE_PASS_TRANSM_COLOR)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_COLOR, RRES_OUT_TRANSM_COLOR);
-               
-       if (passflag & SCE_PASS_SUBSURFACE_DIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_DIRECT, RRES_OUT_SUBSURFACE_DIRECT);
-       if (passflag & SCE_PASS_SUBSURFACE_INDIRECT)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_INDIRECT, RRES_OUT_SUBSURFACE_INDIRECT);
-       if (passflag & SCE_PASS_SUBSURFACE_COLOR)
-               cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_COLOR, RRES_OUT_SUBSURFACE_COLOR);
-
-#ifdef WITH_CYCLES_DEBUG
-       cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DEBUG, RRES_OUT_DEBUG);
-#endif
-}
-
-static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node, RenderLayer *rl)
-{
-       bNodeSocket *sock;
-       NodeImageLayer *sockdata;
-       RenderPass *rpass;
-       int index;
-       int passflag = 0;
-       for (rpass = rl->passes.first, index = 0; rpass; rpass = rpass->next, ++index) {
-               int type;
-               if (rpass->channels == 1)
-                       type = SOCK_FLOAT;
-               else
-                       type = SOCK_RGBA;
-
-               /* we only need one socket per type */
-               if (passflag & rpass->passtype)
-                       continue;
-
-               passflag |= rpass->passtype;
-
-               sock = nodeAddStaticSocket(ntree, node, SOCK_OUT, type, PROP_NONE, rpass->internal_name, rpass->internal_name);
+       int sock_index = BLI_findstringindex(&node->outputs, name, offsetof(bNodeSocket, name));
+
+       if (sock_index < 0) {
+               /* The first 31 sockets always are the legacy hardcoded sockets.
+                * Any dynamically allocated sockets follow afterwards, and are sorted in the order in which they were stored in the RenderResult.
+                * Therefore, we remember the index of the last matched socket. New sockets are placed behind the previously traversed one, but always after the first 31. */
+               int after_index = *prev_index;
+               if (is_rlayers && after_index < 30)
+                       after_index = 30;
+
+               if (rres_index >= 0) {
+                       sock = node_add_socket_from_template(ntree, node, &cmp_node_rlayers_out[rres_index], SOCK_OUT);
+               }
+               else {
+                       sock = nodeAddStaticSocket(ntree, node, SOCK_OUT, type, PROP_NONE, name, name);
+               }
                /* extra socket info */
-               sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
+               NodeImageLayer *sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
                sock->storage = sockdata;
-               
-               sockdata->pass_index = index;
-               sockdata->pass_flag = rpass->passtype;
-
-               if (rpass->passtype == SCE_PASS_COMBINED) {
-                       sock = nodeAddStaticSocket(ntree, node, SOCK_OUT, SOCK_FLOAT, PROP_NONE, "Alpha", "Alpha");
-                       sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
-                       sock->storage = sockdata;
-                       sockdata->pass_index = index;
-                       sockdata->pass_flag = rpass->passtype;
+
+               BLI_strncpy(sockdata->pass_name, passname, sizeof(sockdata->pass_name));
+
+               sock_index = BLI_listbase_count(&node->outputs)-1;
+               if (sock_index != after_index+1) {
+                       bNodeSocket *after_sock = BLI_findlink(&node->outputs, after_index);
+                       BLI_remlink(&node->outputs, sock);
+                       BLI_insertlinkafter(&node->outputs, after_sock, sock);
                }
        }
+       else {
+               sock = BLI_findlink(&node->outputs, sock_index);
+       }
+
+       BLI_linklist_append(available_sockets, sock);
+       *prev_index = sock_index;
 }
 
-static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node)
+static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node, LinkNodePair *available_sockets)
 {
        Image *ima = (Image *)node->id;
+       ImBuf *ibuf;
+       int prev_index = -1;
        if (ima) {
                ImageUser *iuser = node->storage;
                ImageUser load_iuser = {NULL};
-               ImBuf *ibuf;
                int offset = BKE_image_sequence_guess_offset(ima);
 
                /* It is possible that image user in this node is not
@@ -238,104 +150,150 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node)
                        RenderLayer *rl = BLI_findlink(&ima->rr->layers, iuser->layer);
                        
                        if (rl) {
-                               if (ima->type != IMA_TYPE_MULTILAYER)
-                                       cmp_node_image_add_render_pass_outputs(ntree, node, rl->passflag);
-                               else
-                                       cmp_node_image_add_multilayer_outputs(ntree, node, rl);
+                               RenderPass *rpass;
+                               for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
+                                       int type;
+                                       if (rpass->channels == 1)
+                                               type = SOCK_FLOAT;
+                                       else
+                                               type = SOCK_RGBA;
+
+                                       /* Special handling for the Combined pass to ensure compatibility. */
+                                       if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+                                               cmp_node_image_add_pass_output(ntree, node, "Image", rpass->name, -1, type, false, available_sockets, &prev_index);
+                                               cmp_node_image_add_pass_output(ntree, node, "Alpha", rpass->name, -1, SOCK_FLOAT, false, available_sockets, &prev_index);
+                                       }
+                                       else {
+                                               cmp_node_image_add_pass_output(ntree, node, rpass->name, rpass->name, -1, type, false, available_sockets, &prev_index);
+                                       }
+                               }
+                               BKE_image_release_ibuf(ima, ibuf, NULL);
+                               return;
                        }
-                       else
-                               cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE | RRES_OUT_ALPHA);
                }
-               else
-                       cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE | RRES_OUT_ALPHA | RRES_OUT_Z);
-               
+       }
+
+       cmp_node_image_add_pass_output(ntree, node, "Image", RE_PASSNAME_COMBINED, RRES_OUT_IMAGE, SOCK_RGBA, false, available_sockets, &prev_index);
+       cmp_node_image_add_pass_output(ntree, node, "Alpha", RE_PASSNAME_COMBINED, RRES_OUT_ALPHA, SOCK_FLOAT, false, available_sockets, &prev_index);
+
+       if (ima) {
+               if (!ima->rr) {
+                       cmp_node_image_add_pass_output(ntree, node, RE_PASSNAME_Z, RE_PASSNAME_Z, RRES_OUT_Z, SOCK_FLOAT, false, available_sockets, &prev_index);
+               }
                BKE_image_release_ibuf(ima, ibuf, NULL);
        }
-       else
-               cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE | RRES_OUT_ALPHA);
 }
 
-static bNodeSocket *cmp_node_image_output_find_match(bNode *UNUSED(node), bNodeSocket *newsock, ListBase *oldsocklist)
-{
-       bNodeSocket *sock;
-       
-       for (sock = oldsocklist->first; sock; sock = sock->next)
-               if (STREQ(sock->name, newsock->name))
-                       return sock;
-       return NULL;
-}
+typedef struct RLayerUpdateData {
+       LinkNodePair *available_sockets;
+       int prev_index;
+} RLayerUpdateData;
 
-static bNodeSocket *cmp_node_image_output_relink(bNode *node, bNodeSocket *oldsock, int oldindex)
+void node_cmp_rlayers_register_pass(bNodeTree *ntree, bNode *node, Scene *scene, SceneRenderLayer *srl, const char *name, int type)
 {
-       bNodeSocket *sock;
-       
-       /* first try to find matching socket name */
-       for (sock = node->outputs.first; sock; sock = sock->next)
-               if (STREQ(sock->name, oldsock->name))
-                       return sock;
-       
-       /* no matching name, simply link to same index */
-       return BLI_findlink(&node->outputs, oldindex);
+       RLayerUpdateData *data = node->storage;
+
+       if (scene == NULL || srl == NULL || data == NULL || node->id != scene) {
+               return;
+       }
+
+       SceneRenderLayer *node_srl = BLI_findlink(&scene->r.layers, node->custom1);
+       if (node_srl != srl) {
+               return;
+       }
+
+       /* Special handling for the Combined pass to ensure compatibility. */
+       if (STREQ(name, RE_PASSNAME_COMBINED)) {
+               cmp_node_image_add_pass_output(ntree, node, "Image", name, -1, type, true, data->available_sockets, &data->prev_index);
+               cmp_node_image_add_pass_output(ntree, node, "Alpha", name, -1, SOCK_FLOAT, true, data->available_sockets, &data->prev_index);
+       }
+       else {
+               cmp_node_image_add_pass_output(ntree, node, name, name, -1, type, true, data->available_sockets, &data->prev_index);
+       }
 }
 
-static void cmp_node_image_sync_output(bNode *UNUSED(node), bNodeSocket *UNUSED(newsock), bNodeSocket *UNUSED(oldsock))
+static void cmp_node_rlayer_create_outputs(bNodeTree *ntree, bNode *node, LinkNodePair *available_sockets)
 {
-       /* pass */
+       Scene *scene = (Scene *)node->id;
+
+       if (scene) {
+               RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
+               if(engine_type && engine_type->update_render_passes) {
+                       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, node->custom1);
+                       if(srl) {
+                               RLayerUpdateData *data = MEM_mallocN(sizeof(RLayerUpdateData), "render layer update data");
+                               data->available_sockets = available_sockets;
+                               data->prev_index = -1;
+                               node->storage = data;
+
+                               RenderEngine *engine = RE_engine_create(engine_type);
+                               engine_type->update_render_passes(engine, scene, srl);
+                               RE_engine_free(engine);
+
+                               MEM_freeN(data);
+                               node->storage = NULL;
+
+                               return;
+                       }
+               }
+       }
+
+       int prev_index = -1;
+       cmp_node_image_add_pass_output(ntree, node, "Image", RE_PASSNAME_COMBINED, RRES_OUT_IMAGE, SOCK_RGBA, true, available_sockets, &prev_index);
+       cmp_node_image_add_pass_output(ntree, node, "Alpha", RE_PASSNAME_COMBINED, RRES_OUT_ALPHA, SOCK_FLOAT, true, available_sockets, &prev_index);
 }
 
 /* XXX make this into a generic socket verification function for dynamic socket replacement (multilayer, groups, static templates) */
-static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node)
+static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node, bool rlayer)
 {
-       bNodeSocket *newsock, *oldsock, *oldsock_next;
-       ListBase oldsocklist;
-       int oldindex;
-       bNodeLink *link;
-       
-       /* store current nodes in oldsocklist, then clear socket list */
-       oldsocklist = node->outputs;
-       BLI_listbase_clear(&node->outputs);
+       bNodeSocket *sock, *sock_next;
+       LinkNodePair available_sockets = {NULL, NULL};
+       int sock_index;
        
        /* XXX make callback */
-       cmp_node_image_create_outputs(ntree, node);
-       
-       for (newsock = node->outputs.first; newsock; newsock = newsock->next) {
-               /* XXX make callback */
-               oldsock = cmp_node_image_output_find_match(node, newsock, &oldsocklist);
-               if (oldsock) {
-                       /* XXX make callback */
-                       cmp_node_image_sync_output(node, newsock, oldsock);
+       if (rlayer)
+               cmp_node_rlayer_create_outputs(ntree, node, &available_sockets);
+       else
+               cmp_node_image_create_outputs(ntree, node, &available_sockets);
+
+       /* Get rid of sockets whose passes are not available in the image.
+        * If sockets that are not available would be deleted, the connections to them would be lost
+        * when e.g. opening a file (since there's no render at all yet).
+        * Therefore, sockets with connected links will just be set as unavailable.
+        *
+        * Another important detail comes from compatibility with the older socket model, where there
+        * was a fixed socket per pass type that was just hidden or not. Therefore, older versions expect
+        * the first 31 passes to belong to a specific pass type.
+        * So, we keep those 31 always allocated before the others as well, even if they have no links attached. */
+       sock_index = 0;
+       for (sock = node->outputs.first; sock; sock = sock_next, sock_index++) {
+               sock_next = sock->next;
+               if (BLI_linklist_index(available_sockets.list, sock) >= 0) {
+                       sock->flag &= ~(SOCK_UNAVAIL | SOCK_HIDDEN);
                }
-       }
-       
-       /* move links to new socket */
-       for (oldsock = oldsocklist.first, oldindex = 0; oldsock; oldsock = oldsock->next, ++oldindex) {
-               newsock = cmp_node_image_output_relink(node, oldsock, oldindex);
-               
-               if (newsock) {
+               else {
+                       bNodeLink *link;
                        for (link = ntree->links.first; link; link = link->next) {
-                               if (link->fromsock == oldsock)
-                                       link->fromsock = newsock;
+                               if (link->fromsock == sock) break;
+                       }
+                       if (!link && sock_index > 30) {
+                               MEM_freeN(sock->storage);
+                               nodeRemoveSocket(ntree, node, sock);
+                       }
+                       else {
+                               sock->flag |= SOCK_UNAVAIL;
                        }
                }
        }
-       
-       /* delete old sockets
-        * XXX oldsock is not actually in the node->outputs list any more,
-        * but the nodeRemoveSocket function works anyway. In future this
-        * should become part of the core code, so can take care of this behavior.
-        */
-       for (oldsock = oldsocklist.first; oldsock; oldsock = oldsock_next) {
-               oldsock_next = oldsock->next;
-               MEM_freeN(oldsock->storage);
-               nodeRemoveSocket(ntree, node, oldsock);
-       }
+
+       BLI_linklist_free(available_sockets.list, NULL);
 }
 
 static void cmp_node_image_update(bNodeTree *ntree, bNode *node)
 {
        /* avoid unnecessary updates, only changes to the image/image user data are of interest */
        if (node->update & NODE_UPDATE_ID)
-               cmp_node_image_verify_outputs(ntree, node);
+               cmp_node_image_verify_outputs(ntree, node, false);
 }
 
 static void node_composit_init_image(bNodeTree *ntree, bNode *node)
@@ -348,7 +306,7 @@ static void node_composit_init_image(bNodeTree *ntree, bNode *node)
        iuser->ok = 1;
        
        /* setup initial outputs */
-       cmp_node_image_verify_outputs(ntree, node);
+       cmp_node_image_verify_outputs(ntree, node, false);
 }
 
 static void node_composit_free_image(bNode *node)
@@ -388,87 +346,45 @@ void register_node_type_cmp_image(void)
 
 /* **************** RENDER RESULT ******************** */
 
-static void set_output_visible(bNode *node, int passflag, int index, int pass)
+void node_cmp_rlayers_outputs(bNodeTree *ntree, bNode *node)
 {
-       bNodeSocket *sock = BLI_findlink(&node->outputs, index);
-       bool pass_enabled = ((passflag & pass) != 0);
-#ifdef WITH_CYCLES_DEBUG
-       pass_enabled |= (pass == SCE_PASS_DEBUG);
-#endif
-       /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden before */
-       if (pass_enabled)
-               sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL);
-       else
-               sock->flag |= SOCK_UNAVAIL;
+       cmp_node_image_verify_outputs(ntree, node, true);
 }
 
-/* clumsy checking... should do dynamic outputs once */
-void node_cmp_rlayers_force_hidden_passes(bNode *node)
+const char* node_cmp_rlayers_sock_to_pass(int sock_index)
 {
-       Scene *scene = (Scene *)node->id;
-       SceneRenderLayer *srl;
-       int passflag;
-       bNodeSocket *sock;
-       
-       /* must always have valid scene pointer */
-       if (!scene)
-               return;
-       
-       srl = BLI_findlink(&scene->r.layers, node->custom1);
-       if (!srl)
-               return;
-       
-       passflag = srl->passflag;
-       
-       for (sock = node->outputs.first; sock; sock = sock->next)
-               sock->flag &= ~SOCK_UNAVAIL;
-       
-       set_output_visible(node, passflag, RRES_OUT_IMAGE,                  SCE_PASS_COMBINED);
-       set_output_visible(node, passflag, RRES_OUT_ALPHA,                  SCE_PASS_COMBINED);
-
-       set_output_visible(node, passflag, RRES_OUT_Z,                      SCE_PASS_Z);
-       set_output_visible(node, passflag, RRES_OUT_NORMAL,                 SCE_PASS_NORMAL);
-       set_output_visible(node, passflag, RRES_OUT_VEC,                    SCE_PASS_VECTOR);
-       set_output_visible(node, passflag, RRES_OUT_UV,                     SCE_PASS_UV);
-       set_output_visible(node, passflag, RRES_OUT_RGBA,                   SCE_PASS_RGBA);
-       set_output_visible(node, passflag, RRES_OUT_DIFF,                   SCE_PASS_DIFFUSE);
-       set_output_visible(node, passflag, RRES_OUT_SPEC,                   SCE_PASS_SPEC);
-       set_output_visible(node, passflag, RRES_OUT_SHADOW,                 SCE_PASS_SHADOW);
-       set_output_visible(node, passflag, RRES_OUT_AO,                     SCE_PASS_AO);
-       set_output_visible(node, passflag, RRES_OUT_REFLECT,                SCE_PASS_REFLECT);
-       set_output_visible(node, passflag, RRES_OUT_REFRACT,                SCE_PASS_REFRACT);
-       set_output_visible(node, passflag, RRES_OUT_INDIRECT,               SCE_PASS_INDIRECT);
-       set_output_visible(node, passflag, RRES_OUT_INDEXOB,                SCE_PASS_INDEXOB);
-       set_output_visible(node, passflag, RRES_OUT_INDEXMA,                SCE_PASS_INDEXMA);
-       set_output_visible(node, passflag, RRES_OUT_MIST,                   SCE_PASS_MIST);
-       set_output_visible(node, passflag, RRES_OUT_EMIT,                   SCE_PASS_EMIT);
-       set_output_visible(node, passflag, RRES_OUT_ENV,                    SCE_PASS_ENVIRONMENT);
-       set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT,            SCE_PASS_DIFFUSE_DIRECT);
-       set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT,          SCE_PASS_DIFFUSE_INDIRECT);
-       set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR,             SCE_PASS_DIFFUSE_COLOR);
-       set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT,          SCE_PASS_GLOSSY_DIRECT);
-       set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT,        SCE_PASS_GLOSSY_INDIRECT);
-       set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR,           SCE_PASS_GLOSSY_COLOR);
-       set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT,          SCE_PASS_TRANSM_DIRECT);
-       set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT,        SCE_PASS_TRANSM_INDIRECT);
-       set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR,           SCE_PASS_TRANSM_COLOR);
-       set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_DIRECT,      SCE_PASS_SUBSURFACE_DIRECT);
-       set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_INDIRECT,    SCE_PASS_SUBSURFACE_INDIRECT);
-       set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_COLOR,       SCE_PASS_SUBSURFACE_COLOR);
-
-#ifdef WITH_CYCLES_DEBUG
-       set_output_visible(node, passflag, RRES_OUT_DEBUG, SCE_PASS_DEBUG);
-#endif
+       const char* sock_to_passname[] = {
+               RE_PASSNAME_COMBINED, RE_PASSNAME_COMBINED,
+               RE_PASSNAME_Z, RE_PASSNAME_NORMAL, RE_PASSNAME_UV, RE_PASSNAME_VECTOR, RE_PASSNAME_RGBA,
+               RE_PASSNAME_DIFFUSE, RE_PASSNAME_SPEC, RE_PASSNAME_SHADOW, RE_PASSNAME_AO,
+               RE_PASSNAME_REFLECT, RE_PASSNAME_REFRACT, RE_PASSNAME_INDIRECT,
+               RE_PASSNAME_INDEXOB, RE_PASSNAME_INDEXMA, RE_PASSNAME_MIST, RE_PASSNAME_EMIT, RE_PASSNAME_ENVIRONMENT,
+               RE_PASSNAME_DIFFUSE_DIRECT, RE_PASSNAME_DIFFUSE_INDIRECT, RE_PASSNAME_DIFFUSE_COLOR,
+               RE_PASSNAME_GLOSSY_DIRECT, RE_PASSNAME_GLOSSY_INDIRECT, RE_PASSNAME_GLOSSY_COLOR,
+               RE_PASSNAME_TRANSM_DIRECT, RE_PASSNAME_TRANSM_INDIRECT, RE_PASSNAME_TRANSM_COLOR,
+               RE_PASSNAME_SUBSURFACE_DIRECT, RE_PASSNAME_SUBSURFACE_INDIRECT, RE_PASSNAME_SUBSURFACE_COLOR
+       };
+       if (sock_index > 30) {
+               return NULL;
+       }
+       return sock_to_passname[sock_index];
 }
 
 static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr)
 {
        Scene *scene = CTX_data_scene(C);
        bNode *node = ptr->data;
-       
+       int sock_index = 0;
+
        node->id = &scene->id;
-       
-       node_cmp_rlayers_force_hidden_passes(node);
+
+       for (bNodeSocket *sock = node->outputs.first; sock; sock = sock->next, sock_index++)
+       {
+               NodeImageLayer *sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
+               sock->storage = sockdata;
+
+               BLI_strncpy(sockdata->pass_name, node_cmp_rlayers_sock_to_pass(sock_index), sizeof(sockdata->pass_name));
+       }
 }
 
 static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree)
@@ -489,6 +405,29 @@ static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree
        return false;
 }
 
+static void node_composit_free_rlayers(bNode *node)
+{
+       bNodeSocket *sock;
+
+       /* free extra socket info */
+       for (sock = node->outputs.first; sock; sock = sock->next)
+               MEM_freeN(sock->storage);
+}
+
+static void node_composit_copy_rlayers(bNodeTree *UNUSED(dest_ntree), bNode *UNUSED(dest_node), bNode *src_node)
+{
+       bNodeSocket *sock;
+
+       /* copy extra socket info */
+       for (sock = src_node->outputs.first; sock; sock = sock->next)
+               sock->new_sock->storage = MEM_dupallocN(sock->storage);
+}
+
+static void cmp_node_rlayers_update(bNodeTree *ntree, bNode *node)
+{
+       cmp_node_image_verify_outputs(ntree, node, true);
+}
+
 void register_node_type_cmp_rlayers(void)
 {
        static bNodeType ntype;
@@ -497,6 +436,9 @@ void register_node_type_cmp_rlayers(void)
        node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out);
        ntype.initfunc_api = node_composit_init_rlayers;
        ntype.poll = node_composit_poll_rlayers;
+       node_type_storage(&ntype, NULL, node_composit_free_rlayers, node_composit_copy_rlayers);
+       node_type_update(&ntype, cmp_node_rlayers_update, NULL);
+       node_type_init(&ntype, node_cmp_rlayers_outputs);
 
        nodeRegisterType(&ntype);
 }
index 569b207c96669a76dc1950e1420d0441873d491e..a12bdd910c39b6f2b871fa8c5dfe48d4107bbe29 100644 (file)
@@ -34,6 +34,7 @@ set(INC
        ../depsgraph
        ../makesdna
        ../makesrna
+       ../nodes
        ../physics
        ../../../intern/atomic
        ../../../intern/guardedalloc
@@ -165,10 +166,6 @@ if(WITH_INTERNATIONAL)
        add_definitions(-DWITH_INTERNATIONAL)
 endif()
 
-if(WITH_CYCLES AND WITH_CYCLES_DEBUG)
-       add_definitions(-DWITH_CYCLES_DEBUG)
-endif()
-
 if(APPLE)
        # SSE math is enabled by default on x86_64
        if(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
index f83a210275f810033ab81ff618faa683355679f5..491d44b3a4e576e6ef966735a27f84a77b9608fa 100644 (file)
@@ -96,6 +96,7 @@ typedef struct RenderEngineType {
        void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
 
        void (*update_script_node)(struct RenderEngine *engine, struct bNodeTree *ntree, struct bNode *node);
+       void (*update_render_passes)(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl);
 
        /* RNA integration */
        ExtensionRNA ext;
@@ -139,6 +140,7 @@ void RE_result_load_from_file(struct RenderResult *result, struct ReportList *re
 
 struct RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname);
 void RE_engine_update_result(RenderEngine *engine, struct RenderResult *result);
+void RE_engine_add_pass(RenderEngine *engine, const char *name, int channels, const char *chan_id, const char *layername);
 void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int cancel, int merge_results);
 
 const char *RE_engine_active_view_get(RenderEngine *engine);
@@ -160,6 +162,9 @@ bool RE_engine_is_external(struct Render *re);
 
 void RE_engine_frame_set(struct RenderEngine *engine, int frame, float subframe);
 
+void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl,
+                             const char *name, int channels, const char *chanid, int type);
+
 /* Engine Types */
 
 void RE_engines_init(void);
index eaa4cf2c69c1f9a6d424a4cdeeec22f538a96df8..0d2e29ba4c8189947a878a646e424bbf04a8726c 100644 (file)
@@ -83,25 +83,19 @@ typedef struct RenderView {
 
 typedef struct RenderPass {
        struct RenderPass *next, *prev;
-       int passtype, channels;
+       int channels;
        char name[64];          /* amount defined in openexr_multi.h */
        char chan_id[8];        /* amount defined in openexr_multi.h */
        float *rect;
        int rectx, recty;
 
-       char internal_name[64]; /* EXR_PASS_MAXNAME */
+       char fullname[64]; /* EXR_PASS_MAXNAME */
        char view[64];          /* EXR_VIEW_MAXNAME */
        int view_id;    /* quick lookup */
 
-       int debug_type;
+       int pad;
 } RenderPass;
 
-enum {
-       RENDER_PASS_DEBUG_BVH_TRAVERSED_NODES = 0,
-       RENDER_PASS_DEBUG_BVH_TRAVERSED_INSTANCES = 1,
-       RENDER_PASS_DEBUG_RAY_BOUNCES = 2,
-       RENDER_PASS_DEBUG_BVH_INTERSECTIONS = 3,
-};
 
 /* a renderlayer is a full image, but with all passes and samples */
 /* size of the rects is defined in RenderResult */
@@ -236,7 +230,7 @@ void RE_render_result_rect_from_ibuf(
         struct ImBuf *ibuf, const int view_id);
 
 struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name);
-float *RE_RenderLayerGetPass(volatile struct RenderLayer *rl, int passtype, const char *viewname);
+float *RE_RenderLayerGetPass(volatile struct RenderLayer *rl, const char *name, const char *viewname);
 
 /* add passes for grease pencil */
 struct RenderPass *RE_create_gp_pass(struct RenderResult *rr, const char *layername, const char *viewname);
@@ -345,6 +339,7 @@ int RE_seq_render_active(struct Scene *scene, struct RenderData *rd);
 
 bool RE_layers_have_name(struct RenderResult *result);
 
+struct RenderPass *RE_pass_find_by_name(volatile struct RenderLayer *rl, const char *name, const char *viewname);
 struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int passtype, const char *viewname);
 
 /* shaded view or baking options */
@@ -394,13 +389,5 @@ struct RenderView *RE_RenderViewGetByName(struct RenderResult *res, const char *
 
 RenderResult *RE_DuplicateRenderResult(RenderResult *rr);
 
-/******* Debug pass helper functions *********/
-
-#ifdef WITH_CYCLES_DEBUG
-int RE_debug_pass_num_channels_get(int pass_type);
-const char *RE_debug_pass_name_get(int pass_type);
-int RE_debug_pass_type_get(struct Render *re);
-#endif
-
 #endif /* __RE_PIPELINE_H__ */
 
index 0c4f4e203253403503ffb5a665760ea7686cad63..4057d8c10524c78a4da9aceb5a1a9c2c7bf429cf 100644 (file)
@@ -67,6 +67,11 @@ void render_result_views_new(struct RenderResult *rr, struct RenderData *rd);
 
 void render_result_merge(struct RenderResult *rr, struct RenderResult *rrpart);
 
+/* Add Passes */
+
+void render_result_clone_passes(struct Render *re, struct RenderResult *rr, const char *viewname);
+void render_result_add_pass(struct RenderResult *rr, const char *name, int channels, const char *chan_id, const char *layername, const char *viewname);
+
 /* Free */
 
 void render_result_free(struct RenderResult *rr);
@@ -84,7 +89,7 @@ void render_result_exr_file_begin(struct Render *re);
 void render_result_exr_file_end(struct Render *re);
 
 /* render pass wrapper for gpencil */
-struct RenderPass *gp_add_pass(struct RenderResult *rr, struct RenderLayer *rl, int channels, int passtype, const char *viewname);
+struct RenderPass *gp_add_pass(struct RenderResult *rr, struct RenderLayer *rl, int channels, const char *name, const char *viewname);
 
 void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart, const char *viewname);
 
index 7254fd25ee67194cf1ff52fb069b688b7992a2a1..f4c4a50ac27f69ac59fb49ef4cd388e243721dc7 100644 (file)
 
 #include "render_types.h"
 
+#include "RE_engine.h"
+
+#include "DNA_node_types.h"
+
+#include "NOD_composite.h"
+
 struct ShadeInput;
 struct ShadeResult;
 struct World;
@@ -77,6 +83,8 @@ void zbufshade_sss_tile(struct RenderPart *pa);
 
 int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct RenderLayer **rlpp);
 
+void render_internal_update_passes(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl);
+
 
 /* -------- ray.c ------- */
 
index d97e18d6511195d941c1f321534f02c260341222..cfdc285223ccdf822cc0db5a8f9553dcd0734b5a 100644 (file)
@@ -499,7 +499,7 @@ static void render_envmap(Render *re, EnvMap *env)
                        float *rect;
 
                        /* envmap is rendered independently of multiview  */
-                       rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, "");
+                       rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, "");
                        ibuf = IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect | IB_rectfloat);
                        memcpy(ibuf->rect_float, rect, ibuf->channels * ibuf->x * ibuf->y * sizeof(float));
                        
index fd9d95c63b6bef5077cc8eb10f62d8a864efb113..97413c31e1618516a194037e3e41cef6bd1a746f 100644 (file)
 #include "renderpipeline.h"
 #include "render_types.h"
 #include "render_result.h"
+#include "rendercore.h"
 
 /* Render Engine Types */
 
 static RenderEngineType internal_render_type = {
        NULL, NULL,
        "BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL,
-       NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, render_internal_update_passes,
        {NULL, NULL, NULL}
 };
 
@@ -77,7 +78,7 @@ static RenderEngineType internal_render_type = {
 static RenderEngineType internal_game_type = {
        NULL, NULL,
        "BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME,
-       NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        {NULL, NULL, NULL}
 };
 
@@ -212,6 +213,8 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w,
 
        /* can be NULL if we CLAMP the width or height to 0 */
        if (result) {
+               render_result_clone_passes(re, result, viewname);
+
                RenderPart *pa;
 
                /* Copy EXR tile settings, so pipeline knows whether this is a result
@@ -245,6 +248,17 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
        }
 }
 
+void RE_engine_add_pass(RenderEngine *engine, const char *name, int channels, const char *chan_id, const char *layername)
+{
+       Render *re = engine->re;
+
+       if (!re || !re->result) {
+               return;
+       }
+
+       render_result_add_pass(re->result, name, channels, chan_id, layername, NULL);
+}
+
 void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel, int merge_results)
 {
        Render *re = engine->re;
@@ -760,3 +774,16 @@ int RE_engine_render(Render *re, int do_all)
        return 1;
 }
 
+void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl,
+                             const char *name, int UNUSED(channels), const char *UNUSED(chanid), int type)
+{
+       /* The channel information is currently not used, but is part of the API in case it's needed in the future. */
+
+       if (!(scene && srl && engine)) {
+               return;
+       }
+
+       if (scene->nodetree) {
+               ntreeCompositRegisterPass(scene->nodetree, scene, srl, name, type);
+       }
+}
index 52eca5f7005ae2dd36e60faee5753529ed432f77..929eae495cf165d2f943cf9b38e64eeeca00c480 100644 (file)
@@ -239,9 +239,9 @@ void RE_FreeRenderResult(RenderResult *res)
        render_result_free(res);
 }
 
-float *RE_RenderLayerGetPass(volatile RenderLayer *rl, int passtype, const char *viewname)
+float *RE_RenderLayerGetPass(volatile RenderLayer *rl, const char *name, const char *viewname)
 {
-       RenderPass *rpass = RE_pass_find_by_type(rl, passtype, viewname);
+       RenderPass *rpass = RE_pass_find_by_name(rl, name, viewname);
        return rpass ? rpass->rect : NULL;
 }
 
@@ -382,13 +382,13 @@ void RE_AcquireResultImageViews(Render *re, RenderResult *rr)
                        if (rl) {
                                if (rv->rectf == NULL) {
                                        for (rview = (RenderView *)rr->views.first; rview; rview = rview->next) {
-                                               rview->rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, rview->name);
+                                               rview->rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, rview->name);
                                        }
                                }
 
                                if (rv->rectz == NULL) {
                                        for (rview = (RenderView *)rr->views.first; rview; rview = rview->next) {
-                                               rview->rectz = RE_RenderLayerGetPass(rl, SCE_PASS_Z, rview->name);
+                                               rview->rectz = RE_RenderLayerGetPass(rl, RE_PASSNAME_Z, rview->name);
                                        }
                                }
                        }
@@ -442,10 +442,10 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id)
 
                        if (rl) {
                                if (rv->rectf == NULL)
-                                       rr->rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, rv->name);
+                                       rr->rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, rv->name);
 
                                if (rv->rectz == NULL)
-                                       rr->rectz = RE_RenderLayerGetPass(rl, SCE_PASS_Z, rv->name);
+                                       rr->rectz = RE_RenderLayerGetPass(rl, RE_PASSNAME_Z, rv->name);
                        }
 
                        rr->have_combined = (rv->rectf != NULL);
@@ -842,7 +842,7 @@ static void render_result_rescale(Render *re)
        if (src_rectf == NULL) {
                RenderLayer *rl = render_get_active_layer(re, re->result);
                if (rl != NULL) {
-                       src_rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, NULL);
+                       src_rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, NULL);
                }
        }
 
@@ -861,7 +861,7 @@ static void render_result_rescale(Render *re)
                                RenderLayer *rl;
                                rl = render_get_active_layer(re, re->result);
                                if (rl != NULL) {
-                                       dst_rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, NULL);
+                                       dst_rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, NULL);
                                }
                        }
 
@@ -1655,7 +1655,7 @@ static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float b
                /* passes are allocated in sync */
                rpass1 = rl1->passes.first;
                for (rpass = rl->passes.first; rpass && rpass1; rpass = rpass->next, rpass1 = rpass1->next) {
-                       if ((rpass->passtype & SCE_PASS_COMBINED) && key_alpha)
+                       if (STREQ(rpass->name, RE_PASSNAME_COMBINED) && key_alpha)
                                addblur_rect_key(rr, rpass->rect, rpass1->rect, blurfac);
                        else
                                addblur_rect(rr, rpass->rect, rpass1->rect, blurfac, rpass->channels);
@@ -1855,6 +1855,8 @@ static void render_result_uncrop(Render *re)
 
                        rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
 
+                       render_result_clone_passes(re, rres, NULL);
+
                        render_result_merge(rres, re->result);
                        render_result_free(re->result);
                        re->result = rres;
@@ -3887,7 +3889,7 @@ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char
 
        /* multiview: since the API takes no 'view', we use the first combined pass found */
        for (rpass = layer->passes.first; rpass; rpass = rpass->next)
-               if (rpass->passtype == SCE_PASS_COMBINED)
+               if (STREQ(rpass->name, RE_PASSNAME_COMBINED))
                        break;
 
        if (rpass == NULL)
@@ -4013,13 +4015,12 @@ bool RE_layers_have_name(struct RenderResult *rr)
        return false;
 }
 
-RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const char *viewname)
+RenderPass *RE_pass_find_by_name(volatile RenderLayer *rl, const char *name, const char *viewname)
 {
        RenderPass *rp = NULL;
 
        for (rp = rl->passes.last; rp; rp = rp->prev) {
-               if (rp->passtype == passtype) {
-
+               if (STREQ(rp->name, name)) {
                        if (viewname == NULL || viewname[0] == '\0')
                                break;
                        else if (STREQ(rp->view, viewname))
@@ -4029,6 +4030,50 @@ RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const c
        return rp;
 }
 
+/* Only provided for API compatibility, don't use this in new code! */
+RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const char *viewname)
+{
+#define CHECK_PASS(NAME) \
+       if (passtype == SCE_PASS_ ## NAME) \
+               return RE_pass_find_by_name(rl, RE_PASSNAME_ ## NAME, viewname);
+
+       CHECK_PASS(COMBINED);
+       CHECK_PASS(Z);
+       CHECK_PASS(VECTOR);
+       CHECK_PASS(NORMAL);
+       CHECK_PASS(UV);
+       CHECK_PASS(RGBA);
+       CHECK_PASS(EMIT);
+       CHECK_PASS(DIFFUSE);
+       CHECK_PASS(SPEC);
+       CHECK_PASS(SHADOW);
+       CHECK_PASS(AO);
+       CHECK_PASS(ENVIRONMENT);
+       CHECK_PASS(INDIRECT);
+       CHECK_PASS(REFLECT);
+       CHECK_PASS(REFRACT);
+       CHECK_PASS(INDEXOB);
+       CHECK_PASS(INDEXMA);
+       CHECK_PASS(MIST);
+       CHECK_PASS(RAYHITS);
+       CHECK_PASS(DIFFUSE_DIRECT);
+       CHECK_PASS(DIFFUSE_INDIRECT);
+       CHECK_PASS(DIFFUSE_COLOR);
+       CHECK_PASS(GLOSSY_DIRECT);
+       CHECK_PASS(GLOSSY_INDIRECT);
+       CHECK_PASS(GLOSSY_COLOR);
+       CHECK_PASS(TRANSM_DIRECT);
+       CHECK_PASS(TRANSM_INDIRECT);
+       CHECK_PASS(TRANSM_COLOR);
+       CHECK_PASS(SUBSURFACE_DIRECT);
+       CHECK_PASS(SUBSURFACE_INDIRECT);
+       CHECK_PASS(SUBSURFACE_COLOR);
+
+#undef CHECK_PASS
+
+       return NULL;
+}
+
 /* create a renderlayer and renderpass for grease pencil layer */
 RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const char *viewname)
 {
@@ -4046,7 +4091,7 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha
        }
        
        /* clear previous pass if exist or the new image will be over previous one*/
-       RenderPass *rp = RE_pass_find_by_type(rl, SCE_PASS_COMBINED, viewname);
+       RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
        if (rp) {
                if (rp->rect) {
                        MEM_freeN(rp->rect);
@@ -4054,5 +4099,5 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha
                BLI_freelinkN(&rl->passes, rp);
        }
        /* create a totally new pass */
-       return gp_add_pass(rr, rl, 4, SCE_PASS_COMBINED, viewname);
+       return gp_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname);
 }
index f276c01e86ab31a17ffa15a0743270204850373b..8e6e6c9bb7d5d69ba733388747cfea1754919bf6 100644 (file)
@@ -173,363 +173,72 @@ void render_result_views_shallowdelete(RenderResult *rr)
        }
 }
 
-static const char *name_from_passtype(int passtype, int channel)
-{
-       if (passtype == SCE_PASS_COMBINED) {
-               if (channel == -1) return "Combined";
-               if (channel == 0) return "Combined.R";
-               if (channel == 1) return "Combined.G";
-               if (channel == 2) return "Combined.B";
-               return "Combined.A";
-       }
-       if (passtype == SCE_PASS_Z) {
-               if (channel == -1) return "Depth";
-               return "Depth.Z";
-       }
-       if (passtype == SCE_PASS_VECTOR) {
-               if (channel == -1) return "Vector";
-               if (channel == 0) return "Vector.X";
-               if (channel == 1) return "Vector.Y";
-               if (channel == 2) return "Vector.Z";
-               return "Vector.W";
-       }
-       if (passtype == SCE_PASS_NORMAL) {
-               if (channel == -1) return "Normal";
-               if (channel == 0) return "Normal.X";
-               if (channel == 1) return "Normal.Y";
-               return "Normal.Z";
-       }
-       if (passtype == SCE_PASS_UV) {
-               if (channel == -1) return "UV";
-               if (channel == 0) return "UV.U";
-               if (channel == 1) return "UV.V";
-               return "UV.A";
-       }
-       if (passtype == SCE_PASS_RGBA) {
-               if (channel == -1) return "Color";
-               if (channel == 0) return "Color.R";
-               if (channel == 1) return "Color.G";
-               if (channel == 2) return "Color.B";
-               return "Color.A";
-       }
-       if (passtype == SCE_PASS_EMIT) {
-               if (channel == -1) return "Emit";
-               if (channel == 0) return "Emit.R";
-               if (channel == 1) return "Emit.G";
-               return "Emit.B";
-       }
-       if (passtype == SCE_PASS_DIFFUSE) {
-               if (channel == -1) return "Diffuse";
-               if (channel == 0) return "Diffuse.R";
-               if (channel == 1) return "Diffuse.G";
-               return "Diffuse.B";
-       }
-       if (passtype == SCE_PASS_SPEC) {
-               if (channel == -1) return "Spec";
-               if (channel == 0) return "Spec.R";
-               if (channel == 1) return "Spec.G";
-               return "Spec.B";
-       }
-       if (passtype == SCE_PASS_SHADOW) {
-               if (channel == -1) return "Shadow";
-               if (channel == 0) return "Shadow.R";
-               if (channel == 1) return "Shadow.G";
-               return "Shadow.B";
-       }
-       if (passtype == SCE_PASS_AO) {
-               if (channel == -1) return "AO";
-               if (channel == 0) return "AO.R";
-               if (channel == 1) return "AO.G";
-               return "AO.B";
-       }
-       if (passtype == SCE_PASS_ENVIRONMENT) {
-               if (channel == -1) return "Env";
-               if (channel == 0) return "Env.R";
-               if (channel == 1) return "Env.G";
-               return "Env.B";
-       }
-       if (passtype == SCE_PASS_INDIRECT) {
-               if (channel == -1) return "Indirect";
-               if (channel == 0) return "Indirect.R";
-               if (channel == 1) return "Indirect.G";
-               return "Indirect.B";
-       }
-       if (passtype == SCE_PASS_REFLECT) {
-               if (channel == -1) return "Reflect";
-               if (channel == 0) return "Reflect.R";
-               if (channel == 1) return "Reflect.G";
-               return "Reflect.B";
-       }
-       if (passtype == SCE_PASS_REFRACT) {
-               if (channel == -1) return "Refract";
-               if (channel == 0) return "Refract.R";
-               if (channel == 1) return "Refract.G";
-               return "Refract.B";
-       }
-       if (passtype == SCE_PASS_INDEXOB) {
-               if (channel == -1) return "IndexOB";
-               return "IndexOB.X";
-       }
-       if (passtype == SCE_PASS_INDEXMA) {
-               if (channel == -1) return "IndexMA";
-               return "IndexMA.X";
-       }
-       if (passtype == SCE_PASS_MIST) {
-               if (channel == -1) return "Mist";
-               return "Mist.Z";
-       }
-       if (passtype == SCE_PASS_RAYHITS) {
-               if (channel == -1) return "Rayhits";
-               if (channel == 0) return "Rayhits.R";
-               if (channel == 1) return "Rayhits.G";
-               return "Rayhits.B";
-       }
-       if (passtype == SCE_PASS_DIFFUSE_DIRECT) {
-               if (channel == -1) return "DiffDir";
-               if (channel == 0) return "DiffDir.R";
-               if (channel == 1) return "DiffDir.G";
-               return "DiffDir.B";
-       }
-       if (passtype == SCE_PASS_DIFFUSE_INDIRECT) {
-               if (channel == -1) return "DiffInd";
-               if (channel == 0) return "DiffInd.R";
-               if (channel == 1) return "DiffInd.G";
-               return "DiffInd.B";
-       }
-       if (passtype == SCE_PASS_DIFFUSE_COLOR) {
-               if (channel == -1) return "DiffCol";
-               if (channel == 0) return "DiffCol.R";
-               if (channel == 1) return "DiffCol.G";
-               return "DiffCol.B";
-       }
-       if (passtype == SCE_PASS_GLOSSY_DIRECT) {
-               if (channel == -1) return "GlossDir";
-               if (channel == 0) return "GlossDir.R";
-               if (channel == 1) return "GlossDir.G";
-               return "GlossDir.B";
-       }
-       if (passtype == SCE_PASS_GLOSSY_INDIRECT) {
-               if (channel == -1) return "GlossInd";
-               if (channel == 0) return "GlossInd.R";
-               if (channel == 1) return "GlossInd.G";
-               return "GlossInd.B";
-       }
-       if (passtype == SCE_PASS_GLOSSY_COLOR) {
-               if (channel == -1) return "GlossCol";
-               if (channel == 0) return "GlossCol.R";
-               if (channel == 1) return "GlossCol.G";
-               return "GlossCol.B";
-       }
-       if (passtype == SCE_PASS_TRANSM_DIRECT) {
-               if (channel == -1) return "TransDir";
-               if (channel == 0) return "TransDir.R";
-               if (channel == 1) return "TransDir.G";
-               return "TransDir.B";
-       }
-       if (passtype == SCE_PASS_TRANSM_INDIRECT) {
-               if (channel == -1) return "TransInd";
-               if (channel == 0) return "TransInd.R";
-               if (channel == 1) return "TransInd.G";
-               return "TransInd.B";
-       }
-       if (passtype == SCE_PASS_TRANSM_COLOR) {
-               if (channel == -1) return "TransCol";
-               if (channel == 0) return "TransCol.R";
-               if (channel == 1) return "TransCol.G";
-               return "TransCol.B";
-       }
-       if (passtype == SCE_PASS_SUBSURFACE_DIRECT) {
-               if (channel == -1) return "SubsurfaceDir";
-               if (channel == 0) return "SubsurfaceDir.R";
-               if (channel == 1) return "SubsurfaceDir.G";
-               return "SubsurfaceDir.B";
-       }
-       if (passtype == SCE_PASS_SUBSURFACE_INDIRECT) {
-               if (channel == -1) return "SubsurfaceInd";
-               if (channel == 0) return "SubsurfaceInd.R";
-               if (channel == 1) return "SubsurfaceInd.G";
-               return "SubsurfaceInd.B";
-       }
-       if (passtype == SCE_PASS_SUBSURFACE_COLOR) {
-               if (channel == -1) return "SubsurfaceCol";
-               if (channel == 0) return "SubsurfaceCol.R";
-               if (channel == 1) return "SubsurfaceCol.G";
-               return "SubsurfaceCol.B";
-       }
-       return "Unknown";
-}
 
-static int passtype_from_name(const char *str, int passflag)
+static char* set_pass_name(char *outname, const char *name, int channel, const char *chan_id)
 {
-       /* We do not really support several pass of the same types, so in case we are opening an EXR file with several pass
-        * names detected as same pass type, only return that pass type the first time, and return 'uknown' for the others.
-        * See T48466. */
-#define RETURN_PASS(_passtype) return (passflag & (_passtype)) ? 0 : (_passtype)
-
-       if (STRPREFIX(str, "Combined"))
-               RETURN_PASS(SCE_PASS_COMBINED);
-
-       if (STRPREFIX(str, "Depth"))
-               RETURN_PASS(SCE_PASS_Z);
-
-       if (STRPREFIX(str, "Vector"))
-               RETURN_PASS(SCE_PASS_VECTOR);
-
-       if (STRPREFIX(str, "Normal"))
-               RETURN_PASS(SCE_PASS_NORMAL);
-
-       if (STRPREFIX(str, "UV"))
-               RETURN_PASS(SCE_PASS_UV);
-
-       if (STRPREFIX(str, "Color"))
-               RETURN_PASS(SCE_PASS_RGBA);
-
-       if (STRPREFIX(str, "Emit"))
-               RETURN_PASS(SCE_PASS_EMIT);
-
-       if (STRPREFIX(str, "Diffuse"))
-               RETURN_PASS(SCE_PASS_DIFFUSE);
-
-       if (STRPREFIX(str, "Spec"))
-               RETURN_PASS(SCE_PASS_SPEC);
-
-       if (STRPREFIX(str, "Shadow"))
-               RETURN_PASS(SCE_PASS_SHADOW);
-       
-       if (STRPREFIX(str, "AO"))
-               RETURN_PASS(SCE_PASS_AO);
-
-       if (STRPREFIX(str, "Env"))
-               RETURN_PASS(SCE_PASS_ENVIRONMENT);
-
-       if (STRPREFIX(str, "Indirect"))
-               RETURN_PASS(SCE_PASS_INDIRECT);
-
-       if (STRPREFIX(str, "Reflect"))
-               RETURN_PASS(SCE_PASS_REFLECT);
-
-       if (STRPREFIX(str, "Refract"))
-               RETURN_PASS(SCE_PASS_REFRACT);
-
-       if (STRPREFIX(str, "IndexOB"))
-               RETURN_PASS(SCE_PASS_INDEXOB);
-
-       if (STRPREFIX(str, "IndexMA"))
-               RETURN_PASS(SCE_PASS_INDEXMA);
-
-       if (STRPREFIX(str, "Mist"))
-               RETURN_PASS(SCE_PASS_MIST);
-       
-       if (STRPREFIX(str, "RayHits"))
-               RETURN_PASS(SCE_PASS_RAYHITS);
-
-       if (STRPREFIX(str, "DiffDir"))
-               RETURN_PASS(SCE_PASS_DIFFUSE_DIRECT);
-
-       if (STRPREFIX(str, "DiffInd"))
-               RETURN_PASS(SCE_PASS_DIFFUSE_INDIRECT);
-
-       if (STRPREFIX(str, "DiffCol"))
-               RETURN_PASS(SCE_PASS_DIFFUSE_COLOR);
-
-       if (STRPREFIX(str, "GlossDir"))
-               RETURN_PASS(SCE_PASS_GLOSSY_DIRECT);
-
-       if (STRPREFIX(str, "GlossInd"))
-               RETURN_PASS(SCE_PASS_GLOSSY_INDIRECT);
-
-       if (STRPREFIX(str, "GlossCol"))
-               RETURN_PASS(SCE_PASS_GLOSSY_COLOR);
-
-       if (STRPREFIX(str, "TransDir"))
-               RETURN_PASS(SCE_PASS_TRANSM_DIRECT);
-
-       if (STRPREFIX(str, "TransInd"))
-               RETURN_PASS(SCE_PASS_TRANSM_INDIRECT);
-
-       if (STRPREFIX(str, "TransCol"))
-               RETURN_PASS(SCE_PASS_TRANSM_COLOR);
-               
-       if (STRPREFIX(str, "SubsurfaceDir"))
-               RETURN_PASS(SCE_PASS_SUBSURFACE_DIRECT);
-
-       if (STRPREFIX(str, "SubsurfaceInd"))
-               RETURN_PASS(SCE_PASS_SUBSURFACE_INDIRECT);
-
-       if (STRPREFIX(str, "SubsurfaceCol"))
-               RETURN_PASS(SCE_PASS_SUBSURFACE_COLOR);
-
-       return 0;
-
-#undef RETURN_PASS
+       BLI_strncpy(outname, name, EXR_PASS_MAXNAME);
+       if (channel >= 0) {
+               char token[3] = {'.', chan_id[channel], '\0'};
+               strncat(outname, token, EXR_PASS_MAXNAME);
+       }
+       return outname;
 }
 
-
-static void set_pass_name(char *passname, int passtype, int channel, const char *view)
+static void set_pass_full_name(char *fullname, const char *name, int channel, const char *view, const char *chan_id)
 {
-       const char delims[] = {'.', '\0'};
-       const char *sep;
-       const char *token;
-       size_t len;
-
-       const char *passtype_name = name_from_passtype(passtype, channel);
-
-       if (view == NULL || view[0] == '\0') {
-               BLI_strncpy(passname, passtype_name, EXR_PASS_MAXNAME);
-               return;
-       }
-
-       len = BLI_str_rpartition(passtype_name, delims, &sep, &token);
-
-       if (sep) {
-               BLI_snprintf(passname, EXR_PASS_MAXNAME, "%.*s.%s.%s", (int)len, passtype_name, view, token);
+       BLI_strncpy(fullname, name, EXR_PASS_MAXNAME);
+       if (view && view[0]) {
+               strncat(fullname, ".", EXR_PASS_MAXNAME);
+               strncat(fullname, view, EXR_PASS_MAXNAME);
        }
-       else {
-               BLI_snprintf(passname, EXR_PASS_MAXNAME, "%s.%s", passtype_name, view);
+       if (channel >= 0) {
+               char token[3] = {'.', chan_id[channel], '\0'};
+               strncat(fullname, token, EXR_PASS_MAXNAME);
        }
 }
 
 /********************************** New **************************************/
 
-static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype, const char *viewname)
+static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname, const char *chan_id)
 {
        const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
-       const char *typestr = name_from_passtype(passtype, -1);
-       RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr);
+       RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
        size_t rectsize = ((size_t)rr->rectx) * rr->recty * channels;
        
-       rpass->passtype = passtype;
        rpass->channels = channels;
        rpass->rectx = rl->rectx;
        rpass->recty = rl->recty;
        rpass->view_id = view_id;
 
-       set_pass_name(rpass->name, rpass->passtype, -1, viewname);
-       BLI_strncpy(rpass->internal_name, typestr, sizeof(rpass->internal_name));
+       BLI_strncpy(rpass->name, name, sizeof(rpass->name));
+       BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
        BLI_strncpy(rpass->view, viewname, sizeof(rpass->view));
+       set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id);
        
        if (rl->exrhandle) {
                int a;
-               for (a = 0; a < channels; a++)
-                       IMB_exr_add_channel(rl->exrhandle, rl->name, name_from_passtype(passtype, a), viewname, 0, 0, NULL, false);
+               for (a = 0; a < channels; a++) {
+                       char passname[EXR_PASS_MAXNAME];
+                       IMB_exr_add_channel(rl->exrhandle, rl->name, set_pass_name(passname, rpass->name, a, rpass->chan_id), viewname, 0, 0, NULL, false);
+               }
        }
        else {
                float *rect;
                int x;
                
-               rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr);
+               rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, name);
                if (rpass->rect == NULL) {
                        MEM_freeN(rpass);
                        return NULL;
                }
                
-               if (passtype == SCE_PASS_VECTOR) {
+               if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
                        /* initialize to max speed */
                        rect = rpass->rect;
                        for (x = rectsize - 1; x >= 0; x--)
                                rect[x] = PASS_VECTOR_MAX;
                }
-               else if (passtype == SCE_PASS_Z) {
+               else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
                        rect = rpass->rect;
                        for (x = rectsize - 1; x >= 0; x--)
                                rect[x] = 10e10;
@@ -541,58 +250,10 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int
        return rpass;
 }
 /* wrapper called from render_opengl */
-RenderPass *gp_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype, const char *viewname)
-{
-       return render_layer_add_pass(rr, rl, channels, passtype, viewname);
-}
-
-#ifdef WITH_CYCLES_DEBUG
-const char *RE_debug_pass_name_get(int debug_type)
-{
-       switch (debug_type) {
-               case RENDER_PASS_DEBUG_BVH_TRAVERSED_NODES:
-                       return "BVH Traversed Nodes";
-               case RENDER_PASS_DEBUG_BVH_TRAVERSED_INSTANCES:
-                       return "BVH Traversed Instances";
-               case RENDER_PASS_DEBUG_BVH_INTERSECTIONS:
-                       return "BVH Primitive Intersections";
-               case RENDER_PASS_DEBUG_RAY_BOUNCES:
-                       return "Ray Bounces";
-       }
-       return "Unknown";
-}
-
-int RE_debug_pass_num_channels_get(int UNUSED(debug_type))
-{
-       /* Only single case currently, might be handy for further debug passes. */
-       return 1;
-}
-
-static RenderPass *render_layer_add_debug_pass(RenderResult *rr,
-                                               RenderLayer *rl,
-                                               int pass_type,
-                                               int debug_type,
-                                               const char *view)
-{
-       const char *name = RE_debug_pass_name_get(debug_type);
-       int channels = RE_debug_pass_num_channels_get(debug_type);
-       RenderPass *rpass = render_layer_add_pass(rr, rl, channels, pass_type, view);
-       if (rpass == NULL) {
-               return NULL;
-       }
-       rpass->debug_type = debug_type;
-       BLI_strncpy(rpass->name,
-                   name,
-                   sizeof(rpass->name));
-       BLI_strncpy(rpass->internal_name, rpass->name, sizeof(rpass->internal_name));
-       return rpass;
-}
-
-int RE_debug_pass_type_get(Render *re)
+RenderPass *gp_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname)
 {
-       return re->r.debug_pass_type;
+       return render_layer_add_pass(rr, rl, channels, name, viewname, "RGBA");
 }
-#endif
 
 /* called by main render as well for parts */
 /* will read info from Render *re to define layers */
@@ -683,89 +344,77 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
                        if (rr->do_exr_tile)
                                IMB_exr_add_view(rl->exrhandle, view);
 
-#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, passtype, viewname) \
+#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, name, viewname, chan_id) \
                        do { \
-                               if (render_layer_add_pass(rr, rl, channels, passtype, viewname) == NULL) { \
+                               if (render_layer_add_pass(rr, rl, channels, name, viewname, chan_id) == NULL) { \
                                        render_result_free(rr); \
                                        return NULL; \
                                } \
                        } while (false)
 
                        /* a renderlayer should always have a Combined pass*/
-                       render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view);
+                       render_layer_add_pass(rr, rl, 4, "Combined", view, "RGBA");
 
                        if (srl->passflag  & SCE_PASS_Z)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_Z, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_Z, view, "Z");
                        if (srl->passflag  & SCE_PASS_VECTOR)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_VECTOR, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_VECTOR, view, "XYZW");
                        if (srl->passflag  & SCE_PASS_NORMAL)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_NORMAL, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_NORMAL, view, "XYZ");
                        if (srl->passflag  & SCE_PASS_UV)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_UV, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_UV, view, "UVA");
                        if (srl->passflag  & SCE_PASS_RGBA)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_RGBA, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_RGBA, view, "RGBA");
                        if (srl->passflag  & SCE_PASS_EMIT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_EMIT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_EMIT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_DIFFUSE)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE, view, "RGB");
                        if (srl->passflag  & SCE_PASS_SPEC)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SPEC, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SPEC, view, "RGB");
                        if (srl->passflag  & SCE_PASS_AO)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_AO, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_AO, view, "RGB");
                        if (srl->passflag  & SCE_PASS_ENVIRONMENT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_ENVIRONMENT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_ENVIRONMENT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_INDIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_INDIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_INDIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_SHADOW)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SHADOW, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SHADOW, view, "RGB");
                        if (srl->passflag  & SCE_PASS_REFLECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_REFLECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_REFLECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_REFRACT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_REFRACT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_REFRACT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_INDEXOB)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_INDEXOB, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXOB, view, "X");
                        if (srl->passflag  & SCE_PASS_INDEXMA)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_INDEXMA, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXMA, view, "X");
                        if (srl->passflag  & SCE_PASS_MIST)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_MIST, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_MIST, view, "Z");
                        if (rl->passflag & SCE_PASS_RAYHITS)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_RAYHITS, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_RAYHITS, view, "RGB");
                        if (srl->passflag  & SCE_PASS_DIFFUSE_DIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_DIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_DIFFUSE_INDIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_INDIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_DIFFUSE_COLOR)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_COLOR, view, "RGB");
                        if (srl->passflag  & SCE_PASS_GLOSSY_DIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_DIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_GLOSSY_INDIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_INDIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_GLOSSY_COLOR)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_COLOR, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_COLOR, view, "RGB");
                        if (srl->passflag  & SCE_PASS_TRANSM_DIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_DIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_DIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_TRANSM_INDIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_INDIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_TRANSM_COLOR)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_COLOR, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_COLOR, view, "RGB");
                        if (srl->passflag  & SCE_PASS_SUBSURFACE_DIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_DIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_SUBSURFACE_INDIRECT)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT, view);
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_INDIRECT, view, "RGB");
                        if (srl->passflag  & SCE_PASS_SUBSURFACE_COLOR)
-                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR, view);
-
-#ifdef WITH_CYCLES_DEBUG
-                       if (BKE_scene_use_new_shading_nodes(re->scene)) {
-                               if (render_layer_add_debug_pass(rr, rl, SCE_PASS_DEBUG,
-                                                               re->r.debug_pass_type, view) == NULL)
-                               {
-                                       render_result_free(rr);
-                                       return NULL;
-                               }
-                       }
-#endif
-
+                               RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_COLOR, view, "RGB");
 #undef RENDER_LAYER_ADD_PASS_SAFE
                }
        }
@@ -794,7 +443,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
                                IMB_exr_add_view(rl->exrhandle, view);
 
                        /* a renderlayer should always have a Combined pass */
-                       render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view);
+                       render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, view, "RGBA");
                }
 
                /* note, this has to be in sync with scene.c */
@@ -813,6 +462,60 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
        return rr;
 }
 
+void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname)
+{
+       RenderLayer *rl;
+       RenderPass *main_rp;
+
+       for (rl = rr->layers.first; rl; rl = rl->next) {
+               RenderLayer *main_rl = BLI_findstring(&re->result->layers, rl->name, offsetof(RenderLayer, name));
+               if (!main_rl) {
+                       continue;
+               }
+
+               for (main_rp = main_rl->passes.first; main_rp; main_rp = main_rp->next) {
+                       if (viewname && viewname[0] && !STREQ(main_rp->view, viewname)) {
+                               continue;
+                       }
+
+                       /* Compare fullname to make sure that the view also is equal. */
+                       RenderPass *rp = BLI_findstring(&rl->passes, main_rp->fullname, offsetof(RenderPass, fullname));
+                       if (!rp) {
+                               render_layer_add_pass(rr, rl, main_rp->channels, main_rp->name, main_rp->view, main_rp->chan_id);
+                       }
+               }
+       }
+}
+
+void render_result_add_pass(RenderResult *rr, const char *name, int channels, const char *chan_id, const char *layername, const char *viewname)
+{
+       RenderLayer *rl;
+       RenderPass *rp;
+       RenderView *rv;
+
+       for (rl = rr->layers.first; rl; rl = rl->next) {
+               if (layername && layername[0] && !STREQ(rl->name, layername)) {
+                       continue;
+               }
+
+               for (rv = rr->views.first; rv; rv = rv->next) {
+                       const char *view = rv->name;
+
+                       if (viewname && viewname[0] && !STREQ(view, viewname)) continue;
+
+                       /* Ensure that the pass doesn't exist yet. */
+                       for (rp = rl->passes.first; rp; rp = rp->next) {
+                               if (!STREQ(rp->name, name)) continue;
+                               if (!STREQ(rp->view, view)) continue;
+                       }
+
+                       if (!rp) {
+                               render_layer_add_pass(rr, rl, channels, name, view, chan_id);
+                       }
+               }
+       }
+}
+
 /* allocate osa new results for samples */
 RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers, const char *viewname)
 {
@@ -830,6 +533,50 @@ RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *part
        return lb->first;
 }
 
+static int passtype_from_name(const char *name)
+{
+       const char delim[] = {'.', '\0'};
+       const char *sep, *suf;
+       int len = BLI_str_partition(name, delim, &sep, &suf);
+
+#define CHECK_PASS(NAME) if (STREQLEN(name, RE_PASSNAME_ ## NAME, len)) return SCE_PASS_ ## NAME
+
+       CHECK_PASS(COMBINED);
+       CHECK_PASS(Z);
+       CHECK_PASS(VECTOR);
+       CHECK_PASS(NORMAL);
+       CHECK_PASS(UV);
+       CHECK_PASS(RGBA);
+       CHECK_PASS(EMIT);
+       CHECK_PASS(DIFFUSE);
+       CHECK_PASS(SPEC);
+       CHECK_PASS(SHADOW);
+       CHECK_PASS(AO);
+       CHECK_PASS(ENVIRONMENT);
+       CHECK_PASS(INDIRECT);
+       CHECK_PASS(REFLECT);
+       CHECK_PASS(REFRACT);
+       CHECK_PASS(INDEXOB);
+       CHECK_PASS(INDEXMA);
+       CHECK_PASS(MIST);
+       CHECK_PASS(RAYHITS);
+       CHECK_PASS(DIFFUSE_DIRECT);
+       CHECK_PASS(DIFFUSE_INDIRECT);
+       CHECK_PASS(DIFFUSE_COLOR);
+       CHECK_PASS(GLOSSY_DIRECT);
+       CHECK_PASS(GLOSSY_INDIRECT);
+       CHECK_PASS(GLOSSY_COLOR);
+       CHECK_PASS(TRANSM_DIRECT);
+       CHECK_PASS(TRANSM_INDIRECT);
+       CHECK_PASS(TRANSM_COLOR);
+       CHECK_PASS(SUBSURFACE_DIRECT);
+       CHECK_PASS(SUBSURFACE_INDIRECT);
+       CHECK_PASS(SUBSURFACE_COLOR);
+
+#undef CHECK_PASS
+       return 0;
+}
+
 /* callbacks for render_result_new_from_exr */
 static void *ml_addlayer_cb(void *base, const char *str)
 {
@@ -843,36 +590,30 @@ static void *ml_addlayer_cb(void *base, const char *str)
        return rl;
 }
 
-static void ml_addpass_cb(void *base, void *lay, const char *str, float *rect, int totchan, const char *chan_id, const char *view)
+static void ml_addpass_cb(void *base, void *lay, const char *name, float *rect, int totchan, const char *chan_id, const char *view)
 {
        RenderResult *rr = base;
        RenderLayer *rl = lay;
        RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass");
-       int a;
-       
+
        BLI_addtail(&rl->passes, rpass);
        rpass->channels = totchan;
-       rpass->passtype = passtype_from_name(str, rl->passflag);
-       if (rpass->passtype == 0)
-               printf("unknown pass %s\n", str);
-       rl->passflag |= rpass->passtype;
-       
+       rl->passflag |= passtype_from_name(name);
+
        /* channel id chars */
-       for (a = 0; a < totchan; a++)
-               rpass->chan_id[a] = chan_id[a];
+       BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
 
        rpass->rect = rect;
+       BLI_strncpy(rpass->name, name, EXR_PASS_MAXNAME);
+       BLI_strncpy(rpass->view, view, sizeof(rpass->view));
+       set_pass_full_name(rpass->fullname, name, -1, view, rpass->chan_id);
+
        if (view[0] != '\0') {
-               BLI_snprintf(rpass->name, sizeof(rpass->name), "%s.%s", str, view);
                rpass->view_id = BLI_findstringindex(&rr->views, view, offsetof(RenderView, name));
        }
        else {
-               BLI_strncpy(rpass->name,  str, sizeof(rpass->name));
                rpass->view_id = 0;
        }
-
-       BLI_strncpy(rpass->view, view, sizeof(rpass->view));
-       BLI_strncpy(rpass->internal_name, str, sizeof(rpass->internal_name));
 }
 
 static void *ml_addview_cb(void *base, const char *str)
@@ -912,12 +653,30 @@ static int order_render_passes(const void *a, const void *b)
        // 1 if a is after b
        RenderPass *rpa = (RenderPass *) a;
        RenderPass *rpb = (RenderPass *) b;
+       unsigned int passtype_a = passtype_from_name(rpa->name);
+       unsigned int passtype_b = passtype_from_name(rpb->name);
 
-       if (rpa->passtype > rpb->passtype)
+       /* Render passes with default type always go first. */
+       if (passtype_b && !passtype_a)
                return 1;
-       else if (rpa->passtype < rpb->passtype)
+       if (passtype_a && !passtype_b)
                return 0;
 
+       if (passtype_a && passtype_b) {
+               if (passtype_a > passtype_b)
+                       return 1;
+               else if (passtype_a < passtype_b)
+                       return 0;
+       }
+       else {
+               int cmp = strncmp(rpa->name, rpb->name, EXR_PASS_MAXNAME);
+               if (cmp > 0)
+                       return 1;
+               if (cmp < 0)
+                       return 0;
+       }
+
+
        /* they have the same type */
        /* left first */
        if (STREQ(rpa->view, STEREO_LEFT_NAME))
@@ -1049,7 +808,7 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
                             rpass = rpass->next)
                        {
                                /* renderresult have all passes, renderpart only the active view's passes */
-                               if (strcmp(rpassp->name, rpass->name) != 0)
+                               if (strcmp(rpassp->fullname, rpass->fullname) != 0)
                                        continue;
 
                                do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
@@ -1061,21 +820,6 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
        }
 }
 
-/* for passes read from files, these have names stored */
-static char *make_pass_name(RenderPass *rpass, int chan)
-{
-       static char name[EXR_PASS_MAXNAME];
-       int len;
-       
-       BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
-       len = strlen(name);
-       name[len] = '.';
-       name[len + 1] = rpass->chan_id[chan];
-       name[len + 2] = 0;
-
-       return name;
-}
-
 /* called from within UI and render pipeline, saves both rendered result as a file-read result
  * if multiview is true saves all views in a multiview exr
  * else if view is not NULL saves single view
@@ -1136,8 +880,10 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil
                        IMB_exr_add_view(exrhandle, rview->name);
 
                        if (rview->rectf) {
+                               char passname[EXR_PASS_MAXNAME];
                                for (a = 0; a < 4; a++) {
-                                       IMB_exr_add_channel(exrhandle, "Composite", name_from_passtype(SCE_PASS_COMBINED, a),
+                                       set_pass_name(passname, RE_PASSNAME_COMBINED, a, "RGBA");
+                                       IMB_exr_add_channel(exrhandle, RE_PASSNAME_COMBINED, passname,
                                                            chan_view, 4, 4 * width, rview->rectf + a,
                                                            use_half_float);
                                }
@@ -1150,6 +896,7 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil
                        /* passes are allocated in sync */
                        for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
                                const int xstride = rpass->channels;
+                               char passname[EXR_PASS_MAXNAME];
 
                                if (is_mono) {
                                        if (!STREQ(view, rpass->view)) {
@@ -1163,16 +910,10 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil
                                }
 
                                for (a = 0; a < xstride; a++) {
-                                       if (rpass->passtype) {
-                                               IMB_exr_add_channel(exrhandle, rl->name, name_from_passtype(rpass->passtype, a), chan_view,
-                                                                   xstride, xstride * width, rpass->rect + a,
-                                                                   rpass->passtype == SCE_PASS_Z ? false : use_half_float);
-                                       }
-                                       else {
-                                               IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), chan_view,
-                                                                   xstride, xstride * width, rpass->rect + a,
-                                                                   use_half_float);
-                                       }
+                                       set_pass_name(passname, rpass->name, a, rpass->chan_id);
+                                       IMB_exr_add_channel(exrhandle, rl->name, passname, chan_view,
+                                                           xstride, xstride * width, rpass->rect + a,
+                                                           STREQ(rpass->name, RE_PASSNAME_Z) ? false : use_half_float);
                                }
                        }
                }
@@ -1281,12 +1022,12 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons
                for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) {
                        const int xstride = rpassp->channels;
                        int a;
-                       char passname[EXR_PASS_MAXNAME];
+                       char fullname[EXR_PASS_MAXNAME];
 
                        for (a = 0; a < xstride; a++) {
-                               set_pass_name(passname, rpassp->passtype, a, rpassp->view);
+                               set_pass_full_name(fullname, rpassp->name, a, viewname, rpassp->chan_id);
 
-                               IMB_exr_set_channel(rl->exrhandle, rlp->name, passname,
+                               IMB_exr_set_channel(rl->exrhandle, rlp->name, fullname,
                                                    xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs);
                        }
                }
@@ -1449,15 +1190,15 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c
                for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
                        const int xstride = rpass->channels;
                        int a;
-                       char passname[EXR_PASS_MAXNAME];
+                       char fullname[EXR_PASS_MAXNAME];
 
                        for (a = 0; a < xstride; a++) {
-                               set_pass_name(passname, rpass->passtype, a, rpass->view);
-                               IMB_exr_set_channel(exrhandle, rl->name, passname,
+                               set_pass_full_name(fullname, rpass->name, a, rpass->view, rpass->chan_id);
+                               IMB_exr_set_channel(exrhandle, rl->name, fullname,
                                                    xstride, xstride * rectx, rpass->rect + a);
                        }
 
-                       set_pass_name(rpass->name, rpass->passtype, -1, rpass->view);
+                       set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id);
                }
        }
 
index 910ea16607e168e474e6d3e9638c6696d82b448e..0b1004c562e35de15c6ceb75aa0a01abae367e03 100644 (file)
@@ -182,7 +182,7 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in
                                if (fullsample) {
                                        for (sample=0; sample<totsample; sample++)
                                                if (ps->mask & (1 << sample)) {
-                                                       float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+                                                       float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
                                                        addalphaAddfacFloat(pass + od*4, col, har->add);
                                                }
                                }
@@ -217,7 +217,7 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in
        if (fullsample) {
                for (sample=0; sample<totsample; sample++)
                        if (!(mask & (1 << sample))) {
-                               float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+                               float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
                                addalphaAddfacFloat(pass + od*4, col, har->add);
                        }
        }
@@ -228,7 +228,7 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in
                col[3]= accol[3];
                
                for (sample=0; sample<totsample; sample++) {
-                       float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+                       float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
                        addalphaAddfacFloat(pass + od*4, col, har->add);
                }
        }
@@ -312,7 +312,7 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl)
                                                                if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
                                                                        if (shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) {
                                                                                for (sample=0; sample<totsample; sample++) {
-                                                                                       float * rect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+                                                                                       float * rect= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
                                                                                        addalphaAddfacFloat(rect + od*4, col, har->add);
                                                                                }
                                                                        }
@@ -367,7 +367,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
                                        if (fullsample) {
                                                for (sample=0; sample<totsample; sample++) {
                                                        if (ps->mask & (1 << sample)) {
-                                                               pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+                                                               pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
                                                                pass += od * 4;
                                                                pass[0]+= col[0];
                                                                pass[1]+= col[1];
@@ -379,7 +379,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
                                        }
                                        else {
                                                fac= ((float)count)/(float)R.osa;
-                                               pass = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+                                               pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
                                                pass += od * 4;
                                                pass[0]+= fac*col[0];
                                                pass[1]+= fac*col[1];
@@ -401,7 +401,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
                                                for (sample=0; sample<totsample; sample++) {
                                                        if (!(mask & (1 << sample))) {
 
-                                                               pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+                                                               pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
                                                                pass += od * 4;
                                                                pass[0]+= col[0];
                                                                pass[1]+= col[1];
@@ -413,7 +413,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
                                        }
                                        else {
                                                fac= ((float)R.osa-totsamp)/(float)R.osa;
-                                               pass = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+                                               pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
                                                pass += od * 4;
                                                pass[0]+= fac*col[0];
                                                pass[1]+= fac*col[1];
@@ -433,7 +433,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
                                renderspothalo(&shi, col, 1.0f);
 
                                for (sample=0; sample<totsample; sample++) {
-                                       pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+                                       pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
                                        pass += od * 4;
                                        pass[0]+= col[0];
                                        pass[1]+= col[1];
@@ -462,101 +462,96 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
                float *fp, *col= NULL;
                int pixsize= 3;
                
-               switch (rpass->passtype) {
-                       case SCE_PASS_COMBINED:
-                               add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx);
-                               break;
-                       case SCE_PASS_Z:
-                               fp= rpass->rect + offset;
-                               *fp= shr->z;
-                               break;
-                       case SCE_PASS_RGBA:
-                               col= shr->col;
-                               pixsize= 4;
-                               break;
-                       case SCE_PASS_EMIT:
-                               col= shr->emit;
-                               break;
-                       case SCE_PASS_DIFFUSE:
-                               col= shr->diff;
-                               break;
-                       case SCE_PASS_SPEC:
-                               col= shr->spec;
-                               break;
-                       case SCE_PASS_SHADOW:
-                               col= shr->shad;
-                               break;
-                       case SCE_PASS_AO:
-                               col= shr->ao;
-                               break;
-                       case SCE_PASS_ENVIRONMENT:
-                               col= shr->env;
-                               break;
-                       case SCE_PASS_INDIRECT:
-                               col= shr->indirect;
-                               break;
-                       case SCE_PASS_REFLECT:
-                               col= shr->refl;
-                               break;
-                       case SCE_PASS_REFRACT:
-                               col= shr->refr;
-                               break;
-                       case SCE_PASS_NORMAL:
-                               col= shr->nor;
-                               break;
-                       case SCE_PASS_UV:
-                               /* box filter only, gauss will screwup UV too much */
-                               if (shi->totuv) {
-                                       float mult= (float)count_mask(curmask)/(float)R.osa;
-                                       fp= rpass->rect + 3*offset;
-                                       fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
-                                       fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
-                                       fp[2]+= mult;
-                               }
-                               break;
-                       case SCE_PASS_INDEXOB:
-                               /* no filter */
-                               if (shi->vlr) {
-                                       fp= rpass->rect + offset;
+               if(STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+                       add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx);
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_Z)) {
+                       fp = rpass->rect + offset;
+                       *fp = shr->z;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+                       col = shr->col;
+                       pixsize = 4;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+                       col = shr->emit;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+                       col = shr->diff;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+                       col = shr->spec;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+                       col = shr->shad;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_AO)) {
+                       col = shr->ao;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+                       col = shr->env;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+                       col = shr->indirect;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+                       col = shr->refl;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+                       col = shr->refr;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+                       col = shr->nor;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_UV)) {
+                       /* box filter only, gauss will screwup UV too much */
+                       if (shi->totuv) {
+                               float mult = (float)count_mask(curmask)/(float)R.osa;
+                               fp = rpass->rect + 3*offset;
+                               fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
+                               fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
+                               fp[2]+= mult;
+                       }
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_INDEXOB)) {
+                       /* no filter */
+                       if (shi->vlr) {
+                               fp = rpass->rect + offset;
+                               if (*fp==0.0f)
+                                       *fp = (float)shi->obr->ob->index;
+                       }
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_INDEXMA)) {
+                       /* no filter */
+                       if (shi->vlr) {
+                                       fp = rpass->rect + offset;
                                        if (*fp==0.0f)
-                                               *fp= (float)shi->obr->ob->index;
-                               }
-                               break;
-                       case SCE_PASS_INDEXMA:
-                                       /* no filter */
-                                       if (shi->vlr) {
-                                                       fp= rpass->rect + offset;
-                                                       if (*fp==0.0f)
-                                                                       *fp= (float)shi->mat->index;
-                                       }
-                                       break;
-                       case SCE_PASS_MIST:
-                               /*  */
-                               col= &shr->mist;
-                               pixsize= 1;
-                               break;
-                       
-                       case SCE_PASS_VECTOR:
-                       {
-                               /* add minimum speed in pixel, no filter */
-                               fp= rpass->rect + 4*offset;
-                               if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
-                                       fp[0]= shr->winspeed[0];
-                                       fp[1]= shr->winspeed[1];
-                               }
-                               if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
-                                       fp[2]= shr->winspeed[2];
-                                       fp[3]= shr->winspeed[3];
-                               }
-
-                               break;
+                                                       *fp = (float)shi->mat->index;
                        }
-                       case SCE_PASS_RAYHITS:
-                               /*  */
-                               col= shr->rayhits;
-                               pixsize= 4;
-                               break;
                }
+               else if(STREQ(rpass->name, RE_PASSNAME_MIST)) {
+                       /*  */
+                       col = &shr->mist;
+                       pixsize = 1;
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
+                       /* add minimum speed in pixel, no filter */
+                       fp = rpass->rect + 4*offset;
+                       if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
+                               fp[0] = shr->winspeed[0];
+                               fp[1] = shr->winspeed[1];
+                       }
+                       if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
+                               fp[2] = shr->winspeed[2];
+                               fp[3] = shr->winspeed[3];
+                       }
+               }
+               else if(STREQ(rpass->name, RE_PASSNAME_RAYHITS)) {
+                       /*  */
+                       col = shr->rayhits;
+                       pixsize= 4;
+               }
+
                if (col) {
                        fp= rpass->rect + pixsize*offset;
                        add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
@@ -574,86 +569,85 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
                float *col= NULL, uvcol[3];
                int a, pixsize= 3;
                
-               switch (rpass->passtype) {
-                       case SCE_PASS_COMBINED:
-                               /* copy combined to use for preview */
-                               copy_v4_v4(rpass->rect + 4*offset, shr->combined);
-                               break;
-                       case SCE_PASS_Z:
-                               fp= rpass->rect + offset;
-                               *fp= shr->z;
-                               break;
-                       case SCE_PASS_RGBA:
-                               col= shr->col;
-                               pixsize= 4;
-                               break;
-                       case SCE_PASS_EMIT:
-                               col= shr->emit;
-                               break;
-                       case SCE_PASS_DIFFUSE:
-                               col= shr->diff;
-                               break;
-                       case SCE_PASS_SPEC:
-                               col= shr->spec;
-                               break;
-                       case SCE_PASS_SHADOW:
-                               col= shr->shad;
-                               break;
-                       case SCE_PASS_AO:
-                               col= shr->ao;
-                               break;
-                       case SCE_PASS_ENVIRONMENT:
-                               col= shr->env;
-                               break;
-                       case SCE_PASS_INDIRECT:
-                               col= shr->indirect;
-                               break;
-                       case SCE_PASS_REFLECT:
-                               col= shr->refl;
-                               break;
-                       case SCE_PASS_REFRACT:
-                               col= shr->refr;
-                               break;
-                       case SCE_PASS_NORMAL:
-                               col= shr->nor;
-                               break;
-                       case SCE_PASS_UV:
-                               if (shi->totuv) {
-                                       uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
-                                       uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
-                                       uvcol[2]= 1.0f;
-                                       col= uvcol;
-                               }
-                               break;
-                       case SCE_PASS_VECTOR:
-                               col= shr->winspeed;
-                               pixsize= 4;
-                               break;
-                       case SCE_PASS_INDEXOB:
-                               if (shi->vlr) {
-                                       fp= rpass->rect + offset;
-                                       *fp= (float)shi->obr->ob->index;
-                               }
-                               break;
-                       case SCE_PASS_INDEXMA:
-                               if (shi->vlr) {
-                                       fp= rpass->rect + offset;
-                                       *fp= (float)shi->mat->index;
-                               }
-                               break;
-                       case SCE_PASS_MIST:
-                               fp= rpass->rect + offset;
-                               *fp= shr->mist;
-                               break;
-                       case SCE_PASS_RAYHITS:
-                               col= shr->rayhits;
-                               pixsize= 4;
-                               break;
+               if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+                       /* copy combined to use for preview */
+                       copy_v4_v4(rpass->rect + 4*offset, shr->combined);
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+                       fp = rpass->rect + offset;
+                       *fp = shr->z;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+                       col = shr->col;
+                       pixsize = 4;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+                       col = shr->emit;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+                       col = shr->diff;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+                       col = shr->spec;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+                       col = shr->shad;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+                       col = shr->ao;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+                       col = shr->env;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+                       col = shr->indirect;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+                       col = shr->refl;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+                       col = shr->refr;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+                       col = shr->nor;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_UV)) {
+                       if (shi->totuv) {
+                               uvcol[0] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
+                               uvcol[1] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
+                               uvcol[2] = 1.0f;
+                               col = uvcol;
+                       }
                }
+               else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
+                       col = shr->winspeed;
+                       pixsize = 4;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) {
+                       if (shi->vlr) {
+                               fp = rpass->rect + offset;
+                               *fp = (float)shi->obr->ob->index;
+                       }
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) {
+                       if (shi->vlr) {
+                               fp = rpass->rect + offset;
+                               *fp = (float)shi->mat->index;
+                       }
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+                       fp = rpass->rect + offset;
+                       *fp = shr->mist;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) {
+                       col = shr->rayhits;
+                       pixsize = 4;
+               }
+
                if (col) {
-                       fp= rpass->rect + pixsize*offset;
+                       fp = rpass->rect + pixsize*offset;
                        for (a=0; a<pixsize; a++)
-                               fp[a]= col[a];
+                               fp[a] = col[a];
                }
        }
 }
@@ -696,7 +690,7 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
                        bool done = false;
                        
                        for (sample= 0; sample<totsample; sample++) {
-                               float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+                               float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
                                pass += od;
                                
                                if (pass[3]<1.0f) {
@@ -737,7 +731,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
        /* check that z pass is enabled */
        if (pa->rectz==NULL) return;
        for (zpass= rl->passes.first; zpass; zpass= zpass->next)
-               if (zpass->passtype==SCE_PASS_Z)
+               if (STREQ(zpass->name, RE_PASSNAME_Z))
                        break;
        
        if (zpass==NULL) return;
@@ -758,8 +752,8 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
                        int sample;
                        
                        for (sample=0; sample<totsample; sample++) {
-                               const float *zrect = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z, R.viewname) + od;
-                               float *rgbrect = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname) + 4*od;
+                               const float *zrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_Z, R.viewname) + od;
+                               float *rgbrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname) + 4*od;
                                float rgb[3] = {0};
                                bool done = false;
                                
@@ -994,7 +988,7 @@ static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
                return;
        
        for (sample= 0; sample<totsample; sample++) {
-               float *rectf = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+               float *rectf = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
 
                for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
                        rectf[0] = MAX2(rectf[0], 0.0f);
@@ -1076,7 +1070,7 @@ static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
        totsample= get_sample_layers(pa, rl, rlpp);
 
        for (sample= 0; sample<totsample; sample++) {
-               fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR, R.viewname);
+               fp= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_VECTOR, R.viewname);
                if (fp==NULL) break;
 
                for (a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
@@ -1187,7 +1181,7 @@ void zbufshadeDA_tile(RenderPart *pa)
        pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
        pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
        for (rl= rr->layers.first; rl; rl= rl->next) {
-               float *rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+               float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
 
                if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
                        pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
@@ -1339,7 +1333,7 @@ void zbufshade_tile(RenderPart *pa)
        pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
 
        for (rl= rr->layers.first; rl; rl= rl->next) {
-               float *rect= RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+               float *rect= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
                if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
                        pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
 
@@ -1676,7 +1670,7 @@ void zbufshade_sss_tile(RenderPart *pa)
                return;
        }
        
-       fcol= RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+       fcol= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
 
        co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
        color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
@@ -1969,7 +1963,7 @@ void add_halo_flare(Render *re)
                if ((rl->layflag & SCE_LAY_HALO) == 0)
                        continue;
 
-               rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, re->viewname);
+               rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname);
 
                if (rect==NULL)
                        continue;
@@ -1998,3 +1992,37 @@ void add_halo_flare(Render *re)
        }
 }
 
+void render_internal_update_passes(RenderEngine *engine, Scene *scene, SceneRenderLayer *srl)
+{
+       int type;
+
+       RE_engine_register_pass(engine, scene, srl, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
+
+#define CHECK_PASS(name, channels, chanid) \
+       if (srl->passflag & (SCE_PASS_ ## name)) { \
+               if (channels == 4) type = SOCK_RGBA; \
+               else if (channels == 3) type = SOCK_VECTOR; \
+               else type = SOCK_FLOAT; \
+               RE_engine_register_pass(engine, scene, srl, RE_PASSNAME_ ## name, channels, chanid, type); \
+       }
+
+       CHECK_PASS(Z,           1, "Z");
+       CHECK_PASS(VECTOR,      4, "XYZW");
+       CHECK_PASS(NORMAL,      3, "XYZ");
+       CHECK_PASS(UV,          3, "UVA");
+       CHECK_PASS(RGBA,        4, "RGBA");
+       CHECK_PASS(EMIT,        3, "RGB");
+       CHECK_PASS(DIFFUSE,     3, "RGB");
+       CHECK_PASS(SPEC,        3, "RGB");
+       CHECK_PASS(AO,          3, "RGB");
+       CHECK_PASS(ENVIRONMENT, 3, "RGB");
+       CHECK_PASS(INDIRECT,    3, "RGB");
+       CHECK_PASS(SHADOW,      3, "RGB");
+       CHECK_PASS(REFLECT,     3, "RGB");
+       CHECK_PASS(REFRACT,     3, "RGB");
+       CHECK_PASS(INDEXOB,     1, "X");
+       CHECK_PASS(INDEXMA,     1, "X");
+       CHECK_PASS(MIST,        1, "Z");
+
+#undef CHECK_PASS
+}
index 9f777631e522f1d5ef6ca7132937d15368b09a8e..94e03929c4ee67e373ee3860fc8339847bdfa13d 100644 (file)
@@ -3494,7 +3494,7 @@ static void add_transp_speed(RenderLayer *rl, int offset, float speed[4], float
        RenderPass *rpass;
        
        for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
-               if (rpass->passtype==SCE_PASS_VECTOR) {
+               if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
                        float *fp= rpass->rect + 4*offset;
                        
                        if (speed==NULL) {
@@ -3528,7 +3528,7 @@ static void add_transp_obindex(RenderLayer *rl, int offset, Object *ob)
        RenderPass *rpass;
        
        for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
-               if (rpass->passtype == SCE_PASS_INDEXOB) {
+               if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) {
                        float *fp= rpass->rect + offset;
                        *fp= (float)ob->index;
                        break;
@@ -3541,7 +3541,7 @@ static void add_transp_material_index(RenderLayer *rl, int offset, Material *mat
        RenderPass *rpass;
        
        for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
-               if (rpass->passtype == SCE_PASS_INDEXMA) {
+               if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) {
                        float *fp= rpass->rect + offset;
                        *fp= (float)mat->index;
                        break;
@@ -3558,78 +3558,74 @@ static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
        int delta= sizeof(ShadeResult)/4;
        
        for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
-               float *col= NULL;
-               int pixsize= 3;
+               float *col = NULL;
+               int pixsize = 3;
                
-               switch (rpass->passtype) {
-                       case SCE_PASS_RGBA:
-                               col= shr->col;
-                               pixsize= 4;
-                               break;
-                       case SCE_PASS_EMIT:
-                               col= shr->emit;
-                               break;
-                       case SCE_PASS_DIFFUSE:
-                               col= shr->diff;
-                               break;
-                       case SCE_PASS_SPEC:
-                               col= shr->spec;
-                               break;
-                       case SCE_PASS_SHADOW:
-                               col= shr->shad;
-                               break;
-                       case SCE_PASS_AO:
-                               col= shr->ao;
-                               break;
-                       case SCE_PASS_ENVIRONMENT:
-                               col= shr->env;
-                               break;
-                       case SCE_PASS_INDIRECT:
-                               col= shr->indirect;
-                               break;
-                       case SCE_PASS_REFLECT:
-                               col= shr->refl;
-                               break;
-                       case SCE_PASS_REFRACT:
-                               col= shr->refr;
-                               break;
-                       case SCE_PASS_NORMAL:
-                               col= shr->nor;
-                               break;
-                       case SCE_PASS_MIST:
-                               col= &shr->mist;
-                               pixsize= 1;
-                               break;
-                       case SCE_PASS_Z:
-                               col= &shr->z;
-                               pixsize= 1;
-                               break;
-                       case SCE_PASS_VECTOR:
+               if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+                       col = shr->col;
+                       pixsize = 4;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+                       col = shr->emit;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+                       col = shr->diff;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+                       col = shr->spec;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+                       col = shr->shad;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+                       col = shr->ao;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+                       col = shr->env;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+                       col = shr->indirect;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+                       col = shr->refl;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+                       col = shr->refr;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+                       col = shr->nor;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+                       col = &shr->mist;
+                       pixsize = 1;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+                       col = &shr->z;
+                       pixsize = 1;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
+                       ShadeResult *shr_t = shr+1;
+                       float *fp = shr->winspeed;      /* was initialized */
+                       int samp;
+
+                       /* add minimum speed in pixel */
+                       for (samp = 1; samp<R.osa; samp++, shr_t++) {
                                
-                               {
-                                       ShadeResult *shr_t= shr+1;
-                                       float *fp= shr->winspeed;       /* was initialized */
-                                       int samp;
+                               if (shr_t->combined[3] > 0.0f) {
+                                       const float *speed = shr_t->winspeed;
                                        
-                                       /* add minimum speed in pixel */
-                                       for (samp= 1; samp<R.osa; samp++, shr_t++) {
-                                               
-                                               if (shr_t->combined[3] > 0.0f) {
-                                                       const float *speed= shr_t->winspeed;
-                                                       
-                                                       if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
-                                                               fp[0]= speed[0];
-                                                               fp[1]= speed[1];
-                                                       }
-                                                       if ( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
-                                                               fp[2]= speed[2];
-                                                               fp[3]= speed[3];
-                                                       }
-                                               }
+                                       if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
+                                               fp[0] = speed[0];
+                                               fp[1] = speed[1];
+                                       }
+                                       if ( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
+                                               fp[2] = speed[2];
+                                               fp[3] = speed[3];
                                        }
                                }
-                               break;
+                               }
                }
+
                if (col) {
                        const float *fp= col+delta;
                        int samp;
@@ -3661,53 +3657,51 @@ static void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, flo
                float *fp, *col= NULL;
                int pixsize= 3;
                
-               switch (rpass->passtype) {
-                       case SCE_PASS_Z:
-                               fp= rpass->rect + offset;
-                               if (shr->z < *fp)
-                                       *fp= shr->z;
-                               break;
-                       case SCE_PASS_RGBA:
-                               fp= rpass->rect + 4*offset;
-                               addAlphaOverFloat(fp, shr->col);
-                               break;
-                       case SCE_PASS_EMIT:
-                               col= shr->emit;
-                               break;
-                       case SCE_PASS_DIFFUSE:
-                               col= shr->diff;
-                               break;
-                       case SCE_PASS_SPEC:
-                               col= shr->spec;
-                               break;
-                       case SCE_PASS_SHADOW:
-                               col= shr->shad;
-                               break;
-                       case SCE_PASS_AO:
-                               col= shr->ao;
-                               break;
-                       case SCE_PASS_ENVIRONMENT:
-                               col= shr->env;
-                               break;
-                       case SCE_PASS_INDIRECT:
-                               col= shr->indirect;
-                               break;
-                       case SCE_PASS_REFLECT:
-                               col= shr->refl;
-                               break;
-                       case SCE_PASS_REFRACT:
-                               col= shr->refr;
-                               break;
-                       case SCE_PASS_NORMAL:
-                               col= shr->nor;
-                               break;
-                       case SCE_PASS_MIST:
-                               col= &shr->mist;
-                               pixsize= 1;
-                               break;
+               if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+                       fp = rpass->rect + offset;
+                       if (shr->z < *fp)
+                               *fp = shr->z;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+                       fp = rpass->rect + 4*offset;
+                       addAlphaOverFloat(fp, shr->col);
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+                       col = shr->emit;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+                       col = shr->diff;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+                       col = shr->spec;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+                       col = shr->shad;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+                       col = shr->ao;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+                       col = shr->env;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+                       col = shr->indirect;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+                       col = shr->refl;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+                       col = shr->refr;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+                       col = shr->nor;
+               }
+               else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+                       col = &shr->mist;
+                       pixsize = 1;
                }
-               if (col) {
 
+               if (col) {
                        fp= rpass->rect + pixsize*offset;
                        fp[0]= col[0] + (1.0f-alpha)*fp[0];
                        if (pixsize==3) {
@@ -3964,7 +3958,7 @@ static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf
        float *fp, *col;
        int a;
        
-       fp = RE_RenderLayerGetPass(rl, SCE_PASS_VECTOR, R.viewname);
+       fp = RE_RenderLayerGetPass(rl, RE_PASSNAME_VECTOR, R.viewname);
        if (fp==NULL) return;
        col= rectf+3;
        
@@ -4058,7 +4052,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
        /* zero alpha pixels get speed vector max again */
        if (addpassflag & SCE_PASS_VECTOR)
                if (rl->layflag & SCE_LAY_SOLID) {
-                       float *rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+                       float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
                        reset_sky_speedvectors(pa, rl, rl->acolrect ? rl->acolrect : rect);     /* if acolrect is set we use it */
                }
        /* filtered render, for now we assume only 1 filter size */
@@ -4246,7 +4240,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
                                                        if (alpha != 0.0f) {
                                                                RenderLayer *rl_other = ssamp.rlpp[a];
 
-                                                               float *rect = RE_RenderLayerGetPass(rl_other , SCE_PASS_COMBINED, R.viewname);
+                                                               float *rect = RE_RenderLayerGetPass(rl_other , RE_PASSNAME_COMBINED, R.viewname);
                                                                addAlphaOverFloat(rect + 4 * od, samp_shr[a].combined);
                                
                                                                add_transp_passes(rl_other , od, &samp_shr[a], alpha);
index 300185b3b160f1f8e5e7e6e45f335e6abc2d5caf..bbff6790c79841be33446450d43c84f2eb788245 100644 (file)
@@ -230,7 +230,7 @@ void EDBM_mesh_normals_update(struct BMEditMesh *em) RET_NONE
 void *g_system;
 bool EDBM_mtexpoly_check(struct BMEditMesh *em) RET_ZERO
 
-float *RE_RenderLayerGetPass(volatile struct RenderLayer *rl, int passtype, const char *viewname) RET_NULL
+float *RE_RenderLayerGetPass(volatile struct RenderLayer *rl, const char *name, const char *viewname) RET_NULL
 float RE_filter_value(int type, float x) RET_ZERO
 struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name) RET_NULL
 void RE_texture_rng_init() RET_NONE
@@ -244,6 +244,7 @@ float RE_engine_get_camera_shift_x(struct RenderEngine *engine, struct Object *c
 int RE_engine_get_spherical_stereo(struct RenderEngine *engine, struct Object *camera) RET_ZERO
 void RE_SetActiveRenderView(struct Render *re, const char *viewname) RET_NONE
 
+struct RenderPass *RE_pass_find_by_name(volatile struct RenderLayer *rl, const char *name, const char *viewname) RET_NULL
 struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int passtype, const char *viewname) RET_NULL
 bool RE_HasFakeLayer(RenderResult *res) RET_ZERO
 
@@ -653,6 +654,7 @@ struct RenderData *RE_engine_get_render_data(struct Render *re) RET_NULL
 void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result) RET_NONE
 void RE_engine_update_progress(struct RenderEngine *engine, float progress) RET_NONE
 void RE_engine_set_error_message(RenderEngine *engine, const char *msg) RET_NONE
+void RE_engine_add_pass(RenderEngine *engine, const char *name, int channels, const char *chan_id, const char *layername) RET_NONE
 void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int cancel, int merge_results) RET_NONE
 void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info) RET_NONE
 void RE_layer_load_from_file(struct RenderLayer *layer, struct ReportList *reports, const char *filename, int x, int y) RET_NONE
@@ -678,6 +680,7 @@ void RE_point_density_free(struct PointDensity *pd) RET_NONE
 void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE
 void RE_FreeAllPersistentData(void) RET_NONE
 float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta) RET_ZERO
+void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl, const char *name, int channels, const char *chanid, int type) RET_NONE
 
 /* python */
 struct wmOperatorType *WM_operatortype_find(const char *idname, bool quiet) RET_NULL