Fix duplicator visibility logic

Cycles old behaviour is to hide the duplicator on rendering at all times.

We have since a few months an option in 2.8 to control the duplicator
visibility on its own. However when the duplicator is also duplicated, things
were not working properly.

What we do now is, in addition to the duplicator visibility control, is to not
have the source collection of the duplicator object to ever influence its
visibility when the object is been duplicated.

So if the user wants to reproduce Cycles old behaviour all that is required is
to have different collections, one for the original to-be duplicated objects
that you hide in for the view layer used in the final render. And another
collection with only the first duplicator (which in turn duplicates other
duplicators).

I know this all may sound confusing, so please just give it a try, it's simpler
than it sounds.
This commit is contained in:
Dalai Felinto 2018-02-05 19:01:25 -02:00
parent 354f92a494
commit e75c04898f
Notes: blender-bot 2023-02-14 09:02:40 +01:00
Referenced by issue #53985, New duplication system falls short of a mechanism to hide to be duplicated objects
3 changed files with 15 additions and 7 deletions

View File

@ -267,7 +267,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
ViewLayer *view_layer = ctx->view_layer;
for (Base *base = view_layer->object_bases.first; base; base = base->next, baseid++) {
Object *ob = base->object;
if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) {
if (ob != obedit && is_child(ob, parent)) {
DupliContext pctx;
copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid, false);

View File

@ -91,6 +91,7 @@ typedef struct DEGObjectIterData {
int flag;
eDepsObjectIteratorMode mode;
int visibility_check; /* eObjectVisibilityCheck. */
/* **** Iteration over dupli-list. *** */

View File

@ -110,10 +110,18 @@ 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;
/* Duplicated elements shouldn't care whether their original collection is visible or not. */
temp_dupli_object->base_flag |= BASE_VISIBLED;
if (BKE_object_is_visible(temp_dupli_object, (eObjectVisibilityCheck)data->visibility_check) == false) {
continue;
}
temp_dupli_object->transflag &= ~OB_DUPLI;
if (dob->collection_properties != NULL) {
temp_dupli_object->base_collection_properties = dob->collection_properties;
IDP_MergeGroup(temp_dupli_object->base_collection_properties,
@ -181,11 +189,7 @@ 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) {
if (BKE_object_is_visible(object, (eObjectVisibilityCheck)data->visibility_check) == false) {
return;
}
}
@ -220,6 +224,9 @@ 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;
data->visibility_check = (data->mode == DEG_ITER_OBJECT_MODE_RENDER)
? OB_VISIBILITY_CHECK_FOR_RENDER
: OB_VISIBILITY_CHECK_FOR_VIEWPORT;
DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index];
DEG_iterator_objects_step(iter, id_node);