Blender V4.3
MOD_grease_pencil_weight_angle.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#include "BLI_math_rotation.hh"
11#include "BLI_string.h" /* For #STRNCPY. */
12
13#include "BLT_translation.hh"
14
15#include "BLO_read_write.hh"
16
17#include "DNA_defaults.h"
18#include "DNA_modifier_types.h"
19#include "DNA_screen_types.h"
20
21#include "RNA_access.hh"
22
23#include "BKE_curves.hh"
24#include "BKE_deform.hh"
25#include "BKE_geometry_set.hh"
26#include "BKE_grease_pencil.hh"
27#include "BKE_lib_query.hh"
28#include "BKE_modifier.hh"
29
30#include "UI_interface.hh"
31#include "UI_resources.hh"
32
34#include "MOD_modifiertypes.hh"
35#include "MOD_ui_common.hh"
36
37#include "RNA_prototypes.hh"
38
39namespace blender {
40
51
52static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
53{
55 reinterpret_cast<const GreasePencilWeightAngleModifierData *>(md);
57 reinterpret_cast<GreasePencilWeightAngleModifierData *>(target);
58
61}
62
70
71static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
72{
74
75 return (mmd->target_vgname[0] == '\0');
76}
77
78static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
79{
81 reinterpret_cast<GreasePencilWeightAngleModifierData *>(md);
82
84}
85
86static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
87{
89 reinterpret_cast<const GreasePencilWeightAngleModifierData *>(md);
90
93}
94
101
102static int ensure_vertex_group(const StringRefNull name, ListBase &vertex_group_names)
103{
104 int def_nr = BKE_defgroup_name_index(&vertex_group_names, name);
105 if (def_nr < 0) {
106 bDeformGroup *defgroup = MEM_cnew<bDeformGroup>(__func__);
107 STRNCPY(defgroup->name, name.c_str());
108 BLI_addtail(&vertex_group_names, defgroup);
109 def_nr = BLI_listbase_count(&vertex_group_names) - 1;
110 BLI_assert(def_nr >= 0);
111 }
112 return def_nr;
113}
114
116 const ListBase &vertex_group_names)
117{
118 const int def_nr = BKE_defgroup_name_index(&vertex_group_names, name);
119 if (def_nr < 0) {
120 return false;
121 }
122 return true;
123}
124
126 const Object &ob,
128{
129 const auto &mmd = reinterpret_cast<const GreasePencilWeightAngleModifierData &>(md);
130 bke::CurvesGeometry &curves = drawing.strokes_for_write();
131 if (curves.points_num() == 0) {
132 return;
133 }
134 IndexMaskMemory memory;
136 &ob, curves, mmd.influence, memory);
137 if (strokes.is_empty()) {
138 return;
139 }
140
141 /* Make sure that the target vertex group is added to this drawing so we can write to it. */
142 ensure_vertex_group(mmd.target_vgname, curves.vertex_group_names);
143
144 bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
145 bke::SpanAttributeWriter<float> dst_weights = attributes.lookup_for_write_span<float>(
146 mmd.target_vgname);
147
148 BLI_assert(!dst_weights.span.is_empty());
149
151 curves, mmd.influence);
152
153 /* Use default Z up. */
154 const float3 z_up(0.0f, 0.0f, 1.0f);
155 float3 axis(0.0f);
156 axis[mmd.axis] = 1.0f;
157 float3 vec_ref;
158 /* Apply modifier rotation (sub 90 degrees for Y axis due Z-Up vector). */
159 const float rot_angle = mmd.angle - ((mmd.axis == 1) ? M_PI_2 : 0.0f);
160 rotate_normalized_v3_v3v3fl(vec_ref, z_up, axis, rot_angle);
161
162 const float3x3 obmat3x3(ob.object_to_world());
163
164 /* Apply the rotation of the object. */
166 vec_ref = math::transform_point(obmat3x3, vec_ref);
167 }
168
169 const OffsetIndices points_by_curve = curves.points_by_curve();
170 const Span<float3> positions = curves.positions();
171
172 strokes.foreach_index(GrainSize(512), [&](const int stroke) {
173 const IndexRange points = points_by_curve[stroke];
174 if (points.size() == 1) {
175 dst_weights.span[points.start()] = 1.0f;
176 return;
177 }
178 for (const int point : points.drop_front(1)) {
179 const float3 p1 = math::transform_point(obmat3x3, positions[point]);
180 const float3 p2 = math::transform_point(obmat3x3, positions[point - 1]);
181 const float3 vec = p2 - p1;
182 const float angle = angle_on_axis_v3v3_v3(vec_ref, vec, axis);
183 float weight = 1.0f - math::sin(angle);
184
186 weight = 1.0f - weight;
187 }
188
189 dst_weights.span[point] = (mmd.flag & MOD_GREASE_PENCIL_WEIGHT_ANGLE_MULTIPLY_DATA) ?
190 dst_weights.span[point] * weight :
191 weight;
192 dst_weights.span[point] = math::clamp(dst_weights.span[point], mmd.min_weight, 1.0f);
193 }
194 /* First point has the same weight as the second one. */
195 dst_weights.span[points[0]] = dst_weights.span[points[1]];
196 });
197
198 dst_weights.finish();
199}
200
202 const ModifierEvalContext *ctx,
203 bke::GeometrySet *geometry_set)
204{
206 reinterpret_cast<GreasePencilWeightAngleModifierData *>(md);
207
208 if (!geometry_set->has_grease_pencil()) {
209 return;
210 }
211
212 GreasePencil &grease_pencil = *geometry_set->get_grease_pencil_for_write();
213
215 return;
216 }
217
218 const int current_frame = grease_pencil.runtime->eval_frame;
219
220 IndexMaskMemory mask_memory;
222 grease_pencil, mmd->influence, mask_memory);
224 modifier::greasepencil::get_drawings_for_write(grease_pencil, layer_mask, current_frame);
225
227 write_weights_for_drawing(*md, *ctx->object, *drawing);
228 });
229}
230
231static void panel_draw(const bContext *C, Panel *panel)
232{
233 uiLayout *row, *sub;
234 uiLayout *layout = panel->layout;
235
236 PointerRNA ob_ptr;
238
239 uiLayoutSetPropSep(layout, true);
240
241 row = uiLayoutRow(layout, true);
242 uiItemPointerR(row, ptr, "target_vertex_group", &ob_ptr, "vertex_groups", nullptr, ICON_NONE);
243
244 sub = uiLayoutRow(row, true);
245 bool has_output = RNA_string_length(ptr, "target_vertex_group") != 0;
246 uiLayoutSetPropDecorate(sub, false);
247 uiLayoutSetActive(sub, has_output);
248 uiItemR(sub, ptr, "use_invert_output", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
249
250 uiItemR(layout, ptr, "angle", UI_ITEM_NONE, nullptr, ICON_NONE);
251 uiItemR(layout, ptr, "axis", UI_ITEM_NONE, nullptr, ICON_NONE);
252 uiItemR(layout, ptr, "space", UI_ITEM_NONE, nullptr, ICON_NONE);
253
254 uiItemR(layout, ptr, "minimum_weight", UI_ITEM_NONE, nullptr, ICON_NONE);
255 uiItemR(layout, ptr, "use_multiply", UI_ITEM_NONE, nullptr, ICON_NONE);
256
257 if (uiLayout *influence_panel = uiLayoutPanelProp(
258 C, layout, ptr, "open_influence_panel", IFACE_("Influence")))
259 {
263 }
264
265 modifier_panel_end(layout, ptr);
266}
267
272
273} // namespace blender
274
276 /*idname*/ "GreasePencilWeightAngleModifier",
277 /*name*/ N_("Weight Angle"),
278 /*struct_name*/ "GreasePencilWeightAngleModifierData",
279 /*struct_size*/ sizeof(GreasePencilWeightAngleModifierData),
280 /*srna*/ &RNA_GreasePencilWeightAngleModifier,
282 /*flags*/
285 /*icon*/ ICON_MOD_VERTEX_WEIGHT,
286
287 /*copy_data*/ blender::copy_data,
288
289 /*deform_verts*/ nullptr,
290 /*deform_matrices*/ nullptr,
291 /*deform_verts_EM*/ nullptr,
292 /*deform_matrices_EM*/ nullptr,
293 /*modify_mesh*/ nullptr,
294 /*modify_geometry_set*/ blender::modify_geometry_set,
295
296 /*init_data*/ blender::init_data,
297 /*required_data_mask*/ nullptr,
298 /*free_data*/ blender::free_data,
299 /*is_disabled*/ blender::is_disabled,
300 /*update_depsgraph*/ nullptr,
301 /*depends_on_time*/ nullptr,
302 /*depends_on_normals*/ nullptr,
303 /*foreach_ID_link*/ blender::foreach_ID_link,
304 /*foreach_tex_link*/ nullptr,
305 /*free_runtime_data*/ nullptr,
306 /*panel_register*/ blender::panel_register,
307 /*blend_write*/ blender::blend_write,
308 /*blend_read*/ blender::blend_read,
309};
Low-level operations for curves.
support for deformation groups and hooks.
int BKE_defgroup_name_index(const ListBase *defbase, blender::StringRef name)
Definition deform.cc:534
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
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define M_PI_2
float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT
void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], float angle)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#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)
struct GreasePencilWeightAngleModifierData GreasePencilWeightAngleModifierData
@ MOD_GREASE_PENCIL_WEIGHT_ANGLE_SPACE_LOCAL
@ MOD_GREASE_PENCIL_WEIGHT_ANGLE_MULTIPLY_DATA
@ MOD_GREASE_PENCIL_WEIGHT_ANGLE_INVERT_OUTPUT
@ eModifierType_GreasePencilWeightAngle
static bool is_disabled
ModifierTypeInfo modifierType_GreasePencilWeightAngle
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
void uiItemPointerR(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
PanelLayout uiLayoutPanelProp(const bContext *C, uiLayout *layout, PointerRNA *open_prop_owner, const char *open_prop_name)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
bke::CurvesGeometry & strokes_for_write()
void foreach_index(Fn &&fn) const
T clamp(const T &a, const T &min, const T &max)
T sin(const AngleRadianBase< T > &a)
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)
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 write_weights_for_drawing(const ModifierData &md, const Object &ob, bke::greasepencil::Drawing &drawing)
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 int ensure_vertex_group(const StringRefNull name, ListBase &vertex_group_names)
static bool target_vertex_group_available(const StringRefNull name, const ListBase &vertex_group_names)
static bool is_disabled(const Scene *, ModifierData *md, bool)
static void blend_read(BlendDataReader *reader, ModifierData *md)
int RNA_string_length(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