Blender V4.3
MOD_grease_pencil_thickness.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 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
19#include "RNA_access.hh"
20
21#include "BKE_colortools.hh"
22#include "BKE_curves.hh"
23#include "BKE_geometry_set.hh"
24#include "BKE_grease_pencil.hh"
25#include "BKE_modifier.hh"
26
27#include "UI_interface.hh"
28#include "UI_resources.hh"
29
31#include "MOD_ui_common.hh"
32
33#include "RNA_prototypes.hh"
34
35namespace blender {
36
46
47static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
48{
50 reinterpret_cast<const GreasePencilThickModifierData *>(md);
51 GreasePencilThickModifierData *tgmd = reinterpret_cast<GreasePencilThickModifierData *>(target);
52
55}
56
63
64static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
65{
67
69}
70
71static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
72{
74 reinterpret_cast<const GreasePencilThickModifierData *>(md);
75
78}
79
85
86static void deform_drawing(const ModifierData &md,
87 const Object &ob,
89{
90 const auto &mmd = reinterpret_cast<const GreasePencilThickModifierData &>(md);
91
92 bke::CurvesGeometry &curves = drawing.strokes_for_write();
93 if (curves.points_num() == 0) {
94 return;
95 }
96
97 IndexMaskMemory memory;
99 &ob, curves, mmd.influence, memory);
100 if (strokes.is_empty()) {
101 return;
102 }
103
104 MutableSpan<float> radii = drawing.radii_for_write();
105 const OffsetIndices points_by_curve = curves.points_by_curve();
106 bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
107 const VArray<float> vgroup_weights = *attributes.lookup_or_default<float>(
108 mmd.influence.vertex_group_name, bke::AttrDomain::Point, 1.0f);
109 const bool is_normalized = (mmd.flag & MOD_GREASE_PENCIL_THICK_NORMALIZE) != 0;
110 const bool is_inverted = ((mmd.flag & MOD_GREASE_PENCIL_THICK_WEIGHT_FACTOR) == 0) &&
111 ((mmd.influence.flag & GREASE_PENCIL_INFLUENCE_INVERT_VERTEX_GROUP) !=
112 0);
113
114 strokes.foreach_index(GrainSize(512), [&](const int curve) {
115 const IndexRange points = points_by_curve[curve];
116 for (const int i : points.index_range()) {
117 const int point = points[i];
118 const float weight = vgroup_weights[point];
119 if (weight <= 0.0f) {
120 continue;
121 }
122
123 if ((!is_normalized) && (mmd.flag & MOD_GREASE_PENCIL_THICK_WEIGHT_FACTOR)) {
124 radii[point] *= (is_inverted ? 1.0f - weight : weight);
125 radii[point] = math::max(radii[point], 0.0f);
126 continue;
127 }
128
129 const float influence = [&]() {
130 if (mmd.influence.flag & GREASE_PENCIL_INFLUENCE_USE_CUSTOM_CURVE &&
131 (mmd.influence.custom_curve))
132 {
133 /* Normalize value to evaluate curve. */
134 const float value = math::safe_divide(float(i), float(points.size() - 1));
135 return BKE_curvemapping_evaluateF(mmd.influence.custom_curve, 0, value);
136 }
137 return 1.0f;
138 }();
139
140 const float target = [&]() {
141 if (is_normalized) {
142 return mmd.thickness * influence;
143 }
144 return radii[point] * math::interpolate(1.0f, mmd.thickness_fac, influence);
145 }();
146
147 const float radius = math::interpolate(radii[point], target, weight);
148 radii[point] = math::max(radius, 0.0f);
149 }
150 });
151}
152
154 const ModifierEvalContext *ctx,
155 bke::GeometrySet *geometry_set)
156{
158
159 if (!geometry_set->has_grease_pencil()) {
160 return;
161 }
162 GreasePencil &grease_pencil = *geometry_set->get_grease_pencil_for_write();
163 const int current_frame = grease_pencil.runtime->eval_frame;
164
165 IndexMaskMemory mask_memory;
167 grease_pencil, mmd->influence, mask_memory);
169 modifier::greasepencil::get_drawings_for_write(grease_pencil, layer_mask, current_frame);
170
172 deform_drawing(*md, *ctx->object, *drawing);
173 });
174}
175
176static void panel_draw(const bContext *C, Panel *panel)
177{
178 uiLayout *layout = panel->layout;
179
181
182 uiLayoutSetPropSep(layout, true);
183
184 uiItemR(layout, ptr, "use_uniform_thickness", UI_ITEM_NONE, nullptr, ICON_NONE);
185 if (RNA_boolean_get(ptr, "use_uniform_thickness")) {
186 uiItemR(layout, ptr, "thickness", UI_ITEM_NONE, nullptr, ICON_NONE);
187 }
188 else {
189 const bool is_weighted = !RNA_boolean_get(ptr, "use_weight_factor");
190 uiLayout *row = uiLayoutRow(layout, true);
191 uiLayoutSetActive(row, is_weighted);
192 uiItemR(row, ptr, "thickness_factor", UI_ITEM_NONE, nullptr, ICON_NONE);
193 uiLayout *sub = uiLayoutRow(row, true);
194 uiLayoutSetActive(sub, true);
195 uiItemR(row, ptr, "use_weight_factor", UI_ITEM_NONE, "", ICON_MOD_VERTEX_WEIGHT);
196 }
197
198 if (uiLayout *influence_panel = uiLayoutPanelProp(
199 C, layout, ptr, "open_influence_panel", IFACE_("Influence")))
200 {
205 }
206
207 modifier_panel_end(layout, ptr);
208}
209
214
215} // namespace blender
216
218 /*idname*/ "GreasePencilThicknessModifier",
219 /*name*/ N_("Thickness"),
220 /*struct_name*/ "GreasePencilThickModifierData",
221 /*struct_size*/ sizeof(GreasePencilThickModifierData),
222 /*srna*/ &RNA_GreasePencilThickModifierData,
224 /*flags*/
227 /*icon*/ ICON_MOD_THICKNESS,
228
229 /*copy_data*/ blender::copy_data,
230
231 /*deform_verts*/ nullptr,
232 /*deform_matrices*/ nullptr,
233 /*deform_verts_EM*/ nullptr,
234 /*deform_matrices_EM*/ nullptr,
235 /*modify_mesh*/ nullptr,
236 /*modify_geometry_set*/ blender::modify_geometry_set,
237
238 /*init_data*/ blender::init_data,
239 /*required_data_mask*/ nullptr,
240 /*free_data*/ blender::free_data,
241 /*is_disabled*/ nullptr,
242 /*update_depsgraph*/ nullptr,
243 /*depends_on_time*/ nullptr,
244 /*depends_on_normals*/ nullptr,
245 /*foreach_ID_link*/ blender::foreach_ID_link,
246 /*foreach_tex_link*/ nullptr,
247 /*free_runtime_data*/ nullptr,
248 /*panel_register*/ blender::panel_register,
249 /*blend_write*/ blender::blend_write,
250 /*blend_read*/ blender::blend_read,
251};
float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
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 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)
@ GREASE_PENCIL_INFLUENCE_INVERT_VERTEX_GROUP
@ GREASE_PENCIL_INFLUENCE_USE_CUSTOM_CURVE
@ MOD_GREASE_PENCIL_THICK_WEIGHT_FACTOR
@ MOD_GREASE_PENCIL_THICK_NORMALIZE
struct GreasePencilThickModifierData GreasePencilThickModifierData
@ eModifierType_GreasePencilThickness
ModifierTypeInfo modifierType_GreasePencilThickness
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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
void uiLayoutSetActive(uiLayout *layout, bool active)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
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)
MutableSpan< float > radii_for_write()
bke::CurvesGeometry & strokes_for_write()
void foreach_index(Fn &&fn) const
T safe_divide(const T &a, const T &b)
T interpolate(const T &a, const T &b, const FactorT &t)
T max(const T &a, const T &b)
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)
void draw_vertex_group_settings(const bContext *, uiLayout *layout, PointerRNA *ptr)
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 draw_custom_curve_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 deform_drawing(const ModifierData &md, const Object &ob, bke::greasepencil::Drawing &drawing)
static void free_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void blend_read(BlendDataReader *reader, ModifierData *md)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
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