Blender V4.3
MOD_grease_pencil_simplify.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BLI_index_mask.hh"
10
11#include "BLT_translation.hh"
12
13#include "BLO_read_write.hh"
14
15#include "DNA_defaults.h"
16#include "DNA_modifier_types.h"
17#include "DNA_screen_types.h"
18
20#include "BKE_geometry_set.hh"
21#include "BKE_grease_pencil.hh"
22#include "BKE_modifier.hh"
23
24#include "ED_grease_pencil.hh"
25
28
29#include "UI_interface.hh"
30#include "UI_resources.hh"
31
33#include "MOD_ui_common.hh"
34
35#include "RNA_access.hh"
36#include "RNA_prototypes.hh"
37
38namespace blender {
39
40static void init_data(ModifierData *md)
41{
42 auto *gpmd = reinterpret_cast<GreasePencilSimplifyModifierData *>(md);
43
45
47 modifier::greasepencil::init_influence_data(&gpmd->influence, true);
48}
49
50static void free_data(ModifierData *md)
51{
52 auto *mmd = reinterpret_cast<GreasePencilSimplifyModifierData *>(md);
53
55}
56
57static void copy_data(const ModifierData *md, ModifierData *target, int flag)
58{
59 const auto *gmd = reinterpret_cast<const GreasePencilSimplifyModifierData *>(md);
60 auto *tgmd = reinterpret_cast<GreasePencilSimplifyModifierData *>(target);
61
63 modifier::greasepencil::copy_influence_data(&gmd->influence, &tgmd->influence, flag);
64}
65
66static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
67{
68 const auto *mmd = reinterpret_cast<const GreasePencilSimplifyModifierData *>(md);
69
71 modifier::greasepencil::write_influence_data(writer, &mmd->influence);
72}
73
74static void blend_read(BlendDataReader *reader, ModifierData *md)
75{
76 auto *mmd = reinterpret_cast<GreasePencilSimplifyModifierData *>(md);
77
78 modifier::greasepencil::read_influence_data(reader, &mmd->influence);
79}
80
82 const int step,
83 IndexMaskMemory &memory)
84{
85 const OffsetIndices points_by_curve = curves.points_by_curve();
86 const Array<int> point_to_curve_map = curves.point_to_curve_map();
88 curves.points_range(), GrainSize(2048), memory, [&](const int64_t i) {
89 const int curve_i = point_to_curve_map[i];
90 const IndexRange points = points_by_curve[curve_i];
91 if (points.size() <= 2) {
92 return true;
93 }
94 const int local_i = i - points.start();
95 return (local_i % int(math::pow(2.0f, float(step))) == 0) || points.last() == i;
96 });
97}
98
100 const Object &ob,
102{
104 const bke::CurvesGeometry &curves = drawing.strokes();
105
106 IndexMaskMemory memory;
108 &ob, curves, mmd.influence, memory);
109 if (strokes.is_empty()) {
110 return;
111 }
112
113 switch (mmd.mode) {
115 const IndexMask points_to_keep = simplify_fixed(curves, mmd.step, memory);
116 if (points_to_keep.is_empty()) {
117 drawing.strokes_for_write() = {};
118 break;
119 }
120 if (points_to_keep.size() == curves.points_num()) {
121 break;
122 }
123 drawing.strokes_for_write() = bke::curves_copy_point_selection(curves, points_to_keep, {});
124 break;
125 }
127 const IndexMask points_to_delete = geometry::simplify_curve_attribute(
128 curves.positions(),
129 strokes,
130 curves.points_by_curve(),
131 curves.cyclic(),
132 mmd.factor,
133 curves.positions(),
134 memory);
135 drawing.strokes_for_write().remove_points(points_to_delete, {});
136 break;
137 }
140 curves, strokes, VArray<float>::ForSingle(mmd.length, curves.curves_num()), {});
141 break;
142 }
144 const OffsetIndices points_by_curve = curves.points_by_curve();
145 const Array<int> point_to_curve_map = curves.point_to_curve_map();
147 curves.points_range(), GrainSize(2048), memory, [&](const int64_t i) {
148 const int curve_i = point_to_curve_map[i];
149 const IndexRange points = points_by_curve[curve_i];
150 if (points.drop_front(1).drop_back(1).contains(i)) {
151 return true;
152 }
153 return false;
154 });
156 curves, mmd.distance, points, {});
157 break;
158 }
159 default:
160 break;
161 }
162
163 drawing.tag_topology_changed();
164}
165
167 const ModifierEvalContext *ctx,
168 bke::GeometrySet *geometry_set)
169{
170 const auto *mmd = reinterpret_cast<GreasePencilSimplifyModifierData *>(md);
171
172 if (!geometry_set->has_grease_pencil()) {
173 return;
174 }
175
176 GreasePencil &grease_pencil = *geometry_set->get_grease_pencil_for_write();
177 const int current_frame = grease_pencil.runtime->eval_frame;
178
179 IndexMaskMemory mask_memory;
181 grease_pencil, mmd->influence, mask_memory);
183 modifier::greasepencil::get_drawings_for_write(grease_pencil, layer_mask, current_frame);
184
186 simplify_drawing(*mmd, *ctx->object, *drawing);
187 });
188}
189
190static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
191{
192 auto *mmd = reinterpret_cast<GreasePencilSimplifyModifierData *>(md);
193
194 modifier::greasepencil::foreach_influence_ID_link(&mmd->influence, ob, walk, user_data);
195}
196
197static void panel_draw(const bContext *C, Panel *panel)
198{
199 uiLayout *layout = panel->layout;
200
202
203 int mode = RNA_enum_get(ptr, "mode");
204
205 uiLayoutSetPropSep(layout, true);
206
207 uiItemR(layout, ptr, "mode", UI_ITEM_NONE, nullptr, ICON_NONE);
208
210 uiItemR(layout, ptr, "step", UI_ITEM_NONE, nullptr, ICON_NONE);
211 }
212 else if (mode == MOD_GREASE_PENCIL_SIMPLIFY_ADAPTIVE) {
213 uiItemR(layout, ptr, "factor", UI_ITEM_NONE, nullptr, ICON_NONE);
214 }
215 else if (mode == MOD_GREASE_PENCIL_SIMPLIFY_SAMPLE) {
216 uiItemR(layout, ptr, "length", UI_ITEM_NONE, nullptr, ICON_NONE);
217 uiItemR(layout, ptr, "sharp_threshold", UI_ITEM_NONE, nullptr, ICON_NONE);
218 }
219 else if (mode == MOD_GREASE_PENCIL_SIMPLIFY_MERGE) {
220 uiItemR(layout, ptr, "distance", UI_ITEM_NONE, nullptr, ICON_NONE);
221 }
222
223 if (uiLayout *influence_panel = uiLayoutPanelProp(
224 C, layout, ptr, "open_influence_panel", IFACE_("Influence")))
225 {
228 }
229
230 modifier_panel_end(layout, ptr);
231}
232
237
238} // namespace blender
239
241 /*idname*/ "GreasePencilSimplifyModifier",
242 /*name*/ N_("Simplify"),
243 /*struct_name*/ "GreasePencilSimplifyModifierData",
244 /*struct_size*/ sizeof(GreasePencilSimplifyModifierData),
245 /*srna*/ &RNA_GreasePencilSimplifyModifier,
247 /*flags*/
250 /*icon*/ ICON_MOD_SIMPLIFY,
251
252 /*copy_data*/ blender::copy_data,
253
254 /*deform_verts*/ nullptr,
255 /*deform_matrices*/ nullptr,
256 /*deform_verts_EM*/ nullptr,
257 /*deform_matrices_EM*/ nullptr,
258 /*modify_mesh*/ nullptr,
259 /*modify_geometry_set*/ blender::modify_geometry_set,
260
261 /*init_data*/ blender::init_data,
262 /*required_data_mask*/ nullptr,
263 /*free_data*/ blender::free_data,
264 /*is_disabled*/ nullptr,
265 /*update_depsgraph*/ nullptr,
266 /*depends_on_time*/ nullptr,
267 /*depends_on_normals*/ nullptr,
268 /*foreach_ID_link*/ blender::foreach_ID_link,
269 /*foreach_tex_link*/ nullptr,
270 /*free_runtime_data*/ nullptr,
271 /*panel_register*/ blender::panel_register,
272 /*blend_write*/ blender::blend_write,
273 /*blend_read*/ blender::blend_read,
274 /*foreach_cache*/ nullptr,
275};
Low-level operations for grease pencil.
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_AcceptsGreasePencil
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
void(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
#define BLI_assert(a)
Definition BLI_assert.h:50
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define IFACE_(msgid)
#define DNA_struct_default_get(struct_name)
@ MOD_GREASE_PENCIL_SIMPLIFY_FIXED
@ MOD_GREASE_PENCIL_SIMPLIFY_MERGE
@ MOD_GREASE_PENCIL_SIMPLIFY_ADAPTIVE
@ MOD_GREASE_PENCIL_SIMPLIFY_SAMPLE
struct GreasePencilSimplifyModifierData GreasePencilSimplifyModifierData
@ eModifierType_GreasePencilSimplify
ModifierTypeInfo modifierType_GreasePencilSimplify
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
PanelLayout uiLayoutPanelProp(const bContext *C, uiLayout *layout, PointerRNA *open_prop_owner, const char *open_prop_name)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
void remove_points(const IndexMask &points_to_delete, const AttributeFilter &attribute_filter)
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
CurvesGeometry curves_copy_point_selection(const CurvesGeometry &curves, const IndexMask &points_to_copy, const AttributeFilter &attribute_filter)
blender::bke::CurvesGeometry curves_merge_by_distance(const bke::CurvesGeometry &src_curves, const float merge_distance, const IndexMask &selection, const bke::AttributeFilter &attribute_filter)
IndexMask simplify_curve_attribute(const Span< float3 > positions, const IndexMask &curves_selection, const OffsetIndices< int > points_by_curve, const VArray< bool > &cyclic, float epsilon, GSpan attribute_data, IndexMaskMemory &memory)
CurvesGeometry resample_to_length(const CurvesGeometry &src_curves, const IndexMask &selection, const VArray< float > &sample_lengths, const ResampleCurvesOutputAttributeIDs &output_ids={})
T pow(const T &x, const T &power)
void read_influence_data(BlendDataReader *reader, GreasePencilModifierInfluenceData *influence_data)
void init_influence_data(GreasePencilModifierInfluenceData *influence_data, const bool has_custom_curve)
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)
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)
void write_influence_data(BlendWriter *writer, const GreasePencilModifierInfluenceData *influence_data)
Vector< bke::greasepencil::Drawing * > get_drawings_for_write(GreasePencil &grease_pencil, const IndexMask &layer_mask, const int frame)
void draw_material_filter_settings(const bContext *, uiLayout *layout, PointerRNA *ptr)
void draw_layer_filter_settings(const bContext *, uiLayout *layout, PointerRNA *ptr)
void free_influence_data(GreasePencilModifierInfluenceData *influence_data)
void foreach_influence_ID_link(GreasePencilModifierInfluenceData *influence_data, Object *ob, IDWalkFunc walk, void *user_data)
void copy_influence_data(const GreasePencilModifierInfluenceData *influence_data_src, GreasePencilModifierInfluenceData *influence_data_dst, const int)
void ensure_no_bezier_curves(Drawing &drawing)
void parallel_for_each(Range &&range, const Function &function)
Definition BLI_task.hh:58
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
static IndexMask simplify_fixed(const bke::CurvesGeometry &curves, const int step, IndexMaskMemory &memory)
static void init_data(ModifierData *md)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void panel_draw(const bContext *C, Panel *panel)
static void modify_geometry_set(ModifierData *md, const ModifierEvalContext *ctx, bke::GeometrySet *geometry_set)
static void free_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void simplify_drawing(const GreasePencilSimplifyModifierData &mmd, const Object &ob, bke::greasepencil::Drawing &drawing)
static void blend_read(BlendDataReader *reader, ModifierData *md)
int RNA_enum_get(PointerRNA *ptr, const char *name)
__int64 int64_t
Definition stdint.h:89
GreasePencilModifierInfluenceData influence
GreasePencilRuntimeHandle * runtime
Definition DNA_ID.h:413
struct uiLayout * layout
GreasePencil * get_grease_pencil_for_write()
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138