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 b27de775c546a453b6c4de83a7071e6ee1e3f45d..701dba61b5077e57e1b7c93c6fd16f461c60850a 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 bcab527606021f1d1142ecff38f1fa05ddfea27e..0f9994847c062624c6650436d6fee35e0e6a217e 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 8af0de39a470e7c2ba2fa931d0ae141146db0dee..7290ea0cee0e66b9b73da51f78bdddf47b383adb 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 0b405b52a172c469fc1af4d854ef0e4a33adebf7..50e095720e0614ff2c3726a26f0b9c3177bb4a98 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 3d341f5d82fb8401523d67c0b3c559066d056643..fd047c50d2cce17c9eb762bd0895a31c4962cce5 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 c9fa6b0a03542eddd3f7eea48fe3575b964a90f8..11a4ebee8c63e9cb778961b635bcc6dff7e4267b 100644 (file)
@@ -118,7 +118,7 @@ typedef struct DEGObjectIterData {
 
        struct Scene *scene;
 
-       int visibility_check; /* eObjectVisibilityCheck. */
+       eEvaluationMode eval_mode;
 
        /* **** Iteration over dupli-list. *** */
 
index 52c4ab33dc6cd898e70049672055bc5b3bb104ff..88dc74419e5091a7c86ea0fadfeca45cf9a9396f 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 aa2cf3fede3d2f5153d8a216741d1d41c15ee1fb..6a2ca982d53209071ba7f313499f2f02c31f27f9 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 71082268f10dd05483eb98f941ca6f8dc66fa3a7..74cac25367cba3fa170d0b607be3365d6da37cae 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 8d196ee07eb5d0fd1335b2b759806fff346e4ba6..45bfba09890bad891a0bfd0ba8af9bfa61ad3ab8 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 23c539774453145e3d18519fbc533e53a883f34f..79724f6a5d2a6ff31252e0d254613e56e81db19d 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 51a8209fbf2ce1ad77d8bd3ad73badf3a12b4429..1fe008e4d444a968032dbdb2949fbccc7fc49963 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 c3b469674d37a233a95d1939301c94d804d595ee..52caeb6cbf433ab471c0afce1224c4e05171f62c 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 ca02cc2b5ea2fafb2d84c84ab14e94274b76f9ec..6c955ac1fcb72db458119cdd7b6283a69a100dcb 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 89aa55c56b20881541a5e4d22ae4039b530876f0..223868890f272c2730a6aec5929d4c43f4aa2b5d 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 5def2b4146177ec5df1aa9f3b68263a71d01a8ad..a991c51a7c31a916c1945fd625a85e81fa3ab04d 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 91e41f75bedf4281299ab80d1ddd5208f63516b3..c050490124342c16dabd1bfc3916dd714b123828 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 606cbe66d0d20281c5cecafee8a8fbc88c872f3d..524c22a678d8f76ff5610277c2c09c5d48e1d20e 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 1103e5c1f927abdea4b45c1251047106e4f9d8a4..d03dfc65ef40d022381d44156d750d070db6a90a 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);