Blender V4.3
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
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
29#include "UI_interface.hh"
30#include "UI_resources.hh"
31
32#include "RNA_prototypes.hh"
33
34#include "MEM_guardedalloc.h"
35
36#include "MOD_ui_common.hh"
37#include "MOD_util.hh"
38
47
48static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
49{
50#if 0
51 const ArmatureModifierData *amd = (const ArmatureModifierData *)md;
52#endif
54
56 tamd->vert_coords_prev = nullptr;
57}
58
59static void required_data_mask(ModifierData * /*md*/, CustomData_MeshMasks *r_cddata_masks)
60{
61 /* Ask for vertex-groups. */
62 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
63}
64
65static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
66{
68
69 /* The object type check is only needed here in case we have a placeholder
70 * object assigned (because the library containing the armature is missing).
71 *
72 * In other cases it should be impossible to have a type mismatch.
73 */
74 return !amd->object || amd->object->type != OB_ARMATURE;
75}
76
77static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
78{
80
81 walk(user_data, ob, (ID **)&amd->object, IDWALK_CB_NOP);
82}
83
85{
87 if (amd->object != nullptr) {
88 /* If not using envelopes,
89 * create relations to individual bones for more rigging flexibility. */
90 if ((amd->deformflag & ARM_DEF_ENVELOPE) == 0 && (amd->object->pose != nullptr) &&
92 {
93 /* If neither vertex groups nor envelopes are used, the modifier has no bone dependencies. */
94 if ((amd->deformflag & ARM_DEF_VGROUP) != 0) {
95 /* Enumerate groups that match existing bones. */
96 const ListBase *defbase = BKE_object_defgroup_list(ctx->object);
97 LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
98 if (BKE_pose_channel_find_name(amd->object->pose, dg->name) != nullptr) {
99 /* Can't check BONE_NO_DEFORM because it can be animated. */
101 ctx->node, amd->object, dg->name, DEG_OB_COMP_BONE, "Armature Modifier");
102 }
103 }
104 }
105 }
106 /* Otherwise require the whole pose to be complete. */
107 else {
108 DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_EVAL_POSE, "Armature Modifier");
109 }
110
111 DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_TRANSFORM, "Armature Modifier");
112 }
113 DEG_add_depends_on_transform_relation(ctx->node, "Armature Modifier");
114}
115
117 const ModifierEvalContext *ctx,
118 Mesh *mesh,
120{
122
123 /* if next modifier needs original vertices */
124 MOD_previous_vcos_store(md, reinterpret_cast<float(*)[3]>(positions.data()));
125
127 ctx->object,
128 reinterpret_cast<float(*)[3]>(positions.data()),
129 nullptr,
130 positions.size(),
131 amd->deformflag,
132 amd->vert_coords_prev,
133 amd->defgrp_name,
134 mesh);
135
136 /* free cache */
138}
139
141 const ModifierEvalContext *ctx,
142 const BMEditMesh *em,
143 Mesh *mesh,
145{
146 if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) {
147 deform_verts(md, ctx, mesh, positions);
148 return;
149 }
150
152
153 /* if next modifier needs original vertices */
154 MOD_previous_vcos_store(md, reinterpret_cast<float(*)[3]>(positions.data()));
155
157 ctx->object,
158 reinterpret_cast<float(*)[3]>(positions.data()),
159 nullptr,
160 positions.size(),
161 amd->deformflag,
162 amd->vert_coords_prev,
163 amd->defgrp_name,
164 em);
165
166 /* free cache */
168}
169
171 const ModifierEvalContext *ctx,
172 const BMEditMesh *em,
173 Mesh * /*mesh*/,
176{
178
180 ctx->object,
181 reinterpret_cast<float(*)[3]>(positions.data()),
182 reinterpret_cast<float(*)[3][3]>(matrices.data()),
183 positions.size(),
184 amd->deformflag,
185 nullptr,
186 amd->defgrp_name,
187 em);
188}
189
191 const ModifierEvalContext *ctx,
192 Mesh *mesh,
195{
198 ctx->object,
199 reinterpret_cast<float(*)[3]>(positions.data()),
200 reinterpret_cast<float(*)[3][3]>(matrices.data()),
201 positions.size(),
202 amd->deformflag,
203 nullptr,
204 amd->defgrp_name,
205 mesh);
206}
207
208static void panel_draw(const bContext * /*C*/, Panel *panel)
209{
210 uiLayout *col;
211 uiLayout *layout = panel->layout;
212
213 PointerRNA ob_ptr;
215
216 uiLayoutSetPropSep(layout, true);
217
218 uiItemR(layout, ptr, "object", UI_ITEM_NONE, nullptr, ICON_NONE);
219 modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
220
221 col = uiLayoutColumn(layout, true);
222 uiItemR(col, ptr, "use_deform_preserve_volume", UI_ITEM_NONE, nullptr, ICON_NONE);
223 uiItemR(col, ptr, "use_multi_modifier", UI_ITEM_NONE, nullptr, ICON_NONE);
224
225 col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind To"));
226 uiItemR(col, ptr, "use_vertex_groups", UI_ITEM_NONE, IFACE_("Vertex Groups"), ICON_NONE);
227 uiItemR(col, ptr, "use_bone_envelopes", UI_ITEM_NONE, IFACE_("Bone Envelopes"), ICON_NONE);
228
229 modifier_panel_end(layout, ptr);
230}
231
232static void panel_register(ARegionType *region_type)
233{
235}
236
237static void blend_read(BlendDataReader * /*reader*/, ModifierData *md)
238{
240
241 amd->vert_coords_prev = nullptr;
242}
243
245 /*idname*/ "Armature",
246 /*name*/ N_("Armature"),
247 /*struct_name*/ "ArmatureModifierData",
248 /*struct_size*/ sizeof(ArmatureModifierData),
249 /*srna*/ &RNA_ArmatureModifier,
253 /*icon*/ ICON_MOD_ARMATURE,
254
255 /*copy_data*/ copy_data,
256
257 /*deform_verts*/ deform_verts,
258 /*deform_matrices*/ deform_matrices,
259 /*deform_verts_EM*/ deform_verts_EM,
260 /*deform_matrices_EM*/ deform_matrices_EM,
261 /*modify_mesh*/ nullptr,
262 /*modify_geometry_set*/ nullptr,
263
264 /*init_data*/ init_data,
265 /*required_data_mask*/ required_data_mask,
266 /*free_data*/ nullptr,
267 /*is_disabled*/ is_disabled,
268 /*update_depsgraph*/ update_depsgraph,
269 /*depends_on_time*/ nullptr,
270 /*depends_on_normals*/ nullptr,
271 /*foreach_ID_link*/ foreach_ID_link,
272 /*foreach_tex_link*/ nullptr,
273 /*free_runtime_data*/ nullptr,
274 /*panel_register*/ panel_register,
275 /*blend_write*/ nullptr,
276 /*blend_read*/ blend_read,
277 /*foreach_cache*/ nullptr,
278};
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_armature_deform_coords_with_editmesh(const Object *ob_arm, const Object *ob_target, float(*vert_coords)[3], float(*vert_deform_mats)[3][3], int vert_coords_len, int deformflag, float(*vert_coords_prev)[3], const char *defgrp_name, const BMEditMesh *em_target)
void BKE_armature_deform_coords_with_mesh(const Object *ob_arm, const Object *ob_target, float(*vert_coords)[3], float(*vert_deform_mats)[3][3], int vert_coords_len, int deformflag, float(*vert_coords_prev)[3], const char *defgrp_name, const Mesh *me_target)
support for deformation groups and hooks.
const ListBase * BKE_object_defgroup_list(const Object *ob)
Definition deform.cc:579
@ IDWALK_CB_NOP
@ ME_WRAPPER_TYPE_MDATA
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_AcceptsCVs
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsVertexCosOnly
void(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
#define BLI_assert(a)
Definition BLI_assert.h:50
#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
struct ArmatureModifierData ArmatureModifierData
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_ARMATURE
@ OB_MESH
@ OB_GPENCIL_LEGACY
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_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 modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
void MOD_previous_vcos_store(ModifierData *md, const float(*vert_coords)[3])
Definition MOD_util.cc:145
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
uiLayout * uiLayoutColumnWithHeading(uiLayout *layout, bool align, const char *heading)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
constexpr T * data() const
Definition BLI_span.hh:540
uint col
Definition DNA_ID.h:413
ustring name
Definition graph/node.h:177
struct bPose * pose
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138