GPv3: Opacity modifier #116946
|
@ -151,8 +151,8 @@ typedef enum {
|
|||
*/
|
||||
eModifierFlag_Active = (1 << 2),
|
||||
/**
|
||||
* Only set on modifiers in evaluated objects. The flag indicates that the user modified inputs
|
||||
* to the modifier which might invalidate simulation caches.
|
||||
* Only set on modifiers in evaluated objects. The flag indicates that the user modified
|
||||
* inputs to the modifier which might invalidate simulation caches.
|
||||
*/
|
||||
LukasTonne marked this conversation as resolved
Outdated
|
||||
eModifierFlag_UserModified = (1 << 3),
|
||||
} ModifierFlag;
|
||||
|
@ -2484,3 +2484,26 @@ typedef enum VolumeToMeshResolutionMode {
|
|||
typedef enum VolumeToMeshFlag {
|
||||
VOLUME_TO_MESH_USE_SMOOTH_SHADE = 1 << 0,
|
||||
} VolumeToMeshFlag;
|
||||
|
||||
typedef struct GreasePencilModifierFilterData {
|
||||
/** Filter by layer name. */
|
||||
char layer_name[64];
|
||||
/** Filter by stroke material. */
|
||||
struct Material *material;
|
||||
/** Filter by layer pass. */
|
||||
int layer_pass;
|
||||
/** Filter by material pass. */
|
||||
int material_pass;
|
||||
/** GreasePencilModifierFilterFlag */
|
||||
int flag;
|
||||
char _pad[4];
|
||||
} GreasePencilModifierFilterData;
|
||||
|
||||
typedef enum GreasePencilModifierFilterFlag {
|
||||
GREASE_PENCIL_FILTER_USE_LAYER_PASS = (1 << 0),
|
||||
GREASE_PENCIL_FILTER_USE_MATERIAL_PASS = (1 << 1),
|
||||
GREASE_PENCIL_FILTER_INVERT_LAYER = (1 << 2),
|
||||
GREASE_PENCIL_FILTER_INVERT_LAYER_PASS = (1 << 3),
|
||||
GREASE_PENCIL_FILTER_INVERT_MATERIAL = (1 << 4),
|
||||
GREASE_PENCIL_FILTER_INVERT_MATERIAL_PASS = (1 << 5),
|
||||
} GreasePencilModifierFilterFlag;
|
||||
|
|
|
@ -668,11 +668,13 @@ const EnumPropertyItem rna_enum_subdivision_boundary_smooth_items[] = {
|
|||
#ifdef RNA_RUNTIME
|
||||
# include "DNA_curve_types.h"
|
||||
# include "DNA_fluid_types.h"
|
||||
# include "DNA_material_types.h"
|
||||
# include "DNA_particle_types.h"
|
||||
|
||||
# include "BKE_cachefile.h"
|
||||
# include "BKE_context.hh"
|
||||
# include "BKE_deform.h"
|
||||
# include "BKE_grease_pencil.hh"
|
||||
# include "BKE_mesh_runtime.hh"
|
||||
# include "BKE_modifier.hh"
|
||||
# include "BKE_object.hh"
|
||||
|
@ -1705,6 +1707,37 @@ static IDProperty **rna_NodesModifier_properties(PointerRNA *ptr)
|
|||
NodesModifierSettings *settings = &nmd->settings;
|
||||
return &settings->properties;
|
||||
}
|
||||
|
||||
bool rna_GreasePencilModifierFilter_material_poll(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
Object *ob = reinterpret_cast<Object *>(ptr->owner_id);
|
||||
Material *ma = reinterpret_cast<Material *>(value.owner_id);
|
||||
|
||||
return BKE_grease_pencil_object_material_index_get(ob, ma) != -1;
|
||||
}
|
||||
|
||||
static void rna_GreasePencilModifierFilter_material_set(PointerRNA *ptr,
|
||||
PointerRNA value,
|
||||
ReportList *reports)
|
||||
{
|
||||
Object *ob = reinterpret_cast<Object *>(ptr->owner_id);
|
||||
GreasePencilModifierFilterData *filter_data = static_cast<GreasePencilModifierFilterData *>(
|
||||
ptr->data);
|
||||
Material *ma = reinterpret_cast<Material *>(value.owner_id);
|
||||
|
||||
if (ma == nullptr || BKE_grease_pencil_object_material_index_get(ob, ma) != -1) {
|
||||
id_lib_extern(reinterpret_cast<ID *>(ob));
|
||||
filter_data->material = ma;
|
||||
}
|
||||
else {
|
||||
BKE_reportf(
|
||||
reports,
|
||||
RPT_ERROR,
|
||||
"Cannot assign material '%s', it has to be used by the grease pencil object already",
|
||||
ma->id.name);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_modifier_panel_open_prop(StructRNA *srna, const char *identifier, const int id)
|
||||
|
@ -7423,6 +7456,78 @@ static void rna_def_modifier_volume_to_mesh(BlenderRNA *brna)
|
|||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
|
||||
static void rna_def_modifier_grease_pencil_filter(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "GreasePencilModifierFilter", nullptr);
|
||||
RNA_def_struct_ui_text(
|
||||
srna, "Grease Pencil Modifier Filter", "Filter settings for grease pencil modifiers");
|
||||
RNA_def_struct_sdna(srna, "GreasePencilModifierFilterData");
|
||||
|
||||
RNA_define_lib_overridable(true);
|
||||
|
||||
prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, nullptr, "layer_name");
|
||||
RNA_def_property_ui_text(prop, "Layer", "Layer name");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_layer_pass", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GREASE_PENCIL_FILTER_USE_LAYER_PASS);
|
||||
RNA_def_property_ui_text(prop, "Use Layer Pass", "Use layer pass filter");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "layer_pass", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, nullptr, "layer_pass");
|
||||
RNA_def_property_range(prop, 0, 100);
|
||||
RNA_def_property_ui_text(prop, "Layer Pass", "Layer pass filter");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert_layer", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GREASE_PENCIL_FILTER_INVERT_LAYER);
|
||||
RNA_def_property_ui_text(prop, "Invert Layer", "Invert layer filter");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert_layer_pass", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GREASE_PENCIL_FILTER_INVERT_LAYER_PASS);
|
||||
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, "material", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_pointer_funcs(prop,
|
||||
nullptr,
|
||||
"rna_GreasePencilModifierFilter_material_set",
|
||||
nullptr,
|
||||
"rna_GreasePencilModifierFilter_material_poll");
|
||||
RNA_def_property_ui_text(prop, "Material", "Material used for filtering");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_material_pass", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GREASE_PENCIL_FILTER_USE_MATERIAL_PASS);
|
||||
RNA_def_property_ui_text(prop, "Use Material Pass", "Use material pass filter");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "material_pass", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, nullptr, "material_pass");
|
||||
RNA_def_property_range(prop, 0, 100);
|
||||
RNA_def_property_ui_text(prop, "Material Pass", "Material pass");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert_material", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GREASE_PENCIL_FILTER_INVERT_MATERIAL);
|
||||
RNA_def_property_ui_text(prop, "Invert Material", "Invert material filter");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert_material_pass", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GREASE_PENCIL_FILTER_INVERT_MATERIAL_PASS);
|
||||
RNA_def_property_ui_text(prop, "Invert Material Pass", "Invert material pass filter");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
|
||||
void RNA_def_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -7583,6 +7688,7 @@ void RNA_def_modifier(BlenderRNA *brna)
|
|||
rna_def_modifier_mesh_to_volume(brna);
|
||||
rna_def_modifier_volume_displace(brna);
|
||||
rna_def_modifier_volume_to_mesh(brna);
|
||||
rna_def_modifier_grease_pencil_filter(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,6 +44,7 @@ set(SRC
|
|||
intern/MOD_edgesplit.cc
|
||||
intern/MOD_explode.cc
|
||||
intern/MOD_fluid.cc
|
||||
intern/MOD_grease_pencil_util.cc
|
||||
intern/MOD_hook.cc
|
||||
intern/MOD_laplaciandeform.cc
|
||||
intern/MOD_laplaciansmooth.cc
|
||||
|
@ -97,6 +98,7 @@ set(SRC
|
|||
|
||||
MOD_modifiertypes.hh
|
||||
MOD_nodes.hh
|
||||
intern/MOD_grease_pencil_util.hh
|
||||
intern/MOD_meshcache_util.hh
|
||||
intern/MOD_solidify_util.hh
|
||||
intern/MOD_ui_common.hh
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
/* SPDX-FileCopyrightText: 2011 by Bastien Montagne. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup modifiers
|
||||
*/
|
||||
|
||||
#include "MOD_grease_pencil_util.hh"
|
||||
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
#include "DNA_defaults.h"
|
||||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#include "MOD_ui_common.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_prototypes.h"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
|
||||
namespace blender::greasepencil {
|
||||
|
||||
using bke::greasepencil::Drawing;
|
||||
using bke::greasepencil::Layer;
|
||||
|
||||
void init_filter_data(GreasePencilModifierFilterData * /*filter_data*/) {}
|
||||
|
||||
void copy_filter_data(const GreasePencilModifierFilterData *filter_data_src,
|
||||
GreasePencilModifierFilterData *filter_data_dst,
|
||||
const int /*flag*/)
|
||||
{
|
||||
memcpy(filter_data_dst, filter_data_src, sizeof(GreasePencilModifierFilterData));
|
||||
}
|
||||
|
||||
void free_filter_data(GreasePencilModifierFilterData * /*filter_data*/) {}
|
||||
|
||||
void foreach_filter_ID_link(GreasePencilModifierFilterData *filter_data,
|
||||
Object *ob,
|
||||
IDWalkFunc walk,
|
||||
void *user_data)
|
||||
{
|
||||
walk(user_data, ob, (ID **)&filter_data->material, IDWALK_CB_USER);
|
||||
}
|
||||
|
||||
void draw_filter_settings(const bContext * /*C*/, uiLayout *layout, PointerRNA *ptr)
|
||||
{
|
||||
PointerRNA ob_ptr = RNA_pointer_create(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");
|
||||
const bool use_material_pass = RNA_boolean_get(ptr, "use_material_pass");
|
||||
uiLayout *row, *col, *sub;
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
|
||||
col = uiLayoutColumn(layout, true);
|
||||
row = uiLayoutRow(col, true);
|
||||
uiItemPointerR(row, ptr, "layer", &obj_data_ptr, "layers", nullptr, ICON_GREASEPENCIL);
|
||||
sub = uiLayoutRow(row, true);
|
||||
uiLayoutSetPropDecorate(sub, false);
|
||||
uiItemR(sub, ptr, "invert_layer", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
|
||||
|
||||
/* TODO Would be nice to have the checkbox in the same line as the pass button. */
|
||||
row = uiLayoutRow(col, true);
|
||||
uiItemR(row, ptr, "use_layer_pass", UI_ITEM_NONE, "Filter by layer pass", ICON_NONE);
|
||||
row = uiLayoutRow(col, true);
|
||||
uiLayoutSetActive(row, use_layer_pass);
|
||||
uiItemR(row, ptr, "layer_pass", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
sub = uiLayoutRow(row, true);
|
||||
uiLayoutSetPropDecorate(sub, false);
|
||||
uiItemR(sub, ptr, "invert_layer_pass", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
|
||||
|
||||
col = uiLayoutColumn(layout, true);
|
||||
row = uiLayoutRow(col, true);
|
||||
uiItemPointerR(row, ptr, "material", &obj_data_ptr, "materials", nullptr, ICON_SHADING_TEXTURE);
|
||||
sub = uiLayoutRow(row, true);
|
||||
uiLayoutSetPropDecorate(sub, false);
|
||||
uiItemR(sub, ptr, "invert_material", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
|
||||
|
||||
/* TODO Would be nice to have the checkbox in the same line as the pass button. */
|
||||
row = uiLayoutRow(col, true);
|
||||
uiItemR(row, ptr, "use_material_pass", UI_ITEM_NONE, "Filter by material pass", ICON_NONE);
|
||||
row = uiLayoutRow(col, true);
|
||||
uiLayoutSetActive(row, use_material_pass);
|
||||
uiItemR(row, ptr, "material_pass", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
sub = uiLayoutRow(row, true);
|
||||
uiLayoutSetPropDecorate(sub, false);
|
||||
uiItemR(sub, ptr, "invert_material_pass", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of pass IDs used by grease pencil materials.
|
||||
* This way the material pass can be looked up by index instead of having to get the material for
|
||||
* each curve.
|
||||
*/
|
||||
static Vector<int> get_grease_pencil_material_passes(const Object *ob)
|
||||
{
|
||||
short *totcol = BKE_object_material_len_p(const_cast<Object *>(ob));
|
||||
Vector<int> result(*totcol);
|
||||
Material *ma = nullptr;
|
||||
LukasTonne marked this conversation as resolved
Outdated
Lukas Tönne
commented
Would be nice to have the checkbox in the same line as the pass button. I haven't found a good way to combine these buttons yet, could use help from UI experts. Would be nice to have the checkbox in the same line as the pass button. I haven't found a good way to combine these buttons yet, could use help from UI experts.
Hans Goudey
commented
It's ugly but possible, here's an example from the limit location constraint:
It's ugly but possible, here's an example from the limit location constraint:
```
row = col.row(heading="Y", align=True)
row.use_property_decorate = False
sub = row.row(align=True)
sub.prop(con, "use_max_y", text="")
subsub = sub.row(align=True)
subsub.active = con.use_max_y
subsub.prop(con, "max_y", text="")
row.prop_decorator(con, "max_y")
```
Matias Mendiola
commented
I Agree to have the checkbox on the same line. Hans proposal seems a right choice I Agree to have the checkbox on the same line. Hans proposal seems a right choice
Lukas Tönne
commented
I didn't know about the I didn't know about the `uiLayoutRowWithHeading` feature, thanks.
|
||||
for (short i = 0; i < *totcol; i++) {
|
||||
ma = BKE_object_material_get(const_cast<Object *>(ob), i + 1);
|
||||
/* Pass index of the grease pencil material. */
|
||||
result[i] = ma->gp_style->index;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil,
|
||||
const std::optional<StringRef> layer_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) {
|
||||
return full_mask;
|
||||
}
|
||||
|
||||
bke::AttributeAccessor layer_attributes = grease_pencil.attributes();
|
||||
const Span<const Layer *> layers = grease_pencil.layers();
|
||||
const VArray<int> layer_passes =
|
||||
layer_attributes.lookup_or_default<int>("pass", bke::AttrDomain::Layer, 0).varray;
|
||||
|
||||
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 (layer_pass_filter) {
|
||||
const int layer_pass = layer_passes.get(layer_i);
|
||||
const bool match = (layer_pass == layer_pass_filter.value());
|
||||
if (match == layer_pass_filter_invert) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil,
|
||||
const GreasePencilModifierFilterData &filter_data,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return get_filtered_layer_mask(grease_pencil,
|
||||
filter_data.layer_name[0] != '\0' ?
|
||||
std::make_optional<StringRef>(filter_data.layer_name) :
|
||||
std::nullopt,
|
||||
(filter_data.flag & GREASE_PENCIL_FILTER_USE_LAYER_PASS) ?
|
||||
std::make_optional<int>(filter_data.layer_pass) :
|
||||
std::nullopt,
|
||||
filter_data.flag & GREASE_PENCIL_FILTER_INVERT_LAYER,
|
||||
filter_data.flag & GREASE_PENCIL_FILTER_INVERT_LAYER_PASS,
|
||||
memory);
|
||||
}
|
||||
|
||||
static IndexMask get_filtered_stroke_mask(const Object *ob,
|
||||
const bke::CurvesGeometry &curves,
|
||||
const Material *material_filter,
|
||||
const std::optional<int> material_pass_filter,
|
||||
const bool material_filter_invert,
|
||||
const bool material_pass_filter_invert,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
const IndexMask full_mask = curves.curves_range();
|
||||
if (!material_filter && !material_pass_filter) {
|
||||
return full_mask;
|
||||
}
|
||||
|
||||
const int material_filter_index = BKE_grease_pencil_object_material_index_get(
|
||||
const_cast<Object *>(ob), const_cast<Material *>(material_filter));
|
||||
const Vector<int> material_pass_by_index = get_grease_pencil_material_passes(ob);
|
||||
|
||||
bke::AttributeAccessor attributes = curves.attributes();
|
||||
VArray<int> stroke_materials =
|
||||
attributes.lookup_or_default<int>("material_index", bke::AttrDomain::Curve, 0).varray;
|
||||
|
||||
IndexMask result = IndexMask::from_predicate(
|
||||
full_mask, GrainSize(4096), memory, [&](const int64_t stroke_i) {
|
||||
const int material_index = stroke_materials.get(stroke_i);
|
||||
if (material_filter != nullptr) {
|
||||
const bool match = (material_index == material_filter_index);
|
||||
if (match == material_filter_invert) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (material_pass_filter) {
|
||||
const int material_pass = material_pass_by_index[material_index];
|
||||
const bool match = (material_pass == material_pass_filter.value());
|
||||
if (match == material_pass_filter_invert) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
IndexMask get_filtered_stroke_mask(const Object *ob,
|
||||
const bke::CurvesGeometry &curves,
|
||||
const GreasePencilModifierFilterData &filter_data,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
/* TODO Add an option to toggle pass filter on and off, instead of using "pass > 0". */
|
||||
return get_filtered_stroke_mask(ob,
|
||||
curves,
|
||||
filter_data.material,
|
||||
(filter_data.flag & GREASE_PENCIL_FILTER_USE_MATERIAL_PASS) ?
|
||||
std::make_optional<int>(filter_data.material_pass) :
|
||||
std::nullopt,
|
||||
filter_data.flag & GREASE_PENCIL_FILTER_INVERT_MATERIAL,
|
||||
filter_data.flag & GREASE_PENCIL_FILTER_INVERT_MATERIAL_PASS,
|
||||
memory);
|
||||
}
|
||||
|
||||
Vector<bke::greasepencil::Drawing *> get_drawings_for_write(GreasePencil &grease_pencil,
|
||||
const IndexMask &layer_mask,
|
||||
int frame)
|
||||
{
|
||||
/* Set of unique drawing indices. */
|
||||
Set<int> drawing_indices;
|
||||
for (const int64_t i : layer_mask.index_range()) {
|
||||
Layer *layer = grease_pencil.layers_for_write()[layer_mask[i]];
|
||||
const int drawing_index = layer->drawing_index_at(frame);
|
||||
if (drawing_index >= 0) {
|
||||
drawing_indices.add(drawing_index);
|
||||
}
|
||||
}
|
||||
|
||||
/* List of owned drawings, ignore drawing references to other data blocks. */
|
||||
Vector<bke::greasepencil::Drawing *> drawings;
|
||||
for (const int drawing_index : drawing_indices) {
|
||||
GreasePencilDrawingBase *drawing_base = grease_pencil.drawing(drawing_index);
|
||||
if (drawing_base->type == GP_DRAWING) {
|
||||
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
|
||||
drawings.append(&drawing->wrap());
|
||||
}
|
||||
}
|
||||
return drawings;
|
||||
}
|
||||
|
||||
} // namespace blender::greasepencil
|
|
@ -0,0 +1,57 @@
|
|||
/* SPDX-FileCopyrightText: 2011 by Bastien Montagne. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup modifiers
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_index_mask.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BKE_modifier.hh"
|
||||
|
||||
struct ARegionType;
|
||||
struct bContext;
|
||||
struct GreasePencil;
|
||||
struct GreasePencilModifierFilterData;
|
||||
struct PanelType;
|
||||
struct PointerRNA;
|
||||
struct uiLayout;
|
||||
namespace blender::bke {
|
||||
class CurvesGeometry;
|
||||
namespace greasepencil {
|
||||
class Drawing;
|
||||
}
|
||||
} // namespace blender::bke
|
||||
|
||||
namespace blender::greasepencil {
|
||||
|
||||
void init_filter_data(GreasePencilModifierFilterData *filter_data);
|
||||
void copy_filter_data(const GreasePencilModifierFilterData *filter_data_src,
|
||||
GreasePencilModifierFilterData *filter_data_dst,
|
||||
int flag);
|
||||
void free_filter_data(GreasePencilModifierFilterData *filter_data);
|
||||
void foreach_filter_ID_link(GreasePencilModifierFilterData *filter_data,
|
||||
Object *ob,
|
||||
IDWalkFunc walk,
|
||||
void *user_data);
|
||||
|
||||
void draw_filter_settings(const bContext *C, uiLayout *layout, PointerRNA *ptr);
|
||||
|
||||
IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil,
|
||||
const GreasePencilModifierFilterData &filter_data,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
IndexMask get_filtered_stroke_mask(const Object *ob,
|
||||
const bke::CurvesGeometry &curves,
|
||||
const GreasePencilModifierFilterData &filter_data,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
Vector<bke::greasepencil::Drawing *> get_drawings_for_write(GreasePencil &grease_pencil,
|
||||
const IndexMask &layer_mask,
|
||||
int frame);
|
||||
|
||||
} // namespace blender::greasepencil
|
Loading…
Reference in New Issue
Looks like a
clang-format
issue here.