1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup modifiers
22 */
23
24 #include <string.h>
25
26 #include "BLI_listbase.h"
27 #include "BLI_utildefines.h"
28
29 #include "BLT_translation.h"
30
31 #include "DNA_armature_types.h"
32 #include "DNA_defaults.h"
33 #include "DNA_mesh_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_screen_types.h"
36
37 #include "BKE_action.h"
38 #include "BKE_armature.h"
39 #include "BKE_context.h"
40 #include "BKE_editmesh.h"
41 #include "BKE_lib_id.h"
42 #include "BKE_lib_query.h"
43 #include "BKE_mesh.h"
44 #include "BKE_mesh_wrapper.h"
45 #include "BKE_modifier.h"
46 #include "BKE_screen.h"
47
48 #include "UI_interface.h"
49 #include "UI_resources.h"
50
51 #include "RNA_access.h"
52
53 #include "BLO_read_write.h"
54
55 #include "DEG_depsgraph_query.h"
56
57 #include "bmesh.h"
58 #include "bmesh_tools.h"
59
60 #include "MEM_guardedalloc.h"
61
62 #include "MOD_ui_common.h"
63 #include "MOD_util.h"
64
initData(ModifierData * md)65 static void initData(ModifierData *md)
66 {
67 ArmatureModifierData *amd = (ArmatureModifierData *)md;
68
69 BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(amd, modifier));
70
71 MEMCPY_STRUCT_AFTER(amd, DNA_struct_default_get(ArmatureModifierData), modifier);
72 }
73
copyData(const ModifierData * md,ModifierData * target,const int flag)74 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
75 {
76 #if 0
77 const ArmatureModifierData *amd = (const ArmatureModifierData *)md;
78 #endif
79 ArmatureModifierData *tamd = (ArmatureModifierData *)target;
80
81 BKE_modifier_copydata_generic(md, target, flag);
82 tamd->vert_coords_prev = NULL;
83 }
84
requiredDataMask(Object * UNUSED (ob),ModifierData * UNUSED (md),CustomData_MeshMasks * r_cddata_masks)85 static void requiredDataMask(Object *UNUSED(ob),
86 ModifierData *UNUSED(md),
87 CustomData_MeshMasks *r_cddata_masks)
88 {
89 /* ask for vertexgroups */
90 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
91 }
92
isDisabled(const struct Scene * UNUSED (scene),ModifierData * md,bool UNUSED (useRenderParams))93 static bool isDisabled(const struct Scene *UNUSED(scene),
94 ModifierData *md,
95 bool UNUSED(useRenderParams))
96 {
97 ArmatureModifierData *amd = (ArmatureModifierData *)md;
98
99 /* The object type check is only needed here in case we have a placeholder
100 * object assigned (because the library containing the armature is missing).
101 *
102 * In other cases it should be impossible to have a type mismatch.
103 */
104 return !amd->object || amd->object->type != OB_ARMATURE;
105 }
106
foreachIDLink(ModifierData * md,Object * ob,IDWalkFunc walk,void * userData)107 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
108 {
109 ArmatureModifierData *amd = (ArmatureModifierData *)md;
110
111 walk(userData, ob, (ID **)&amd->object, IDWALK_CB_NOP);
112 }
113
updateDepsgraph(ModifierData * md,const ModifierUpdateDepsgraphContext * ctx)114 static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
115 {
116 ArmatureModifierData *amd = (ArmatureModifierData *)md;
117 if (amd->object != NULL) {
118 /* If not using envelopes,
119 * create relations to individual bones for more rigging flexibility. */
120 if ((amd->deformflag & ARM_DEF_ENVELOPE) == 0 && (amd->object->pose != NULL) &&
121 ELEM(ctx->object->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
122 /* If neither vertex groups nor envelopes are used, the modifier has no bone dependencies. */
123 if ((amd->deformflag & ARM_DEF_VGROUP) != 0) {
124 /* Enumerate groups that match existing bones. */
125 LISTBASE_FOREACH (bDeformGroup *, dg, &ctx->object->defbase) {
126 if (BKE_pose_channel_find_name(amd->object->pose, dg->name) != NULL) {
127 /* Can't check BONE_NO_DEFORM because it can be animated. */
128 DEG_add_bone_relation(
129 ctx->node, amd->object, dg->name, DEG_OB_COMP_BONE, "Armature Modifier");
130 }
131 }
132 }
133 }
134 /* Otherwise require the whole pose to be complete. */
135 else {
136 DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_EVAL_POSE, "Armature Modifier");
137 }
138
139 DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_TRANSFORM, "Armature Modifier");
140 }
141 DEG_add_modifier_to_transform_relation(ctx->node, "Armature Modifier");
142 }
143
deformVerts(ModifierData * md,const ModifierEvalContext * ctx,Mesh * mesh,float (* vertexCos)[3],int numVerts)144 static void deformVerts(ModifierData *md,
145 const ModifierEvalContext *ctx,
146 Mesh *mesh,
147 float (*vertexCos)[3],
148 int numVerts)
149 {
150 ArmatureModifierData *amd = (ArmatureModifierData *)md;
151
152 MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
153
154 BKE_armature_deform_coords_with_mesh(amd->object,
155 ctx->object,
156 vertexCos,
157 NULL,
158 numVerts,
159 amd->deformflag,
160 amd->vert_coords_prev,
161 amd->defgrp_name,
162 mesh);
163
164 /* free cache */
165 MEM_SAFE_FREE(amd->vert_coords_prev);
166 }
167
deformVertsEM(ModifierData * md,const ModifierEvalContext * ctx,struct BMEditMesh * em,Mesh * mesh,float (* vertexCos)[3],int numVerts)168 static void deformVertsEM(ModifierData *md,
169 const ModifierEvalContext *ctx,
170 struct BMEditMesh *em,
171 Mesh *mesh,
172 float (*vertexCos)[3],
173 int numVerts)
174 {
175 if (mesh != NULL) {
176 deformVerts(md, ctx, mesh, vertexCos, numVerts);
177 return;
178 }
179
180 ArmatureModifierData *amd = (ArmatureModifierData *)md;
181
182 MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
183
184 BKE_armature_deform_coords_with_editmesh(amd->object,
185 ctx->object,
186 vertexCos,
187 NULL,
188 numVerts,
189 amd->deformflag,
190 amd->vert_coords_prev,
191 amd->defgrp_name,
192 em);
193
194 /* free cache */
195 MEM_SAFE_FREE(amd->vert_coords_prev);
196 }
197
deformMatricesEM(ModifierData * md,const ModifierEvalContext * ctx,struct BMEditMesh * em,Mesh * UNUSED (mesh),float (* vertexCos)[3],float (* defMats)[3][3],int numVerts)198 static void deformMatricesEM(ModifierData *md,
199 const ModifierEvalContext *ctx,
200 struct BMEditMesh *em,
201 Mesh *UNUSED(mesh),
202 float (*vertexCos)[3],
203 float (*defMats)[3][3],
204 int numVerts)
205 {
206 ArmatureModifierData *amd = (ArmatureModifierData *)md;
207
208 BKE_armature_deform_coords_with_editmesh(amd->object,
209 ctx->object,
210 vertexCos,
211 defMats,
212 numVerts,
213 amd->deformflag,
214 NULL,
215 amd->defgrp_name,
216 em);
217 }
218
deformMatrices(ModifierData * md,const ModifierEvalContext * ctx,Mesh * mesh,float (* vertexCos)[3],float (* defMats)[3][3],int numVerts)219 static void deformMatrices(ModifierData *md,
220 const ModifierEvalContext *ctx,
221 Mesh *mesh,
222 float (*vertexCos)[3],
223 float (*defMats)[3][3],
224 int numVerts)
225 {
226 ArmatureModifierData *amd = (ArmatureModifierData *)md;
227 Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
228
229 BKE_armature_deform_coords_with_mesh(amd->object,
230 ctx->object,
231 vertexCos,
232 defMats,
233 numVerts,
234 amd->deformflag,
235 NULL,
236 amd->defgrp_name,
237 mesh_src);
238
239 if (!ELEM(mesh_src, NULL, mesh)) {
240 BKE_id_free(NULL, mesh_src);
241 }
242 }
243
panel_draw(const bContext * UNUSED (C),Panel * panel)244 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
245 {
246 uiLayout *col;
247 uiLayout *layout = panel->layout;
248
249 PointerRNA ob_ptr;
250 PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
251
252 uiLayoutSetPropSep(layout, true);
253
254 uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
255 modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
256
257 col = uiLayoutColumn(layout, true);
258 uiItemR(col, ptr, "use_deform_preserve_volume", 0, NULL, ICON_NONE);
259 uiItemR(col, ptr, "use_multi_modifier", 0, NULL, ICON_NONE);
260
261 col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind to"));
262 uiItemR(col, ptr, "use_vertex_groups", 0, IFACE_("Vertex Groups"), ICON_NONE);
263 uiItemR(col, ptr, "use_bone_envelopes", 0, IFACE_("Bone Envelopes"), ICON_NONE);
264
265 modifier_panel_end(layout, ptr);
266 }
267
panelRegister(ARegionType * region_type)268 static void panelRegister(ARegionType *region_type)
269 {
270 modifier_panel_register(region_type, eModifierType_Armature, panel_draw);
271 }
272
blendRead(BlendDataReader * UNUSED (reader),ModifierData * md)273 static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
274 {
275 ArmatureModifierData *amd = (ArmatureModifierData *)md;
276
277 amd->vert_coords_prev = NULL;
278 }
279
280 ModifierTypeInfo modifierType_Armature = {
281 /* name */ "Armature",
282 /* structName */ "ArmatureModifierData",
283 /* structSize */ sizeof(ArmatureModifierData),
284 /* srna */ &RNA_ArmatureModifier,
285 /* type */ eModifierTypeType_OnlyDeform,
286 /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly |
287 eModifierTypeFlag_SupportsEditmode,
288 /* icon */ ICON_MOD_ARMATURE,
289
290 /* copyData */ copyData,
291
292 /* deformVerts */ deformVerts,
293 /* deformMatrices */ deformMatrices,
294 /* deformVertsEM */ deformVertsEM,
295 /* deformMatricesEM */ deformMatricesEM,
296 /* modifyMesh */ NULL,
297 /* modifyHair */ NULL,
298 /* modifyPointCloud */ NULL,
299 /* modifyVolume */ NULL,
300
301 /* initData */ initData,
302 /* requiredDataMask */ requiredDataMask,
303 /* freeData */ NULL,
304 /* isDisabled */ isDisabled,
305 /* updateDepsgraph */ updateDepsgraph,
306 /* dependsOnTime */ NULL,
307 /* dependsOnNormals */ NULL,
308 /* foreachIDLink */ foreachIDLink,
309 /* foreachTexLink */ NULL,
310 /* freeRuntimeData */ NULL,
311 /* panelRegister */ panelRegister,
312 /* blendWrite */ NULL,
313 /* blendRead */ blendRead,
314 };
315