Grease Pencil: Allow filtering by layer groups in modifiers
Previously modifiers can only filter single layers, now filtering by layer group is also supported. This adds a toggle to the layer filter to switch to filtering by groups. Resolves #123323. Pull Request: https://projects.blender.org/blender/blender/pulls/123353
This commit is contained in:
@@ -2663,6 +2663,7 @@ typedef enum GreasePencilModifierInfluenceFlag {
|
||||
GREASE_PENCIL_INFLUENCE_INVERT_MATERIAL_PASS_FILTER = (1 << 5),
|
||||
GREASE_PENCIL_INFLUENCE_INVERT_VERTEX_GROUP = (1 << 6),
|
||||
GREASE_PENCIL_INFLUENCE_USE_CUSTOM_CURVE = (1 << 7),
|
||||
GREASE_PENCIL_INFLUENCE_USE_LAYER_GROUP_FILTER = (1 << 8),
|
||||
} GreasePencilModifierInfluenceFlag;
|
||||
|
||||
typedef struct GreasePencilOpacityModifierData {
|
||||
|
||||
@@ -8374,7 +8374,7 @@ static void rna_def_modifier_grease_pencil_layer_filter(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_property(srna, "layer_filter", PROP_STRING, PROP_NONE);
|
||||
prop = RNA_def_property(srna, "tree_node_filter", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, nullptr, "influence.layer_name");
|
||||
RNA_def_property_ui_text(prop, "Layer", "Layer name");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
@@ -8402,6 +8402,12 @@ static void rna_def_modifier_grease_pencil_layer_filter(StructRNA *srna)
|
||||
prop, nullptr, "influence.flag", GREASE_PENCIL_INFLUENCE_INVERT_LAYER_PASS_FILTER);
|
||||
RNA_def_property_ui_text(prop, "Invert Layer Pass", "Invert layer pass filter");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_layer_group_filter", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(
|
||||
prop, nullptr, "influence.flag", GREASE_PENCIL_INFLUENCE_USE_LAYER_GROUP_FILTER);
|
||||
RNA_def_property_ui_text(prop, "Layer Group", "Filter by layer group name");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
}
|
||||
|
||||
static void rna_def_modifier_grease_pencil_material_filter(StructRNA *srna,
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace blender::modifier::greasepencil {
|
||||
using bke::greasepencil::Drawing;
|
||||
using bke::greasepencil::FramesMapKeyT;
|
||||
using bke::greasepencil::Layer;
|
||||
using bke::greasepencil::LayerGroup;
|
||||
|
||||
void init_influence_data(GreasePencilModifierInfluenceData *influence_data,
|
||||
const bool has_custom_curve)
|
||||
@@ -96,6 +97,7 @@ void draw_layer_filter_settings(const bContext * /*C*/, uiLayout *layout, Pointe
|
||||
PointerRNA ob_ptr = RNA_pointer_create_discrete(ptr->owner_id, &RNA_Object, ptr->owner_id);
|
||||
PointerRNA obj_data_ptr = RNA_pointer_get(&ob_ptr, "data");
|
||||
const bool use_layer_pass = RNA_boolean_get(ptr, "use_layer_pass_filter");
|
||||
const bool use_layer_group_filter = RNA_boolean_get(ptr, "use_layer_group_filter");
|
||||
uiLayout *row, *col, *sub, *subsub;
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
@@ -103,14 +105,26 @@ void draw_layer_filter_settings(const bContext * /*C*/, uiLayout *layout, Pointe
|
||||
col = &layout->column(true);
|
||||
row = &col->row(true);
|
||||
uiLayoutSetPropDecorate(row, false);
|
||||
uiItemPointerR(row,
|
||||
ptr,
|
||||
"layer_filter",
|
||||
&obj_data_ptr,
|
||||
"layers",
|
||||
std::nullopt,
|
||||
ICON_OUTLINER_DATA_GP_LAYER);
|
||||
if (use_layer_group_filter) {
|
||||
uiItemPointerR(row,
|
||||
ptr,
|
||||
"tree_node_filter",
|
||||
&obj_data_ptr,
|
||||
"layer_groups",
|
||||
"Group",
|
||||
ICON_GREASEPENCIL_LAYER_GROUP);
|
||||
}
|
||||
else {
|
||||
uiItemPointerR(row,
|
||||
ptr,
|
||||
"tree_node_filter",
|
||||
&obj_data_ptr,
|
||||
"layers",
|
||||
std::nullopt,
|
||||
ICON_OUTLINER_DATA_GP_LAYER);
|
||||
}
|
||||
sub = &row->row(true);
|
||||
sub->prop(ptr, "use_layer_group_filter", UI_ITEM_NONE, "", ICON_GREASEPENCIL_LAYER_GROUP);
|
||||
sub->prop(ptr, "invert_layer_filter", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
|
||||
|
||||
row = &col->row(true, IFACE_("Layer Pass"));
|
||||
@@ -202,14 +216,14 @@ static Vector<int> get_grease_pencil_material_passes(const Object *ob)
|
||||
}
|
||||
|
||||
static IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil,
|
||||
const std::optional<StringRef> layer_name_filter,
|
||||
const std::optional<StringRef> tree_node_name_filter,
|
||||
const std::optional<int> layer_pass_filter,
|
||||
const bool layer_filter_invert,
|
||||
const bool layer_pass_filter_invert,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
const IndexMask full_mask = grease_pencil.layers().index_range();
|
||||
if (!layer_name_filter && !layer_pass_filter) {
|
||||
if (!tree_node_name_filter && !layer_pass_filter) {
|
||||
return full_mask;
|
||||
}
|
||||
|
||||
@@ -218,13 +232,31 @@ static IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil,
|
||||
const VArray<int> layer_passes =
|
||||
layer_attributes.lookup_or_default<int>("pass_index", bke::AttrDomain::Layer, 0).varray;
|
||||
|
||||
const LayerGroup *filter_layer_group = nullptr;
|
||||
if (tree_node_name_filter) {
|
||||
for (const LayerGroup *group : grease_pencil.layer_groups()) {
|
||||
if (group->name() == tree_node_name_filter.value()) {
|
||||
filter_layer_group = group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IndexMask result = IndexMask::from_predicate(
|
||||
full_mask, GrainSize(4096), memory, [&](const int64_t layer_i) {
|
||||
if (layer_name_filter) {
|
||||
const Layer &layer = *layers[layer_i];
|
||||
const bool match = (layer.name() == layer_name_filter.value());
|
||||
if (match == layer_filter_invert) {
|
||||
return false;
|
||||
if (tree_node_name_filter) {
|
||||
const Layer *layer = layers[layer_i];
|
||||
if (filter_layer_group) {
|
||||
const bool match = layer->is_child_of(*filter_layer_group);
|
||||
if (match == layer_filter_invert) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const bool match = (layer->name() == tree_node_name_filter.value());
|
||||
if (match == layer_filter_invert) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layer_pass_filter) {
|
||||
|
||||
Reference in New Issue
Block a user