Blender V5.0
MOD_armature.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
8
9#include <cstring>
10
11#include "BLI_listbase.h"
12#include "BLI_utildefines.h"
13
14#include "BLT_translation.hh"
15
16#include "DNA_armature_types.h"
17#include "DNA_defaults.h"
18#include "DNA_mesh_types.h"
19#include "DNA_object_types.h"
20#include "DNA_screen_types.h"
21
22#include "BKE_action.hh"
23#include "BKE_armature.hh"
24#include "BKE_deform.hh"
25#include "BKE_lib_query.hh"
26#include "BKE_mesh.hh"
27#include "BKE_modifier.hh"
28
30#include "UI_resources.hh"
31
32#include "RNA_prototypes.hh"
33#include "RNA_types.hh"
34
35#include "MEM_guardedalloc.h"
36
37#include "MOD_ui_common.hh"
38#include "MOD_util.hh"
39
48
49static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
50{
51#if 0
52 const ArmatureModifierData *amd = (const ArmatureModifierData *)md;
53#endif
55
57 tamd->vert_coords_prev = nullptr;
58}
59
60static void required_data_mask(ModifierData * /*md*/, CustomData_MeshMasks *r_cddata_masks)
61{
62 /* Ask for vertex-groups. */
63 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
64}
65
66static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
67{
69
70 /* The object type check is only needed here in case we have a placeholder
71 * object assigned (because the library containing the armature is missing).
72 *
73 * In other cases it should be impossible to have a type mismatch.
74 */
75 return !amd->object || amd->object->type != OB_ARMATURE;
76}
77
78static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
79{
81
82 walk(user_data, ob, (ID **)&amd->object, IDWALK_CB_NOP);
83}
84
86{
88 if (amd->object != nullptr) {
89 /* If not using envelopes,
90 * create relations to individual bones for more rigging flexibility. */
91 if ((amd->deformflag & ARM_DEF_ENVELOPE) == 0 && (amd->object->pose != nullptr) &&
93 {
94 /* If neither vertex groups nor envelopes are used, the modifier has no bone dependencies. */
95 if ((amd->deformflag & ARM_DEF_VGROUP) != 0) {
96 /* Enumerate groups that match existing bones. */
97 const ListBase *defbase = BKE_object_defgroup_list(ctx->object);
98 LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
99 if (BKE_pose_channel_find_name(amd->object->pose, dg->name) != nullptr) {
100 /* Can't check BONE_NO_DEFORM because it can be animated. */
102 ctx->node, amd->object, dg->name, DEG_OB_COMP_BONE, "Armature Modifier");
103 }
104 }
105 }
106 }
107 /* Otherwise require the whole pose to be complete. */
108 else {
109 DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_EVAL_POSE, "Armature Modifier");
110 }
111
112 DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_TRANSFORM, "Armature Modifier");
113 }
114 DEG_add_depends_on_transform_relation(ctx->node, "Armature Modifier");
115}
116
118 const ModifierEvalContext *ctx,
119 Mesh *mesh,
121{
123 std::optional<blender::Span<blender::float3>> vert_coords_prev;
124 if (amd->vert_coords_prev) {
125 vert_coords_prev = {reinterpret_cast<blender::float3 *>(amd->vert_coords_prev),
126 positions.size()};
127 }
128
129 /* if next modifier needs original vertices */
130 MOD_previous_vcos_store(md, reinterpret_cast<float (*)[3]>(positions.data()));
131
133 *ctx->object,
134 positions,
135 vert_coords_prev,
136 std::nullopt,
137 amd->deformflag,
138 amd->defgrp_name,
139 mesh);
140
141 /* free cache */
143}
144
146 const ModifierEvalContext *ctx,
147 const BMEditMesh *em,
148 Mesh *mesh,
150{
151 if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
152 deform_verts(md, ctx, mesh, positions);
153 return;
154 }
155
157 std::optional<blender::Span<blender::float3>> vert_coords_prev;
158 if (amd->vert_coords_prev) {
159 vert_coords_prev = {reinterpret_cast<blender::float3 *>(amd->vert_coords_prev),
160 positions.size()};
161 }
162
163 /* if next modifier needs original vertices */
164 MOD_previous_vcos_store(md, reinterpret_cast<float (*)[3]>(positions.data()));
165
167 *ctx->object,
168 positions,
169 vert_coords_prev,
170 std::nullopt,
171 amd->deformflag,
172 amd->defgrp_name,
173 *em);
174
175 /* free cache */
177}
178
180 const ModifierEvalContext *ctx,
181 const BMEditMesh *em,
182 Mesh * /*mesh*/,
185{
188 *ctx->object,
189 positions,
190 std::nullopt,
191 matrices,
192 amd->deformflag,
193 amd->defgrp_name,
194 *em);
195}
196
198 const ModifierEvalContext *ctx,
199 Mesh *mesh,
202{
205 *ctx->object,
206 positions,
207 std::nullopt,
208 matrices,
209 amd->deformflag,
210 amd->defgrp_name,
211 mesh);
212}
213
214static void panel_draw(const bContext * /*C*/, Panel *panel)
215{
216 uiLayout *col;
217 uiLayout *layout = panel->layout;
218
219 PointerRNA ob_ptr;
221
222 layout->use_property_split_set(true);
223
224 layout->prop(ptr, "object", UI_ITEM_NONE, std::nullopt, ICON_NONE);
225 modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", std::nullopt);
226
227 col = &layout->column(true);
228 col->prop(ptr, "use_deform_preserve_volume", UI_ITEM_NONE, std::nullopt, ICON_NONE);
229 col->prop(ptr, "use_multi_modifier", UI_ITEM_NONE, std::nullopt, ICON_NONE);
230
231 col = &layout->column(true, IFACE_("Bind To"));
232 col->prop(ptr, "use_vertex_groups", UI_ITEM_NONE, IFACE_("Vertex Groups"), ICON_NONE);
233 col->prop(ptr, "use_bone_envelopes", UI_ITEM_NONE, IFACE_("Bone Envelopes"), ICON_NONE);
234
236}
237
238static void panel_register(ARegionType *region_type)
239{
241}
242
243static void blend_read(BlendDataReader * /*reader*/, ModifierData *md)
244{
246
247 amd->vert_coords_prev = nullptr;
248}
249
251 /*idname*/ "Armature",
252 /*name*/ N_("Armature"),
253 /*struct_name*/ "ArmatureModifierData",
254 /*struct_size*/ sizeof(ArmatureModifierData),
255 /*srna*/ &RNA_ArmatureModifier,
259 /*icon*/ ICON_MOD_ARMATURE,
260
261 /*copy_data*/ copy_data,
262
263 /*deform_verts*/ deform_verts,
264 /*deform_matrices*/ deform_matrices,
265 /*deform_verts_EM*/ deform_verts_EM,
266 /*deform_matrices_EM*/ deform_matrices_EM,
267 /*modify_mesh*/ nullptr,
268 /*modify_geometry_set*/ nullptr,
269
270 /*init_data*/ init_data,
271 /*required_data_mask*/ required_data_mask,
272 /*free_data*/ nullptr,
273 /*is_disabled*/ is_disabled,
274 /*update_depsgraph*/ update_depsgraph,
275 /*depends_on_time*/ nullptr,
276 /*depends_on_normals*/ nullptr,
277 /*foreach_ID_link*/ foreach_ID_link,
278 /*foreach_tex_link*/ nullptr,
279 /*free_runtime_data*/ nullptr,
280 /*panel_register*/ panel_register,
281 /*blend_write*/ nullptr,
282 /*blend_read*/ blend_read,
283 /*foreach_cache*/ nullptr,
284 /*foreach_working_space_color*/ nullptr,
285};
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_armature_deform_coords_with_mesh(const Object &ob_arm, const Object &ob_target, blender::MutableSpan< blender::float3 > vert_coords, std::optional< blender::Span< blender::float3 > > vert_coords_prev, std::optional< blender::MutableSpan< blender::float3x3 > > vert_deform_mats, int deformflag, blender::StringRefNull defgrp_name, const Mesh *me_target)
void BKE_armature_deform_coords_with_editmesh(const Object &ob_arm, const Object &ob_target, blender::MutableSpan< blender::float3 > vert_coords, std::optional< blender::Span< blender::float3 > > vert_coords_prev, std::optional< blender::MutableSpan< blender::float3x3 > > vert_deform_mats, int deformflag, blender::StringRefNull defgrp_name, const BMEditMesh &em_target)
support for deformation groups and hooks.
const ListBase * BKE_object_defgroup_list(const Object *ob)
Definition deform.cc:585
@ IDWALK_CB_NOP
@ ME_WRAPPER_TYPE_MDATA
void(*)(void *user_data, Object *ob, ID **idpoin, LibraryForeachIDCallbackFlag cb_flag) IDWalkFunc
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_AcceptsCVs
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsVertexCosOnly
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(msgid)
void DEG_add_depends_on_transform_relation(DepsNodeHandle *node_handle, const char *description)
void DEG_add_bone_relation(DepsNodeHandle *handle, Object *object, const char *bone_name, eDepsObjectComponentType component, const char *description)
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
@ DEG_OB_COMP_EVAL_POSE
@ DEG_OB_COMP_TRANSFORM
@ DEG_OB_COMP_BONE
@ ARM_DEF_VGROUP
@ ARM_DEF_ENVELOPE
#define CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
@ eModifierType_Armature
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_ARMATURE
@ OB_MESH
static bool is_disabled
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static void deform_matrices(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions, blender::MutableSpan< blender::float3x3 > matrices)
static void init_data(ModifierData *md)
static void deform_verts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
static void panel_register(ARegionType *region_type)
static void deform_matrices_EM(ModifierData *md, const ModifierEvalContext *ctx, const BMEditMesh *em, Mesh *, blender::MutableSpan< blender::float3 > positions, blender::MutableSpan< blender::float3x3 > matrices)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void deform_verts_EM(ModifierData *md, const ModifierEvalContext *ctx, const BMEditMesh *em, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
static void blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
ModifierTypeInfo modifierType_Armature
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const StringRefNull vgroup_prop, const std::optional< StringRefNull > invert_vgroup_prop, const std::optional< StringRefNull > text)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_error_message_draw(uiLayout *layout, PointerRNA *ptr)
void MOD_previous_vcos_store(ModifierData *md, const float(*vert_coords)[3])
Definition MOD_util.cc:142
#define UI_ITEM_NONE
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr T * data() const
Definition BLI_span.hh:539
uint col
static void update_depsgraph(tGraphSliderOp *gso)
VecBase< float, 3 > float3
Definition DNA_ID.h:414
MeshRuntimeHandle * runtime
ustring name
Definition graph/node.h:177
struct bPose * pose
struct uiLayout * layout
uiLayout & column(bool align)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4238
uint8_t flag
Definition wm_window.cc:145