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