Blender V4.3
MOD_grease_pencil_offset.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_hash.h"
10#include "BLI_math_matrix.hh"
11#include "BLI_rand.h"
12
13#include "DNA_defaults.h"
14#include "DNA_modifier_types.h"
15
16#include "BKE_curves.hh"
17#include "BKE_geometry_set.hh"
18#include "BKE_grease_pencil.hh"
19#include "BKE_material.h"
20#include "BKE_modifier.hh"
21#include "BKE_screen.hh"
22
23#include "BLO_read_write.hh"
24
25#include "UI_interface.hh"
26#include "UI_resources.hh"
27
28#include "BLT_translation.hh"
29
30#include "WM_types.hh"
31
32#include "RNA_access.hh"
33#include "RNA_prototypes.hh"
34
36#include "MOD_modifiertypes.hh"
37#include "MOD_ui_common.hh"
38
39namespace blender {
40
41static void init_data(ModifierData *md)
42{
43 auto *omd = reinterpret_cast<GreasePencilOffsetModifierData *>(md);
44
46
48 modifier::greasepencil::init_influence_data(&omd->influence, false);
49}
50
51static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
52{
53 const auto *omd = reinterpret_cast<const GreasePencilOffsetModifierData *>(md);
54 auto *tomd = reinterpret_cast<GreasePencilOffsetModifierData *>(target);
55
57
59 modifier::greasepencil::copy_influence_data(&omd->influence, &tomd->influence, flag);
60}
61
62static void free_data(ModifierData *md)
63{
64 auto *omd = reinterpret_cast<GreasePencilOffsetModifierData *>(md);
66}
67
68static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
69{
70 auto *omd = reinterpret_cast<GreasePencilOffsetModifierData *>(md);
71 modifier::greasepencil::foreach_influence_ID_link(&omd->influence, ob, walk, user_data);
72}
73
75{
77 ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Grease Pencil Offset Modifier");
78}
79
81 const VArray<float> &weights,
82 const IndexRange &points,
83 const float3 &loc_factor,
84 const float3 &rot_factor,
85 const float3 &scale_factor,
86 const MutableSpan<float3> positions,
87 const MutableSpan<float> radii)
88{
89 const bool has_global_offset = !(math::is_zero(float3(omd.loc)) &&
90 math::is_zero(float3(omd.rot)) &&
92 const bool has_stroke_offset = !(math::is_zero(float3(omd.stroke_loc)) &&
95
96 for (const int64_t i : points) {
97 const float weight = weights[i];
98 float3 &pos = positions[i];
99 float &radius = radii[i];
100
101 /* Add per-stroke offset. */
102 if (has_stroke_offset) {
104 omd.stroke_loc * loc_factor * weight,
105 omd.stroke_rot * rot_factor * weight,
106 float3(1.0f) + omd.stroke_scale * scale_factor * weight);
107 pos = math::transform_point(matrix, pos);
108 }
109 /* Add global offset. */
110 if (has_global_offset) {
111 const float3 scale = float3(1.0f) + float3(omd.scale) * weight;
113 float3(omd.loc) * weight, float3(omd.rot) * weight, scale);
114 pos = math::transform_point(matrix, pos);
115
116 /* Apply scale to thickness. */
117 const float unit_scale = (math::abs(scale.x) + math::abs(scale.y) + math::abs(scale.z)) /
118 3.0f;
119 radius *= unit_scale;
120 }
121 }
122}
123
125static void modify_stroke_random(const Object &ob,
127 const IndexMask &curves_mask,
128 bke::CurvesGeometry &curves)
129{
130 const bool use_uniform_scale = (omd.flag & MOD_GREASE_PENCIL_OFFSET_UNIFORM_RANDOM_SCALE);
131
132 const OffsetIndices<int> points_by_curve = curves.points_by_curve();
133 bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
134 bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
135 "radius", bke::AttrDomain::Point);
136 const MutableSpan<float3> positions = curves.positions_for_write();
138 curves, omd.influence);
139
140 /* Make sure different modifiers get different seeds. */
141 const int seed = omd.seed + BLI_hash_string(ob.id.name + 2) + BLI_hash_string(omd.modifier.name);
142 const float rand_offset = BLI_hash_int_01(seed);
143
144 /* Generates a random number for loc/rot/scale channels, based on seed and a per-stroke random
145 * value r. */
146 auto get_random_channel = [&](const char channel, const double r) {
147 float rand = fmodf(r * 2.0f - 1.0f + rand_offset, 1.0f);
148 return fmodf(sin(rand * 12.9898f + channel * 78.233f) * 43758.5453f, 1.0f);
149 };
150
151 auto get_random_value = [&](const char channel, const int64_t curve_i) {
152 const uint halton_primes[3] = {2, 3, 7};
153 double halton_offset[3] = {0.0f, 0.0f, 0.0f};
154 double r[3];
155 /* To ensure a nice distribution, we use halton sequence and offset using the curve index. */
156 BLI_halton_3d(halton_primes, halton_offset, curve_i, r);
157 return get_random_channel(channel, r[0]);
158 };
159
160 auto get_random_vector = [&](const char channel, const int64_t curve_i) {
161 const uint halton_primes[3] = {2, 3, 7};
162 double halton_offset[3] = {0.0f, 0.0f, 0.0f};
163 double r[3];
164 /* To ensure a nice distribution, we use halton sequence and offset using the curve index. */
165 BLI_halton_3d(halton_primes, halton_offset, curve_i, r);
166 return float3(get_random_channel(channel, r[0]),
167 get_random_channel(channel, r[1]),
168 get_random_channel(channel, r[2]));
169 };
170
171 curves_mask.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
172 const IndexRange points = points_by_curve[curve_i];
173
174 /* Randomness factors for loc/rot/scale per curve. */
175 const float3 loc_factor = get_random_vector(0, curve_i);
176 const float3 rot_factor = get_random_vector(1, curve_i);
177 const float3 scale_factor = use_uniform_scale ? float3(get_random_value(2, curve_i)) :
178 get_random_vector(2, curve_i);
179
181 omd, vgroup_weights, points, loc_factor, rot_factor, scale_factor, positions, radii.span);
182 });
183
184 radii.finish();
185}
186
187/* This is a very weird/broken formula, but kept for compatibility. */
189 const int size,
190 const int index)
191{
192 const int step = max_ii(omd.stroke_step, 1);
193 const int start_offset = omd.stroke_start_offset;
194 return ((size - (index / step + start_offset % size) % size * step % size) - 1) / float(size);
195}
196
199 const IndexMask &curves_mask,
200 bke::CurvesGeometry &curves)
201{
202 const OffsetIndices<int> points_by_curve = curves.points_by_curve();
203 bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
204 bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
205 "radius", bke::AttrDomain::Point);
206 const MutableSpan<float3> positions = curves.positions_for_write();
208 curves, omd.influence);
209
210 curves_mask.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
211 const IndexRange points = points_by_curve[curve_i];
212 const float factor = get_factor_from_index(omd, curves.curves_num(), curve_i);
214 vgroup_weights,
215 points,
216 float3(factor),
217 float3(factor),
218 float3(factor),
219 positions,
220 radii.span);
221 });
222
223 radii.finish();
224}
225
227static void modify_stroke_by_material(const Object &ob,
229 const IndexMask &curves_mask,
230 bke::CurvesGeometry &curves)
231{
232 const short *totcolp = BKE_object_material_len_p(const_cast<Object *>(&ob));
233 const short totcol = totcolp ? *totcolp : 0;
234
235 const OffsetIndices<int> points_by_curve = curves.points_by_curve();
236 bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
237 bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
238 "radius", bke::AttrDomain::Point);
239 const MutableSpan<float3> positions = curves.positions_for_write();
241 curves, omd.influence);
242 const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
243 "material_index", bke::AttrDomain::Curve, 0);
244
245 curves_mask.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
246 const IndexRange points = points_by_curve[curve_i];
247 const float factor = get_factor_from_index(omd, totcol, stroke_materials[curve_i]);
249 vgroup_weights,
250 points,
251 float3(factor),
252 float3(factor),
253 float3(factor),
254 positions,
255 radii.span);
256 });
257
258 radii.finish();
259}
260
263 const int layer_index,
264 const int layers_num,
265 const IndexMask &curves_mask,
266 bke::CurvesGeometry &curves)
267{
268 const OffsetIndices<int> points_by_curve = curves.points_by_curve();
269 bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
270 bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
271 "radius", bke::AttrDomain::Point);
272 const MutableSpan<float3> positions = curves.positions_for_write();
274 curves, omd.influence);
275
276 const float factor = get_factor_from_index(omd, layers_num, layer_index);
277
278 curves_mask.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
279 const IndexRange points = points_by_curve[curve_i];
281 vgroup_weights,
282 points,
283 float3(factor),
284 float3(factor),
285 float3(factor),
286 positions,
287 radii.span);
288 });
289
290 radii.finish();
291}
292
293static void modify_drawing(const ModifierData &md,
294 const ModifierEvalContext &ctx,
296{
297 const auto &omd = reinterpret_cast<const GreasePencilOffsetModifierData &>(md);
298
299 bke::CurvesGeometry &curves = drawing.strokes_for_write();
300 IndexMaskMemory mask_memory;
302 ctx.object, curves, omd.influence, mask_memory);
303
304 switch (omd.offset_mode) {
306 modify_stroke_random(*ctx.object, omd, curves_mask, curves);
307 break;
309 modify_stroke_by_material(*ctx.object, omd, curves_mask, curves);
310 break;
312 modify_stroke_by_index(omd, curves_mask, curves);
313 break;
316 break;
317 }
318}
319
321 const ModifierEvalContext &ctx,
323 int layer_index,
324 int layers_num)
325{
326 const auto &omd = reinterpret_cast<const GreasePencilOffsetModifierData &>(md);
327
328 bke::CurvesGeometry &curves = drawing.strokes_for_write();
329 IndexMaskMemory mask_memory;
331 ctx.object, curves, omd.influence, mask_memory);
332
333 switch (omd.offset_mode) {
335 modify_stroke_by_layer(omd, layer_index, layers_num, curves_mask, curves);
336 break;
341 break;
342 }
343}
344
346 const ModifierEvalContext *ctx,
347 bke::GeometrySet *geometry_set)
348{
351
352 auto *omd = reinterpret_cast<GreasePencilOffsetModifierData *>(md);
353
354 if (!geometry_set->has_grease_pencil()) {
355 return;
356 }
357 GreasePencil &grease_pencil = *geometry_set->get_grease_pencil_for_write();
358 const int frame = grease_pencil.runtime->eval_frame;
359
360 IndexMaskMemory mask_memory;
362 grease_pencil, omd->influence, mask_memory);
363
364 if (omd->offset_mode == MOD_GREASE_PENCIL_OFFSET_LAYER) {
366 grease_pencil, layer_mask, frame);
367 threading::parallel_for_each(drawings, [&](const LayerDrawingInfo &info) {
369 *md, *ctx, *info.drawing, info.layer_index, grease_pencil.layers().size());
370 });
371 }
372 else {
374 grease_pencil, layer_mask, frame);
376 [&](Drawing *drawing) { modify_drawing(*md, *ctx, *drawing); });
377 }
378}
379
380static void panel_draw(const bContext *C, Panel *panel)
381{
382 uiLayout *layout = panel->layout;
383
384 PointerRNA ob_ptr;
386 const auto offset_mode = GreasePencilOffsetModifierMode(RNA_enum_get(ptr, "offset_mode"));
387
388 uiLayoutSetPropSep(layout, true);
389 if (uiLayout *general_panel = uiLayoutPanelProp(
390 C, layout, ptr, "open_general_panel", IFACE_("General")))
391 {
392 uiLayoutSetPropSep(general_panel, true);
393 uiItemR(general_panel, ptr, "location", UI_ITEM_NONE, nullptr, ICON_NONE);
394 uiItemR(general_panel, ptr, "rotation", UI_ITEM_NONE, nullptr, ICON_NONE);
395 uiItemR(general_panel, ptr, "scale", UI_ITEM_NONE, nullptr, ICON_NONE);
396 }
397
399 panel, "advanced", true);
400 PointerRNA advanced_state_ptr = RNA_pointer_create(
401 nullptr, &RNA_LayoutPanelState, advanced_panel_state);
402 if (uiLayout *advanced_panel = uiLayoutPanelProp(
403 C, layout, &advanced_state_ptr, "is_open", IFACE_("Advanced")))
404 {
405 uiItemR(advanced_panel, ptr, "offset_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
406
407 uiItemR(advanced_panel, ptr, "stroke_location", UI_ITEM_NONE, IFACE_("Offset"), ICON_NONE);
408 uiItemR(advanced_panel, ptr, "stroke_rotation", UI_ITEM_NONE, IFACE_("Rotation"), ICON_NONE);
409 uiItemR(advanced_panel, ptr, "stroke_scale", UI_ITEM_NONE, IFACE_("Scale"), ICON_NONE);
410
411 uiLayout *col = uiLayoutColumn(advanced_panel, true);
412 switch (offset_mode) {
414 uiItemR(advanced_panel, ptr, "use_uniform_random_scale", UI_ITEM_NONE, nullptr, ICON_NONE);
415 uiItemR(advanced_panel, ptr, "seed", UI_ITEM_NONE, nullptr, ICON_NONE);
416 break;
418 uiItemR(col, ptr, "stroke_step", UI_ITEM_NONE, IFACE_("Stroke Step"), ICON_NONE);
419 uiItemR(col, ptr, "stroke_start_offset", UI_ITEM_NONE, IFACE_("Offset"), ICON_NONE);
420 break;
422 uiItemR(col, ptr, "stroke_step", UI_ITEM_NONE, IFACE_("Material Step"), ICON_NONE);
423 uiItemR(col, ptr, "stroke_start_offset", UI_ITEM_NONE, IFACE_("Offset"), ICON_NONE);
424 break;
426 uiItemR(col, ptr, "stroke_step", UI_ITEM_NONE, IFACE_("Layer Step"), ICON_NONE);
427 uiItemR(col, ptr, "stroke_start_offset", UI_ITEM_NONE, IFACE_("Offset"), ICON_NONE);
428 break;
429 }
430 }
431
432 if (uiLayout *influence_panel = uiLayoutPanelProp(
433 C, layout, ptr, "open_influence_panel", IFACE_("Influence")))
434 {
438 }
439
440 modifier_panel_end(layout, ptr);
441}
442
447
448static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
449{
450 const auto *omd = reinterpret_cast<const GreasePencilOffsetModifierData *>(md);
451
453 modifier::greasepencil::write_influence_data(writer, &omd->influence);
454}
455
456static void blend_read(BlendDataReader *reader, ModifierData *md)
457{
458 auto *omd = reinterpret_cast<GreasePencilOffsetModifierData *>(md);
459
460 modifier::greasepencil::read_influence_data(reader, &omd->influence);
461}
462
463} // namespace blender
464
466 /*idname*/ "GreasePencilOffset",
467 /*name*/ N_("Offset"),
468 /*struct_name*/ "GreasePencilOffsetModifierData",
469 /*struct_size*/ sizeof(GreasePencilOffsetModifierData),
470 /*srna*/ &RNA_GreasePencilOffsetModifier,
474 /*icon*/ ICON_MOD_OFFSET,
475
476 /*copy_data*/ blender::copy_data,
477
478 /*deform_verts*/ nullptr,
479 /*deform_matrices*/ nullptr,
480 /*deform_verts_EM*/ nullptr,
481 /*deform_matrices_EM*/ nullptr,
482 /*modify_mesh*/ nullptr,
483 /*modify_geometry_set*/ blender::modify_geometry_set,
484
485 /*init_data*/ blender::init_data,
486 /*required_data_mask*/ nullptr,
487 /*free_data*/ blender::free_data,
488 /*is_disabled*/ nullptr,
489 /*update_depsgraph*/ blender::update_depsgraph,
490 /*depends_on_time*/ nullptr,
491 /*depends_on_normals*/ nullptr,
492 /*foreach_ID_link*/ blender::foreach_ID_link,
493 /*foreach_tex_link*/ nullptr,
494 /*free_runtime_data*/ nullptr,
495 /*panel_register*/ blender::panel_register,
496 /*blend_write*/ blender::blend_write,
497 /*blend_read*/ blender::blend_read,
498};
Low-level operations for curves.
Low-level operations for grease pencil.
General operations, lookup, etc. for materials.
short * BKE_object_material_len_p(struct Object *ob)
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
LayoutPanelState * BKE_panel_layout_panel_state_ensure(Panel *panel, const char *idname, bool default_closed)
Definition screen.cc:502
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE float BLI_hash_int_01(unsigned int k)
Definition BLI_hash.h:96
BLI_INLINE unsigned int BLI_hash_string(const char *str)
Definition BLI_hash.h:71
MINLINE int max_ii(int a, int b)
Random number functions.
void BLI_halton_3d(const unsigned int prime[3], double offset[3], int n, double *r)
Definition rand.cc:308
unsigned int uint
#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)
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
@ DEG_OB_COMP_TRANSFORM
#define DNA_struct_default_get(struct_name)
@ MOD_GREASE_PENCIL_OFFSET_UNIFORM_RANDOM_SCALE
@ eModifierType_GreasePencilOffset
struct GreasePencilOffsetModifierData GreasePencilOffsetModifierData
GreasePencilOffsetModifierMode
@ MOD_GREASE_PENCIL_OFFSET_STROKE
@ MOD_GREASE_PENCIL_OFFSET_MATERIAL
@ MOD_GREASE_PENCIL_OFFSET_LAYER
@ MOD_GREASE_PENCIL_OFFSET_RANDOM
ModifierTypeInfo modifierType_GreasePencilOffset
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)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
static unsigned long seed
Definition btSoftBody.h:39
bke::CurvesGeometry & strokes_for_write()
void foreach_index(Fn &&fn) const
#define fmodf(x, y)
draw_view in_light_buf[] float
uint col
bool is_zero(const T &a)
T abs(const T &a)
MatT from_loc_rot_scale(const typename MatT::loc_type &location, const RotationT &rotation, const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void read_influence_data(BlendDataReader *reader, GreasePencilModifierInfluenceData *influence_data)
void init_influence_data(GreasePencilModifierInfluenceData *influence_data, const bool has_custom_curve)
Vector< LayerDrawingInfo > get_drawing_infos_by_layer(GreasePencil &grease_pencil, const IndexMask &layer_mask, const int frame)
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)
void draw_vertex_group_settings(const bContext *, uiLayout *layout, PointerRNA *ptr)
VArray< float > get_influence_vertex_weights(const bke::CurvesGeometry &curves, 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 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 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 modify_stroke_by_index(const GreasePencilOffsetModifierData &omd, const IndexMask &curves_mask, bke::CurvesGeometry &curves)
static void free_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void apply_stroke_transform(const GreasePencilOffsetModifierData &omd, const VArray< float > &weights, const IndexRange &points, const float3 &loc_factor, const float3 &rot_factor, const float3 &scale_factor, const MutableSpan< float3 > positions, const MutableSpan< float > radii)
static void modify_drawing(const GreasePencilArrayModifierData &mmd, const ModifierEvalContext &ctx, bke::greasepencil::Drawing &drawing)
static void modify_drawing_by_layer(const ModifierData &md, const ModifierEvalContext &ctx, bke::greasepencil::Drawing &drawing, int layer_index, int layers_num)
static float get_factor_from_index(const GreasePencilOffsetModifierData &omd, const int size, const int index)
static void modify_stroke_random(const Object &ob, const GreasePencilOffsetModifierData &omd, const IndexMask &curves_mask, bke::CurvesGeometry &curves)
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
VecBase< float, 3 > float3
static void blend_read(BlendDataReader *reader, ModifierData *md)
static void modify_stroke_by_material(const Object &ob, const GreasePencilOffsetModifierData &omd, const IndexMask &curves_mask, bke::CurvesGeometry &curves)
static void modify_stroke_by_layer(const GreasePencilOffsetModifierData &omd, const int layer_index, const int layers_num, const IndexMask &curves_mask, bke::CurvesGeometry &curves)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
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
char name[66]
Definition DNA_ID.h:425
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