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