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) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  * API's for creating vertex groups from bones
19  * - Interfaces with heat weighting in meshlaplacian
20  */
21 
22 /** \file
23  * \ingroup edarmature
24  */
25 
26 #include "DNA_armature_types.h"
27 #include "DNA_mesh_types.h"
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_blenlib.h"
34 #include "BLI_math.h"
35 #include "BLI_string_utils.h"
36 
37 #include "BKE_action.h"
38 #include "BKE_armature.h"
39 #include "BKE_deform.h"
40 #include "BKE_mesh_iterators.h"
41 #include "BKE_mesh_runtime.h"
42 #include "BKE_modifier.h"
43 #include "BKE_object_deform.h"
44 #include "BKE_report.h"
45 #include "BKE_subsurf.h"
46 
47 #include "DEG_depsgraph.h"
48 #include "DEG_depsgraph_query.h"
49 
50 #include "ED_armature.h"
51 #include "ED_mesh.h"
52 
53 #include "eigen_capi.h"
54 
55 #include "armature_intern.h"
56 #include "meshlaplacian.h"
57 
58 /* ******************************* Bone Skinning *********************************************** */
59 
bone_skinnable_cb(Object * UNUSED (ob),Bone * bone,void * datap)60 static int bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap)
61 {
62   /* Bones that are deforming
63    * are regarded to be "skinnable" and are eligible for
64    * auto-skinning.
65    *
66    * This function performs 2 functions:
67    *
68    *   a) It returns 1 if the bone is skinnable.
69    *      If we loop over all bones with this
70    *      function, we can count the number of
71    *      skinnable bones.
72    *   b) If the pointer data is non null,
73    *      it is treated like a handle to a
74    *      bone pointer -- the bone pointer
75    *      is set to point at this bone, and
76    *      the pointer the handle points to
77    *      is incremented to point to the
78    *      next member of an array of pointers
79    *      to bones. This way we can loop using
80    *      this function to construct an array of
81    *      pointers to bones that point to all
82    *      skinnable bones.
83    */
84   Bone ***hbone;
85   int a, segments;
86   struct {
87     Object *armob;
88     void *list;
89     int heat;
90     bool is_weight_paint;
91   } *data = datap;
92 
93   if (!(data->is_weight_paint) || !(bone->flag & BONE_HIDDEN_P)) {
94     if (!(bone->flag & BONE_NO_DEFORM)) {
95       if (data->heat && data->armob->pose &&
96           BKE_pose_channel_find_name(data->armob->pose, bone->name)) {
97         segments = bone->segments;
98       }
99       else {
100         segments = 1;
101       }
102 
103       if (data->list != NULL) {
104         hbone = (Bone ***)&data->list;
105 
106         for (a = 0; a < segments; a++) {
107           **hbone = bone;
108           (*hbone)++;
109         }
110       }
111       return segments;
112     }
113   }
114   return 0;
115 }
116 
vgroup_add_unique_bone_cb(Object * ob,Bone * bone,void * UNUSED (ptr))117 static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
118 {
119   /* This group creates a vertex group to ob that has the
120    * same name as bone (provided the bone is skinnable).
121    * If such a vertex group already exist the routine exits.
122    */
123   if (!(bone->flag & BONE_NO_DEFORM)) {
124     if (!BKE_object_defgroup_find_name(ob, bone->name)) {
125       BKE_object_defgroup_add_name(ob, bone->name);
126       return 1;
127     }
128   }
129   return 0;
130 }
131 
dgroup_skinnable_cb(Object * ob,Bone * bone,void * datap)132 static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
133 {
134   /* Bones that are deforming
135    * are regarded to be "skinnable" and are eligible for
136    * auto-skinning.
137    *
138    * This function performs 2 functions:
139    *
140    *   a) If the bone is skinnable, it creates
141    *      a vertex group for ob that has
142    *      the name of the skinnable bone
143    *      (if one doesn't exist already).
144    *   b) If the pointer data is non null,
145    *      it is treated like a handle to a
146    *      bDeformGroup pointer -- the
147    *      bDeformGroup pointer is set to point
148    *      to the deform group with the bone's
149    *      name, and the pointer the handle
150    *      points to is incremented to point to the
151    *      next member of an array of pointers
152    *      to bDeformGroups. This way we can loop using
153    *      this function to construct an array of
154    *      pointers to bDeformGroups, all with names
155    *      of skinnable bones.
156    */
157   bDeformGroup ***hgroup, *defgroup = NULL;
158   int a, segments;
159   struct {
160     Object *armob;
161     void *list;
162     int heat;
163     bool is_weight_paint;
164   } *data = datap;
165   bArmature *arm = data->armob->data;
166 
167   if (!data->is_weight_paint || !(bone->flag & BONE_HIDDEN_P)) {
168     if (!(bone->flag & BONE_NO_DEFORM)) {
169       if (data->heat && data->armob->pose &&
170           BKE_pose_channel_find_name(data->armob->pose, bone->name)) {
171         segments = bone->segments;
172       }
173       else {
174         segments = 1;
175       }
176 
177       if (!data->is_weight_paint || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) {
178         if (!(defgroup = BKE_object_defgroup_find_name(ob, bone->name))) {
179           defgroup = BKE_object_defgroup_add_name(ob, bone->name);
180         }
181         else if (defgroup->flag & DG_LOCK_WEIGHT) {
182           /* In case vgroup already exists and is locked, do not modify it here. See T43814. */
183           defgroup = NULL;
184         }
185       }
186 
187       if (data->list != NULL) {
188         hgroup = (bDeformGroup ***)&data->list;
189 
190         for (a = 0; a < segments; a++) {
191           **hgroup = defgroup;
192           (*hgroup)++;
193         }
194       }
195       return segments;
196     }
197   }
198   return 0;
199 }
200 
envelope_bone_weighting(Object * ob,Mesh * mesh,float (* verts)[3],int numbones,Bone ** bonelist,bDeformGroup ** dgrouplist,bDeformGroup ** dgroupflip,float (* root)[3],float (* tip)[3],const int * selected,float scale)201 static void envelope_bone_weighting(Object *ob,
202                                     Mesh *mesh,
203                                     float (*verts)[3],
204                                     int numbones,
205                                     Bone **bonelist,
206                                     bDeformGroup **dgrouplist,
207                                     bDeformGroup **dgroupflip,
208                                     float (*root)[3],
209                                     float (*tip)[3],
210                                     const int *selected,
211                                     float scale)
212 {
213   /* Create vertex group weights from envelopes */
214 
215   bool use_topology = (mesh->editflag & ME_EDIT_MIRROR_TOPO) != 0;
216   bool use_mask = false;
217 
218   if ((ob->mode & OB_MODE_WEIGHT_PAINT) &&
219       (mesh->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL))) {
220     use_mask = true;
221   }
222 
223   /* for each vertex in the mesh */
224   for (int i = 0; i < mesh->totvert; i++) {
225 
226     if (use_mask && !(mesh->mvert[i].flag & SELECT)) {
227       continue;
228     }
229 
230     int iflip = (dgroupflip) ? mesh_get_x_mirror_vert(ob, NULL, i, use_topology) : -1;
231 
232     /* for each skinnable bone */
233     for (int j = 0; j < numbones; j++) {
234       if (!selected[j]) {
235         continue;
236       }
237 
238       Bone *bone = bonelist[j];
239       bDeformGroup *dgroup = dgrouplist[j];
240 
241       /* store the distance-factor from the vertex to the bone */
242       float distance = distfactor_to_bone(verts[i],
243                                           root[j],
244                                           tip[j],
245                                           bone->rad_head * scale,
246                                           bone->rad_tail * scale,
247                                           bone->dist * scale);
248 
249       /* add the vert to the deform group if (weight != 0.0) */
250       if (distance != 0.0f) {
251         ED_vgroup_vert_add(ob, dgroup, i, distance, WEIGHT_REPLACE);
252       }
253       else {
254         ED_vgroup_vert_remove(ob, dgroup, i);
255       }
256 
257       /* do same for mirror */
258       if (dgroupflip && dgroupflip[j] && iflip != -1) {
259         if (distance != 0.0f) {
260           ED_vgroup_vert_add(ob, dgroupflip[j], iflip, distance, WEIGHT_REPLACE);
261         }
262         else {
263           ED_vgroup_vert_remove(ob, dgroupflip[j], iflip);
264         }
265       }
266     }
267   }
268 }
269 
add_verts_to_dgroups(ReportList * reports,Depsgraph * depsgraph,Scene * UNUSED (scene),Object * ob,Object * par,int heat,const bool mirror)270 static void add_verts_to_dgroups(ReportList *reports,
271                                  Depsgraph *depsgraph,
272                                  Scene *UNUSED(scene),
273                                  Object *ob,
274                                  Object *par,
275                                  int heat,
276                                  const bool mirror)
277 {
278   /* This functions implements the automatic computation of vertex group
279    * weights, either through envelopes or using a heat equilibrium.
280    *
281    * This function can be called both when parenting a mesh to an armature,
282    * or in weight-paint + pose-mode. In the latter case selection is taken
283    * into account and vertex weights can be mirrored.
284    *
285    * The mesh vertex positions used are either the final deformed coords
286    * from the evaluated mesh in weight-paint mode, the final sub-surface coords
287    * when parenting, or simply the original mesh coords.
288    */
289 
290   bArmature *arm = par->data;
291   Bone **bonelist, *bone;
292   bDeformGroup **dgrouplist, **dgroupflip;
293   bDeformGroup *dgroup;
294   bPoseChannel *pchan;
295   Mesh *mesh;
296   Mat4 bbone_array[MAX_BBONE_SUBDIV], *bbone = NULL;
297   float(*root)[3], (*tip)[3], (*verts)[3];
298   int *selected;
299   int numbones, vertsfilled = 0, segments = 0;
300   const bool wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT);
301   struct {
302     Object *armob;
303     void *list;
304     int heat;
305     bool is_weight_paint;
306   } looper_data;
307 
308   looper_data.armob = par;
309   looper_data.heat = heat;
310   looper_data.list = NULL;
311   looper_data.is_weight_paint = wpmode;
312 
313   /* count the number of skinnable bones */
314   numbones = bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable_cb);
315 
316   if (numbones == 0) {
317     return;
318   }
319 
320   if (BKE_object_defgroup_data_create(ob->data) == NULL) {
321     return;
322   }
323 
324   /* create an array of pointer to bones that are skinnable
325    * and fill it with all of the skinnable bones */
326   bonelist = MEM_callocN(numbones * sizeof(Bone *), "bonelist");
327   looper_data.list = bonelist;
328   bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable_cb);
329 
330   /* create an array of pointers to the deform groups that
331    * correspond to the skinnable bones (creating them
332    * as necessary. */
333   dgrouplist = MEM_callocN(numbones * sizeof(bDeformGroup *), "dgrouplist");
334   dgroupflip = MEM_callocN(numbones * sizeof(bDeformGroup *), "dgroupflip");
335 
336   looper_data.list = dgrouplist;
337   bone_looper(ob, arm->bonebase.first, &looper_data, dgroup_skinnable_cb);
338 
339   /* create an array of root and tip positions transformed into
340    * global coords */
341   root = MEM_callocN(sizeof(float[3]) * numbones, "root");
342   tip = MEM_callocN(sizeof(float[3]) * numbones, "tip");
343   selected = MEM_callocN(sizeof(int) * numbones, "selected");
344 
345   for (int j = 0; j < numbones; j++) {
346     bone = bonelist[j];
347     dgroup = dgrouplist[j];
348 
349     /* handle bbone */
350     if (heat) {
351       if (segments == 0) {
352         segments = 1;
353         bbone = NULL;
354 
355         if ((par->pose) && (pchan = BKE_pose_channel_find_name(par->pose, bone->name))) {
356           if (bone->segments > 1) {
357             segments = bone->segments;
358             BKE_pchan_bbone_spline_setup(pchan, true, false, bbone_array);
359             bbone = bbone_array;
360           }
361         }
362       }
363 
364       segments--;
365     }
366 
367     /* compute root and tip */
368     if (bbone) {
369       mul_v3_m4v3(root[j], bone->arm_mat, bbone[segments].mat[3]);
370       if ((segments + 1) < bone->segments) {
371         mul_v3_m4v3(tip[j], bone->arm_mat, bbone[segments + 1].mat[3]);
372       }
373       else {
374         copy_v3_v3(tip[j], bone->arm_tail);
375       }
376     }
377     else {
378       copy_v3_v3(root[j], bone->arm_head);
379       copy_v3_v3(tip[j], bone->arm_tail);
380     }
381 
382     mul_m4_v3(par->obmat, root[j]);
383     mul_m4_v3(par->obmat, tip[j]);
384 
385     /* set selected */
386     if (wpmode) {
387       if ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED)) {
388         selected[j] = 1;
389       }
390     }
391     else {
392       selected[j] = 1;
393     }
394 
395     /* find flipped group */
396     if (dgroup && mirror) {
397       char name_flip[MAXBONENAME];
398 
399       BLI_string_flip_side_name(name_flip, dgroup->name, false, sizeof(name_flip));
400       dgroupflip[j] = BKE_object_defgroup_find_name(ob, name_flip);
401     }
402   }
403 
404   /* create verts */
405   mesh = (Mesh *)ob->data;
406   verts = MEM_callocN(mesh->totvert * sizeof(*verts), "closestboneverts");
407 
408   if (wpmode) {
409     /* if in weight paint mode, use final verts from evaluated mesh */
410     Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
411     Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
412     Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
413 
414     BKE_mesh_foreach_mapped_vert_coords_get(me_eval, verts, mesh->totvert);
415     vertsfilled = 1;
416   }
417   else if (BKE_modifiers_findby_type(ob, eModifierType_Subsurf)) {
418     /* is subsurf on? Lets use the verts on the limit surface then.
419      * = same amount of vertices as mesh, but vertices  moved to the
420      * subsurfed position, like for 'optimal'. */
421     subsurf_calculate_limit_positions(mesh, verts);
422     vertsfilled = 1;
423   }
424 
425   /* transform verts to global space */
426   for (int i = 0; i < mesh->totvert; i++) {
427     if (!vertsfilled) {
428       copy_v3_v3(verts[i], mesh->mvert[i].co);
429     }
430     mul_m4_v3(ob->obmat, verts[i]);
431   }
432 
433   /* compute the weights based on gathered vertices and bones */
434   if (heat) {
435     const char *error = NULL;
436 
437     heat_bone_weighting(
438         ob, mesh, verts, numbones, dgrouplist, dgroupflip, root, tip, selected, &error);
439     if (error) {
440       BKE_report(reports, RPT_WARNING, error);
441     }
442   }
443   else {
444     envelope_bone_weighting(ob,
445                             mesh,
446                             verts,
447                             numbones,
448                             bonelist,
449                             dgrouplist,
450                             dgroupflip,
451                             root,
452                             tip,
453                             selected,
454                             mat4_to_scale(par->obmat));
455   }
456 
457   /* only generated in some cases but can call anyway */
458   ED_mesh_mirror_spatial_table_end(ob);
459 
460   /* free the memory allocated */
461   MEM_freeN(bonelist);
462   MEM_freeN(dgrouplist);
463   MEM_freeN(dgroupflip);
464   MEM_freeN(root);
465   MEM_freeN(tip);
466   MEM_freeN(selected);
467   MEM_freeN(verts);
468 }
469 
ED_object_vgroup_calc_from_armature(ReportList * reports,Depsgraph * depsgraph,Scene * scene,Object * ob,Object * par,const int mode,const bool mirror)470 void ED_object_vgroup_calc_from_armature(ReportList *reports,
471                                          Depsgraph *depsgraph,
472                                          Scene *scene,
473                                          Object *ob,
474                                          Object *par,
475                                          const int mode,
476                                          const bool mirror)
477 {
478   /* Lets try to create some vertex groups
479    * based on the bones of the parent armature.
480    */
481   bArmature *arm = par->data;
482 
483   if (mode == ARM_GROUPS_NAME) {
484     const int defbase_tot = BLI_listbase_count(&ob->defbase);
485     int defbase_add;
486     /* Traverse the bone list, trying to create empty vertex
487      * groups corresponding to the bone.
488      */
489     defbase_add = bone_looper(ob, arm->bonebase.first, NULL, vgroup_add_unique_bone_cb);
490 
491     if (defbase_add) {
492       /* its possible there are DWeight's outside the range of the current
493        * objects deform groups, in this case the new groups wont be empty T33889. */
494       ED_vgroup_data_clamp_range(ob->data, defbase_tot);
495     }
496   }
497   else if (ELEM(mode, ARM_GROUPS_ENVELOPE, ARM_GROUPS_AUTO)) {
498     /* Traverse the bone list, trying to create vertex groups
499      * that are populated with the vertices for which the
500      * bone is closest.
501      */
502     add_verts_to_dgroups(reports, depsgraph, scene, ob, par, (mode == ARM_GROUPS_AUTO), mirror);
503   }
504 }
505