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:
authorSergey Sharybin <sergey.vfx@gmail.com>2020-03-23 13:38:07 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2020-03-23 19:19:44 +0300
commited386507e19543decf2422e96610284da8c98112 (patch)
tree9feb0489e8f4d70fdfe12cd7702288a7104c64e7
parent58ac113b76d950c72c7319094f7e6cc61c70dc59 (diff)
Fix T74984: Crash opening specific production files
More detailed symptoms: there was no curve cache created for an object which was used by draw manager. A bit tricky situation, which involves collection instances and their proxies. The root of the problem in the dependency graph was that instanced collections visibility was not updated when object is requested with different visibility. So what was happening is that one of the objects was pulled as an indirect dependency of something invisible, so it built instanced collections as if the instancer is invisible. After that the same object was built as visible. Before this fix this was only update object flags, the instanced collections still believed they are invisible. Since there is no path via relations which would connect visible object with instanced objects the visibility flush which is happening during graph finalization did not "fix" the visibility flags. This change makes it so instanced collections are updating their visibility when their instancer's visibility is changing to truth. This is similar to how collections will accumulate their visibility when same collection is used from multiple ones with different visibility. However, this alone wasn't enough to get crash fixed. This marked collections as visible, but the geometry component of the curve object was still considering self as invisible. This is something tricky, since the code which is responsible for this issue was added as an optimization in afb4da6650d. This looks like like an oversight in that commit since it's rather weird that ID node's flag would depend on construction order (in "normal" object builder the ID node's directly_visible flag is initialized to object's visibility). So it seems logical to get this part of code in sync between "regular" and "accumulative" object builder. And last but not least the naming is_directly_visible is old and does not really represent what it actually mans now: a more correct name would be "will be used by the draw manager". Differential Revision: https://developer.blender.org/D7217
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc35
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h1
2 files changed, 26 insertions, 10 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 2912d3aecd7..70cf0f757bc 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -551,21 +551,28 @@ void DepsgraphNodeBuilder::build_object(int base_index,
object->proxy->proxy_from = object;
}
const bool has_object = built_map_.checkIsBuiltAndTag(object);
- /* Skip rest of components if the ID node was already there. */
+
+ /* When there is already object in the dependency graph accumulate visibility an linked state
+ * flags. Only do it on the object itself (apart from very special cases) and leave dealing with
+ * visibility of dependnecies to the visibility flush step which happens at the end of the build
+ * process. */
if (has_object) {
IDNode *id_node = find_id_node(&object->id);
- /* We need to build some extra stuff if object becomes linked
- * directly. */
if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
build_object_flags(base_index, object, linked_state);
}
id_node->linked_state = max(id_node->linked_state, linked_state);
- if (id_node->linked_state == DEG_ID_LINKED_DIRECTLY) {
- id_node->is_directly_visible |= is_visible;
- }
+ id_node->is_directly_visible |= is_visible;
id_node->has_base |= (base_index != -1);
+
+ /* There is no relation path which will connect current object with all the ones which come
+ * via the instanced collection, so build the collection again. Note that it will do check
+ * whether visibility update is needed on its own. */
+ build_object_instance_collection(object, is_visible);
+
return;
}
+
/* Create ID node for object and begin init. */
IDNode *id_node = add_id_node(&object->id);
Object *object_cow = get_cow_datablock(object);
@@ -636,10 +643,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
build_object_proxy_group(object, is_visible);
/* Object dupligroup. */
if (object->instance_collection != nullptr) {
- const bool is_current_parent_collection_visible = is_parent_collection_visible_;
- is_parent_collection_visible_ = is_visible;
- build_collection(nullptr, object->instance_collection);
- is_parent_collection_visible_ = is_current_parent_collection_visible;
+ build_object_instance_collection(object, is_visible);
OperationNode *op_node = add_operation_node(
&object->id, NodeType::DUPLI, OperationCode::DUPLI);
op_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
@@ -690,6 +694,17 @@ void DepsgraphNodeBuilder::build_object_proxy_group(Object *object, bool is_visi
build_object(-1, object->proxy_group, DEG_ID_LINKED_INDIRECTLY, is_visible);
}
+void DepsgraphNodeBuilder::build_object_instance_collection(Object *object, bool is_object_visible)
+{
+ if (object->instance_collection == nullptr) {
+ return;
+ }
+ const bool is_current_parent_collection_visible = is_parent_collection_visible_;
+ is_parent_collection_visible_ = is_object_visible;
+ build_collection(nullptr, object->instance_collection);
+ is_parent_collection_visible_ = is_current_parent_collection_visible;
+}
+
void DepsgraphNodeBuilder::build_object_data(Object *object, bool is_object_visible)
{
if (object->data == nullptr) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 7ddd8d0ade0..7fcc8b431e7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -164,6 +164,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
bool is_visible);
virtual void build_object_proxy_from(Object *object, bool is_object_visible);
virtual void build_object_proxy_group(Object *object, bool is_object_visible);
+ virtual void build_object_instance_collection(Object *object, bool is_object_visible);
virtual void build_object_flags(int base_index,
Object *object,
eDepsNode_LinkedState_Type linked_state);