Fix inconsistent/broken Cycles object visibility for instances.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 18 Dec 2018 17:18:00 +0000 (18:18 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Fri, 21 Dec 2018 15:05:48 +0000 (16:05 +0100)
Object visibility is now handled by the depsgraph iterator, but this API
was incomplete as it made no distinction for visibility of the object itself,
particles and generated instances.

The depsgraph iterator API now includes information about which part of the
object is visible, and this is used by Cycles to replace the old custom logic.
Cycles and EEVEE visibility should now be consistent, which unfortunately does
means some subtle compatibility breakage for both.

Fixes T58956, T58202, T59284.

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

19 files changed:
intern/cycles/blender/blender_mesh.cpp
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_sync.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/object.c
source/blender/depsgraph/DEG_depsgraph_query.h
source/blender/depsgraph/intern/depsgraph_query_iter.cc
source/blender/draw/engines/eevee/eevee_engine.c
source/blender/draw/engines/eevee/eevee_lightcache.c
source/blender/draw/engines/eevee/eevee_render.c
source/blender/draw/engines/gpencil/gpencil_engine.c
source/blender/draw/engines/gpencil/gpencil_render.c
source/blender/draw/engines/workbench/workbench_deferred.c
source/blender/draw/engines/workbench/workbench_forward.c
source/blender/draw/intern/DRW_render.h
source/blender/draw/intern/draw_manager.c
source/blender/draw/modes/object_mode.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/rna_depsgraph.c

index b27de77..701dba6 100644 (file)
@@ -979,7 +979,8 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
                              BL::Object& b_ob,
                              BL::Object& b_ob_instance,
                              bool object_updated,
-                             bool hide_tris)
+                             bool show_self,
+                             bool show_particles)
 {
        /* test if we can instance or if the object is modified */
        BL::ID b_ob_data = b_ob.data();
@@ -1086,7 +1087,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
                                                 mesh->subdivision_type);
 
                if(b_mesh) {
-                       if(view_layer.use_surfaces && !hide_tris) {
+                       if(view_layer.use_surfaces && show_self) {
                                if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
                                        create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders,
                                                         dicing_rate, max_subdivisions);
@@ -1096,7 +1097,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
                                create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
                        }
 
-                       if(view_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
+                       if(view_layer.use_hair && show_particles && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
                                sync_curves(mesh, b_mesh, b_ob, false);
 
                        /* free derived mesh */
index bcab527..0f99948 100644 (file)
@@ -295,7 +295,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
                                  BL::ViewLayer& b_view_layer,
                                  BL::DepsgraphObjectInstance& b_instance,
                                  float motion_time,
-                                 bool hide_tris,
+                                 bool show_self,
+                                 bool show_particles,
                                  BlenderObjectCulling& culling,
                                  bool *use_portal)
 {
@@ -403,7 +404,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
                object_updated = true;
 
        /* mesh sync */
-       object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, hide_tris);
+       object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles);
 
        /* special case not tracked by object update flags */
 
@@ -505,82 +506,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
        return object;
 }
 
-static bool object_render_hide_original(BL::Object::type_enum ob_type,
-                                        BL::Object::instance_type_enum dupli_type)
-{
-       /* metaball exception, they duplicate self */
-       if(ob_type == BL::Object::type_META)
-               return false;
-
-       return (dupli_type == BL::Object::instance_type_VERTS ||
-               dupli_type == BL::Object::instance_type_FACES ||
-               dupli_type == BL::Object::instance_type_FRAMES);
-}
-
-static bool object_render_hide(BL::Object& b_ob,
-                               bool top_level,
-                               bool parent_hide,
-                               bool& hide_triangles,
-                               BL::Depsgraph::mode_enum depsgraph_mode)
-{
-       /* check if we should render or hide particle emitter */
-       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;
-       bool hide_as_dupli_child_original = false;
-
-       for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
-               if((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
-                  (b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
-                       hair_present = true;
-               has_particles = true;
-       }
-
-       /* Both mode_PREVIEW and mode_VIEWPORT are treated the same here.*/
-       const bool show_instancer = depsgraph_mode == BL::Depsgraph::mode_RENDER
-                                    ? b_ob.show_instancer_for_render()
-                                    : b_ob.show_instancer_for_viewport();
-
-       if(has_particles) {
-               show_emitter = show_instancer;
-               hide_emitter = !show_emitter;
-       } else if(b_ob.is_instancer()) {
-               if(top_level || show_instancer) {
-                       hide_as_dupli_parent = true;
-               }
-       }
-
-       /* hide original object for duplis */
-       BL::Object parent = b_ob.parent();
-       while(parent) {
-               if(object_render_hide_original(b_ob.type(),
-                                              parent.instance_type()))
-               {
-                       if(parent_hide) {
-                               hide_as_dupli_child_original = true;
-                               break;
-                       }
-               }
-               parent = parent.parent();
-       }
-
-       hide_triangles = hide_emitter;
-
-       if(show_emitter) {
-               return false;
-       }
-       else if(hair_present) {
-               return hide_as_dupli_child_original;
-       }
-       else {
-               return (hide_as_dupli_parent || hide_as_dupli_child_original);
-       }
-}
-
 /* Object Loop */
 
 void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
@@ -608,7 +533,6 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
        bool use_portal = false;
 
        BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
-       BL::Depsgraph::mode_enum depsgraph_mode = b_depsgraph.mode();
 
        BL::Depsgraph::object_instances_iterator b_instance_iter;
        for(b_depsgraph.object_instances.begin(b_instance_iter);
@@ -624,15 +548,17 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
                culling.init_object(scene, b_ob);
 
                /* test if object needs to be hidden */
-               bool hide_tris;
+               const bool show_self = b_instance.show_self();
+               const bool show_particles = b_instance.show_particles();
 
-                if(!object_render_hide(b_ob, true, true, hide_tris, depsgraph_mode)) {
+                if(show_self || show_particles) {
                        /* object itself */
                        sync_object(b_depsgraph,
                                    b_view_layer,
                                    b_instance,
                                    motion_time,
-                                   hide_tris,
+                                   show_self,
+                                   show_particles,
                                    culling,
                                    &use_portal);
                 }
index 8af0de3..7290ea0 100644 (file)
@@ -117,7 +117,8 @@ private:
                        BL::Object& b_ob,
                        BL::Object& b_ob_instance,
                        bool object_updated,
-                       bool hide_tris);
+                       bool show_self,
+                       bool show_particles);
        void sync_curves(Mesh *mesh,
                         BL::Mesh& b_mesh,
                         BL::Object& b_ob,
@@ -127,7 +128,8 @@ private:
                            BL::ViewLayer& b_view_layer,
                            BL::DepsgraphObjectInstance& b_instance,
                            float motion_time,
-                           bool hide_tris,
+                           bool show_self,
+                           bool show_particles,
                            BlenderObjectCulling& culling,
                            bool *use_portal);
        void sync_light(BL::Object& b_parent,
index 0b405b5..50e0957 100644 (file)
@@ -97,13 +97,14 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
 
 bool BKE_object_data_is_in_editmode(const struct ID *id);
 
-typedef enum eObjectVisibilityCheck {
-       OB_VISIBILITY_CHECK_FOR_VIEWPORT,
-       OB_VISIBILITY_CHECK_FOR_RENDER,
-       OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE,
-} eObjectVisibilityCheck;
-
-bool BKE_object_is_visible(const struct Object *ob, const eObjectVisibilityCheck mode);
+typedef enum eObjectVisibilityResult {
+       OB_VISIBLE_SELF = 1,
+       OB_VISIBLE_PARTICLES = 2,
+       OB_VISIBLE_INSTANCES = 4,
+       OB_VISIBLE_ALL = (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES | OB_VISIBLE_INSTANCES),
+} eObjectVisibilityResult;
+
+int BKE_object_visibility(const struct Object *ob, const int dag_eval_mode);
 
 void BKE_object_init(struct Object *ob);
 struct Object *BKE_object_add_only_object(
index 3d341f5..fd047c5 100644 (file)
@@ -714,33 +714,40 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
 }
 
 /**
- * Return if the object is visible, as evaluated by depsgraph
+ * Return which parts of the object are visible, as evaluated by depsgraph
  */
-bool BKE_object_is_visible(const Object *ob, const eObjectVisibilityCheck mode)
+int BKE_object_visibility(const Object *ob, const int dag_eval_mode)
 {
        if ((ob->base_flag & BASE_VISIBLE) == 0) {
-               return false;
+               return 0;
        }
 
-       if (mode == OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) {
-               return true;
+       /* Test which components the object has. */
+       int visibility = OB_VISIBLE_SELF;
+       if (ob->particlesystem.first) {
+               visibility |= OB_VISIBLE_INSTANCES | OB_VISIBLE_PARTICLES;
        }
-
-       if (((ob->transflag & OB_DUPLI) == 0) &&
-           (ob->particlesystem.first == NULL))
-       {
-               return true;
+       else if (ob->transflag & OB_DUPLI) {
+               visibility |= OB_VISIBLE_INSTANCES;
        }
 
-       switch (mode) {
-               case OB_VISIBILITY_CHECK_FOR_VIEWPORT:
-                       return ((ob->duplicator_visibility_flag & OB_DUPLI_FLAG_VIEWPORT) != 0);
-               case OB_VISIBILITY_CHECK_FOR_RENDER:
-                       return ((ob->duplicator_visibility_flag & OB_DUPLI_FLAG_RENDER) != 0);
-               default:
-                       BLI_assert(!"Object visible test mode not supported.");
-                       return false;
+       /* Optional hiding of self if there are particles or instancers. */
+       if (visibility & (OB_VISIBLE_PARTICLES | OB_VISIBLE_INSTANCES)) {
+               switch ((eEvaluationMode)dag_eval_mode) {
+                       case DAG_EVAL_VIEWPORT:
+                               if (!(ob->duplicator_visibility_flag & OB_DUPLI_FLAG_VIEWPORT)) {
+                                       visibility &= ~OB_VISIBLE_SELF;
+                               }
+                               break;
+                       case DAG_EVAL_RENDER:
+                               if (!(ob->duplicator_visibility_flag & OB_DUPLI_FLAG_RENDER)) {
+                                       visibility &= ~OB_VISIBLE_SELF;
+                               }
+                               break;
+               }
        }
+
+       return visibility;
 }
 
 bool BKE_object_exists_check(Main *bmain, const Object *obtest)
index c9fa6b0..11a4ebe 100644 (file)
@@ -118,7 +118,7 @@ typedef struct DEGObjectIterData {
 
        struct Scene *scene;
 
-       int visibility_check; /* eObjectVisibilityCheck. */
+       eEvaluationMode eval_mode;
 
        /* **** Iteration over dupli-list. *** */
 
index 52c4ab3..88dc744 100644 (file)
@@ -107,6 +107,26 @@ void verify_id_properties_freed(DEGObjectIterData *data)
        temp_dupli_object->id.properties = NULL;
 }
 
+static bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject *dob)
+{
+       /* Automatic hiding if this object is being instanced on verts/faces/frames
+        * by its parent. Ideally this should not be needed, but due to the wrong
+        * dependency direction in the data design there is no way to keep the object
+        * visible otherwise. The better solution eventually would be for objects
+        * to specify which object they instance, instead of through parenting. */
+       if (eval_mode == DAG_EVAL_RENDER || dob) {
+               const int hide_original_types = OB_DUPLIFRAMES | OB_DUPLIVERTS | OB_DUPLIFACES;
+
+               if (!dob || !(dob->type & hide_original_types)) {
+                       if (ob->parent && (ob->parent->transflag & hide_original_types)) {
+                               return true;
+                       }
+               }
+       }
+
+       return false;
+}
+
 bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
 {
        DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
@@ -116,16 +136,15 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
 
                data->dupli_object_next = data->dupli_object_next->next;
 
-               /* Group duplis need to set ob matrices correct, for deform. so no_draw
-                * is part handled.
-                */
-               if ((obd->transflag & OB_RENDER_DUPLI) == 0 && dob->no_draw) {
+               if (dob->no_draw) {
                        continue;
                }
-
                if (obd->type == OB_MBALL) {
                        continue;
                }
+               if (deg_object_hide_original(data->eval_mode, dob->ob, dob)) {
+                       continue;
+               }
 
                verify_id_properties_freed(data);
 
@@ -142,12 +161,11 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
                /* Duplicated elements shouldn't care whether their original collection is visible or not. */
                temp_dupli_object->base_flag |= BASE_VISIBLE;
 
-               if (BKE_object_is_visible(temp_dupli_object, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) == false) {
+               int ob_visibility = BKE_object_visibility(temp_dupli_object, data->eval_mode);
+               if (ob_visibility == 0) {
                        continue;
                }
 
-               temp_dupli_object->transflag &= ~OB_DUPLI;
-
                copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
                iter->current = &data->temp_dupli_object;
                BLI_assert(
@@ -196,25 +214,29 @@ void deg_iterator_objects_step(BLI_Iterator *iter, DEG::IDDepsNode *id_node)
        Object *object = (Object *)id_node->id_cow;
        BLI_assert(DEG::deg_validate_copy_on_write_datablock(&object->id));
 
-       if ((BKE_object_is_visible(object, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) == false) &&
-           ((data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) != 0))
-       {
-               return;
-       }
+       int ob_visibility = OB_VISIBLE_ALL;
+       if (data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) {
+               ob_visibility = BKE_object_visibility(object, data->eval_mode);
 
-       if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
-           (object->transflag & OB_DUPLI))
-       {
-               data->dupli_parent = object;
-               data->dupli_list = object_duplilist(data->graph, data->scene, object);
-               data->dupli_object_next = (DupliObject *)data->dupli_list->first;
-               if (BKE_object_is_visible(object, (eObjectVisibilityCheck)data->visibility_check) == false) {
+               if (deg_object_hide_original(data->eval_mode, object, NULL)) {
                        return;
                }
        }
 
-       iter->current = object;
-       iter->skip = false;
+       if (ob_visibility & OB_VISIBLE_INSTANCES) {
+               if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
+                       (object->transflag & OB_DUPLI))
+               {
+                       data->dupli_parent = object;
+                       data->dupli_list = object_duplilist(data->graph, data->scene, object);
+                       data->dupli_object_next = (DupliObject *)data->dupli_list->first;
+               }
+       }
+
+       if (ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) {
+               iter->current = object;
+               iter->skip = false;
+       }
 }
 
 }  // namespace
@@ -239,10 +261,7 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
        data->scene = DEG_get_evaluated_scene(depsgraph);
        data->id_node_index = 0;
        data->num_id_nodes = num_id_nodes;
-       eEvaluationMode eval_mode = DEG_get_mode(depsgraph);
-       data->visibility_check = (eval_mode == DAG_EVAL_RENDER)
-                                ? OB_VISIBILITY_CHECK_FOR_RENDER
-                                : OB_VISIBILITY_CHECK_FOR_VIEWPORT;
+       data->eval_mode = DEG_get_mode(depsgraph);
        deg_invalidate_iterator_work_data(data);
 
        DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index];
index aa2cf3f..6a2ca98 100644 (file)
@@ -130,15 +130,14 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
        EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
 
        const DRWContextState *draw_ctx = DRW_context_state_get();
+       const int ob_visibility = DRW_object_visibility_in_active_context(ob);
        bool cast_shadow = false;
 
-       if (ob->base_flag & BASE_VISIBLE) {
+       if (ob_visibility & OB_VISIBLE_PARTICLES) {
                EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
        }
 
-       if (DRW_object_is_renderable(ob) &&
-           DRW_object_is_visible_in_active_context(ob))
-       {
+       if (DRW_object_is_renderable(ob) && (ob_visibility & OB_VISIBLE_SELF)) {
                if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
                        EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
                }
index 7108226..74cac25 100644 (file)
@@ -411,7 +411,8 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
 
        DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
        {
-               if (!BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_FOR_RENDER)) {
+               const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
+               if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
                        continue;
                }
 
@@ -1006,7 +1007,8 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
         * This allows a large number of probe to be precomputed (even dupli ones). */
        DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
        {
-               if (!BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_FOR_RENDER)) {
+               const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
+               if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
                        continue;
                }
 
index 8d196ee..45bfba0 100644 (file)
@@ -34,6 +34,7 @@
 #include "DNA_object_types.h"
 
 #include "BKE_camera.h"
+#include "BKE_object.h"
 
 #include "BLI_rand.h"
 #include "BLI_rect.h"
@@ -179,11 +180,12 @@ void EEVEE_render_cache(
                RE_engine_update_stats(engine, NULL, info);
        }
 
-       if (ob->base_flag & BASE_VISIBLE) {
+       const int ob_visibility = DRW_object_visibility_in_active_context(ob);
+       if (ob_visibility & OB_VISIBLE_PARTICLES) {
                EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
        }
 
-       if (DRW_object_is_visible_in_active_context(ob)) {
+       if (ob_visibility & OB_VISIBLE_SELF) {
                if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
                        EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
                }
index 23c5397..79724f6 100644 (file)
@@ -559,7 +559,7 @@ static void gpencil_add_draw_data(void *vedata, Object *ob)
 void GPENCIL_cache_populate(void *vedata, Object *ob)
 {
        /* object must be visible */
-       if (!DRW_object_is_visible_in_active_context(ob)) {
+       if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
                return;
        }
 
index 51a8209..1fe008e 100644 (file)
@@ -28,6 +28,7 @@
 #include "DRW_render.h"
 
 #include "BKE_camera.h"
+#include "BKE_object.h"
 
 #include "DNA_gpencil_types.h"
 
@@ -130,12 +131,10 @@ static void GPENCIL_render_cache(
        void *vedata, struct Object *ob,
        struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
 {
-       if ((ob == NULL) || (DRW_object_is_visible_in_active_context(ob) == false)) {
-               return;
-       }
-
-       if (ob->type == OB_GPENCIL) {
-               GPENCIL_cache_populate(vedata, ob);
+       if (ob && ob->type == OB_GPENCIL) {
+               if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
+                       GPENCIL_cache_populate(vedata, ob);
+               }
        }
 }
 
index c3b4696..52caeb6 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "BKE_node.h"
 #include "BKE_modifier.h"
+#include "BKE_object.h"
 #include "BKE_particle.h"
 
 #include "DNA_image_types.h"
@@ -808,7 +809,10 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
                return; /* Do not draw solid in this case. */
        }
 
-       if (!DRW_object_is_visible_in_active_context(ob) || (ob->dt < OB_SOLID)) {
+       if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
+               return;
+       }
+       if (ob->dt < OB_SOLID) {
                return;
        }
 
index ca02cc2..6c955ac 100644 (file)
@@ -34,6 +34,7 @@
 #include "BKE_node.h"
 #include "BKE_particle.h"
 #include "BKE_modifier.h"
+#include "BKE_object.h"
 
 #include "DNA_image_types.h"
 #include "DNA_mesh_types.h"
@@ -489,7 +490,10 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
                return; /* Do not draw solid in this case. */
        }
 
-       if (!DRW_object_is_visible_in_active_context(ob) || (ob->dt < OB_WIRE)) {
+       if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
+               return;
+       }
+       if (ob->dt < OB_WIRE) {
                return;
        }
 
index 89aa55c..2238688 100644 (file)
@@ -511,7 +511,7 @@ DrawData *DRW_drawdata_ensure(
 
 /* Settings */
 bool DRW_object_is_renderable(const struct Object *ob);
-bool DRW_object_is_visible_in_active_context(const struct Object *ob);
+int DRW_object_visibility_in_active_context(const struct Object *ob);
 bool DRW_object_is_flat_normal(const struct Object *ob);
 bool DRW_object_use_hide_faces(const struct Object *ob);
 
index 5def2b4..a991c51 100644 (file)
@@ -151,7 +151,7 @@ struct DRWTextStore *DRW_text_cache_ensure(void)
 
 bool DRW_object_is_renderable(const Object *ob)
 {
-       BLI_assert(BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE));
+       BLI_assert((ob->base_flag & BASE_VISIBLE) != 0);
 
        if (ob->type == OB_MESH) {
                if ((ob == DST.draw_ctx.object_edit) || BKE_object_is_in_editmode(ob)) {
@@ -171,12 +171,12 @@ bool DRW_object_is_renderable(const Object *ob)
  * Return whether this object is visible depending if
  * we are rendering or drawing in the viewport.
  */
-bool DRW_object_is_visible_in_active_context(const Object *ob)
+int DRW_object_visibility_in_active_context(const Object *ob)
 {
-       const eObjectVisibilityCheck mode = DRW_state_is_scene_render() ?
-                                            OB_VISIBILITY_CHECK_FOR_RENDER :
-                                            OB_VISIBILITY_CHECK_FOR_VIEWPORT;
-       return BKE_object_is_visible(ob, mode);
+       const eEvaluationMode mode = DRW_state_is_scene_render() ?
+                                            DAG_EVAL_RENDER :
+                                            DAG_EVAL_VIEWPORT;
+       return BKE_object_visibility(ob, mode);
 }
 
 bool DRW_object_is_flat_normal(const Object *ob)
@@ -1673,8 +1673,10 @@ bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
 {
        DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
        {
-               if ((ob->type == OB_GPENCIL) && (DRW_object_is_visible_in_active_context(ob))) {
-                       return true;
+               if (ob->type == OB_GPENCIL) {
+                       if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
+                               return true;
+                       }
                }
        }
        DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
index 91e41f7..c050490 100644 (file)
@@ -2271,7 +2271,7 @@ static void DRW_shgroup_relationship_lines(
         Scene *scene,
         Object *ob)
 {
-       if (ob->parent && DRW_object_is_visible_in_active_context(ob->parent)) {
+       if (ob->parent && (DRW_object_visibility_in_active_context(ob->parent) & OB_VISIBLE_SELF)) {
                DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->orig);
                DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
        }
@@ -2279,11 +2279,11 @@ static void DRW_shgroup_relationship_lines(
        if (ob->rigidbody_constraint) {
                Object *rbc_ob1 = ob->rigidbody_constraint->ob1;
                Object *rbc_ob2 = ob->rigidbody_constraint->ob2;
-               if (rbc_ob1 && DRW_object_is_visible_in_active_context(rbc_ob1)) {
+               if (rbc_ob1 && (DRW_object_visibility_in_active_context(rbc_ob1) & OB_VISIBLE_SELF)) {
                        DRW_shgroup_call_dynamic_add(sgl->relationship_lines, rbc_ob1->obmat[3]);
                        DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
                }
-               if (rbc_ob2 && DRW_object_is_visible_in_active_context(rbc_ob2)) {
+               if (rbc_ob2 && (DRW_object_visibility_in_active_context(rbc_ob2) & OB_VISIBLE_SELF)) {
                        DRW_shgroup_call_dynamic_add(sgl->relationship_lines, rbc_ob2->obmat[3]);
                        DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
                }
@@ -2608,13 +2608,14 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
        RegionView3D *rv3d = draw_ctx->rv3d;
        ModifierData *md = NULL;
        int theme_id = TH_UNDEFINED;
+       const int ob_visibility = DRW_object_visibility_in_active_context(ob);
 
        /* Handle particles first in case the emitter itself shouldn't be rendered. */
-       if (ob->type == OB_MESH) {
+       if (ob_visibility & OB_VISIBLE_PARTICLES) {
                OBJECT_cache_populate_particles(ob, psl);
        }
 
-       if (DRW_object_is_visible_in_active_context(ob) == false) {
+       if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
                return;
        }
 
index 606cbe6..524c22a 100644 (file)
@@ -434,7 +434,7 @@ enum {
        OB_DUPLIFACES       = 1 << 9,
        OB_DUPLIFACES_SCALE = 1 << 10,
        OB_DUPLIPARTS       = 1 << 11,
-       OB_RENDER_DUPLI     = 1 << 12,
+       OB_TRANSLFAG_DEPRECATED_2 = 1 << 12,
        OB_NO_CONSTRAINTS   = 1 << 13,  /* runtime constraints disable */
        OB_NO_PSYS_UPDATE   = 1 << 14,  /* hack to work around particle issue */
 
index 1103e5c..d03dfc6 100644 (file)
@@ -46,6 +46,7 @@
 #include "BLI_math.h"
 
 #include "BKE_anim.h"
+#include "BKE_object.h"
 
 #include "DEG_depsgraph_build.h"
 #include "DEG_depsgraph_debug.h"
@@ -79,6 +80,22 @@ static PointerRNA rna_DepsgraphObjectInstance_instance_object_get(PointerRNA *pt
        return rna_pointer_inherit_refine(ptr, &RNA_Object, instance_object);
 }
 
+static bool rna_DepsgraphObjectInstance_show_self_get(PointerRNA *ptr)
+{
+       BLI_Iterator *iterator = ptr->data;
+       DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+       int ob_visibility = BKE_object_visibility(iterator->current, deg_iter->eval_mode);
+       return (ob_visibility & OB_VISIBLE_SELF) != 0;
+}
+
+static bool rna_DepsgraphObjectInstance_show_particles_get(PointerRNA *ptr)
+{
+       BLI_Iterator *iterator = ptr->data;
+       DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+       int ob_visibility = BKE_object_visibility(iterator->current, deg_iter->eval_mode);
+       return (ob_visibility & OB_VISIBLE_PARTICLES) != 0;
+}
+
 static PointerRNA rna_DepsgraphObjectInstance_parent_get(PointerRNA *ptr)
 {
        BLI_Iterator *iterator = ptr->data;
@@ -444,9 +461,19 @@ static void rna_def_depsgraph_instance(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
        RNA_def_property_pointer_funcs(prop, "rna_DepsgraphObjectInstance_object_get", NULL, NULL, NULL);
 
+       prop = RNA_def_property(srna, "show_self", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Show Self", "The object geometry itself should be visible in the render");
+       RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_show_self_get", NULL);
+
+       prop = RNA_def_property(srna, "show_particles", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Show Particles", "Particles part of the object should be visible in the render");
+       RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_show_particles_get", NULL);
+
        prop = RNA_def_property(srna, "is_instance", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Is Instance", "Denotes whether the object is coming from dupli-list");
+       RNA_def_property_ui_text(prop, "Is Instance", "Denotes if the object is generated by another object");
        RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_is_instance_get", NULL);
 
        prop = RNA_def_property(srna, "instance_object", PROP_POINTER, PROP_NONE);
@@ -457,7 +484,7 @@ static void rna_def_depsgraph_instance(BlenderRNA *brna)
 
        prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "Object");
-       RNA_def_property_ui_text(prop, "Parent", "Evaluated parent object of the duplication list");
+       RNA_def_property_ui_text(prop, "Parent", "If the object is an instance, the parent object that generated it");
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
        RNA_def_property_pointer_funcs(prop, "rna_DepsgraphObjectInstance_parent_get", NULL, NULL, NULL);
 
@@ -476,7 +503,7 @@ static void rna_def_depsgraph_instance(BlenderRNA *brna)
 
        prop = RNA_def_property(srna, "random_id", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Dupli random id", "Random id for this dupli object");
+       RNA_def_property_ui_text(prop, "Dupli random id", "Random id for this instance, typically for randomized shading");
        RNA_def_property_int_funcs(prop, "rna_DepsgraphObjectInstance_random_id_get", NULL, NULL);
 
        prop = RNA_def_property(srna, "matrix_world", PROP_FLOAT, PROP_MATRIX);