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  */
19 
20 /** \file
21  * \ingroup bke
22  */
23 
24 #include <ctype.h>
25 #include <math.h>
26 #include <stddef.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "MEM_guardedalloc.h"
31 
32 #include "DNA_mesh_types.h"
33 #include "DNA_meshdata_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_scene_types.h"
36 
37 #include "BLI_listbase.h"
38 #include "BLI_math.h"
39 #include "BLI_string.h"
40 #include "BLI_string_utils.h"
41 #include "BLI_utildefines.h"
42 
43 #include "BLT_translation.h"
44 
45 #include "BKE_customdata.h"
46 #include "BKE_data_transfer.h"
47 #include "BKE_deform.h" /* own include */
48 #include "BKE_mesh.h"
49 #include "BKE_mesh_mapping.h"
50 #include "BKE_object.h"
51 #include "BKE_object_deform.h"
52 
53 #include "BLO_read_write.h"
54 
55 #include "data_transfer_intern.h"
56 
BKE_object_defgroup_new(Object * ob,const char * name)57 bDeformGroup *BKE_object_defgroup_new(Object *ob, const char *name)
58 {
59   bDeformGroup *defgroup;
60 
61   BLI_assert(OB_TYPE_SUPPORT_VGROUP(ob->type));
62 
63   defgroup = MEM_callocN(sizeof(bDeformGroup), __func__);
64 
65   BLI_strncpy(defgroup->name, name, sizeof(defgroup->name));
66 
67   BLI_addtail(&ob->defbase, defgroup);
68   BKE_object_defgroup_unique_name(defgroup, ob);
69 
70   BKE_object_batch_cache_dirty_tag(ob);
71 
72   return defgroup;
73 }
74 
BKE_defgroup_copy_list(ListBase * outbase,const ListBase * inbase)75 void BKE_defgroup_copy_list(ListBase *outbase, const ListBase *inbase)
76 {
77   bDeformGroup *defgroup, *defgroupn;
78 
79   BLI_listbase_clear(outbase);
80 
81   for (defgroup = inbase->first; defgroup; defgroup = defgroup->next) {
82     defgroupn = BKE_defgroup_duplicate(defgroup);
83     BLI_addtail(outbase, defgroupn);
84   }
85 }
86 
BKE_defgroup_duplicate(const bDeformGroup * ingroup)87 bDeformGroup *BKE_defgroup_duplicate(const bDeformGroup *ingroup)
88 {
89   bDeformGroup *outgroup;
90 
91   if (!ingroup) {
92     BLI_assert(0);
93     return NULL;
94   }
95 
96   outgroup = MEM_callocN(sizeof(bDeformGroup), "copy deformGroup");
97 
98   /* For now, just copy everything over. */
99   memcpy(outgroup, ingroup, sizeof(bDeformGroup));
100 
101   outgroup->next = outgroup->prev = NULL;
102 
103   return outgroup;
104 }
105 
106 /**
107  * Overwrite weights filtered by vgroup_subset.
108  * - do nothing if neither are set.
109  * - add destination weight if needed
110  */
BKE_defvert_copy_subset(MDeformVert * dvert_dst,const MDeformVert * dvert_src,const bool * vgroup_subset,const int vgroup_tot)111 void BKE_defvert_copy_subset(MDeformVert *dvert_dst,
112                              const MDeformVert *dvert_src,
113                              const bool *vgroup_subset,
114                              const int vgroup_tot)
115 {
116   int defgroup;
117   for (defgroup = 0; defgroup < vgroup_tot; defgroup++) {
118     if (vgroup_subset[defgroup]) {
119       BKE_defvert_copy_index(dvert_dst, defgroup, dvert_src, defgroup);
120     }
121   }
122 }
123 
124 /**
125  * Overwrite weights filtered by vgroup_subset and with mirroring specified by the flip map
126  * - do nothing if neither are set.
127  * - add destination weight if needed
128  */
BKE_defvert_mirror_subset(MDeformVert * dvert_dst,const MDeformVert * dvert_src,const bool * vgroup_subset,const int vgroup_tot,const int * flip_map,const int flip_map_len)129 void BKE_defvert_mirror_subset(MDeformVert *dvert_dst,
130                                const MDeformVert *dvert_src,
131                                const bool *vgroup_subset,
132                                const int vgroup_tot,
133                                const int *flip_map,
134                                const int flip_map_len)
135 {
136   int defgroup;
137   for (defgroup = 0; defgroup < vgroup_tot && defgroup < flip_map_len; defgroup++) {
138     if (vgroup_subset[defgroup] && (dvert_dst != dvert_src || flip_map[defgroup] != defgroup)) {
139       BKE_defvert_copy_index(dvert_dst, flip_map[defgroup], dvert_src, defgroup);
140     }
141   }
142 }
143 
BKE_defvert_copy(MDeformVert * dvert_dst,const MDeformVert * dvert_src)144 void BKE_defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
145 {
146   if (dvert_dst->totweight == dvert_src->totweight) {
147     if (dvert_src->totweight) {
148       memcpy(dvert_dst->dw, dvert_src->dw, dvert_src->totweight * sizeof(MDeformWeight));
149     }
150   }
151   else {
152     if (dvert_dst->dw) {
153       MEM_freeN(dvert_dst->dw);
154     }
155 
156     if (dvert_src->totweight) {
157       dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
158     }
159     else {
160       dvert_dst->dw = NULL;
161     }
162 
163     dvert_dst->totweight = dvert_src->totweight;
164   }
165 }
166 
167 /**
168  * Copy an index from one dvert to another.
169  * - do nothing if neither are set.
170  * - add destination weight if needed.
171  */
BKE_defvert_copy_index(MDeformVert * dvert_dst,const int defgroup_dst,const MDeformVert * dvert_src,const int defgroup_src)172 void BKE_defvert_copy_index(MDeformVert *dvert_dst,
173                             const int defgroup_dst,
174                             const MDeformVert *dvert_src,
175                             const int defgroup_src)
176 {
177   MDeformWeight *dw_src, *dw_dst;
178 
179   dw_src = BKE_defvert_find_index(dvert_src, defgroup_src);
180 
181   if (dw_src) {
182     /* Source is valid, ensure destination is created. */
183     dw_dst = BKE_defvert_ensure_index(dvert_dst, defgroup_dst);
184     dw_dst->weight = dw_src->weight;
185   }
186   else {
187     /* Source was NULL, assign zero (could also remove). */
188     dw_dst = BKE_defvert_find_index(dvert_dst, defgroup_dst);
189 
190     if (dw_dst) {
191       dw_dst->weight = 0.0f;
192     }
193   }
194 }
195 
196 /**
197  * Only sync over matching weights, don't add or remove groups
198  * warning, loop within loop.
199  */
BKE_defvert_sync(MDeformVert * dvert_dst,const MDeformVert * dvert_src,const bool use_ensure)200 void BKE_defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const bool use_ensure)
201 {
202   if (dvert_src->totweight && dvert_dst->totweight) {
203     MDeformWeight *dw_src = dvert_src->dw;
204     for (int i = 0; i < dvert_src->totweight; i++, dw_src++) {
205       MDeformWeight *dw_dst;
206       if (use_ensure) {
207         dw_dst = BKE_defvert_ensure_index(dvert_dst, dw_src->def_nr);
208       }
209       else {
210         dw_dst = BKE_defvert_find_index(dvert_dst, dw_src->def_nr);
211       }
212 
213       if (dw_dst) {
214         dw_dst->weight = dw_src->weight;
215       }
216     }
217   }
218 }
219 
220 /**
221  * be sure all flip_map values are valid
222  */
BKE_defvert_sync_mapped(MDeformVert * dvert_dst,const MDeformVert * dvert_src,const int * flip_map,const int flip_map_len,const bool use_ensure)223 void BKE_defvert_sync_mapped(MDeformVert *dvert_dst,
224                              const MDeformVert *dvert_src,
225                              const int *flip_map,
226                              const int flip_map_len,
227                              const bool use_ensure)
228 {
229   if (dvert_src->totweight && dvert_dst->totweight) {
230     MDeformWeight *dw_src = dvert_src->dw;
231     for (int i = 0; i < dvert_src->totweight; i++, dw_src++) {
232       if (dw_src->def_nr < flip_map_len) {
233         MDeformWeight *dw_dst;
234         if (use_ensure) {
235           dw_dst = BKE_defvert_ensure_index(dvert_dst, flip_map[dw_src->def_nr]);
236         }
237         else {
238           dw_dst = BKE_defvert_find_index(dvert_dst, flip_map[dw_src->def_nr]);
239         }
240 
241         if (dw_dst) {
242           dw_dst->weight = dw_src->weight;
243         }
244       }
245     }
246   }
247 }
248 
249 /**
250  * be sure all flip_map values are valid
251  */
BKE_defvert_remap(MDeformVert * dvert,const int * map,const int map_len)252 void BKE_defvert_remap(MDeformVert *dvert, const int *map, const int map_len)
253 {
254   MDeformWeight *dw = dvert->dw;
255   for (int i = dvert->totweight; i != 0; i--, dw++) {
256     if (dw->def_nr < map_len) {
257       BLI_assert(map[dw->def_nr] >= 0);
258 
259       dw->def_nr = map[dw->def_nr];
260     }
261   }
262 }
263 
264 /**
265  * Same as #BKE_defvert_normalize but takes a bool array.
266  */
BKE_defvert_normalize_subset(MDeformVert * dvert,const bool * vgroup_subset,const int vgroup_tot)267 void BKE_defvert_normalize_subset(MDeformVert *dvert,
268                                   const bool *vgroup_subset,
269                                   const int vgroup_tot)
270 {
271   if (dvert->totweight == 0) {
272     /* nothing */
273   }
274   else if (dvert->totweight == 1) {
275     MDeformWeight *dw = dvert->dw;
276     if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
277       dw->weight = 1.0f;
278     }
279   }
280   else {
281     MDeformWeight *dw = dvert->dw;
282     float tot_weight = 0.0f;
283     for (int i = dvert->totweight; i != 0; i--, dw++) {
284       if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
285         tot_weight += dw->weight;
286       }
287     }
288 
289     if (tot_weight > 0.0f) {
290       float scalar = 1.0f / tot_weight;
291       dw = dvert->dw;
292       for (int i = dvert->totweight; i != 0; i--, dw++) {
293         if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
294           dw->weight *= scalar;
295 
296           /* in case of division errors with very low weights */
297           CLAMP(dw->weight, 0.0f, 1.0f);
298         }
299       }
300     }
301   }
302 }
303 
BKE_defvert_normalize(MDeformVert * dvert)304 void BKE_defvert_normalize(MDeformVert *dvert)
305 {
306   if (dvert->totweight == 0) {
307     /* nothing */
308   }
309   else if (dvert->totweight == 1) {
310     dvert->dw[0].weight = 1.0f;
311   }
312   else {
313     MDeformWeight *dw;
314     unsigned int i;
315     float tot_weight = 0.0f;
316 
317     for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
318       tot_weight += dw->weight;
319     }
320 
321     if (tot_weight > 0.0f) {
322       float scalar = 1.0f / tot_weight;
323       for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
324         dw->weight *= scalar;
325 
326         /* in case of division errors with very low weights */
327         CLAMP(dw->weight, 0.0f, 1.0f);
328       }
329     }
330   }
331 }
332 
333 /**
334  * Same as BKE_defvert_normalize() if the locked vgroup is not a member of the subset
335  */
BKE_defvert_normalize_lock_single(MDeformVert * dvert,const bool * vgroup_subset,const int vgroup_tot,const uint def_nr_lock)336 void BKE_defvert_normalize_lock_single(MDeformVert *dvert,
337                                        const bool *vgroup_subset,
338                                        const int vgroup_tot,
339                                        const uint def_nr_lock)
340 {
341   if (dvert->totweight == 0) {
342     /* nothing */
343   }
344   else if (dvert->totweight == 1) {
345     MDeformWeight *dw = dvert->dw;
346     if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
347       if (def_nr_lock != dw->def_nr) {
348         dw->weight = 1.0f;
349       }
350     }
351   }
352   else {
353     MDeformWeight *dw_lock = NULL;
354     MDeformWeight *dw;
355     unsigned int i;
356     float tot_weight = 0.0f;
357     float lock_iweight = 1.0f;
358 
359     for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
360       if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
361         if (dw->def_nr != def_nr_lock) {
362           tot_weight += dw->weight;
363         }
364         else {
365           dw_lock = dw;
366           lock_iweight = (1.0f - dw_lock->weight);
367           CLAMP(lock_iweight, 0.0f, 1.0f);
368         }
369       }
370     }
371 
372     if (tot_weight > 0.0f) {
373       /* paranoid, should be 1.0 but in case of float error clamp anyway */
374 
375       float scalar = (1.0f / tot_weight) * lock_iweight;
376       for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
377         if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
378           if (dw != dw_lock) {
379             dw->weight *= scalar;
380 
381             /* in case of division errors with very low weights */
382             CLAMP(dw->weight, 0.0f, 1.0f);
383           }
384         }
385       }
386     }
387   }
388 }
389 
390 /**
391  * Same as BKE_defvert_normalize() if no locked vgroup is a member of the subset
392  */
BKE_defvert_normalize_lock_map(MDeformVert * dvert,const bool * vgroup_subset,const int vgroup_tot,const bool * lock_flags,const int defbase_tot)393 void BKE_defvert_normalize_lock_map(MDeformVert *dvert,
394                                     const bool *vgroup_subset,
395                                     const int vgroup_tot,
396                                     const bool *lock_flags,
397                                     const int defbase_tot)
398 {
399   if (dvert->totweight == 0) {
400     /* nothing */
401   }
402   else if (dvert->totweight == 1) {
403     MDeformWeight *dw = dvert->dw;
404     if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
405       if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
406         dw->weight = 1.0f;
407       }
408     }
409   }
410   else {
411     MDeformWeight *dw;
412     unsigned int i;
413     float tot_weight = 0.0f;
414     float lock_iweight = 0.0f;
415 
416     for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
417       if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
418         if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
419           tot_weight += dw->weight;
420         }
421         else {
422           /* invert after */
423           lock_iweight += dw->weight;
424         }
425       }
426     }
427 
428     lock_iweight = max_ff(0.0f, 1.0f - lock_iweight);
429 
430     if (tot_weight > 0.0f) {
431       /* paranoid, should be 1.0 but in case of float error clamp anyway */
432 
433       float scalar = (1.0f / tot_weight) * lock_iweight;
434       for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
435         if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
436           if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
437             dw->weight *= scalar;
438 
439             /* in case of division errors with very low weights */
440             CLAMP(dw->weight, 0.0f, 1.0f);
441           }
442         }
443       }
444     }
445   }
446 }
447 
BKE_defvert_flip(MDeformVert * dvert,const int * flip_map,const int flip_map_len)448 void BKE_defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
449 {
450   MDeformWeight *dw;
451   int i;
452 
453   for (dw = dvert->dw, i = 0; i < dvert->totweight; dw++, i++) {
454     if (dw->def_nr < flip_map_len) {
455       if (flip_map[dw->def_nr] >= 0) {
456         dw->def_nr = flip_map[dw->def_nr];
457       }
458     }
459   }
460 }
461 
BKE_defvert_flip_merged(MDeformVert * dvert,const int * flip_map,const int flip_map_len)462 void BKE_defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
463 {
464   MDeformWeight *dw, *dw_cpy;
465   float weight;
466   int i, totweight = dvert->totweight;
467 
468   /* copy weights */
469   for (dw = dvert->dw, i = 0; i < totweight; dw++, i++) {
470     if (dw->def_nr < flip_map_len) {
471       if (flip_map[dw->def_nr] >= 0) {
472         /* error checkers complain of this but we'll never get NULL return */
473         dw_cpy = BKE_defvert_ensure_index(dvert, flip_map[dw->def_nr]);
474         dw = &dvert->dw[i]; /* in case array got realloced */
475 
476         /* distribute weights: if only one of the vertex groups was
477          * assigned this will halve the weights, otherwise it gets
478          * evened out. this keeps it proportional to other groups */
479         weight = 0.5f * (dw_cpy->weight + dw->weight);
480         dw_cpy->weight = weight;
481         dw->weight = weight;
482       }
483     }
484   }
485 }
486 
BKE_object_defgroup_find_name(const Object * ob,const char * name)487 bDeformGroup *BKE_object_defgroup_find_name(const Object *ob, const char *name)
488 {
489   return (name && name[0] != '\0') ?
490              BLI_findstring(&ob->defbase, name, offsetof(bDeformGroup, name)) :
491              NULL;
492 }
493 
BKE_object_defgroup_name_index(const Object * ob,const char * name)494 int BKE_object_defgroup_name_index(const Object *ob, const char *name)
495 {
496   return (name && name[0] != '\0') ?
497              BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) :
498              -1;
499 }
500 
501 /**
502  * \note caller must free.
503  */
BKE_object_defgroup_flip_map(const Object * ob,int * flip_map_len,const bool use_default)504 int *BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const bool use_default)
505 {
506   int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
507 
508   if (defbase_tot == 0) {
509     return NULL;
510   }
511 
512   bDeformGroup *dg;
513   char name_flip[sizeof(dg->name)];
514   int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
515 
516   for (i = 0; i < defbase_tot; i++) {
517     map[i] = -1;
518   }
519 
520   for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
521     if (map[i] == -1) { /* may be calculated previously */
522 
523       /* in case no valid value is found, use this */
524       if (use_default) {
525         map[i] = i;
526       }
527 
528       BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
529 
530       if (!STREQ(name_flip, dg->name)) {
531         flip_num = BKE_object_defgroup_name_index(ob, name_flip);
532         if (flip_num >= 0) {
533           map[i] = flip_num;
534           map[flip_num] = i; /* save an extra lookup */
535         }
536       }
537     }
538   }
539   return map;
540 }
541 
542 /**
543  * \note caller must free.
544  */
BKE_object_defgroup_flip_map_single(const Object * ob,int * flip_map_len,const bool use_default,int defgroup)545 int *BKE_object_defgroup_flip_map_single(const Object *ob,
546                                          int *flip_map_len,
547                                          const bool use_default,
548                                          int defgroup)
549 {
550   int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
551 
552   if (defbase_tot == 0) {
553     return NULL;
554   }
555 
556   bDeformGroup *dg;
557   char name_flip[sizeof(dg->name)];
558   int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
559 
560   for (i = 0; i < defbase_tot; i++) {
561     map[i] = use_default ? i : -1;
562   }
563 
564   dg = BLI_findlink(&ob->defbase, defgroup);
565 
566   BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
567   if (!STREQ(name_flip, dg->name)) {
568     flip_num = BKE_object_defgroup_name_index(ob, name_flip);
569 
570     if (flip_num != -1) {
571       map[defgroup] = flip_num;
572       map[flip_num] = defgroup;
573     }
574   }
575 
576   return map;
577 }
578 
BKE_object_defgroup_flip_index(const Object * ob,int index,const bool use_default)579 int BKE_object_defgroup_flip_index(const Object *ob, int index, const bool use_default)
580 {
581   bDeformGroup *dg = BLI_findlink(&ob->defbase, index);
582   int flip_index = -1;
583 
584   if (dg) {
585     char name_flip[sizeof(dg->name)];
586     BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
587 
588     if (!STREQ(name_flip, dg->name)) {
589       flip_index = BKE_object_defgroup_name_index(ob, name_flip);
590     }
591   }
592 
593   return (flip_index == -1 && use_default) ? index : flip_index;
594 }
595 
defgroup_find_name_dupe(const char * name,bDeformGroup * dg,Object * ob)596 static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
597 {
598   bDeformGroup *curdef;
599 
600   for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
601     if (dg != curdef) {
602       if (STREQ(curdef->name, name)) {
603         return true;
604       }
605     }
606   }
607 
608   return false;
609 }
610 
defgroup_unique_check(void * arg,const char * name)611 static bool defgroup_unique_check(void *arg, const char *name)
612 {
613   struct {
614     Object *ob;
615     void *dg;
616   } *data = arg;
617   return defgroup_find_name_dupe(name, data->dg, data->ob);
618 }
619 
BKE_object_defgroup_unique_name(bDeformGroup * dg,Object * ob)620 void BKE_object_defgroup_unique_name(bDeformGroup *dg, Object *ob)
621 {
622   struct {
623     Object *ob;
624     void *dg;
625   } data;
626   data.ob = ob;
627   data.dg = dg;
628 
629   BLI_uniquename_cb(defgroup_unique_check, &data, DATA_("Group"), '.', dg->name, sizeof(dg->name));
630 }
631 
BKE_defvert_find_weight(const struct MDeformVert * dvert,const int defgroup)632 float BKE_defvert_find_weight(const struct MDeformVert *dvert, const int defgroup)
633 {
634   MDeformWeight *dw = BKE_defvert_find_index(dvert, defgroup);
635   return dw ? dw->weight : 0.0f;
636 }
637 
638 /**
639  * Take care with this the rationale is:
640  * - if the object has no vertex group. act like vertex group isn't set and return 1.0,
641  * - if the vertex group exists but the 'defgroup' isn't found on this vertex, _still_ return 0.0
642  *
643  * This is a bit confusing, just saves some checks from the caller.
644  */
BKE_defvert_array_find_weight_safe(const struct MDeformVert * dvert,const int index,const int defgroup)645 float BKE_defvert_array_find_weight_safe(const struct MDeformVert *dvert,
646                                          const int index,
647                                          const int defgroup)
648 {
649   /* Invalid defgroup index means the vgroup selected is invalid,
650    * does not exist, in that case it is OK to return 1.0
651    * (i.e. maximum weight, as if no vgroup was selected).
652    * But in case of valid defgroup and NULL dvert data pointer, it means that vgroup **is** valid,
653    * and just totally empty, so we shall return '0.0' value then! */
654   if (defgroup == -1) {
655     return 1.0f;
656   }
657   if (dvert == NULL) {
658     return 0.0f;
659   }
660 
661   return BKE_defvert_find_weight(dvert + index, defgroup);
662 }
663 
BKE_defvert_find_index(const MDeformVert * dvert,const int defgroup)664 MDeformWeight *BKE_defvert_find_index(const MDeformVert *dvert, const int defgroup)
665 {
666   if (dvert && defgroup >= 0) {
667     MDeformWeight *dw = dvert->dw;
668     unsigned int i;
669 
670     for (i = dvert->totweight; i != 0; i--, dw++) {
671       if (dw->def_nr == defgroup) {
672         return dw;
673       }
674     }
675   }
676   else {
677     BLI_assert(0);
678   }
679 
680   return NULL;
681 }
682 
683 /**
684  * Ensures that mv has a deform weight entry for the specified defweight group.
685  *
686  * \note this function is mirrored in editmesh_tools.c, for use for editvertices.
687  */
BKE_defvert_ensure_index(MDeformVert * dvert,const int defgroup)688 MDeformWeight *BKE_defvert_ensure_index(MDeformVert *dvert, const int defgroup)
689 {
690   MDeformWeight *dw_new;
691 
692   /* do this check always, this function is used to check for it */
693   if (!dvert || defgroup < 0) {
694     BLI_assert(0);
695     return NULL;
696   }
697 
698   dw_new = BKE_defvert_find_index(dvert, defgroup);
699   if (dw_new) {
700     return dw_new;
701   }
702 
703   dw_new = MEM_mallocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "deformWeight");
704   if (dvert->dw) {
705     memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
706     MEM_freeN(dvert->dw);
707   }
708   dvert->dw = dw_new;
709   dw_new += dvert->totweight;
710   dw_new->weight = 0.0f;
711   dw_new->def_nr = defgroup;
712   /* Group index */
713 
714   dvert->totweight++;
715 
716   return dw_new;
717 }
718 
719 /* TODO. merge with code above! */
720 
721 /**
722  * Adds the given vertex to the specified vertex group, with given weight.
723  *
724  * \warning this does NOT check for existing, assume caller already knows its not there.
725  */
BKE_defvert_add_index_notest(MDeformVert * dvert,int defgroup,const float weight)726 void BKE_defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight)
727 {
728   MDeformWeight *dw_new;
729 
730   /* do this check always, this function is used to check for it */
731   if (!dvert || defgroup < 0) {
732     BLI_assert(0);
733     return;
734   }
735 
736   dw_new = MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1),
737                        "defvert_add_to group, new deformWeight");
738   if (dvert->dw) {
739     memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
740     MEM_freeN(dvert->dw);
741   }
742   dvert->dw = dw_new;
743   dw_new += dvert->totweight;
744   dw_new->weight = weight;
745   dw_new->def_nr = defgroup;
746   dvert->totweight++;
747 }
748 
749 /**
750  * Removes the given vertex from the vertex group.
751  *
752  * \warning This function frees the given MDeformWeight, do not use it afterward!
753  */
BKE_defvert_remove_group(MDeformVert * dvert,MDeformWeight * dw)754 void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
755 {
756   if (dvert && dw) {
757     int i = dw - dvert->dw;
758 
759     /* Security check! */
760     if (i < 0 || i >= dvert->totweight) {
761       return;
762     }
763 
764     dvert->totweight--;
765     /* If there are still other deform weights attached to this vert then remove
766      * this deform weight, and reshuffle the others.
767      */
768     if (dvert->totweight) {
769       BLI_assert(dvert->dw != NULL);
770 
771       if (i != dvert->totweight) {
772         dvert->dw[i] = dvert->dw[dvert->totweight];
773       }
774 
775       dvert->dw = MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
776     }
777     else {
778       /* If there are no other deform weights left then just remove this one. */
779       MEM_freeN(dvert->dw);
780       dvert->dw = NULL;
781     }
782   }
783 }
784 
BKE_defvert_clear(MDeformVert * dvert)785 void BKE_defvert_clear(MDeformVert *dvert)
786 {
787   if (dvert->dw) {
788     MEM_freeN(dvert->dw);
789     dvert->dw = NULL;
790   }
791 
792   dvert->totweight = 0;
793 }
794 
795 /**
796  * \return The first group index shared by both deform verts
797  * or -1 if none are found.
798  */
BKE_defvert_find_shared(const MDeformVert * dvert_a,const MDeformVert * dvert_b)799 int BKE_defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
800 {
801   if (dvert_a->totweight && dvert_b->totweight) {
802     MDeformWeight *dw = dvert_a->dw;
803     unsigned int i;
804 
805     for (i = dvert_a->totweight; i != 0; i--, dw++) {
806       if (dw->weight > 0.0f && BKE_defvert_find_weight(dvert_b, dw->def_nr) > 0.0f) {
807         return dw->def_nr;
808       }
809     }
810   }
811 
812   return -1;
813 }
814 
815 /**
816  * return true if has no weights
817  */
BKE_defvert_is_weight_zero(const struct MDeformVert * dvert,const int defgroup_tot)818 bool BKE_defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_tot)
819 {
820   MDeformWeight *dw = dvert->dw;
821   for (int i = dvert->totweight; i != 0; i--, dw++) {
822     if (dw->weight != 0.0f) {
823       /* check the group is in-range, happens on rare situations */
824       if (LIKELY(dw->def_nr < defgroup_tot)) {
825         return false;
826       }
827     }
828   }
829   return true;
830 }
831 
832 /**
833  * \return The total weight in all groups marked in the selection mask.
834  */
BKE_defvert_total_selected_weight(const struct MDeformVert * dv,int defbase_tot,const bool * defbase_sel)835 float BKE_defvert_total_selected_weight(const struct MDeformVert *dv,
836                                         int defbase_tot,
837                                         const bool *defbase_sel)
838 {
839   float total = 0.0f;
840   const MDeformWeight *dw = dv->dw;
841 
842   if (defbase_sel == NULL) {
843     return total;
844   }
845 
846   for (int i = dv->totweight; i != 0; i--, dw++) {
847     if (dw->def_nr < defbase_tot) {
848       if (defbase_sel[dw->def_nr]) {
849         total += dw->weight;
850       }
851     }
852   }
853 
854   return total;
855 }
856 
857 /**
858  * \return The representative weight of a multipaint group, used for
859  * viewport colors and actual painting.
860  *
861  * Result equal to sum of weights with auto normalize, and average otherwise.
862  * Value is not clamped, since painting relies on multiplication being always
863  * commutative with the collective weight function.
864  */
BKE_defvert_multipaint_collective_weight(const struct MDeformVert * dv,int defbase_tot,const bool * defbase_sel,int defbase_tot_sel,bool is_normalized)865 float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv,
866                                                int defbase_tot,
867                                                const bool *defbase_sel,
868                                                int defbase_tot_sel,
869                                                bool is_normalized)
870 {
871   float total = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_sel);
872 
873   /* in multipaint, get the average if auto normalize is inactive
874    * get the sum if it is active */
875   if (!is_normalized) {
876     total /= defbase_tot_sel;
877   }
878 
879   return total;
880 }
881 
882 /**
883  * Computes the display weight for the lock relative weight paint mode.
884  *
885  * \return weight divided by 1-locked_weight with division by zero check
886  */
BKE_defvert_calc_lock_relative_weight(float weight,float locked_weight,float unlocked_weight)887 float BKE_defvert_calc_lock_relative_weight(float weight,
888                                             float locked_weight,
889                                             float unlocked_weight)
890 {
891   /* First try normalizing unlocked weights. */
892   if (unlocked_weight > 0.0f) {
893     return weight / unlocked_weight;
894   }
895 
896   /* If no unlocked weight exists, take locked into account. */
897   if (locked_weight <= 0.0f) {
898     return weight;
899   }
900 
901   /* handle division by zero */
902   if (locked_weight >= 1.0f) {
903     if (weight != 0.0f) {
904       return 1.0f;
905     }
906 
907     /* resolve 0/0 to 0 */
908     return 0.0f;
909   }
910 
911   /* non-degenerate division */
912   return weight / (1.0f - locked_weight);
913 }
914 
915 /**
916  * Computes the display weight for the lock relative weight paint mode, using weight data.
917  *
918  * \return weight divided by unlocked, or 1-locked_weight with division by zero check.
919  */
BKE_defvert_lock_relative_weight(float weight,const struct MDeformVert * dv,int defbase_tot,const bool * defbase_locked,const bool * defbase_unlocked)920 float BKE_defvert_lock_relative_weight(float weight,
921                                        const struct MDeformVert *dv,
922                                        int defbase_tot,
923                                        const bool *defbase_locked,
924                                        const bool *defbase_unlocked)
925 {
926   float unlocked = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_unlocked);
927 
928   if (unlocked > 0.0f) {
929     return weight / unlocked;
930   }
931 
932   float locked = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_locked);
933 
934   return BKE_defvert_calc_lock_relative_weight(weight, locked, unlocked);
935 }
936 
937 /* -------------------------------------------------------------------- */
938 /** \name Defvert Array functions
939  * \{ */
940 
BKE_defvert_array_copy(MDeformVert * dst,const MDeformVert * src,int totvert)941 void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int totvert)
942 {
943   /* Assumes dst is already set up */
944 
945   if (!src || !dst) {
946     return;
947   }
948 
949   memcpy(dst, src, totvert * sizeof(MDeformVert));
950 
951   for (int i = 0; i < totvert; i++) {
952     if (src[i].dw) {
953       dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
954       memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
955     }
956   }
957 }
958 
BKE_defvert_array_free_elems(MDeformVert * dvert,int totvert)959 void BKE_defvert_array_free_elems(MDeformVert *dvert, int totvert)
960 {
961   /* Instead of freeing the verts directly,
962    * call this function to delete any special
963    * vert data */
964 
965   if (!dvert) {
966     return;
967   }
968 
969   /* Free any special data from the verts */
970   for (int i = 0; i < totvert; i++) {
971     if (dvert[i].dw) {
972       MEM_freeN(dvert[i].dw);
973     }
974   }
975 }
976 
BKE_defvert_array_free(MDeformVert * dvert,int totvert)977 void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
978 {
979   /* Instead of freeing the verts directly,
980    * call this function to delete any special
981    * vert data */
982   if (!dvert) {
983     return;
984   }
985 
986   /* Free any special data from the verts */
987   BKE_defvert_array_free_elems(dvert, totvert);
988 
989   MEM_freeN(dvert);
990 }
991 
BKE_defvert_extract_vgroup_to_vertweights(MDeformVert * dvert,const int defgroup,const int num_verts,float * r_weights,const bool invert_vgroup)992 void BKE_defvert_extract_vgroup_to_vertweights(MDeformVert *dvert,
993                                                const int defgroup,
994                                                const int num_verts,
995                                                float *r_weights,
996                                                const bool invert_vgroup)
997 {
998   if (dvert && defgroup != -1) {
999     int i = num_verts;
1000 
1001     while (i--) {
1002       const float w = BKE_defvert_find_weight(&dvert[i], defgroup);
1003       r_weights[i] = invert_vgroup ? (1.0f - w) : w;
1004     }
1005   }
1006   else {
1007     copy_vn_fl(r_weights, num_verts, invert_vgroup ? 1.0f : 0.0f);
1008   }
1009 }
1010 
1011 /**
1012  * The following three make basic interpolation,
1013  * using temp vert_weights array to avoid looking up same weight several times.
1014  */
BKE_defvert_extract_vgroup_to_edgeweights(MDeformVert * dvert,const int defgroup,const int num_verts,MEdge * edges,const int num_edges,float * r_weights,const bool invert_vgroup)1015 void BKE_defvert_extract_vgroup_to_edgeweights(MDeformVert *dvert,
1016                                                const int defgroup,
1017                                                const int num_verts,
1018                                                MEdge *edges,
1019                                                const int num_edges,
1020                                                float *r_weights,
1021                                                const bool invert_vgroup)
1022 {
1023   if (dvert && defgroup != -1) {
1024     int i = num_edges;
1025     float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
1026 
1027     BKE_defvert_extract_vgroup_to_vertweights(
1028         dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
1029 
1030     while (i--) {
1031       MEdge *me = &edges[i];
1032 
1033       r_weights[i] = (tmp_weights[me->v1] + tmp_weights[me->v2]) * 0.5f;
1034     }
1035 
1036     MEM_freeN(tmp_weights);
1037   }
1038   else {
1039     copy_vn_fl(r_weights, num_edges, 0.0f);
1040   }
1041 }
1042 
BKE_defvert_extract_vgroup_to_loopweights(MDeformVert * dvert,const int defgroup,const int num_verts,MLoop * loops,const int num_loops,float * r_weights,const bool invert_vgroup)1043 void BKE_defvert_extract_vgroup_to_loopweights(MDeformVert *dvert,
1044                                                const int defgroup,
1045                                                const int num_verts,
1046                                                MLoop *loops,
1047                                                const int num_loops,
1048                                                float *r_weights,
1049                                                const bool invert_vgroup)
1050 {
1051   if (dvert && defgroup != -1) {
1052     int i = num_loops;
1053     float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
1054 
1055     BKE_defvert_extract_vgroup_to_vertweights(
1056         dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
1057 
1058     while (i--) {
1059       MLoop *ml = &loops[i];
1060 
1061       r_weights[i] = tmp_weights[ml->v];
1062     }
1063 
1064     MEM_freeN(tmp_weights);
1065   }
1066   else {
1067     copy_vn_fl(r_weights, num_loops, 0.0f);
1068   }
1069 }
1070 
BKE_defvert_extract_vgroup_to_polyweights(MDeformVert * dvert,const int defgroup,const int num_verts,MLoop * loops,const int UNUSED (num_loops),MPoly * polys,const int num_polys,float * r_weights,const bool invert_vgroup)1071 void BKE_defvert_extract_vgroup_to_polyweights(MDeformVert *dvert,
1072                                                const int defgroup,
1073                                                const int num_verts,
1074                                                MLoop *loops,
1075                                                const int UNUSED(num_loops),
1076                                                MPoly *polys,
1077                                                const int num_polys,
1078                                                float *r_weights,
1079                                                const bool invert_vgroup)
1080 {
1081   if (dvert && defgroup != -1) {
1082     int i = num_polys;
1083     float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
1084 
1085     BKE_defvert_extract_vgroup_to_vertweights(
1086         dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
1087 
1088     while (i--) {
1089       MPoly *mp = &polys[i];
1090       MLoop *ml = &loops[mp->loopstart];
1091       int j = mp->totloop;
1092       float w = 0.0f;
1093 
1094       for (; j--; ml++) {
1095         w += tmp_weights[ml->v];
1096       }
1097       r_weights[i] = w / (float)mp->totloop;
1098     }
1099 
1100     MEM_freeN(tmp_weights);
1101   }
1102   else {
1103     copy_vn_fl(r_weights, num_polys, 0.0f);
1104   }
1105 }
1106 
1107 /** \} */
1108 
1109 /* -------------------------------------------------------------------- */
1110 /** \name Data Transfer
1111  * \{ */
1112 
vgroups_datatransfer_interp(const CustomDataTransferLayerMap * laymap,void * dest,const void ** sources,const float * weights,const int count,const float mix_factor)1113 static void vgroups_datatransfer_interp(const CustomDataTransferLayerMap *laymap,
1114                                         void *dest,
1115                                         const void **sources,
1116                                         const float *weights,
1117                                         const int count,
1118                                         const float mix_factor)
1119 {
1120   MDeformVert **data_src = (MDeformVert **)sources;
1121   MDeformVert *data_dst = (MDeformVert *)dest;
1122   const int idx_src = laymap->data_src_n;
1123   const int idx_dst = laymap->data_dst_n;
1124 
1125   const int mix_mode = laymap->mix_mode;
1126 
1127   int i, j;
1128 
1129   MDeformWeight *dw_src;
1130   MDeformWeight *dw_dst = BKE_defvert_find_index(data_dst, idx_dst);
1131   float weight_src = 0.0f, weight_dst = 0.0f;
1132 
1133   if (sources) {
1134     for (i = count; i--;) {
1135       for (j = data_src[i]->totweight; j--;) {
1136         if ((dw_src = &data_src[i]->dw[j])->def_nr == idx_src) {
1137           weight_src += dw_src->weight * weights[i];
1138           break;
1139         }
1140       }
1141     }
1142   }
1143 
1144   if (dw_dst) {
1145     weight_dst = dw_dst->weight;
1146   }
1147   else if (mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD) {
1148     return; /* Do not affect destination. */
1149   }
1150 
1151   weight_src = data_transfer_interp_float_do(mix_mode, weight_dst, weight_src, mix_factor);
1152 
1153   CLAMP(weight_src, 0.0f, 1.0f);
1154 
1155   if (!dw_dst) {
1156     BKE_defvert_add_index_notest(data_dst, idx_dst, weight_src);
1157   }
1158   else {
1159     dw_dst->weight = weight_src;
1160   }
1161 }
1162 
data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase * r_map,const int mix_mode,const float mix_factor,const float * mix_weights,const int num_elem_dst,const bool use_create,const bool use_delete,Object * ob_src,Object * ob_dst,MDeformVert * data_src,MDeformVert * data_dst,CustomData * UNUSED (cd_src),CustomData * cd_dst,const bool UNUSED (use_dupref_dst),const int tolayers,const bool * use_layers_src,const int num_layers_src)1163 static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
1164                                                                 const int mix_mode,
1165                                                                 const float mix_factor,
1166                                                                 const float *mix_weights,
1167                                                                 const int num_elem_dst,
1168                                                                 const bool use_create,
1169                                                                 const bool use_delete,
1170                                                                 Object *ob_src,
1171                                                                 Object *ob_dst,
1172                                                                 MDeformVert *data_src,
1173                                                                 MDeformVert *data_dst,
1174                                                                 CustomData *UNUSED(cd_src),
1175                                                                 CustomData *cd_dst,
1176                                                                 const bool UNUSED(use_dupref_dst),
1177                                                                 const int tolayers,
1178                                                                 const bool *use_layers_src,
1179                                                                 const int num_layers_src)
1180 {
1181   int idx_src;
1182   int idx_dst;
1183   int tot_dst = BLI_listbase_count(&ob_dst->defbase);
1184 
1185   const size_t elem_size = sizeof(*((MDeformVert *)NULL));
1186 
1187   switch (tolayers) {
1188     case DT_LAYERS_INDEX_DST:
1189       idx_dst = tot_dst;
1190 
1191       /* Find last source actually used! */
1192       idx_src = num_layers_src;
1193       while (idx_src-- && !use_layers_src[idx_src]) {
1194         /* pass */
1195       }
1196       idx_src++;
1197 
1198       if (idx_dst < idx_src) {
1199         if (use_create) {
1200           /* Create as much vgroups as necessary! */
1201           for (; idx_dst < idx_src; idx_dst++) {
1202             BKE_object_defgroup_add(ob_dst);
1203           }
1204         }
1205         else {
1206           /* Otherwise, just try to map what we can with existing dst vgroups. */
1207           idx_src = idx_dst;
1208         }
1209       }
1210       else if (use_delete && idx_dst > idx_src) {
1211         while (idx_dst-- > idx_src) {
1212           BKE_object_defgroup_remove(ob_dst, ob_dst->defbase.last);
1213         }
1214       }
1215       if (r_map) {
1216         /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest!
1217          * Again, use_create is not relevant in this case */
1218         if (!data_dst) {
1219           data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst);
1220         }
1221 
1222         while (idx_src--) {
1223           if (!use_layers_src[idx_src]) {
1224             continue;
1225           }
1226           data_transfer_layersmapping_add_item(r_map,
1227                                                CD_FAKE_MDEFORMVERT,
1228                                                mix_mode,
1229                                                mix_factor,
1230                                                mix_weights,
1231                                                data_src,
1232                                                data_dst,
1233                                                idx_src,
1234                                                idx_src,
1235                                                elem_size,
1236                                                0,
1237                                                0,
1238                                                0,
1239                                                vgroups_datatransfer_interp,
1240                                                NULL);
1241         }
1242       }
1243       break;
1244     case DT_LAYERS_NAME_DST: {
1245       bDeformGroup *dg_src, *dg_dst;
1246 
1247       if (use_delete) {
1248         /* Remove all unused dst vgroups first, simpler in this case. */
1249         for (dg_dst = ob_dst->defbase.first; dg_dst;) {
1250           bDeformGroup *dg_dst_next = dg_dst->next;
1251 
1252           if (BKE_object_defgroup_name_index(ob_src, dg_dst->name) == -1) {
1253             BKE_object_defgroup_remove(ob_dst, dg_dst);
1254           }
1255           dg_dst = dg_dst_next;
1256         }
1257       }
1258 
1259       for (idx_src = 0, dg_src = ob_src->defbase.first; idx_src < num_layers_src;
1260            idx_src++, dg_src = dg_src->next) {
1261         if (!use_layers_src[idx_src]) {
1262           continue;
1263         }
1264 
1265         if ((idx_dst = BKE_object_defgroup_name_index(ob_dst, dg_src->name)) == -1) {
1266           if (use_create) {
1267             BKE_object_defgroup_add_name(ob_dst, dg_src->name);
1268             idx_dst = ob_dst->actdef - 1;
1269           }
1270           else {
1271             /* If we are not allowed to create missing dst vgroups, just skip matching src one. */
1272             continue;
1273           }
1274         }
1275         if (r_map) {
1276           /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest!
1277            * use_create is not relevant in this case */
1278           if (!data_dst) {
1279             data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst);
1280           }
1281 
1282           data_transfer_layersmapping_add_item(r_map,
1283                                                CD_FAKE_MDEFORMVERT,
1284                                                mix_mode,
1285                                                mix_factor,
1286                                                mix_weights,
1287                                                data_src,
1288                                                data_dst,
1289                                                idx_src,
1290                                                idx_dst,
1291                                                elem_size,
1292                                                0,
1293                                                0,
1294                                                0,
1295                                                vgroups_datatransfer_interp,
1296                                                NULL);
1297         }
1298       }
1299       break;
1300     }
1301     default:
1302       return false;
1303   }
1304 
1305   return true;
1306 }
1307 
data_transfer_layersmapping_vgroups(ListBase * r_map,const int mix_mode,const float mix_factor,const float * mix_weights,const int num_elem_dst,const bool use_create,const bool use_delete,Object * ob_src,Object * ob_dst,CustomData * cd_src,CustomData * cd_dst,const bool use_dupref_dst,const int fromlayers,const int tolayers)1308 bool data_transfer_layersmapping_vgroups(ListBase *r_map,
1309                                          const int mix_mode,
1310                                          const float mix_factor,
1311                                          const float *mix_weights,
1312                                          const int num_elem_dst,
1313                                          const bool use_create,
1314                                          const bool use_delete,
1315                                          Object *ob_src,
1316                                          Object *ob_dst,
1317                                          CustomData *cd_src,
1318                                          CustomData *cd_dst,
1319                                          const bool use_dupref_dst,
1320                                          const int fromlayers,
1321                                          const int tolayers)
1322 {
1323   int idx_src, idx_dst;
1324   MDeformVert *data_src, *data_dst = NULL;
1325 
1326   const size_t elem_size = sizeof(*((MDeformVert *)NULL));
1327 
1328   /* Note:
1329    * VGroups are a bit hairy, since their layout is defined on object level (ob->defbase),
1330    * while their actual data is a (mesh) CD layer.
1331    * This implies we may have to handle data layout itself while having NULL data itself,
1332    * and even have to support NULL data_src in transfer data code
1333    * (we always create a data_dst, though).
1334    */
1335   if (BLI_listbase_is_empty(&ob_src->defbase)) {
1336     if (use_delete) {
1337       BKE_object_defgroup_remove_all(ob_dst);
1338     }
1339     return true;
1340   }
1341 
1342   data_src = CustomData_get_layer(cd_src, CD_MDEFORMVERT);
1343 
1344   data_dst = CustomData_get_layer(cd_dst, CD_MDEFORMVERT);
1345   if (data_dst && use_dupref_dst && r_map) {
1346     /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
1347     data_dst = CustomData_duplicate_referenced_layer(cd_dst, CD_MDEFORMVERT, num_elem_dst);
1348   }
1349 
1350   if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {
1351     /* Note: use_delete has not much meaning in this case, ignored. */
1352 
1353     if (fromlayers >= 0) {
1354       idx_src = fromlayers;
1355       if (idx_src >= BLI_listbase_count(&ob_src->defbase)) {
1356         /* This can happen when vgroups are removed from source object...
1357          * Remapping would be really tricky here, we'd need to go over all objects in
1358          * Main every time we delete a vgroup... for now, simpler and safer to abort. */
1359         return false;
1360       }
1361     }
1362     else if ((idx_src = ob_src->actdef - 1) == -1) {
1363       return false;
1364     }
1365 
1366     if (tolayers >= 0) {
1367       /* Note: in this case we assume layer exists! */
1368       idx_dst = tolayers;
1369       BLI_assert(idx_dst < BLI_listbase_count(&ob_dst->defbase));
1370     }
1371     else if (tolayers == DT_LAYERS_ACTIVE_DST) {
1372       if ((idx_dst = ob_dst->actdef - 1) == -1) {
1373         bDeformGroup *dg_src;
1374         if (!use_create) {
1375           return true;
1376         }
1377         dg_src = BLI_findlink(&ob_src->defbase, idx_src);
1378         BKE_object_defgroup_add_name(ob_dst, dg_src->name);
1379         idx_dst = ob_dst->actdef - 1;
1380       }
1381     }
1382     else if (tolayers == DT_LAYERS_INDEX_DST) {
1383       int num = BLI_listbase_count(&ob_src->defbase);
1384       idx_dst = idx_src;
1385       if (num <= idx_dst) {
1386         if (!use_create) {
1387           return true;
1388         }
1389         /* Create as much vgroups as necessary! */
1390         for (; num <= idx_dst; num++) {
1391           BKE_object_defgroup_add(ob_dst);
1392         }
1393       }
1394     }
1395     else if (tolayers == DT_LAYERS_NAME_DST) {
1396       bDeformGroup *dg_src = BLI_findlink(&ob_src->defbase, idx_src);
1397       if ((idx_dst = BKE_object_defgroup_name_index(ob_dst, dg_src->name)) == -1) {
1398         if (!use_create) {
1399           return true;
1400         }
1401         BKE_object_defgroup_add_name(ob_dst, dg_src->name);
1402         idx_dst = ob_dst->actdef - 1;
1403       }
1404     }
1405     else {
1406       return false;
1407     }
1408 
1409     if (r_map) {
1410       /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest!
1411        * use_create is not relevant in this case */
1412       if (!data_dst) {
1413         data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst);
1414       }
1415 
1416       data_transfer_layersmapping_add_item(r_map,
1417                                            CD_FAKE_MDEFORMVERT,
1418                                            mix_mode,
1419                                            mix_factor,
1420                                            mix_weights,
1421                                            data_src,
1422                                            data_dst,
1423                                            idx_src,
1424                                            idx_dst,
1425                                            elem_size,
1426                                            0,
1427                                            0,
1428                                            0,
1429                                            vgroups_datatransfer_interp,
1430                                            NULL);
1431     }
1432   }
1433   else {
1434     int num_src, num_sel_unused;
1435     bool *use_layers_src = NULL;
1436     bool ret = false;
1437 
1438     switch (fromlayers) {
1439       case DT_LAYERS_ALL_SRC:
1440         use_layers_src = BKE_object_defgroup_subset_from_select_type(
1441             ob_src, WT_VGROUP_ALL, &num_src, &num_sel_unused);
1442         break;
1443       case DT_LAYERS_VGROUP_SRC_BONE_SELECT:
1444         use_layers_src = BKE_object_defgroup_subset_from_select_type(
1445             ob_src, WT_VGROUP_BONE_SELECT, &num_src, &num_sel_unused);
1446         break;
1447       case DT_LAYERS_VGROUP_SRC_BONE_DEFORM:
1448         use_layers_src = BKE_object_defgroup_subset_from_select_type(
1449             ob_src, WT_VGROUP_BONE_DEFORM, &num_src, &num_sel_unused);
1450         break;
1451     }
1452 
1453     if (use_layers_src) {
1454       ret = data_transfer_layersmapping_vgroups_multisrc_to_dst(r_map,
1455                                                                 mix_mode,
1456                                                                 mix_factor,
1457                                                                 mix_weights,
1458                                                                 num_elem_dst,
1459                                                                 use_create,
1460                                                                 use_delete,
1461                                                                 ob_src,
1462                                                                 ob_dst,
1463                                                                 data_src,
1464                                                                 data_dst,
1465                                                                 cd_src,
1466                                                                 cd_dst,
1467                                                                 use_dupref_dst,
1468                                                                 tolayers,
1469                                                                 use_layers_src,
1470                                                                 num_src);
1471     }
1472 
1473     MEM_SAFE_FREE(use_layers_src);
1474     return ret;
1475   }
1476 
1477   return true;
1478 }
1479 
1480 /** \} */
1481 
1482 /* -------------------------------------------------------------------- */
1483 /** \name Various utils & helpers.
1484  * \{ */
1485 
BKE_defvert_weight_to_rgb(float r_rgb[3],const float weight)1486 void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight)
1487 {
1488   const float blend = ((weight / 2.0f) + 0.5f);
1489 
1490   if (weight <= 0.25f) { /* blue->cyan */
1491     r_rgb[0] = 0.0f;
1492     r_rgb[1] = blend * weight * 4.0f;
1493     r_rgb[2] = blend;
1494   }
1495   else if (weight <= 0.50f) { /* cyan->green */
1496     r_rgb[0] = 0.0f;
1497     r_rgb[1] = blend;
1498     r_rgb[2] = blend * (1.0f - ((weight - 0.25f) * 4.0f));
1499   }
1500   else if (weight <= 0.75f) { /* green->yellow */
1501     r_rgb[0] = blend * ((weight - 0.50f) * 4.0f);
1502     r_rgb[1] = blend;
1503     r_rgb[2] = 0.0f;
1504   }
1505   else if (weight <= 1.0f) { /* yellow->red */
1506     r_rgb[0] = blend;
1507     r_rgb[1] = blend * (1.0f - ((weight - 0.75f) * 4.0f));
1508     r_rgb[2] = 0.0f;
1509   }
1510   else {
1511     /* exceptional value, unclamped or nan,
1512      * avoid uninitialized memory use */
1513     r_rgb[0] = 1.0f;
1514     r_rgb[1] = 0.0f;
1515     r_rgb[2] = 1.0f;
1516   }
1517 }
1518 
1519 /** \} */
1520 
1521 /* -------------------------------------------------------------------- */
1522 /** \name .blend file I/O
1523  * \{ */
1524 
BKE_defvert_blend_write(BlendWriter * writer,int count,MDeformVert * dvlist)1525 void BKE_defvert_blend_write(BlendWriter *writer, int count, MDeformVert *dvlist)
1526 {
1527   if (dvlist == NULL) {
1528     return;
1529   }
1530 
1531   /* Write the dvert list */
1532   BLO_write_struct_array(writer, MDeformVert, count, dvlist);
1533 
1534   /* Write deformation data for each dvert */
1535   for (int i = 0; i < count; i++) {
1536     if (dvlist[i].dw) {
1537       BLO_write_struct_array(writer, MDeformWeight, dvlist[i].totweight, dvlist[i].dw);
1538     }
1539   }
1540 }
1541 
BKE_defvert_blend_read(BlendDataReader * reader,int count,MDeformVert * mdverts)1542 void BKE_defvert_blend_read(BlendDataReader *reader, int count, MDeformVert *mdverts)
1543 {
1544   if (mdverts == NULL) {
1545     return;
1546   }
1547 
1548   for (int i = count; i > 0; i--, mdverts++) {
1549     /* Convert to vertex group allocation system. */
1550     MDeformWeight *dw;
1551     if (mdverts->dw && (dw = BLO_read_get_new_data_address(reader, mdverts->dw))) {
1552       const size_t dw_len = sizeof(MDeformWeight) * mdverts->totweight;
1553       void *dw_tmp = MEM_mallocN(dw_len, __func__);
1554       memcpy(dw_tmp, dw, dw_len);
1555       mdverts->dw = dw_tmp;
1556       MEM_freeN(dw);
1557     }
1558     else {
1559       mdverts->dw = NULL;
1560       mdverts->totweight = 0;
1561     }
1562   }
1563 }
1564 
1565 /** \} */
1566