Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/blender/blender_object.cpp20
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py1
-rw-r--r--source/blender/blenkernel/BKE_object.h9
-rw-r--r--source/blender/blenkernel/intern/object.c28
-rw-r--r--source/blender/blenkernel/intern/particle.c2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c25
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h13
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc17
-rw-r--r--source/blender/draw/engines/clay/clay_engine.c71
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c4
-rw-r--r--source/blender/draw/intern/DRW_render.h3
-rw-r--r--source/blender/draw/intern/draw_manager.c30
-rw-r--r--source/blender/draw/modes/object_mode.c13
-rw-r--r--source/blender/editors/space_view3d/drawobject.c5
-rw-r--r--source/blender/makesdna/DNA_object_types.h8
-rw-r--r--source/blender/makesrna/intern/rna_depsgraph.c2
-rw-r--r--source/blender/makesrna/intern/rna_layer.c2
-rw-r--r--source/blender/makesrna/intern/rna_object.c16
-rw-r--r--source/blender/makesrna/intern/rna_particle.c5
-rw-r--r--source/blender/render/intern/source/convertblender.c3
21 files changed, 215 insertions, 69 deletions
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 0c29c606df8..6564eea4767 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -469,6 +469,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;
@@ -478,20 +479,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();
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 23787756121..de608c42cb5 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -278,6 +278,13 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel):
col.label(text="Object Color:")
col.prop(obj, "color", text="")
+ col = layout.column()
+ col.active = bool(is_dupli or obj.particle_systems)
+ col.label(text="Duplicator Visibility:")
+ row = col.row(align=True)
+ row.prop(obj, "show_duplicator_for_viewport", text="Viewport")
+ row.prop(obj, "show_duplicator_for_render", text="Render")
+
class OBJECT_PT_duplication(ObjectButtonsPanel, Panel):
bl_label = "Duplication"
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index a5793e6d9a9..fda3096a3f5 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -926,7 +926,6 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
split = layout.split()
col = split.column()
- col.prop(part, "use_render_emitter")
col.prop(part, "use_parent_particles")
col = split.column()
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 2b183906f57..d98c52aa91a 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -82,7 +82,14 @@ bool BKE_object_exists_check(struct Object *obtest);
bool BKE_object_is_in_editmode(struct Object *ob);
bool BKE_object_is_in_editmode_vgroup(struct Object *ob);
bool BKE_object_is_in_wpaint_select_vert(struct Object *ob);
-bool BKE_object_is_visible(struct Object *ob);
+
+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(struct Object *ob, const eObjectVisibilityCheck mode);
void BKE_object_init(struct Object *ob);
struct Object *BKE_object_add_only_object(
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 66c87ac7a5c..923cea6acff 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -552,11 +552,32 @@ bool BKE_object_is_in_wpaint_select_vert(Object *ob)
/**
* Return if the object is visible, as evaluated by depsgraph
- * Keep in sync with rna_object.c (object.is_visible).
*/
-bool BKE_object_is_visible(Object *ob)
+bool BKE_object_is_visible(Object *ob, const eObjectVisibilityCheck mode)
{
- return (ob->base_flag & BASE_VISIBLED) != 0;
+ if ((ob->base_flag & BASE_VISIBLED) == 0) {
+ return false;
+ }
+
+ if (mode == OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) {
+ return true;
+ }
+
+ if (((ob->transflag & OB_DUPLI) == 0) &&
+ (ob->particlesystem.first == NULL))
+ {
+ return true;
+ }
+
+ 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;
+ }
}
bool BKE_object_exists_check(Object *obtest)
@@ -684,6 +705,7 @@ void BKE_object_init(Object *ob)
ob->col_group = 0x01;
ob->col_mask = 0xffff;
ob->preview = NULL;
+ ob->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT | OB_DUPLI_FLAG_RENDER;
/* NT fluid sim defaults */
ob->fluidsimSettings = NULL;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index a161dd4fac3..77c648e53fe 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3279,7 +3279,7 @@ static void default_particle_settings(ParticleSettings *part)
part->clength = 1.0f;
part->clength_thres = 0.0f;
- part->draw = PART_DRAW_EMITTER;
+ part->draw = 0;
part->draw_line[0] = 0.5;
part->path_start = 0.0f;
part->path_end = 1.0f;
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 944ddf1763d..547ae6709b2 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -45,6 +45,7 @@
#include "DNA_lightprobe_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
@@ -855,4 +856,28 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+
+ {
+ if (!DNA_struct_elem_find(fd->filesdna, "Object", "char", "duplicator_visibility_flag")) {
+ for (Object *object = main->object.first; object; object = object->id.next) {
+ if (object->particlesystem.first) {
+ bool show_emitter = false;
+ for (ParticleSystem *psys = object->particlesystem.first; psys; psys=psys->next) {
+ show_emitter |= (psys->part->draw & PART_DRAW_EMITTER) != 0;
+ }
+
+ object->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT;
+ if (show_emitter) {
+ object->duplicator_visibility_flag |= OB_DUPLI_FLAG_RENDER;
+ }
+ }
+ else if (object->transflag & OB_DUPLI){
+ object->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT;
+ }
+ else {
+ object->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT | OB_DUPLI_FLAG_RENDER;
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index c782a91f76e..83fb100436c 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -77,12 +77,18 @@ enum {
DEG_ITER_OBJECT_FLAG_DUPLI = (1 << 4),
};
+typedef enum eDepsObjectIteratorMode {
+ DEG_ITER_OBJECT_MODE_VIEWPORT = 0,
+ DEG_ITER_OBJECT_MODE_RENDER = 1,
+} eDepsObjectIteratorMode;
+
typedef struct DEGObjectIterData {
struct Depsgraph *graph;
struct Scene *scene;
struct EvaluationContext eval_ctx;
int flag;
+ eDepsObjectIteratorMode mode;
/* **** Iteration over dupli-list. *** */
@@ -115,10 +121,11 @@ void DEG_iterator_objects_end(struct BLI_Iterator *iter);
* Although they are available they have no overrides (collection_properties)
* and will crash if you try to access it.
*/
-#define DEG_OBJECT_ITER(graph_, instance_, flag_) \
+#define DEG_OBJECT_ITER(graph_, instance_, mode_, flag_) \
{ \
DEGObjectIterData data_ = { \
.graph = (graph_), \
+ .mode = (mode_), \
.flag = (flag_), \
}; \
\
@@ -134,8 +141,8 @@ void DEG_iterator_objects_end(struct BLI_Iterator *iter);
/**
* Depsgraph objects iterator for draw manager and final render
*/
-#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE(graph_, instance_) \
- DEG_OBJECT_ITER(graph_, instance_, \
+#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE(graph_, instance_, mode_) \
+ DEG_OBJECT_ITER(graph_, instance_, mode_, \
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | \
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | \
DEG_ITER_OBJECT_FLAG_VISIBLE | \
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 2a323fe63bd..42d512d473c 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -84,6 +84,7 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
Object *dupli_parent = data->dupli_parent;
Object *temp_dupli_object = &data->temp_dupli_object;
*temp_dupli_object = *dob->ob;
+ temp_dupli_object->transflag &= ~OB_DUPLI;
temp_dupli_object->select_color = dupli_parent->select_color;
temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROMDUPLI;
@@ -139,7 +140,7 @@ static void DEG_iterator_objects_step(BLI_Iterator *iter, DEG::IDDepsNode *id_no
Object *object = (Object *)id_node->id_cow;
BLI_assert(DEG::deg_validate_copy_on_write_datablock(&object->id));
- if ((BKE_object_is_visible(object) == false) &&
+ if ((BKE_object_is_visible(object, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) == false) &&
((data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) != 0))
{
return;
@@ -149,6 +150,14 @@ static void DEG_iterator_objects_step(BLI_Iterator *iter, DEG::IDDepsNode *id_no
data->dupli_parent = object;
data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, object);
data->dupli_object_next = (DupliObject *)data->dupli_list->first;
+
+ const eObjectVisibilityCheck mode = (data->mode == DEG_ITER_OBJECT_MODE_RENDER) ?
+ OB_VISIBILITY_CHECK_FOR_RENDER :
+ OB_VISIBILITY_CHECK_FOR_VIEWPORT;
+
+ if (BKE_object_is_visible(object, mode) == false) {
+ return;
+ }
}
iter->current = object;
@@ -167,7 +176,10 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
}
/* TODO(sergey): What evaluation type we want here? */
- DEG_evaluation_context_init(&data->eval_ctx, DAG_EVAL_RENDER);
+ /* TODO(dfelinto): Get rid of evaluation context here, it's only used to do
+ * direct dupli-objects update in group.c. Which is terribly bad, and all
+ * objects are expected to be evaluated already. */
+ DEG_evaluation_context_init(&data->eval_ctx, DAG_EVAL_VIEWPORT);
data->eval_ctx.view_layer = DEG_get_evaluated_view_layer(depsgraph);
iter->data = data;
@@ -193,6 +205,7 @@ void DEG_iterator_objects_next(BLI_Iterator *iter)
Depsgraph *depsgraph = data->graph;
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
do {
+ iter->skip = false;
if (data->dupli_list) {
if (deg_objects_dupli_iterator_next(iter)) {
return;
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index 01f89ae6b1c..9f9ebd692b9 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -746,12 +746,45 @@ static void clay_cache_init(void *vedata)
}
}
+static void clay_cache_populate_particles(void *vedata, Object *ob)
+{
+ CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
+ CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+
+ Scene *scene = draw_ctx->scene;
+ Object *obedit = scene->obedit;
+
+ if (ob != obedit) {
+ for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
+ if (psys_check_enabled(ob, psys, false)) {
+ ParticleSettings *part = psys->part;
+ int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+
+ if (draw_as == PART_DRAW_PATH && !psys->pathcache && !psys->childcache) {
+ draw_as = PART_DRAW_DOT;
+ }
+
+ static float mat[4][4];
+ unit_m4(mat);
+
+ if (draw_as == PART_DRAW_PATH) {
+ struct Gwn_Batch *geom = DRW_cache_particles_get_hair(psys, NULL);
+ DRWShadingGroup *hair_shgrp = CLAY_hair_shgrp_get(vedata, ob, stl, psl);
+ DRW_shgroup_call_add(hair_shgrp, geom, mat);
+ }
+ }
+ }
+ }
+}
+
static void clay_cache_populate(void *vedata, Object *ob)
{
CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
- DRWShadingGroup *clay_shgrp, *hair_shgrp;
+ DRWShadingGroup *clay_shgrp;
if (!DRW_object_is_renderable(ob))
return;
@@ -764,6 +797,15 @@ static void clay_cache_populate(void *vedata, Object *ob)
}
}
+ /* Handle particles first in case the emitter itself shouldn't be rendered. */
+ if (ob->type == OB_MESH) {
+ clay_cache_populate_particles(vedata, ob);
+ }
+
+ if (DRW_check_object_visible_within_active_context(ob) == false) {
+ return;
+ }
+
struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
@@ -797,33 +839,6 @@ static void clay_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
}
}
-
- if (ob->type == OB_MESH) {
- Scene *scene = draw_ctx->scene;
- Object *obedit = scene->obedit;
-
- if (ob != obedit) {
- for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
- if (psys_check_enabled(ob, psys, false)) {
- ParticleSettings *part = psys->part;
- int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
-
- if (draw_as == PART_DRAW_PATH && !psys->pathcache && !psys->childcache) {
- draw_as = PART_DRAW_DOT;
- }
-
- static float mat[4][4];
- unit_m4(mat);
-
- if (draw_as == PART_DRAW_PATH) {
- geom = DRW_cache_particles_get_hair(psys, NULL);
- hair_shgrp = CLAY_hair_shgrp_get(vedata, ob, stl, psl);
- DRW_shgroup_call_add(hair_shgrp, geom, mat);
- }
- }
- }
- }
- }
}
static void clay_cache_finish(void *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index b5806c9f8af..31ce5d4174d 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -113,6 +113,10 @@ static void eevee_cache_populate(void *vedata, Object *ob)
}
}
+ if (DRW_check_object_visible_within_active_context(ob) == false) {
+ return;
+ }
+
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
EEVEE_materials_cache_populate(vedata, sldata, ob);
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 868c9ed1ebf..505371d8e3b 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -396,6 +396,7 @@ void DRW_lamp_engine_data_free(struct LampEngineData *led);
/* Settings */
bool DRW_object_is_renderable(struct Object *ob);
+bool DRW_check_object_visible_within_active_context(struct Object *ob);
bool DRW_object_is_flat_normal(const struct Object *ob);
int DRW_object_is_mode_shade(const struct Object *ob);
@@ -433,6 +434,8 @@ bool DRW_state_show_text(void);
bool DRW_state_draw_support(void);
bool DRW_state_draw_background(void);
+enum eDepsObjectIteratorMode DRW_iterator_mode_get(void);
+
struct DRWTextStore *DRW_state_text_cache_get(void);
/* Avoid too many lookups while drawing */
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 80e11c2ac8b..76a92be98d9 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -2215,7 +2215,7 @@ bool DRW_object_is_renderable(Object *ob)
Scene *scene = DST.draw_ctx.scene;
Object *obedit = scene->obedit;
- BLI_assert(BKE_object_is_visible(ob));
+ BLI_assert(BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE));
if (ob->type == OB_MESH) {
if (ob == obedit) {
@@ -2234,6 +2234,18 @@ bool DRW_object_is_renderable(Object *ob)
return true;
}
+/**
+ * Return whether this object is visible depending if
+ * we are rendering or drawing in the viewport.
+ */
+bool DRW_check_object_visible_within_active_context(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);
+}
+
bool DRW_object_is_flat_normal(const Object *ob)
{
if (ob->type == OB_MESH) {
@@ -2245,7 +2257,6 @@ bool DRW_object_is_flat_normal(const Object *ob)
return true;
}
-
/**
* Return true if the object has its own draw mode.
* Caller must check this is active */
@@ -3403,7 +3414,7 @@ void DRW_draw_render_loop_ex(
PROFILE_START(stime);
drw_engines_cache_init();
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE(graph, ob)
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE(graph, ob, DRW_iterator_mode_get())
{
drw_engines_cache_populate(ob);
}
@@ -3620,7 +3631,7 @@ void DRW_draw_select_loop(
drw_engines_cache_populate(scene->obedit);
}
else {
- DEG_OBJECT_ITER(graph, ob,
+ DEG_OBJECT_ITER(graph, ob, DRW_iterator_mode_get(),
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_DUPLI)
@@ -3715,7 +3726,7 @@ void DRW_draw_depth_loop(
if (cache_is_dirty) {
drw_engines_cache_init();
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE(graph, ob)
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE(graph, ob, DRW_iterator_mode_get())
{
drw_engines_cache_populate(ob);
}
@@ -3801,6 +3812,15 @@ bool DRW_state_is_scene_render(void)
}
/**
+ * Gives you the iterator mode to use for depsgraph.
+ */
+eDepsObjectIteratorMode DRW_iterator_mode_get(void)
+{
+ return DRW_state_is_scene_render() ? DEG_ITER_OBJECT_MODE_RENDER :
+ DEG_ITER_OBJECT_MODE_VIEWPORT;
+}
+
+/**
* Should text draw in this mode?
*/
bool DRW_state_show_text(void)
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 3d84611f94d..e3800d87a53 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -1648,7 +1648,7 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl
static void DRW_shgroup_relationship_lines(OBJECT_StorageList *stl, Object *ob)
{
- if (ob->parent && BKE_object_is_visible(ob->parent)) {
+ if (ob->parent && DRW_check_object_visible_within_active_context(ob->parent)) {
DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->obmat[3]);
DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->parent->obmat[3]);
}
@@ -1763,6 +1763,15 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
View3D *v3d = draw_ctx->v3d;
int theme_id = TH_UNDEFINED;
+ /* Handle particles first in case the emitter itself shouldn't be rendered. */
+ if (ob->type == OB_MESH) {
+ OBJECT_cache_populate_particles(ob, psl);
+ }
+
+ if (DRW_check_object_visible_within_active_context(ob) == false) {
+ return;
+ }
+
//CollectionEngineSettings *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
//bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire");
@@ -1800,8 +1809,6 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
}
}
}
-
- OBJECT_cache_populate_particles(ob, psl);
break;
}
case OB_SURF:
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index c1e45f8280f..50d3593aef6 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -9217,7 +9217,10 @@ afterdraw:
/* help lines and so */
if (ob != scene->obedit && ob->parent) {
- if (BKE_object_is_visible(ob->parent)) {
+ const eObjectVisibilityCheck mode = eval_ctx->mode != DAG_EVAL_VIEWPORT ?
+ OB_VISIBILITY_CHECK_FOR_RENDER :
+ OB_VISIBILITY_CHECK_FOR_VIEWPORT;
+ if (BKE_object_is_visible(ob->parent, mode)) {
setlinestyle(3);
immBegin(GWN_PRIM_LINES, 2);
immVertex3fv(pos, ob->obmat[3]);
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 79cf5040d9e..dae0a057450 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -208,7 +208,7 @@ typedef struct Object {
/* did last modifier stack generation need mapping support? */
char lastNeedMapping; /* bool */
- char pad;
+ char duplicator_visibility_flag;
/* dupli-frame settings */
int dupon, dupoff, dupsta, dupend;
@@ -708,6 +708,12 @@ enum {
OB_LOCK_ROT4D = 1 << 10,
};
+/* ob->duplicator_visibility_flag */
+enum {
+ OB_DUPLI_FLAG_VIEWPORT = 1 << 0,
+ OB_DUPLI_FLAG_RENDER = 1 << 1,
+};
+
/* ob->mode */
typedef enum eObjectMode {
OB_MODE_OBJECT = 0,
diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index 20ce54a4a01..706fb23ab56 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -168,6 +168,7 @@ static void rna_Depsgraph_objects_begin(CollectionPropertyIterator *iter, Pointe
data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
+ data->mode = DEG_ITER_OBJECT_MODE_RENDER;
((BLI_Iterator *)iter->internal.custom)->valid = true;
DEG_iterator_objects_begin(iter->internal.custom, data);
@@ -208,6 +209,7 @@ static void rna_Depsgraph_duplis_begin(CollectionPropertyIterator *iter, Pointer
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_DUPLI;
+ data->mode = DEG_ITER_OBJECT_MODE_RENDER;
((BLI_Iterator *)iter->internal.custom)->valid = true;
DEG_iterator_objects_begin(iter->internal.custom, data);
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 00b08957fdd..f64cfef45df 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -870,7 +870,7 @@ static void rna_LayerObjects_selected_begin(CollectionPropertyIterator *iter, Po
static void rna_ViewLayer_update_tagged(ViewLayer *UNUSED(view_layer), bContext *C)
{
Depsgraph *graph = CTX_data_depsgraph(C);
- DEG_OBJECT_ITER(graph, ob,
+ DEG_OBJECT_ITER(graph, ob, DEG_ITER_OBJECT_MODE_VIEWPORT,
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY |
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 786598b0731..b83b793b431 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -232,7 +232,13 @@ static void rna_Object_hide_update(Main *bmain, Scene *UNUSED(scene), PointerRNA
static int rna_Object_is_visible_get(PointerRNA *ptr)
{
Object *ob = ptr->id.data;
- return BKE_object_is_visible(ob);
+ /* The duplicators final visibility is not evaluated by depsgraph, so it's
+ * in ob->base_flag & VISIBLED. Instead we need to take into account whether
+ * we are rendering or not, and the ob->duplicator_visibility_flag.
+ * However for this assessor we don't know if we are rendering, so we just
+ * ignore the duplicator visibility
+ */
+ return BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE);
}
static void rna_Object_collection_properties_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@@ -2798,6 +2804,14 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update");
+ prop = RNA_def_property(srna, "show_duplicator_for_render", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "duplicator_visibility_flag", OB_DUPLI_FLAG_RENDER);
+ RNA_def_property_ui_text(prop, "Render Duplicator", "Make duplicator visible when rendering");
+
+ prop = RNA_def_property(srna, "show_duplicator_for_viewport", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "duplicator_visibility_flag", OB_DUPLI_FLAG_VIEWPORT);
+ RNA_def_property_ui_text(prop, "Show Duplicator", "Make duplicator visible in the viewport");
+
prop = RNA_def_property(srna, "is_visible", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Object_is_visible_get", NULL);
RNA_def_property_ui_text(prop, "Visible", "Visible to camera rays, set only on objects evaluated by depsgraph");
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 67eaa22fbe4..12e56b8e926 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -2292,11 +2292,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Size", "Show particle size");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
- prop = RNA_def_property(srna, "use_render_emitter", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_EMITTER);
- RNA_def_property_ui_text(prop, "Emitter", "Render emitter Object also");
- RNA_def_property_update(prop, 0, "rna_Particle_redo");
-
prop = RNA_def_property(srna, "show_health", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_HEALTH);
RNA_def_property_ui_text(prop, "Health", "Draw boid health");
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 74de3fcded6..fc60c70c2c4 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -4668,9 +4668,8 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
/* the emitter has to be processed first (render levels of modifiers) */
/* so here we only check if the emitter should be rendered */
if (ob->particlesystem.first) {
- show_emitter= 0;
+ show_emitter = (ob->duplicator_visibility_flag & OB_DUPLI_FLAG_RENDER) != 0;
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
- show_emitter += psys->part->draw & PART_DRAW_EMITTER;
if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) {
psys_has_renderdata |= (psys->renderdata != NULL);
psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);