Fix #135773: Grease Pencil: Applying modifier changes layer order

Rather than trying to change the order of layers to match the evaluated
Grease Pencil geometry, keep the original layer order for now.

Generally, it's less common to change the layer order of original
layers inside a modifier. It's much more common to have the
evaluated layers and original layers in the same order, so for now,
keep the original order instead.

To correctly support this, we probably need to propagate layer groups
inside of geometry nodes. Currently, layer groups are mostly
ignored inside of evaluated data.

Part of #136300.

Pull Request: https://projects.blender.org/blender/blender/pulls/137727
This commit is contained in:
Falk David
2025-04-18 16:08:59 +02:00
committed by Falk David
parent c220e45282
commit 8b3f49381a

View File

@@ -1793,10 +1793,6 @@ void apply_eval_grease_pencil_data(const GreasePencil &eval_grease_pencil,
Map<const Layer *, const Layer *> eval_to_orig_layer_map;
{
/* Keep track of the last layer in each group to ensure layers get added to the same groups in
* the same order as the original. This is better than using the layer cache since it avoids
* updating the cache every time a new layer is added. */
Map<const LayerGroup *, TreeNode *> last_node_by_group;
/* Set of orig layers that require the drawing on `eval_frame` to be cleared. These are layers
* that existed in original geometry but were removed in the evaluated data. */
Set<Layer *> orig_layers_to_clear;
@@ -1811,46 +1807,32 @@ void apply_eval_grease_pencil_data(const GreasePencil &eval_grease_pencil,
TreeNode *node_orig = orig_grease_pencil.find_node_by_name(node_eval->name());
BLI_assert(node_eval != nullptr);
if (node_eval->is_layer()) {
/* If the orig layer isn't valid then a new layer with a unique name will be generated. */
const bool has_valid_orig_layer = (node_orig != nullptr && node_orig->is_layer());
if (!has_valid_orig_layer) {
/* Note: This name might be empty! This has to be resolved at a later stage! */
Layer &layer_orig = orig_grease_pencil.add_layer(node_eval->name(), true);
orig_layers_to_apply.add(&layer_orig);
/* Make sure to add a new keyframe with a new drawing. */
orig_grease_pencil.insert_frame(layer_orig, eval_frame);
node_orig = &layer_orig.as_node();
}
BLI_assert(node_orig != nullptr);
Layer &layer_orig = node_orig->as_layer();
/* This layer has a matching evaluated layer, so don't clear its keyframe. */
orig_layers_to_clear.remove(&layer_orig);
/* Only map layers in `eval_to_orig_layer_map` that we want to apply. */
if (orig_layers_to_apply.contains(&layer_orig)) {
/* Copy layer properties to original geometry. */
const Layer &layer_eval = node_eval->as_layer();
layer_orig.opacity = layer_eval.opacity;
layer_orig.set_local_transform(layer_eval.local_transform());
/* Add new mapping for `layer_eval` -> `layer_orig`. */
eval_to_orig_layer_map.add_new(&layer_eval, &layer_orig);
}
if (!node_eval->is_layer()) {
continue;
}
/* If the orig layer isn't valid then a new layer with a unique name will be generated. */
const bool has_valid_orig_layer = (node_orig != nullptr && node_orig->is_layer());
if (!has_valid_orig_layer) {
/* Note: This name might be empty! This has to be resolved at a later stage! */
Layer &layer_orig = orig_grease_pencil.add_layer(node_eval->name(), true);
orig_layers_to_apply.add(&layer_orig);
/* Make sure to add a new keyframe with a new drawing. */
orig_grease_pencil.insert_frame(layer_orig, eval_frame);
node_orig = &layer_orig.as_node();
}
BLI_assert(node_orig != nullptr);
Layer &layer_orig = node_orig->as_layer();
/* This layer has a matching evaluated layer, so don't clear its keyframe. */
orig_layers_to_clear.remove(&layer_orig);
/* Only map layers in `eval_to_orig_layer_map` that we want to apply. */
if (orig_layers_to_apply.contains(&layer_orig)) {
/* Copy layer properties to original geometry. */
const Layer &layer_eval = node_eval->as_layer();
layer_orig.opacity = layer_eval.opacity;
layer_orig.set_local_transform(layer_eval.local_transform());
/* Insert the updated node after the last node in the same group.
* This keeps the layer order consistent. */
if (node_orig && node_orig->parent_group()) {
last_node_by_group.add_or_modify(
node_orig->parent_group(),
[&](TreeNode **node_ptr) {
/* First layer in the group, set the last-layer pointer. */
*node_ptr = node_orig;
},
[&](TreeNode **node_ptr) {
orig_grease_pencil.move_node_after(*node_orig, **node_ptr);
*node_ptr = node_orig;
});
/* Add new mapping for `layer_eval` -> `layer_orig`. */
eval_to_orig_layer_map.add_new(&layer_eval, &layer_orig);
}
}