Fix #106943: driver on inactive view layer doesn't work #107031

Manually merged
Sybren A. Stüvel merged 3 commits from dr.sybren/blender:anim/106943-bg-view-layer-driver into main 2023-04-17 13:02:55 +02:00
3 changed files with 38 additions and 33 deletions

View File

@ -75,6 +75,12 @@ void BKE_view_layer_free(struct ViewLayer *view_layer);
*/
void BKE_view_layer_free_ex(struct ViewLayer *view_layer, bool do_id_user);
/**
* Free the bases of this #ViewLayer, and what they reference.
* This includes baseact, object_bases, object_bases_hash, and layer_collections.
*/
void BKE_view_layer_free_object_content(struct ViewLayer *view_layer);
/**
* Tag all the selected objects of a render-layer.
*/

View File

@ -246,19 +246,7 @@ void BKE_view_layer_free(ViewLayer *view_layer)
void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
{
view_layer->basact = nullptr;
BLI_freelistN(&view_layer->object_bases);
if (view_layer->object_bases_hash) {
BLI_ghash_free(view_layer->object_bases_hash, nullptr, nullptr);
}
LISTBASE_FOREACH_MUTABLE (LayerCollection *, lc, &view_layer->layer_collections) {
layer_collection_free(view_layer, lc);
MEM_freeN(lc);
}
BLI_listbase_clear(&view_layer->layer_collections);
BKE_view_layer_free_object_content(view_layer);
LISTBASE_FOREACH (ViewLayerEngineData *, sled, &view_layer->drawdata) {
if (sled->storage) {
@ -287,6 +275,23 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
MEM_freeN(view_layer);
}
void BKE_view_layer_free_object_content(ViewLayer *view_layer)
{
view_layer->basact = nullptr;
BLI_freelistN(&view_layer->object_bases);
if (view_layer->object_bases_hash) {
BLI_ghash_free(view_layer->object_bases_hash, nullptr, nullptr);
}
LISTBASE_FOREACH_MUTABLE (LayerCollection *, lc, &view_layer->layer_collections) {
layer_collection_free(view_layer, lc);
MEM_freeN(lc);
}
BLI_listbase_clear(&view_layer->layer_collections);
}
void BKE_view_layer_selected_objects_tag(const Scene *scene, ViewLayer *view_layer, const int tag)
{
BKE_view_layer_synced_ensure(scene, view_layer);

View File

@ -353,12 +353,11 @@ ViewLayer *get_original_view_layer(const Depsgraph *depsgraph, const IDNode *id_
return nullptr;
}
/* Remove all view layers but the one which corresponds to an input one. */
void scene_remove_unused_view_layers(const Depsgraph *depsgraph,
const IDNode *id_node,
Scene *scene_cow)
/* Remove all bases from all view layers except the input one. */
void scene_minimize_unused_view_layers(const Depsgraph *depsgraph,
const IDNode *id_node,
Scene *scene_cow)
{
const ViewLayer *view_layer_input;
if (depsgraph->is_render_pipeline_depsgraph) {
/* If the dependency graph is used for post-processing (such as compositor) we do need to
* have access to its view layer names so can not remove any view layers.
@ -370,18 +369,12 @@ void scene_remove_unused_view_layers(const Depsgraph *depsgraph,
* NOTE: Need to keep view layers for all scenes, even indirect ones. This is because of
* render layer node possibly pointing to another scene. */
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene_cow->view_layers) {
view_layer->basact = nullptr;
BKE_view_layer_free_object_content(view_layer);
}
return;
}
if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
/* Indirectly linked scenes means it's not an input scene and not a set scene, and is pulled
* via some driver. Such scenes should not have view layers after copy. */
view_layer_input = nullptr;
}
else {
view_layer_input = get_original_view_layer(depsgraph, id_node);
}
const ViewLayer *view_layer_input = get_original_view_layer(depsgraph, id_node);
ViewLayer *view_layer_eval = nullptr;
/* Find evaluated view layer. At the same time we free memory used by
* all other of the view layers. */
@ -394,15 +387,16 @@ void scene_remove_unused_view_layers(const Depsgraph *depsgraph,
view_layer_eval = view_layer_cow;
}
else {
BKE_view_layer_free_ex(view_layer_cow, false);
BKE_view_layer_free_object_content(view_layer_cow);
}
}
/* Make evaluated view layer the only one in the evaluated scene (if it exists). */
/* Make evaluated view layer the first one in the evaluated scene (if it exists). This is for
* legacy sake, as this used to remove all other view layers, automatically making the evaluated
* one the first. Some other code may still assume it is. */
if (view_layer_eval != nullptr) {
view_layer_eval->prev = view_layer_eval->next = nullptr;
BLI_listbase_swaplinks(&scene_cow->view_layers, scene_cow->view_layers.first, view_layer_eval);
}
scene_cow->view_layers.first = view_layer_eval;
scene_cow->view_layers.last = view_layer_eval;
}
void scene_remove_all_bases(Scene *scene_cow)
@ -467,7 +461,7 @@ void scene_setup_view_layers_before_remap(const Depsgraph *depsgraph,
const IDNode *id_node,
Scene *scene_cow)
{
scene_remove_unused_view_layers(depsgraph, id_node, scene_cow);
scene_minimize_unused_view_layers(depsgraph, id_node, scene_cow);
/* If dependency graph is used for post-processing we don't need any bases and can free of them.
* Do it before re-mapping to make that process faster. */
if (depsgraph->is_render_pipeline_depsgraph) {