Merge branch 'master' into blender2.8
[blender.git] / intern / cycles / blender / blender_object.cpp
index 4b40f4d458b48d39c28597c25eaba7eb8ee2291a..d949eaf30093fa9a34804287e717b2f7a616849c 100644 (file)
@@ -112,13 +112,14 @@ static uint object_ray_visibility(BL::Object& b_ob)
 void BlenderSync::sync_light(BL::Object& b_parent,
                              int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
                              BL::Object& b_ob,
-                             BL::DupliObject& b_dupli_ob,
+                             BL::Object& b_ob_instance,
+                             int random_id,
                              Transform& tfm,
                              bool *use_portal)
 {
        /* test if we need to sync */
        Light *light;
-       ObjectKey key(b_parent, persistent_id, b_ob);
+       ObjectKey key(b_parent, persistent_id, b_ob_instance);
 
        if(!light_map.sync(&light, b_ob, b_parent, key)) {
                if(light->is_portal)
@@ -194,8 +195,8 @@ void BlenderSync::sync_light(BL::Object& b_parent,
 
        light->max_bounces = get_int(clamp, "max_bounces");
 
-       if(b_dupli_ob) {
-               light->random_id = b_dupli_ob.random_id();
+       if(b_ob != b_ob_instance) {
+               light->random_id = random_id;
        }
        else {
                light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
@@ -262,24 +263,43 @@ void BlenderSync::sync_background_light(bool use_portal)
 
 /* Object */
 
-Object *BlenderSync::sync_object(BL::Object& b_parent,
-                                 int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
-                                 BL::DupliObject& b_dupli_ob,
-                                 Transform& tfm,
+Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
+                                 BL::Depsgraph::duplis_iterator& b_dupli_iter,
                                  uint layer_flag,
                                  float motion_time,
                                  bool hide_tris,
                                  BlenderObjectCulling& culling,
                                  bool *use_portal)
 {
-       BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
-       bool motion = motion_time != 0.0f;
-       
+       const bool is_instance = b_dupli_iter->is_instance();
+       BL::Object b_ob = b_dupli_iter->object();
+       BL::Object b_parent = is_instance ? b_dupli_iter->parent()
+                                         : b_dupli_iter->object();
+       BL::Object b_ob_instance = is_instance ? b_dupli_iter->instance_object()
+                                              : b_ob;
+       const bool motion = motion_time != 0.0f;
+       /*const*/ Transform tfm = get_transform(b_ob.matrix_world());
+       int *persistent_id = NULL;
+       BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
+       if(is_instance) {
+               persistent_id_array = b_dupli_iter->persistent_id();
+               persistent_id = persistent_id_array.data;
+       }
+
        /* light is handled separately */
        if(object_is_light(b_ob)) {
                /* don't use lamps for excluded layers used as mask layer */
-               if(!motion && !((layer_flag & render_layer.holdout_layer) && (layer_flag & render_layer.exclude_layer)))
-                       sync_light(b_parent, persistent_id, b_ob, b_dupli_ob, tfm, use_portal);
+               if(!motion && !((layer_flag & view_layer.holdout_layer) &&
+                               (layer_flag & view_layer.exclude_layer)))
+               {
+                       sync_light(b_parent,
+                                  persistent_id,
+                                  b_ob,
+                                  b_ob_instance,
+                                  is_instance ? b_dupli_iter->random_id() : 0,
+                                  tfm,
+                                  use_portal);
+               }
 
                return NULL;
        }
@@ -296,7 +316,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
 
        /* Visibility flags for both parent and child. */
        PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
-       bool use_holdout = (layer_flag & render_layer.holdout_layer) != 0 ||
+       bool use_holdout = (layer_flag & view_layer.holdout_layer) != 0 ||
                           get_boolean(cobject, "is_holdout");
        uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
 
@@ -305,12 +325,12 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
        }
 
        /* Make holdout objects on excluded layer invisible for non-camera rays. */
-       if(use_holdout && (layer_flag & render_layer.exclude_layer)) {
+       if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
                visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
        }
 
        /* Hide objects not on render layer from camera rays. */
-       if(!(layer_flag & render_layer.layer)) {
+       if(!(layer_flag & view_layer.layer)) {
                visibility &= ~PATH_RAY_CAMERA;
        }
 
@@ -320,7 +340,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
        }
 
        /* key to lookup object */
-       ObjectKey key(b_parent, persistent_id, b_ob);
+       ObjectKey key(b_parent, persistent_id, b_ob_instance);
        Object *object;
 
        /* motion vector case */
@@ -336,7 +356,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
 
                        /* mesh deformation */
                        if(object->mesh)
-                               sync_mesh_motion(b_ob, object, motion_time);
+                               sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
                }
 
                return object;
@@ -349,7 +369,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
                object_updated = true;
        
        /* mesh sync */
-       object->mesh = sync_mesh(b_ob, object_updated, hide_tris);
+       object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, hide_tris);
 
        /* special case not tracked by object update flags */
 
@@ -410,10 +430,10 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
                }
 
                /* dupli texture coordinates and random_id */
-               if(b_dupli_ob) {
-                       object->dupli_generated = 0.5f*get_float3(b_dupli_ob.orco()) - make_float3(0.5f, 0.5f, 0.5f);
-                       object->dupli_uv = get_float2(b_dupli_ob.uv());
-                       object->random_id = b_dupli_ob.random_id();
+               if(is_instance) {
+                       object->dupli_generated = 0.5f*get_float3(b_dupli_iter->orco()) - make_float3(0.5f, 0.5f, 0.5f);
+                       object->dupli_uv = get_float2(b_dupli_iter->uv());
+                       object->random_id = b_dupli_iter->random_id();
                }
                else {
                        object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
@@ -448,6 +468,7 @@ static bool object_render_hide(BL::Object& b_ob,
        BL::Object::particle_systems_iterator b_psys;
 
        bool hair_present = false;
+       bool has_particles = false;
        bool show_emitter = false;
        bool hide_emitter = false;
        bool hide_as_dupli_parent = false;
@@ -457,20 +478,17 @@ static bool object_render_hide(BL::Object& b_ob,
                if((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
                   (b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
                        hair_present = true;
-
-               if(b_psys->settings().use_render_emitter())
-                       show_emitter = true;
-               else
-                       hide_emitter = true;
+               has_particles = true;
        }
 
-       if(show_emitter)
-               hide_emitter = false;
-
-       /* duplicators hidden by default, except dupliframes which duplicate self */
-       if(b_ob.is_duplicator())
-               if(top_level || b_ob.dupli_type() != BL::Object::dupli_type_FRAMES)
+       if(has_particles) {
+               show_emitter = b_ob.show_duplicator_for_render();
+               hide_emitter = !show_emitter;
+       } else if(b_ob.is_duplicator()) {
+               if(top_level || b_ob.show_duplicator_for_render()) {
                        hide_as_dupli_parent = true;
+               }
+       }
 
        /* hide original object for duplis */
        BL::Object parent = b_ob.parent();
@@ -499,19 +517,11 @@ static bool object_render_hide(BL::Object& b_ob,
        }
 }
 
-static bool object_render_hide_duplis(BL::Object& b_ob)
-{
-       BL::Object parent = b_ob.parent();
-
-       return (parent && object_render_hide_original(b_ob.type(), parent.dupli_type()));
-}
-
 /* Object Loop */
 
-void BlenderSync::sync_objects(float motion_time)
+void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
 {
        /* layer data */
-       uint scene_layer = render_layer.scene_layer;
        bool motion = motion_time != 0.0f;
        
        if(!motion) {
@@ -530,100 +540,39 @@ void BlenderSync::sync_objects(float motion_time)
        BlenderObjectCulling culling(scene, b_scene);
 
        /* object loop */
-       BL::Scene::object_bases_iterator b_base;
-       BL::Scene b_sce = b_scene;
-       /* modifier result type (not exposed as enum in C++ API)
-        * 1 : DAG_EVAL_PREVIEW
-        * 2 : DAG_EVAL_RENDER
-        */
-       int dupli_settings = (render_layer.use_viewport_visibility) ? 1 : 2;
-
        bool cancel = false;
        bool use_portal = false;
 
-       uint layer_override = get_layer(b_engine.layer_override());
-       for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
-               /* Render layer's scene_layer is affected by local view already,
-                * which is not a desired behavior here.
-                */
-               uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers());
-               for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) {
-                       BL::Object b_ob = b_base->object();
-                       bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render();
-                       uint ob_layer = get_layer(b_base->layers(),
-                                                 b_base->layers_local_view(),
-                                                 object_is_light(b_ob),
-                                                 scene_layers);
-                       hide = hide || !(ob_layer & scene_layer);
-
-                       if(!hide) {
-                               progress.set_sync_status("Synchronizing object", b_ob.name());
-
-                               /* load per-object culling data */
-                               culling.init_object(scene, b_ob);
-
-                               if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) {
-                                       /* dupli objects */
-                                       b_ob.dupli_list_create(b_scene, dupli_settings);
-
-                                       BL::Object::dupli_list_iterator b_dup;
-
-                                       for(b_ob.dupli_list.begin(b_dup); b_dup != b_ob.dupli_list.end(); ++b_dup) {
-                                               Transform tfm = get_transform(b_dup->matrix());
-                                               BL::Object b_dup_ob = b_dup->object();
-                                               bool dup_hide = (render_layer.use_viewport_visibility)? b_dup_ob.hide(): b_dup_ob.hide_render();
-                                               bool in_dupli_group = (b_dup->type() == BL::DupliObject::type_GROUP);
-                                               bool hide_tris;
-
-                                               if(!(b_dup->hide() || dup_hide || object_render_hide(b_dup_ob, false, in_dupli_group, hide_tris))) {
-                                                       /* the persistent_id allows us to match dupli objects
-                                                        * between frames and updates */
-                                                       BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
-
-                                                       /* sync object and mesh or light data */
-                                                       Object *object = sync_object(b_ob,
-                                                                                    persistent_id.data,
-                                                                                    *b_dup,
-                                                                                    tfm,
-                                                                                    ob_layer,
-                                                                                    motion_time,
-                                                                                    hide_tris,
-                                                                                    culling,
-                                                                                    &use_portal);
-
-                                                       /* sync possible particle data, note particle_id
-                                                        * starts counting at 1, first is dummy particle */
-                                                       if(!motion && object) {
-                                                               sync_dupli_particle(b_ob, *b_dup, object);
-                                                       }
-
-                                               }
-                                       }
-
-                                       b_ob.dupli_list_clear();
-                               }
+       BL::Depsgraph::duplis_iterator b_dupli_iter;
+       for(b_depsgraph.duplis.begin(b_dupli_iter);
+           b_dupli_iter != b_depsgraph.duplis.end() && !cancel;
+           ++b_dupli_iter)
+       {
+               BL::Object b_ob = b_dupli_iter->object();
+               if(!b_ob.is_visible()) {
+                       continue;
+               }
 
-                               /* test if object needs to be hidden */
-                               bool hide_tris;
-
-                               if(!object_render_hide(b_ob, true, true, hide_tris)) {
-                                       /* object itself */
-                                       Transform tfm = get_transform(b_ob.matrix_world());
-                                       BL::DupliObject b_empty_dupli_ob(PointerRNA_NULL);
-                                       sync_object(b_ob,
-                                                   NULL,
-                                                   b_empty_dupli_ob,
-                                                   tfm,
-                                                   ob_layer,
-                                                   motion_time,
-                                                   hide_tris,
-                                                   culling,
-                                                   &use_portal);
-                               }
-                       }
+               progress.set_sync_status("Synchronizing object", b_ob.name());
 
-                       cancel = progress.get_cancel();
-               }
+               /* load per-object culling data */
+               culling.init_object(scene, b_ob);
+
+               /* test if object needs to be hidden */
+               bool hide_tris;
+
+                if(!object_render_hide(b_ob, true, true, hide_tris)) {
+                       /* object itself */
+                       sync_object(b_depsgraph,
+                                   b_dupli_iter,
+                                   ~(0), /* until we get rid of layers */
+                                   motion_time,
+                                   hide_tris,
+                                   culling,
+                                   &use_portal);
+                }
+
+               cancel = progress.get_cancel();
        }
 
        progress.set_sync_status("");
@@ -647,6 +596,7 @@ void BlenderSync::sync_objects(float motion_time)
 }
 
 void BlenderSync::sync_motion(BL::RenderSettings& b_render,
+                              BL::Depsgraph& b_depsgraph,
                               BL::Object& b_override,
                               int width, int height,
                               void **python_thread_state)
@@ -676,6 +626,8 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
                        assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
                        frame_center_delta = shuttertime * 0.5f;
                }
+
+               /* TODO: move frame on depsgraph. */
                float time = frame_center + subframe_center + frame_center_delta;
                int frame = (int)floorf(time);
                float subframe = time - frame;
@@ -683,7 +635,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
                b_engine.frame_set(frame, subframe);
                python_thread_state_save(python_thread_state);
                sync_camera_motion(b_render, b_cam, width, height, 0.0f);
-               sync_objects(0.0f);
+               sync_objects(b_depsgraph, 0.0f);
        }
 
        /* always sample these times for camera motion */
@@ -708,6 +660,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
                int frame = (int)floorf(time);
                float subframe = time - frame;
 
+               /* TODO: move frame on depsgraph. */
                /* change frame */
                python_thread_state_restore(python_thread_state);
                b_engine.frame_set(frame, subframe);
@@ -722,7 +675,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
                }
 
                /* sync object */
-               sync_objects(relative_time);
+               sync_objects(b_depsgraph, relative_time);
        }
 
        /* we need to set the python thread state again because this