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