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--source/blender/blenkernel/intern/layer.c17
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc33
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc16
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc20
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc9
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc71
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_id.cc1
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_id.h4
10 files changed, 143 insertions, 35 deletions
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index fbfa47c8939..0e4a38503ae 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1425,8 +1425,9 @@ void BKE_layer_eval_view_layer(
/* Visibility based on depsgraph mode. */
const eEvaluationMode mode = DEG_get_mode(depsgraph);
- const int base_flag = (mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER;
-
+ const int base_visible_flag = (mode == DAG_EVAL_VIEWPORT)
+ ? BASE_ENABLED_VIEWPORT
+ : BASE_ENABLED_RENDER;
/* Create array of bases, for fast index-based lookup. */
const int num_object_bases = BLI_listbase_count(&view_layer->object_bases);
MEM_SAFE_FREE(view_layer->object_bases_array);
@@ -1435,9 +1436,8 @@ void BKE_layer_eval_view_layer(
int base_index = 0;
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
/* Compute visibility for depsgraph evaluation mode. */
- if (base->flag & base_flag) {
+ if (base->flag & base_visible_flag) {
base->flag |= BASE_ENABLED | BASE_VISIBLE;
-
if (mode == DAG_EVAL_VIEWPORT && (base->flag & BASE_HIDDEN)) {
base->flag &= ~BASE_VISIBLE;
}
@@ -1445,24 +1445,23 @@ void BKE_layer_eval_view_layer(
else {
base->flag &= ~(BASE_ENABLED | BASE_VISIBLE | BASE_SELECTABLE);
}
-
/* If base is not selectabled, clear select. */
if ((base->flag & BASE_SELECTABLE) == 0) {
base->flag &= ~BASE_SELECTED;
}
-
view_layer->object_bases_array[base_index++] = base;
}
-
/* Flush back base flag to the original view layer for editing. */
if (view_layer == DEG_get_evaluated_view_layer(depsgraph)) {
ViewLayer *view_layer_orig = DEG_get_input_view_layer(depsgraph);
Base *base_orig = view_layer_orig->object_bases.first;
const Base *base_eval = view_layer->object_bases.first;
while (base_orig != NULL) {
- base_orig->flag = base_eval->flag;
+ if (base_orig->flag & base_visible_flag) {
+ base_orig->flag = base_eval->flag;
+ base_eval = base_eval->next;
+ }
base_orig = base_orig->next;
- base_eval = base_eval->next;
}
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 637fd5887a0..c705f229669 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -419,7 +419,7 @@ void DepsgraphNodeBuilder::build_id(ID *id)
build_camera((Camera *)id);
break;
case ID_GR:
- build_collection((Collection *)id);
+ build_collection(NULL, (Collection *)id);
break;
case ID_OB:
/* TODO(sergey): Get visibility from a "parent" somehow.
@@ -489,7 +489,9 @@ void DepsgraphNodeBuilder::build_id(ID *id)
}
}
-void DepsgraphNodeBuilder::build_collection(Collection *collection)
+void DepsgraphNodeBuilder::build_collection(
+ LayerCollection *from_layer_collection,
+ Collection *collection)
{
const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT)
? COLLECTION_RESTRICT_VIEW
@@ -497,13 +499,16 @@ void DepsgraphNodeBuilder::build_collection(Collection *collection)
const bool is_collection_restricted = (collection->flag & restrict_flag);
const bool is_collection_visible =
!is_collection_restricted && is_parent_collection_visible_;
+ IDDepsNode *id_node;
if (built_map_.checkIsBuiltAndTag(collection)) {
- IDDepsNode *id_node = find_id_node(&collection->id);
- if (is_collection_visible && !id_node->is_directly_visible) {
+ id_node = find_id_node(&collection->id);
+ if (is_collection_visible &&
+ id_node->is_directly_visible == false &&
+ id_node->is_collection_fully_expanded == true)
+ {
/* Collection became visible, make sure nested collections and
* objects are poked with the new visibility flag, since they
- * might become visible too.
- */
+ * might become visible too. */
}
else {
return;
@@ -511,9 +516,14 @@ void DepsgraphNodeBuilder::build_collection(Collection *collection)
}
else {
/* Collection itself. */
- IDDepsNode *id_node = add_id_node(&collection->id);
+ id_node = add_id_node(&collection->id);
id_node->is_directly_visible = is_collection_visible;
}
+ if (from_layer_collection != NULL) {
+ /* If we came from layer collection we don't go deeper, view layer
+ * builder takes care of going deeper. */
+ return;
+ }
/* Backup state. */
Collection *current_state_collection = collection_;
const bool is_current_parent_collection_visible =
@@ -528,11 +538,12 @@ void DepsgraphNodeBuilder::build_collection(Collection *collection)
}
/* Build child collections. */
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- build_collection(child->collection);
+ build_collection(NULL, child->collection);
}
/* Restore state. */
collection_ = current_state_collection;
is_parent_collection_visible_ = is_current_parent_collection_visible;
+ id_node->is_collection_fully_expanded = true;
}
void DepsgraphNodeBuilder::build_object(int base_index,
@@ -635,7 +646,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
const bool is_current_parent_collection_visible =
is_parent_collection_visible_;
is_parent_collection_visible_ = is_visible;
- build_collection(object->dup_group);
+ build_collection(NULL, object->dup_group);
is_parent_collection_visible_ = is_current_parent_collection_visible;
add_operation_node(&object->id,
DEG_NODE_TYPE_DUPLI,
@@ -1059,7 +1070,7 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
/* objects - simulation participants */
if (rbw->group) {
- build_collection(rbw->group);
+ build_collection(NULL, rbw->group);
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
{
@@ -1137,7 +1148,7 @@ void DepsgraphNodeBuilder::build_particles(Object *object,
break;
case PART_DRAW_GR:
if (part->dup_group != NULL) {
- build_collection(part->dup_group);
+ build_collection(NULL, part->dup_group);
}
break;
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 3c0c5f749ca..3b795bf9d58 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -165,7 +165,8 @@ struct DepsgraphNodeBuilder {
void build_view_layer(Scene *scene,
ViewLayer *view_layer,
eDepsNode_LinkedState_Type linked_state);
- void build_collection(Collection *collection);
+ void build_collection(LayerCollection *from_layer_collection,
+ Collection *collection);
void build_object(int base_index,
Object *object,
eDepsNode_LinkedState_Type linked_state,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 5efa427fcdb..70bd533647c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -75,7 +75,7 @@ void DepsgraphNodeBuilder::build_layer_collections(ListBase *lb)
continue;
}
if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
- build_collection(lc->collection);
+ build_collection(lc, lc->collection);
}
build_layer_collections(&lc->layer_collections);
}
@@ -86,8 +86,9 @@ void DepsgraphNodeBuilder::build_view_layer(
ViewLayer *view_layer,
eDepsNode_LinkedState_Type linked_state)
{
- view_layer_index_ = BLI_findindex(&scene->view_layers, view_layer);
- BLI_assert(view_layer_index_ != -1);
+ /* NOTE: Pass view layer index of 0 since after scene CoW there is
+ * only one view layer in there. */
+ view_layer_index_ = 0;
/* Scene ID block. */
add_id_node(&scene->id);
/* Time source. */
@@ -109,9 +110,14 @@ void DepsgraphNodeBuilder::build_view_layer(
LISTBASE_FOREACH(Base *, base, &view_layer->object_bases) {
/* object itself */
const bool is_object_visible = (base->flag & base_flag);
- build_object(base_index, base->object, linked_state, is_object_visible);
+ if (is_object_visible) {
+ build_object(base_index,
+ base->object,
+ linked_state,
+ is_object_visible);
+ ++base_index;
+ }
base->object->select_color = select_color++;
- ++base_index;
}
build_layer_collections(&view_layer->layer_collections);
if (scene->camera != NULL) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 8080376488b..3fb6138d001 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -434,7 +434,7 @@ void DepsgraphRelationBuilder::build_id(ID *id)
build_camera((Camera *)id);
break;
case ID_GR:
- build_collection(NULL, (Collection *)id);
+ build_collection(NULL, NULL, (Collection *)id);
break;
case ID_OB:
build_object(NULL, (Object *)id);
@@ -486,9 +486,19 @@ void DepsgraphRelationBuilder::build_id(ID *id)
}
void DepsgraphRelationBuilder::build_collection(
+ LayerCollection *from_layer_collection,
Object *object,
Collection *collection)
{
+ if (from_layer_collection != NULL) {
+ /* If we came from layer collection we don't go deeper, view layer
+ * builder takes care of going deeper.
+ *
+ * NOTE: Do early output before tagging build as done, so possbile
+ * subsequent builds from outside of the layer collection properly
+ * recurses into all the nested objects and collections. */
+ return;
+ }
const bool group_done = built_map_.checkIsBuiltAndTag(collection);
OperationKey object_transform_final_key(object != NULL ? &object->id : NULL,
DEG_NODE_TYPE_TRANSFORM,
@@ -500,7 +510,7 @@ void DepsgraphRelationBuilder::build_collection(
build_object(NULL, cob->ob);
}
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- build_collection(NULL, child->collection);
+ build_collection(NULL, NULL, child->collection);
}
}
if (object != NULL) {
@@ -644,7 +654,7 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
}
/* Object dupligroup. */
if (object->dup_group != NULL) {
- build_collection(object, object->dup_group);
+ build_collection(NULL, object, object->dup_group);
}
/* Point caches. */
build_object_pointcache(object);
@@ -1576,7 +1586,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* objects - simulation participants */
if (rbw->group) {
- build_collection(NULL, rbw->group);
+ build_collection(NULL, NULL, rbw->group);
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
{
@@ -1758,7 +1768,7 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
break;
case PART_DRAW_GR:
if (part->dup_group != NULL) {
- build_collection(NULL, part->dup_group);
+ build_collection(NULL, NULL, part->dup_group);
LISTBASE_FOREACH (CollectionObject *, go, &part->dup_group->gobject) {
build_particles_visualization_object(object,
psys,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index e86c6504693..81f21f5bf77 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -206,7 +206,9 @@ struct DepsgraphRelationBuilder
void build_id(ID *id);
void build_layer_collections(ListBase *lb);
void build_view_layer(Scene *scene, ViewLayer *view_layer);
- void build_collection(Object *object, Collection *collection);
+ void build_collection(LayerCollection *from_layer_collection,
+ Object *object,
+ Collection *collection);
void build_object(Base *base, Object *object);
void build_object_flags(Base *base, Object *object);
void build_object_data(Object *object);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index 360e823d1bd..999508cffed 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -79,7 +79,7 @@ void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
continue;
}
if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
- build_collection(NULL, lc->collection);
+ build_collection(lc, NULL, lc->collection);
}
build_layer_collections(&lc->layer_collections);
}
@@ -94,8 +94,13 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la
* passed to the evaluation functions. During relations builder we only
* do NULL-pointer check of the base, so it's fine to pass original one.
*/
+ const int base_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ?
+ BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER;
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
- build_object(base, base->object);
+ const bool is_object_visible = (base->flag & base_flag);
+ if (is_object_visible) {
+ build_object(base, base->object);
+ }
}
build_layer_collections(&view_layer->layer_collections);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 573de18e532..3e3bd91a08c 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -57,6 +57,7 @@
#include "BKE_scene.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "MEM_guardedalloc.h"
@@ -326,6 +327,71 @@ bool scene_copy_inplace_no_main(const Scene *scene, Scene *new_scene)
return result;
}
+/* Remove all view layers but the one which corresponds to an input one. */
+void scene_remove_unused_view_layers(const Depsgraph *depsgraph,
+ Scene *scene_cow)
+{
+ ViewLayer *view_layer_input = depsgraph->view_layer;
+ ViewLayer *view_layer_eval = NULL;
+ /* Find evaluated view layer. At the same time we free memory used by
+ * all other of the view layers. */
+ for (ViewLayer *view_layer_cow =
+ reinterpret_cast<ViewLayer *>(scene_cow->view_layers.first),
+ *view_layer_next;
+ view_layer_cow != NULL;
+ view_layer_cow = view_layer_next)
+ {
+ view_layer_next = view_layer_cow->next;
+ if (STREQ(view_layer_input->name, view_layer_cow->name)) {
+ view_layer_eval = view_layer_cow;
+ }
+ else {
+ BKE_view_layer_free_ex(view_layer_cow, false);
+ }
+ }
+ BLI_assert(view_layer_eval != NULL);
+ /* Make evaluated view layer the only one in the evaluated scene. */
+ view_layer_eval->prev = view_layer_eval->next = NULL;
+ scene_cow->view_layers.first = view_layer_eval;
+ scene_cow->view_layers.last = view_layer_eval;
+}
+
+/* Makes it so given view layer only has bases corresponding to a visible
+ * objects. */
+void view_layer_remove_invisible_bases(const Depsgraph *depsgraph,
+ ViewLayer *view_layer)
+{
+ const int base_visible_flag = (depsgraph->mode == DAG_EVAL_VIEWPORT) ?
+ BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER;
+ ListBase visible_bases = {NULL, NULL};
+ for (Base *base = reinterpret_cast<Base *>(view_layer->object_bases.first),
+ *base_next;
+ base != NULL;
+ base = base_next)
+ {
+ base_next = base->next;
+ const bool is_object_visible = (base->flag & base_visible_flag);
+ if (is_object_visible) {
+ BLI_addtail(&visible_bases, base);
+ }
+ else {
+ MEM_freeN(base);
+ }
+ }
+ view_layer->object_bases = visible_bases;
+}
+
+void scene_cleanup_view_layers(const Depsgraph *depsgraph, Scene *scene_cow)
+{
+ scene_remove_unused_view_layers(depsgraph, scene_cow);
+ view_layer_remove_invisible_bases(
+ depsgraph,
+ reinterpret_cast<ViewLayer *>(scene_cow->view_layers.first));
+ /* TODO(sergey): Remove objects from collections as well.
+ * Not a HUGE deal for now, nobody is looking into those CURRENTLY.
+ * Still not an excuse to have those. */
+}
+
/* Check whether given ID is expanded or still a shallow copy. */
BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
{
@@ -338,7 +404,7 @@ BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
* TODO(sergey): How to make it more robust for the future, so we don't have
* to maintain exception lists all over the code?
*/
-static bool check_datablocks_copy_on_writable(const ID *id_orig)
+bool check_datablocks_copy_on_writable(const ID *id_orig)
{
const ID_Type id_type = GS(id_orig->name);
/* We shouldn't bother if copied ID is same as original one. */
@@ -643,6 +709,9 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
case ID_SCE:
{
done = scene_copy_inplace_no_main((Scene *)id_orig, (Scene *)id_cow);
+ if (done) {
+ scene_cleanup_view_layers(depsgraph, (Scene *)id_cow);
+ }
break;
}
case ID_ME:
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.cc b/source/blender/depsgraph/intern/nodes/deg_node_id.cc
index 808379006af..b194e304e99 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_id.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node_id.cc
@@ -106,6 +106,7 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
previous_eval_flags = 0;
linked_state = DEG_ID_LINKED_INDIRECTLY;
is_directly_visible = true;
+ is_collection_fully_expanded = false;
visible_components_mask = 0;
previously_visible_components_mask = 0;
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.h b/source/blender/depsgraph/intern/nodes/deg_node_id.h
index ed87e7f6ef1..f8d05eddffd 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_id.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node_id.h
@@ -86,6 +86,10 @@ struct IDDepsNode : public DepsNode {
/* Indicates the datablock is visible in the evaluated scene. */
bool is_directly_visible;
+ /* For the collection type of ID, denotes whether collection was fully
+ * recursed into. */
+ bool is_collection_fully_expanded;
+
IDComponentsMask visible_components_mask;
IDComponentsMask previously_visible_components_mask;