Blender V4.3
MOD_grease_pencil_armature.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 "MEM_guardedalloc.h"
10
11#include "BLI_math_matrix.hh"
12
13#include "DNA_defaults.h"
14#include "DNA_material_types.h"
15#include "DNA_meshdata_types.h"
16#include "DNA_modifier_types.h"
17#include "DNA_scene_types.h"
18
19#include "BKE_armature.hh"
20#include "BKE_colorband.hh"
21#include "BKE_curves.hh"
22#include "BKE_geometry_set.hh"
23#include "BKE_grease_pencil.hh"
24#include "BKE_lib_query.hh"
25#include "BKE_material.h"
26#include "BKE_modifier.hh"
27#include "BKE_screen.hh"
28
29#include "BLO_read_write.hh"
30
32
33#include "UI_interface.hh"
34#include "UI_resources.hh"
35
36#include "BLT_translation.hh"
37
38#include "WM_types.hh"
39
40#include "RNA_access.hh"
41#include "RNA_enum_types.hh"
42#include "RNA_prototypes.hh"
43
45#include "MOD_modifiertypes.hh"
46#include "MOD_ui_common.hh"
47
48namespace blender {
49
50using bke::greasepencil::Drawing;
51
52static void init_data(ModifierData *md)
53{
54 auto *amd = reinterpret_cast<GreasePencilArmatureModifierData *>(md);
55
57
59 modifier::greasepencil::init_influence_data(&amd->influence, false);
60}
61
62static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
63{
64 const auto *amd = reinterpret_cast<const GreasePencilArmatureModifierData *>(md);
65 auto *tamd = reinterpret_cast<GreasePencilArmatureModifierData *>(target);
66
68
70 modifier::greasepencil::copy_influence_data(&amd->influence, &tamd->influence, flag);
71}
72
73static void free_data(ModifierData *md)
74{
75 auto *amd = reinterpret_cast<GreasePencilArmatureModifierData *>(md);
77}
78
79static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
80{
81 auto *amd = reinterpret_cast<GreasePencilArmatureModifierData *>(md);
82 modifier::greasepencil::foreach_influence_ID_link(&amd->influence, ob, walk, user_data);
83 walk(user_data, ob, (ID **)&amd->object, IDWALK_CB_NOP);
84}
85
86static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
87{
88 auto *amd = reinterpret_cast<GreasePencilArmatureModifierData *>(md);
89
90 /* The object type check is only needed here in case we have a placeholder
91 * object assigned (because the library containing the armature is missing).
92 *
93 * In other cases it should be impossible to have a type mismatch. */
94 return !amd->object || amd->object->type != OB_ARMATURE;
95}
96
98{
99 auto *amd = reinterpret_cast<GreasePencilArmatureModifierData *>(md);
100 if (amd->object != nullptr) {
101 DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_EVAL_POSE, "Armature Modifier");
102 DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_TRANSFORM, "Armature Modifier");
103 }
104 DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Armature Modifier");
105}
106
107static void modify_curves(ModifierData &md, const ModifierEvalContext &ctx, Drawing &drawing)
108{
109 auto &amd = reinterpret_cast<GreasePencilArmatureModifierData &>(md);
111 bke::CurvesGeometry &curves = drawing.strokes_for_write();
112
113 /* The influence flag is where the "invert" flag is stored,
114 * but armature functions expect `deformflag` to have the flag set as well.
115 * Copy to `deformflag` here to keep old functions happy. */
116 const int deformflag = amd.deformflag |
117 (amd.influence.flag & GREASE_PENCIL_INFLUENCE_INVERT_VERTEX_GROUP ?
119 0);
120
121 IndexMaskMemory mask_memory;
123 ctx.object, curves, amd.influence, mask_memory);
124
125 const OffsetIndices<int> points_by_curve = curves.points_by_curve();
126 const MutableSpan<float3> positions = curves.positions_for_write();
127 const Span<MDeformVert> dverts = curves.deform_verts();
128
129 if (dverts.is_empty()) {
130 return;
131 }
132
133 curves_mask.foreach_index(blender::GrainSize(128), [&](const int curve_i) {
134 const IndexRange points = points_by_curve[curve_i];
135
137 *ctx.object,
138 &curves.vertex_group_names,
139 positions.slice(points),
140 std::nullopt,
141 std::nullopt,
142 dverts.slice(points),
143 deformflag,
144 amd.influence.vertex_group_name);
145 });
146
147 drawing.tag_positions_changed();
148}
149
151 const ModifierEvalContext *ctx,
152 bke::GeometrySet *geometry_set)
153{
154 const auto *amd = reinterpret_cast<GreasePencilArmatureModifierData *>(md);
155
156 if (!geometry_set->has_grease_pencil()) {
157 return;
158 }
159 GreasePencil &grease_pencil = *geometry_set->get_grease_pencil_for_write();
160 const int frame = grease_pencil.runtime->eval_frame;
161
162 IndexMaskMemory mask_memory;
164 grease_pencil, amd->influence, mask_memory);
166 grease_pencil, layer_mask, frame);
168 [&](Drawing *drawing) { modify_curves(*md, *ctx, *drawing); });
169}
170
171static void panel_draw(const bContext *C, Panel *panel)
172{
173 uiLayout *layout = panel->layout;
174
175 PointerRNA ob_ptr;
177
178 uiLayoutSetPropSep(layout, true);
179
180 uiItemR(layout, ptr, "object", UI_ITEM_NONE, nullptr, ICON_NONE);
182
183 uiLayout *col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind To"));
184 uiItemR(col, ptr, "use_vertex_groups", UI_ITEM_NONE, IFACE_("Vertex Groups"), ICON_NONE);
185 uiItemR(col, ptr, "use_bone_envelopes", UI_ITEM_NONE, IFACE_("Bone Envelopes"), ICON_NONE);
186
187 modifier_panel_end(layout, ptr);
188}
189
194
195static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
196{
197 const auto *amd = reinterpret_cast<const GreasePencilArmatureModifierData *>(md);
198
200 modifier::greasepencil::write_influence_data(writer, &amd->influence);
201}
202
203static void blend_read(BlendDataReader *reader, ModifierData *md)
204{
205 auto *amd = reinterpret_cast<GreasePencilArmatureModifierData *>(md);
206
207 modifier::greasepencil::read_influence_data(reader, &amd->influence);
208}
209
210} // namespace blender
211
213 /*idname*/ "GreasePencilArmature",
214 /*name*/ N_("Armature"),
215 /*struct_name*/ "GreasePencilArmatureModifierData",
216 /*struct_size*/ sizeof(GreasePencilArmatureModifierData),
217 /*srna*/ &RNA_GreasePencilArmatureModifier,
221 /*icon*/ ICON_MOD_ARMATURE,
222
223 /*copy_data*/ blender::copy_data,
224
225 /*deform_verts*/ nullptr,
226 /*deform_matrices*/ nullptr,
227 /*deform_verts_EM*/ nullptr,
228 /*deform_matrices_EM*/ nullptr,
229 /*modify_mesh*/ nullptr,
230 /*modify_geometry_set*/ blender::modify_geometry_set,
231
232 /*init_data*/ blender::init_data,
233 /*required_data_mask*/ nullptr,
234 /*free_data*/ blender::free_data,
235 /*is_disabled*/ blender::is_disabled,
236 /*update_depsgraph*/ blender::update_depsgraph,
237 /*depends_on_time*/ nullptr,
238 /*depends_on_normals*/ nullptr,
239 /*foreach_ID_link*/ blender::foreach_ID_link,
240 /*foreach_tex_link*/ nullptr,
241 /*free_runtime_data*/ nullptr,
242 /*panel_register*/ blender::panel_register,
243 /*blend_write*/ blender::blend_write,
244 /*blend_read*/ blender::blend_read,
245};
void BKE_armature_deform_coords_with_curves(const Object &ob_arm, const Object &ob_target, const ListBase *defbase, blender::MutableSpan< blender::float3 > vert_coords, std::optional< blender::MutableSpan< blender::float3 > > vert_coords_prev, std::optional< blender::MutableSpan< blender::float3x3 > > vert_deform_mats, blender::Span< MDeformVert > dverts, int deformflag, blender::StringRefNull defgrp_name)
Low-level operations for curves.
Low-level operations for grease pencil.
@ IDWALK_CB_NOP
General operations, lookup, etc. for materials.
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)
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
@ DEG_OB_COMP_EVAL_POSE
@ DEG_OB_COMP_TRANSFORM
@ ARM_DEF_INVERT_VGROUP
#define DNA_struct_default_get(struct_name)
@ GREASE_PENCIL_INFLUENCE_INVERT_VERTEX_GROUP
struct GreasePencilArmatureModifierData GreasePencilArmatureModifierData
@ eModifierType_GreasePencilArmature
@ OB_ARMATURE
static bool is_disabled
Read Guarded memory(de)allocation.
ModifierTypeInfo modifierType_GreasePencilArmature
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
uiLayout * uiLayoutColumnWithHeading(uiLayout *layout, bool align, const char *heading)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:138
constexpr bool is_empty() const
Definition BLI_span.hh:261
bke::CurvesGeometry & strokes_for_write()
void foreach_index(Fn &&fn) const
uint col
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 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 void modify_curves(ModifierData &md, const ModifierEvalContext &ctx, 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 void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static bool is_disabled(const Scene *, ModifierData *md, bool)
static void blend_read(BlendDataReader *reader, ModifierData *md)
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