Changeset View
Changeset View
Standalone View
Standalone View
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
| Show First 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | if (deg_copy_on_write_is_needed(id_type)) { | ||||
| graph_->operations.append(op_cow); | graph_->operations.append(op_cow); | ||||
| } | } | ||||
| ComponentNode *visibility_component = id_node->add_component(NodeType::VISIBILITY); | ComponentNode *visibility_component = id_node->add_component(NodeType::VISIBILITY); | ||||
| OperationNode *visibility_operation = visibility_component->add_operation( | OperationNode *visibility_operation = visibility_component->add_operation( | ||||
| nullptr, OperationCode::OPERATION, "", -1); | nullptr, OperationCode::OPERATION, "", -1); | ||||
| /* Pin the node so that it and its relations are preserved by the unused nodes/relations | /* Pin the node so that it and its relations are preserved by the unused nodes/relations | ||||
| * deletion. This is mainly to make it easier to debug visibility. */ | * deletion. This is mainly to make it easier to debug visibility. */ | ||||
| /* NOTE: Keep un-pinned for the 3.0 release. This way we are more sure that side effects of the | visibility_operation->flag |= OperationFlag::DEPSOP_FLAG_PINNED; | ||||
| * change is minimal outside of the dependency graph area. */ | |||||
| // visibility_operation->flag |= OperationFlag::DEPSOP_FLAG_PINNED; | |||||
| graph_->operations.append(visibility_operation); | graph_->operations.append(visibility_operation); | ||||
| } | } | ||||
| return id_node; | return id_node; | ||||
| } | } | ||||
| IDNode *DepsgraphNodeBuilder::find_id_node(ID *id) | IDNode *DepsgraphNodeBuilder::find_id_node(ID *id) | ||||
| { | { | ||||
| return graph_->find_id_node(id); | return graph_->find_id_node(id); | ||||
| ▲ Show 20 Lines • Show All 371 Lines • ▼ Show 20 Lines | switch (id_type) { | ||||
| case ID_ME: | case ID_ME: | ||||
| case ID_MB: | case ID_MB: | ||||
| case ID_CU: | case ID_CU: | ||||
| case ID_LT: | case ID_LT: | ||||
| case ID_GD: | case ID_GD: | ||||
| case ID_HA: | case ID_HA: | ||||
| case ID_PT: | case ID_PT: | ||||
| case ID_VO: | case ID_VO: | ||||
| /* TODO(sergey): Get visibility from a "parent" somehow. | build_object_data_geometry_datablock(id); | ||||
| * | |||||
| * NOTE: Similarly to above, we don't want false-positives on | |||||
| * visibility. */ | |||||
| build_object_data_geometry_datablock(id, false); | |||||
| break; | break; | ||||
| case ID_SPK: | case ID_SPK: | ||||
| build_speaker((Speaker *)id); | build_speaker((Speaker *)id); | ||||
| break; | break; | ||||
| case ID_SO: | case ID_SO: | ||||
| build_sound((bSound *)id); | build_sound((bSound *)id); | ||||
| break; | break; | ||||
| case ID_TXT: | case ID_TXT: | ||||
| ▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | void DepsgraphNodeBuilder::build_object(int base_index, | ||||
| /* Parent. */ | /* Parent. */ | ||||
| if (object->parent != nullptr) { | if (object->parent != nullptr) { | ||||
| build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY, is_visible); | build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY, is_visible); | ||||
| } | } | ||||
| /* Modifiers. */ | /* Modifiers. */ | ||||
| if (object->modifiers.first != nullptr) { | if (object->modifiers.first != nullptr) { | ||||
| BuilderWalkUserData data; | BuilderWalkUserData data; | ||||
| data.builder = this; | data.builder = this; | ||||
| data.is_parent_visible = is_visible; | |||||
| BKE_modifiers_foreach_ID_link(object, modifier_walk, &data); | BKE_modifiers_foreach_ID_link(object, modifier_walk, &data); | ||||
| } | } | ||||
| /* Grease Pencil Modifiers. */ | /* Grease Pencil Modifiers. */ | ||||
| if (object->greasepencil_modifiers.first != nullptr) { | if (object->greasepencil_modifiers.first != nullptr) { | ||||
| BuilderWalkUserData data; | BuilderWalkUserData data; | ||||
| data.builder = this; | data.builder = this; | ||||
| data.is_parent_visible = is_visible; | |||||
| BKE_gpencil_modifiers_foreach_ID_link(object, modifier_walk, &data); | BKE_gpencil_modifiers_foreach_ID_link(object, modifier_walk, &data); | ||||
| } | } | ||||
| /* Shader FX. */ | /* Shader FX. */ | ||||
| if (object->shader_fx.first != nullptr) { | if (object->shader_fx.first != nullptr) { | ||||
| BuilderWalkUserData data; | BuilderWalkUserData data; | ||||
| data.builder = this; | data.builder = this; | ||||
| data.is_parent_visible = is_visible; | |||||
| BKE_shaderfx_foreach_ID_link(object, modifier_walk, &data); | BKE_shaderfx_foreach_ID_link(object, modifier_walk, &data); | ||||
| } | } | ||||
| /* Constraints. */ | /* Constraints. */ | ||||
| if (object->constraints.first != nullptr) { | if (object->constraints.first != nullptr) { | ||||
| BuilderWalkUserData data; | BuilderWalkUserData data; | ||||
| data.builder = this; | data.builder = this; | ||||
| data.is_parent_visible = is_visible; | |||||
| BKE_constraints_id_loop(&object->constraints, constraint_walk, &data); | BKE_constraints_id_loop(&object->constraints, constraint_walk, &data); | ||||
| } | } | ||||
| /* Object data. */ | /* Object data. */ | ||||
| build_object_data(object, is_visible); | build_object_data(object); | ||||
| /* Parameters, used by both drivers/animation and also to inform dependency | /* Parameters, used by both drivers/animation and also to inform dependency | ||||
| * from object's data. */ | * from object's data. */ | ||||
| build_parameters(&object->id); | build_parameters(&object->id); | ||||
| build_idproperties(object->id.properties); | build_idproperties(object->id.properties); | ||||
| /* Build animation data, | /* Build animation data, | ||||
| * | * | ||||
| * Do it now because it's possible object data will affect | * Do it now because it's possible object data will affect | ||||
| * on object's level animation, for example in case of rebuilding | * on object's level animation, for example in case of rebuilding | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | if (object->instance_collection == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| const bool is_current_parent_collection_visible = is_parent_collection_visible_; | const bool is_current_parent_collection_visible = is_parent_collection_visible_; | ||||
| is_parent_collection_visible_ = is_object_visible; | is_parent_collection_visible_ = is_object_visible; | ||||
| build_collection(nullptr, object->instance_collection); | build_collection(nullptr, object->instance_collection); | ||||
| is_parent_collection_visible_ = is_current_parent_collection_visible; | is_parent_collection_visible_ = is_current_parent_collection_visible; | ||||
| } | } | ||||
| void DepsgraphNodeBuilder::build_object_data(Object *object, bool is_object_visible) | void DepsgraphNodeBuilder::build_object_data(Object *object) | ||||
| { | { | ||||
| if (object->data == nullptr) { | if (object->data == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* type-specific data. */ | /* type-specific data. */ | ||||
| switch (object->type) { | switch (object->type) { | ||||
| case OB_MESH: | case OB_MESH: | ||||
| case OB_CURVE: | case OB_CURVE: | ||||
| case OB_FONT: | case OB_FONT: | ||||
| case OB_SURF: | case OB_SURF: | ||||
| case OB_MBALL: | case OB_MBALL: | ||||
| case OB_LATTICE: | case OB_LATTICE: | ||||
| case OB_GPENCIL: | case OB_GPENCIL: | ||||
| case OB_HAIR: | case OB_HAIR: | ||||
| case OB_POINTCLOUD: | case OB_POINTCLOUD: | ||||
| case OB_VOLUME: | case OB_VOLUME: | ||||
| build_object_data_geometry(object, is_object_visible); | build_object_data_geometry(object); | ||||
| break; | break; | ||||
| case OB_ARMATURE: | case OB_ARMATURE: | ||||
| if (ID_IS_LINKED(object) && object->proxy_from != nullptr) { | if (ID_IS_LINKED(object) && object->proxy_from != nullptr) { | ||||
| build_proxy_rig(object, is_object_visible); | build_proxy_rig(object); | ||||
| } | } | ||||
| else { | else { | ||||
| build_rig(object, is_object_visible); | build_rig(object); | ||||
| } | } | ||||
| break; | break; | ||||
| case OB_LAMP: | case OB_LAMP: | ||||
| build_object_data_light(object); | build_object_data_light(object); | ||||
| break; | break; | ||||
| case OB_CAMERA: | case OB_CAMERA: | ||||
| build_object_data_camera(object); | build_object_data_camera(object); | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 534 Lines • ▼ Show 20 Lines | void DepsgraphNodeBuilder::build_shapekeys(Key *key) | ||||
| LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) { | LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) { | ||||
| add_operation_node( | add_operation_node( | ||||
| &key->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, key_block->name); | &key->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, key_block->name); | ||||
| } | } | ||||
| } | } | ||||
| /* ObData Geometry Evaluation */ | /* ObData Geometry Evaluation */ | ||||
| /* XXX: what happens if the datablock is shared! */ | /* XXX: what happens if the datablock is shared! */ | ||||
| void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_object_visible) | void DepsgraphNodeBuilder::build_object_data_geometry(Object *object) | ||||
| { | { | ||||
| OperationNode *op_node; | OperationNode *op_node; | ||||
| Scene *scene_cow = get_cow_datablock(scene_); | Scene *scene_cow = get_cow_datablock(scene_); | ||||
| Object *object_cow = get_cow_datablock(object); | Object *object_cow = get_cow_datablock(object); | ||||
| /* Entry operation, takes care of initialization, and some other | /* Entry operation, takes care of initialization, and some other | ||||
| * relations which needs to be run prior actual geometry evaluation. */ | * relations which needs to be run prior actual geometry evaluation. */ | ||||
| op_node = add_operation_node(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); | op_node = add_operation_node(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); | ||||
| op_node->set_as_entry(); | op_node->set_as_entry(); | ||||
| /* Geometry evaluation. */ | /* Geometry evaluation. */ | ||||
| op_node = add_operation_node(&object->id, | op_node = add_operation_node(&object->id, | ||||
| NodeType::GEOMETRY, | NodeType::GEOMETRY, | ||||
| OperationCode::GEOMETRY_EVAL, | OperationCode::GEOMETRY_EVAL, | ||||
| [scene_cow, object_cow](::Depsgraph *depsgraph) { | [scene_cow, object_cow](::Depsgraph *depsgraph) { | ||||
| BKE_object_eval_uber_data(depsgraph, scene_cow, object_cow); | BKE_object_eval_uber_data(depsgraph, scene_cow, object_cow); | ||||
| }); | }); | ||||
| op_node->set_as_exit(); | op_node->set_as_exit(); | ||||
| /* Materials. */ | /* Materials. */ | ||||
| build_materials(object->mat, object->totcol); | build_materials(object->mat, object->totcol); | ||||
| /* Point caches. */ | /* Point caches. */ | ||||
| build_object_pointcache(object); | build_object_pointcache(object); | ||||
| /* Geometry. */ | /* Geometry. */ | ||||
| build_object_data_geometry_datablock((ID *)object->data, is_object_visible); | build_object_data_geometry_datablock((ID *)object->data); | ||||
| build_dimensions(object); | build_dimensions(object); | ||||
| /* Batch cache. */ | /* Batch cache. */ | ||||
| add_operation_node( | add_operation_node( | ||||
| &object->id, | &object->id, | ||||
| NodeType::BATCH_CACHE, | NodeType::BATCH_CACHE, | ||||
| OperationCode::GEOMETRY_SELECT_UPDATE, | OperationCode::GEOMETRY_SELECT_UPDATE, | ||||
| [object_cow](::Depsgraph *depsgraph) { BKE_object_select_update(depsgraph, object_cow); }); | [object_cow](::Depsgraph *depsgraph) { BKE_object_select_update(depsgraph, object_cow); }); | ||||
| } | } | ||||
| void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool is_object_visible) | void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata) | ||||
| { | { | ||||
| if (built_map_.checkIsBuiltAndTag(obdata)) { | if (built_map_.checkIsBuiltAndTag(obdata)) { | ||||
| return; | return; | ||||
| } | } | ||||
| OperationNode *op_node; | OperationNode *op_node; | ||||
| /* Make sure we've got an ID node before requesting CoW pointer. */ | /* Make sure we've got an ID node before requesting CoW pointer. */ | ||||
| (void)add_id_node((ID *)obdata); | (void)add_id_node((ID *)obdata); | ||||
| ID *obdata_cow = get_cow_id(obdata); | ID *obdata_cow = get_cow_id(obdata); | ||||
| Show All 27 Lines | switch (id_type) { | ||||
| case ID_CU: { | case ID_CU: { | ||||
| op_node = add_operation_node(obdata, | op_node = add_operation_node(obdata, | ||||
| NodeType::GEOMETRY, | NodeType::GEOMETRY, | ||||
| OperationCode::GEOMETRY_EVAL, | OperationCode::GEOMETRY_EVAL, | ||||
| [obdata_cow](::Depsgraph *depsgraph) { | [obdata_cow](::Depsgraph *depsgraph) { | ||||
| BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow); | BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow); | ||||
| }); | }); | ||||
| op_node->set_as_entry(); | op_node->set_as_entry(); | ||||
| /* Make sure objects used for bevel.taper are in the graph. | |||||
| * NOTE: This objects might be not linked to the scene. */ | |||||
| Curve *cu = (Curve *)obdata; | Curve *cu = (Curve *)obdata; | ||||
| if (cu->bevobj != nullptr) { | if (cu->bevobj != nullptr) { | ||||
| build_object(-1, cu->bevobj, DEG_ID_LINKED_INDIRECTLY, is_object_visible); | build_object(-1, cu->bevobj, DEG_ID_LINKED_INDIRECTLY, false); | ||||
| } | } | ||||
| if (cu->taperobj != nullptr) { | if (cu->taperobj != nullptr) { | ||||
| build_object(-1, cu->taperobj, DEG_ID_LINKED_INDIRECTLY, is_object_visible); | build_object(-1, cu->taperobj, DEG_ID_LINKED_INDIRECTLY, false); | ||||
| } | } | ||||
| if (cu->textoncurve != nullptr) { | if (cu->textoncurve != nullptr) { | ||||
| build_object(-1, cu->textoncurve, DEG_ID_LINKED_INDIRECTLY, is_object_visible); | build_object(-1, cu->textoncurve, DEG_ID_LINKED_INDIRECTLY, false); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case ID_LT: { | case ID_LT: { | ||||
| op_node = add_operation_node(obdata, | op_node = add_operation_node(obdata, | ||||
| NodeType::GEOMETRY, | NodeType::GEOMETRY, | ||||
| OperationCode::GEOMETRY_EVAL, | OperationCode::GEOMETRY_EVAL, | ||||
| [obdata_cow](::Depsgraph *depsgraph) { | [obdata_cow](::Depsgraph *depsgraph) { | ||||
| ▲ Show 20 Lines • Show All 546 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; | BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; | ||||
| ID *id = *idpoin; | ID *id = *idpoin; | ||||
| if (id == nullptr) { | if (id == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| switch (GS(id->name)) { | switch (GS(id->name)) { | ||||
| case ID_OB: | case ID_OB: | ||||
| /* Special case for object, so we take owner visibility into | data->builder->build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, false); | ||||
| * account. */ | |||||
| data->builder->build_object( | |||||
| -1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, data->is_parent_visible); | |||||
| break; | break; | ||||
| default: | default: | ||||
| data->builder->build_id(id); | data->builder->build_id(id); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| void DepsgraphNodeBuilder::constraint_walk(bConstraint * /*con*/, | void DepsgraphNodeBuilder::constraint_walk(bConstraint * /*con*/, | ||||
| ID **idpoin, | ID **idpoin, | ||||
| bool /*is_reference*/, | bool /*is_reference*/, | ||||
| void *user_data) | void *user_data) | ||||
| { | { | ||||
| BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; | BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; | ||||
| ID *id = *idpoin; | ID *id = *idpoin; | ||||
| if (id == nullptr) { | if (id == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| switch (GS(id->name)) { | switch (GS(id->name)) { | ||||
| case ID_OB: | case ID_OB: | ||||
| /* Special case for object, so we take owner visibility into | data->builder->build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, false); | ||||
| * account. */ | |||||
| data->builder->build_object( | |||||
| -1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, data->is_parent_visible); | |||||
| break; | break; | ||||
| default: | default: | ||||
| data->builder->build_id(id); | data->builder->build_id(id); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } // namespace blender::deg | } // namespace blender::deg | ||||