Blender V4.3
MOD_grease_pencil_dash.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_range.hh"
10#include "BLI_span.hh"
11#include "BLI_string.h"
12#include "BLI_string_utf8.h"
13
14#include "DNA_defaults.h"
15#include "DNA_modifier_types.h"
16
17#include "BKE_curves.hh"
18#include "BKE_geometry_set.hh"
19#include "BKE_grease_pencil.hh"
20#include "BKE_instances.hh"
21#include "BKE_modifier.hh"
22#include "BKE_screen.hh"
23
24#include "BLO_read_write.hh"
25
26#include "UI_interface.hh"
27#include "UI_resources.hh"
28
29#include "BLT_translation.hh"
30
31#include "WM_api.hh"
32#include "WM_types.hh"
33
34#include "RNA_access.hh"
35#include "RNA_prototypes.hh"
36
38#include "MOD_ui_common.hh"
39
40namespace blender {
41
42static void init_data(ModifierData *md)
43{
44 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
45
47
49 modifier::greasepencil::init_influence_data(&dmd->influence, false);
50
52 STRNCPY_UTF8(ds->name, DATA_("Segment"));
53 dmd->segments_array = ds;
54 dmd->segments_num = 1;
55}
56
57static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
58{
59 const auto *dmd = reinterpret_cast<const GreasePencilDashModifierData *>(md);
60 auto *tmmd = reinterpret_cast<GreasePencilDashModifierData *>(target);
61
63
65 modifier::greasepencil::copy_influence_data(&dmd->influence, &tmmd->influence, flag);
66
67 tmmd->segments_array = static_cast<GreasePencilDashModifierSegment *>(
68 MEM_dupallocN(dmd->segments_array));
69}
70
71static void free_data(ModifierData *md)
72{
73 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
75
76 MEM_SAFE_FREE(dmd->segments_array);
77}
78
79static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
80{
81 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
82 modifier::greasepencil::foreach_influence_ID_link(&dmd->influence, ob, walk, user_data);
83}
84
85static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
86{
87 const auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
88 /* Enable if at least one segment has non-zero length. */
89 for (const GreasePencilDashModifierSegment &dash_segment : dmd->segments()) {
90 if (dash_segment.dash + dash_segment.gap - 1 > 0) {
91 return false;
92 }
93 }
94 return true;
95}
96
97static int floored_modulo(const int a, const int b)
98{
99 return a - math::floor(float(a) / float(b)) * b;
100}
101
102/* Combined segment info used by all strokes. */
112
114{
115 PatternInfo info;
116 for (const GreasePencilDashModifierSegment &dash_segment : dmd.segments()) {
117 info.length += dash_segment.dash + dash_segment.gap;
118 }
119
120 info.segments.reinitialize(dmd.segments().size());
121 info.cyclic.reinitialize(dmd.segments().size());
122 info.material.reinitialize(dmd.segments().size());
123 info.radius.reinitialize(dmd.segments().size());
124 info.opacity.reinitialize(dmd.segments().size());
125 info.offset = floored_modulo(dmd.dash_offset, info.length);
126
127 /* Store segments as ranges. */
128 IndexRange dash_range(0);
129 IndexRange gap_range(0);
130 for (const int i : dmd.segments().index_range()) {
131 const GreasePencilDashModifierSegment &dash_segment = dmd.segments()[i];
132 dash_range = gap_range.after(dash_segment.dash);
133 gap_range = dash_range.after(dash_segment.gap);
134 info.segments[i] = dash_range;
135 info.cyclic[i] = dash_segment.flag & MOD_GREASE_PENCIL_DASH_USE_CYCLIC;
136 info.material[i] = dash_segment.mat_nr;
137 info.radius[i] = dash_segment.radius;
138 info.opacity[i] = dash_segment.opacity;
139 }
140 return info;
141}
142
143/* Returns the segment covering the given index, including repetitions. */
144static int find_dash_segment(const PatternInfo &pattern_info, const int index)
145{
146 const int repeat = index / pattern_info.length;
147 const int segments_num = pattern_info.segments.size();
148
149 const int local_index = index - repeat * pattern_info.length;
150 for (const int i : pattern_info.segments.index_range().drop_back(1)) {
151 const IndexRange segment = pattern_info.segments[i];
152 const IndexRange next_segment = pattern_info.segments[i + 1];
153 if (local_index >= segment.start() && local_index < next_segment.start()) {
154 return i + repeat * segments_num;
155 }
156 }
157 return segments_num - 1 + repeat * segments_num;
158}
159
165static void foreach_dash(const PatternInfo &pattern_info,
166 const IndexRange src_points,
167 const bool cyclic,
168 FunctionRef<void(IndexRange, bool, int, float, float)> fn)
169{
170 const int points_num = src_points.size();
171 const int segments_num = pattern_info.segments.size();
172
173 const int first_segment = find_dash_segment(pattern_info, pattern_info.offset);
174 const int last_segment = find_dash_segment(pattern_info, pattern_info.offset + points_num - 1);
175 BLI_assert(first_segment < segments_num);
176 BLI_assert(last_segment >= first_segment);
177
178 const IndexRange all_segments = IndexRange(first_segment, last_segment - first_segment + 1);
179 for (const int i : all_segments) {
180 const int repeat = i / segments_num;
181 const int segment_index = i - repeat * segments_num;
182 const IndexRange range = pattern_info.segments[segment_index].shift(repeat *
183 pattern_info.length);
184
185 const int64_t point_shift = src_points.start() - pattern_info.offset;
186 const int64_t min_point = src_points.start();
187 const int64_t max_point = cyclic ? src_points.one_after_last() : src_points.last();
188 const int64_t start = std::clamp(range.start() + point_shift, min_point, max_point);
189 const int64_t end = std::clamp(range.one_after_last() + point_shift, min_point, max_point + 1);
190
191 IndexRange points(start, end - start);
192 if (!points.is_empty()) {
193 fn(points,
194 pattern_info.cyclic[segment_index],
195 pattern_info.material[segment_index],
196 pattern_info.radius[segment_index],
197 pattern_info.opacity[segment_index]);
198 }
199 }
200}
201
203 const bke::CurvesGeometry &src_curves,
204 const IndexMask &curves_mask)
205{
206 const bke::AttributeAccessor src_attributes = src_curves.attributes();
207 const VArray<bool> src_cyclic = src_curves.cyclic();
208 const VArray<int> src_material = *src_attributes.lookup_or_default(
209 "material_index", bke::AttrDomain::Curve, 0);
210 const VArray<float> src_radius = *src_attributes.lookup_or_default<float>(
211 "radius", bke::AttrDomain::Point, 0.01f);
212 const VArray<float> src_opacity = *src_attributes.lookup_or_default<float>(
213 "opacity", bke::AttrDomain::Point, 1.0f);
214
215 /* Count new curves and points. */
216 int dst_point_num = 0;
217 int dst_curve_num = 0;
218 curves_mask.foreach_index([&](const int64_t src_curve_i) {
219 const IndexRange src_points = src_curves.points_by_curve()[src_curve_i];
220
221 foreach_dash(pattern_info,
222 src_points,
223 src_cyclic[src_curve_i],
224 [&](const IndexRange copy_points,
225 bool /*cyclic*/,
226 int /*material*/,
227 float /*radius*/,
228 float /*opacity*/) {
229 dst_point_num += copy_points.size();
230 dst_curve_num += 1;
231 });
232 });
233
234 bke::CurvesGeometry dst_curves(dst_point_num, dst_curve_num);
235 bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
236 bke::SpanAttributeWriter<bool> dst_cyclic = dst_attributes.lookup_or_add_for_write_span<bool>(
237 "cyclic", bke::AttrDomain::Curve);
238 bke::SpanAttributeWriter<int> dst_material = dst_attributes.lookup_or_add_for_write_span<int>(
239 "material_index", bke::AttrDomain::Curve);
240 bke::SpanAttributeWriter<float> dst_radius = dst_attributes.lookup_or_add_for_write_span<float>(
241 "radius", bke::AttrDomain::Point);
242 bke::SpanAttributeWriter<float> dst_opacity = dst_attributes.lookup_or_add_for_write_span<float>(
243 "opacity", bke::AttrDomain::Point);
244 /* Map each destination point and curve to its source. */
245 Array<int> src_point_indices(dst_point_num);
246 Array<int> src_curve_indices(dst_curve_num);
247
248 {
249 /* Start at curve offset and add points for each dash. */
250 IndexRange dst_point_range(0);
251 int dst_curve_i = 0;
252 auto add_dash_curve = [&](const int src_curve,
253 const IndexRange src_points,
254 const IndexRange copy_points,
255 bool cyclic,
256 int material,
257 float radius,
258 float opacity) {
259 dst_point_range = dst_point_range.after(copy_points.size());
260 dst_curves.offsets_for_write()[dst_curve_i] = dst_point_range.start();
261
262 if (src_points.contains(copy_points.last())) {
263 array_utils::fill_index_range(src_point_indices.as_mutable_span().slice(dst_point_range),
264 int(copy_points.start()));
265 }
266 else {
267 /* Cyclic curve. */
269 src_point_indices.as_mutable_span().slice(dst_point_range.drop_back(1)),
270 int(copy_points.start()));
271 src_point_indices[dst_point_range.last()] = src_points.first();
272 }
273 src_curve_indices[dst_curve_i] = src_curve;
274 dst_cyclic.span[dst_curve_i] = cyclic;
275 dst_material.span[dst_curve_i] = material >= 0 ? material : src_material[src_curve];
276 for (const int i : dst_point_range) {
277 dst_radius.span[i] = src_radius[src_point_indices[i]] * radius;
278 dst_opacity.span[i] = src_opacity[src_point_indices[i]] * opacity;
279 }
280
281 ++dst_curve_i;
282 };
283
284 curves_mask.foreach_index([&](const int64_t src_curve_i) {
285 const IndexRange src_points = src_curves.points_by_curve()[src_curve_i];
286 foreach_dash(pattern_info,
287 src_points,
288 src_cyclic[src_curve_i],
289 [&](const IndexRange copy_points,
290 bool cyclic,
291 int material,
292 float radius,
293 float opacity) {
294 add_dash_curve(
295 src_curve_i, src_points, copy_points, cyclic, material, radius, opacity);
296 });
297 });
298 if (dst_curve_i > 0) {
299 /* Last offset entry is total point count. */
300 dst_curves.offsets_for_write()[dst_curve_i] = dst_point_range.one_after_last();
301 }
302 }
303
304 bke::gather_attributes(src_attributes,
307 bke::attribute_filter_from_skip_ref({"radius", "opacity"}),
308 src_point_indices,
309 dst_attributes);
310 bke::gather_attributes(src_attributes,
313 bke::attribute_filter_from_skip_ref({"cyclic", "material_index"}),
314 src_curve_indices,
315 dst_attributes);
316
317 dst_cyclic.finish();
318 dst_material.finish();
319 dst_radius.finish();
320 dst_opacity.finish();
321 dst_curves.update_curve_types();
322
323 return dst_curves;
324}
325
327 const ModifierEvalContext &ctx,
328 const PatternInfo &pattern_info,
330{
332 const bke::CurvesGeometry &src_curves = drawing.strokes();
333 if (src_curves.curve_num == 0) {
334 return;
335 }
336 /* Selected source curves. */
337 IndexMaskMemory curve_mask_memory;
339 ctx.object, src_curves, dmd.influence, curve_mask_memory);
340
341 drawing.strokes_for_write() = create_dashes(pattern_info, src_curves, curves_mask);
342 drawing.tag_topology_changed();
343}
344
346 const ModifierEvalContext *ctx,
347 bke::GeometrySet *geometry_set)
348{
350
351 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
352
353 if (!geometry_set->has_grease_pencil()) {
354 return;
355 }
356 GreasePencil &grease_pencil = *geometry_set->get_grease_pencil_for_write();
357 const int frame = grease_pencil.runtime->eval_frame;
358
359 const PatternInfo pattern_info = get_pattern_info(*dmd);
360
361 IndexMaskMemory mask_memory;
363 grease_pencil, dmd->influence, mask_memory);
364
366 grease_pencil, layer_mask, frame);
368 drawings, [&](Drawing *drawing) { modify_drawing(*dmd, *ctx, pattern_info, *drawing); });
369}
370
371static void panel_draw(const bContext *C, Panel *panel)
372{
373 uiLayout *layout = panel->layout;
374
375 PointerRNA ob_ptr;
377 auto *dmd = static_cast<GreasePencilDashModifierData *>(ptr->data);
378
379 uiLayoutSetPropSep(layout, true);
380
381 uiItemR(layout, ptr, "dash_offset", UI_ITEM_NONE, nullptr, ICON_NONE);
382
383 uiLayout *row = uiLayoutRow(layout, false);
384 uiLayoutSetPropSep(row, false);
385
386 uiTemplateList(row,
387 (bContext *)C,
388 "MOD_UL_grease_pencil_dash_modifier_segments",
389 "",
390 ptr,
391 "segments",
392 ptr,
393 "segment_active_index",
394 nullptr,
395 3,
396 10,
397 0,
398 1,
400
401 uiLayout *col = uiLayoutColumn(row, false);
402 uiLayout *sub = uiLayoutColumn(col, true);
403 uiItemO(sub, "", ICON_ADD, "OBJECT_OT_grease_pencil_dash_modifier_segment_add");
404 uiItemO(sub, "", ICON_REMOVE, "OBJECT_OT_grease_pencil_dash_modifier_segment_remove");
405 uiItemS(col);
406 sub = uiLayoutColumn(col, true);
408 sub, "", ICON_TRIA_UP, "OBJECT_OT_grease_pencil_dash_modifier_segment_move", "type", "UP");
410 "",
411 ICON_TRIA_DOWN,
412 "OBJECT_OT_grease_pencil_dash_modifier_segment_move",
413 "type",
414 "DOWN");
415
416 if (dmd->segment_active_index >= 0 && dmd->segment_active_index < dmd->segments_num) {
418 &RNA_GreasePencilDashModifierSegment,
419 &dmd->segments()[dmd->segment_active_index]);
420
421 sub = uiLayoutColumn(layout, true);
422 uiItemR(sub, &ds_ptr, "dash", UI_ITEM_NONE, nullptr, ICON_NONE);
423 uiItemR(sub, &ds_ptr, "gap", UI_ITEM_NONE, nullptr, ICON_NONE);
424
425 sub = uiLayoutColumn(layout, false);
426 uiItemR(sub, &ds_ptr, "radius", UI_ITEM_NONE, nullptr, ICON_NONE);
427 uiItemR(sub, &ds_ptr, "opacity", UI_ITEM_NONE, nullptr, ICON_NONE);
428 uiItemR(sub, &ds_ptr, "material_index", UI_ITEM_NONE, nullptr, ICON_NONE);
429 uiItemR(sub, &ds_ptr, "use_cyclic", UI_ITEM_NONE, nullptr, ICON_NONE);
430 }
431
432 if (uiLayout *influence_panel = uiLayoutPanelProp(
433 C, layout, ptr, "open_influence_panel", IFACE_("Influence")))
434 {
437 }
438
439 modifier_panel_end(layout, ptr);
440}
441
442static void segment_list_item_draw(uiList * /*ui_list*/,
443 const bContext * /*C*/,
444 uiLayout *layout,
445 PointerRNA * /*idataptr*/,
446 PointerRNA *itemptr,
447 int /*icon*/,
448 PointerRNA * /*active_dataptr*/,
449 const char * /*active_propname*/,
450 int /*index*/,
451 int /*flt_flag*/)
452{
453 uiLayout *row = uiLayoutRow(layout, true);
454 uiItemR(row, itemptr, "name", UI_ITEM_R_NO_BG, "", ICON_NONE);
455}
456
457static void panel_register(ARegionType *region_type)
458{
460
461 uiListType *list_type = static_cast<uiListType *>(
462 MEM_callocN(sizeof(uiListType), "Grease Pencil Dash modifier segments"));
463 STRNCPY(list_type->idname, "MOD_UL_grease_pencil_dash_modifier_segments");
465 WM_uilisttype_add(list_type);
466}
467
468static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
469{
470 const auto *dmd = reinterpret_cast<const GreasePencilDashModifierData *>(md);
471
473 modifier::greasepencil::write_influence_data(writer, &dmd->influence);
474
476 writer, GreasePencilDashModifierSegment, dmd->segments_num, dmd->segments_array);
477}
478
479static void blend_read(BlendDataReader *reader, ModifierData *md)
480{
481 auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
482
483 modifier::greasepencil::read_influence_data(reader, &dmd->influence);
484
486 reader, GreasePencilDashModifierSegment, dmd->segments_num, &dmd->segments_array);
487}
488
489} // namespace blender
490
492 /*idname*/ "GreasePencilDash",
493 /*name*/ N_("Dot Dash"),
494 /*struct_name*/ "GreasePencilDashModifierData",
495 /*struct_size*/ sizeof(GreasePencilDashModifierData),
496 /*srna*/ &RNA_GreasePencilDashModifierData,
500 /*icon*/ ICON_MOD_DASH,
501
502 /*copy_data*/ blender::copy_data,
503
504 /*deform_verts*/ nullptr,
505 /*deform_matrices*/ nullptr,
506 /*deform_verts_EM*/ nullptr,
507 /*deform_matrices_EM*/ nullptr,
508 /*modify_mesh*/ nullptr,
509 /*modify_geometry_set*/ blender::modify_geometry_set,
510
511 /*init_data*/ blender::init_data,
512 /*required_data_mask*/ nullptr,
513 /*free_data*/ blender::free_data,
514 /*is_disabled*/ blender::is_disabled,
515 /*update_depsgraph*/ nullptr,
516 /*depends_on_time*/ nullptr,
517 /*depends_on_normals*/ nullptr,
518 /*foreach_ID_link*/ blender::foreach_ID_link,
519 /*foreach_tex_link*/ nullptr,
520 /*free_runtime_data*/ nullptr,
521 /*panel_register*/ blender::panel_register,
522 /*blend_write*/ blender::blend_write,
523 /*blend_read*/ blender::blend_read,
524};
525
526blender::Span<GreasePencilDashModifierSegment> GreasePencilDashModifierData::segments() const
527{
528 return {this->segments_array, this->segments_num};
529}
530
531blender::MutableSpan<GreasePencilDashModifierSegment> GreasePencilDashModifierData::segments()
532{
533 return {this->segments_array, this->segments_num};
534}
Low-level operations for curves.
Low-level operations for grease pencil.
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsMapping
@ 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 STRNCPY(dst, src)
Definition BLI_string.h:593
#define STRNCPY_UTF8(dst, src)
#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 BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
#define IFACE_(msgid)
#define DATA_(msgid)
#define DNA_struct_default_get(struct_name)
#define DNA_struct_default_alloc(struct_name)
struct GreasePencilDashModifierData GreasePencilDashModifierData
@ MOD_GREASE_PENCIL_DASH_USE_CYCLIC
@ eModifierType_GreasePencilDash
static bool is_disabled
#define MEM_SAFE_FREE(v)
ModifierTypeInfo modifierType_GreasePencilDash
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 uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value_str)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
void uiTemplateList(uiLayout *layout, const bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns, enum uiTemplateListFlags flags)
#define UI_ITEM_NONE
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
PanelLayout uiLayoutPanelProp(const bContext *C, uiLayout *layout, PointerRNA *open_prop_owner, const char *open_prop_name)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
@ UI_TEMPLATE_LIST_FLAG_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_NO_BG
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:388
constexpr int64_t one_after_last() const
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr IndexRange after(int64_t n) const
constexpr int64_t start() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
OffsetIndices< int > points_by_curve() const
MutableAttributeAccessor attributes_for_write()
MutableSpan< int > offsets_for_write()
VArray< bool > cyclic() const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
void foreach_index(Fn &&fn) const
local_group_size(16, 16) .push_constant(Type b
Material material
uint col
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
void fill_index_range(MutableSpan< T > span, const T start=0)
auto attribute_filter_from_skip_ref(const Span< StringRef > skip)
void gather_attributes(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
T floor(const T &a)
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 int floored_modulo(const int a, const int b)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
static void segment_list_item_draw(uiList *, const bContext *, uiLayout *layout, PointerRNA *, PointerRNA *itemptr, int, PointerRNA *, const char *, int, int)
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 foreach_dash(const PatternInfo &pattern_info, const IndexRange src_points, const bool cyclic, FunctionRef< void(IndexRange, bool, int, float, float)> fn)
static bke::CurvesGeometry create_dashes(const PatternInfo &pattern_info, const bke::CurvesGeometry &src_curves, const IndexMask &curves_mask)
static void modify_drawing(const GreasePencilArrayModifierData &mmd, const ModifierEvalContext &ctx, bke::greasepencil::Drawing &drawing)
static int find_dash_segment(const PatternInfo &pattern_info, const int index)
static PatternInfo get_pattern_info(const GreasePencilDashModifierData &dmd)
static bool is_disabled(const Scene *, ModifierData *md, bool)
static void blend_read(BlendDataReader *reader, ModifierData *md)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
__int64 int64_t
Definition stdint.h:89
GreasePencilModifierInfluenceData influence
GreasePencilDashModifierSegment * segments_array
GreasePencilRuntimeHandle * runtime
Definition DNA_ID.h:413
struct uiLayout * layout
ID * owner_id
Definition RNA_types.hh:40
void * data
Definition RNA_types.hh:42
GreasePencil * get_grease_pencil_for_write()
char idname[BKE_ST_MAXNAME]
uiListDrawItemFunc draw_item
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126
bool WM_uilisttype_add(uiListType *ult)
uint8_t flag
Definition wm_window.cc:138