Blender  V2.93
deform.c
Go to the documentation of this file.
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 
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 
58 {
59  bDeformGroup *defgroup;
60 
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 
71 
72  return defgroup;
73 }
74 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
786 {
787  if (dvert->dw) {
788  MEM_freeN(dvert->dw);
789  dvert->dw = NULL;
790  }
791 
792  dvert->totweight = 0;
793 }
794 
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 
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 
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 
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 
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 - VERTEX_WEIGHT_LOCK_EPSILON) {
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 
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 /* -------------------------------------------------------------------- */
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
1109 /* -------------------------------------------------------------------- */
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 
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  }
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,
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 
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,
1296  NULL);
1297  }
1298  }
1299  break;
1300  }
1301  default:
1302  return false;
1303  }
1304 
1305  return true;
1306 }
1307 
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) {
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 
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,
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:
1441  ob_src, WT_VGROUP_ALL, &num_src, &num_sel_unused);
1442  break;
1445  ob_src, WT_VGROUP_BONE_SELECT, &num_src, &num_sel_unused);
1446  break;
1449  ob_src, WT_VGROUP_BONE_DEFORM, &num_src, &num_sel_unused);
1450  break;
1451  }
1452 
1453  if (use_layers_src) {
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 
1482 /* -------------------------------------------------------------------- */
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 
1521 /* -------------------------------------------------------------------- */
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 
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 
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
@ CD_CALLOC
@ CDT_MIX_REPLACE_ABOVE_THRESHOLD
void * CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem)
Definition: customdata.c:2788
void * CustomData_get_layer(const struct CustomData *data, int type)
@ CD_FAKE_MDEFORMVERT
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.c:2620
@ DT_LAYERS_VGROUP_SRC_BONE_SELECT
@ DT_LAYERS_VGROUP_SRC_BONE_DEFORM
@ DT_LAYERS_ALL_SRC
@ DT_LAYERS_ACTIVE_SRC
@ DT_LAYERS_ACTIVE_DST
@ DT_LAYERS_INDEX_DST
@ DT_LAYERS_NAME_DST
support for deformation groups and hooks.
#define VERTEX_WEIGHT_LOCK_EPSILON
Definition: BKE_deform.h:84
General operations, lookup, etc. for blender objects.
void BKE_object_batch_cache_dirty_tag(struct Object *ob)
Functions for dealing with objects and deform verts, used by painting and tools.
void BKE_object_defgroup_remove(struct Object *ob, struct bDeformGroup *defgroup)
struct bDeformGroup * BKE_object_defgroup_add(struct Object *ob)
bool * BKE_object_defgroup_subset_from_select_type(struct Object *ob, enum eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count)
struct bDeformGroup * BKE_object_defgroup_add_name(struct Object *ob, const char *name)
void BKE_object_defgroup_remove_all(struct Object *ob)
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
void copy_vn_fl(float *array_tar, const int size, const float val)
Definition: math_vector.c:1410
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len)
Definition: string_utils.c:159
bool BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_len)
Definition: string_utils.c:294
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define STREQ(a, b)
#define LIKELY(x)
void * BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address)
Definition: readfile.c:5600
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define DATA_(msgid)
@ CD_MDEFORMVERT
struct MDeformWeight MDeformWeight
Object is a sort of wrapper for general info.
#define OB_TYPE_SUPPORT_VGROUP(_type)
@ WT_VGROUP_BONE_SELECT
@ WT_VGROUP_ALL
@ WT_VGROUP_BONE_DEFORM
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
Group RGB to Bright Vector Camera CLAMP
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
void data_transfer_layersmapping_add_item(ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights, const void *data_src, void *data_dst, const int data_src_n, const int data_dst_n, const size_t elem_size, const size_t data_size, const size_t data_offset, const uint64_t data_flag, cd_datatransfer_interp interp, void *interp_data)
float data_transfer_interp_float_do(const int mix_mode, const float val_dst, const float val_src, const float mix_factor)
static bool 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)
Definition: deform.c:1163
bDeformGroup * BKE_object_defgroup_find_name(const Object *ob, const char *name)
Definition: deform.c:487
bDeformGroup * BKE_defgroup_duplicate(const bDeformGroup *ingroup)
Definition: deform.c:87
void BKE_defvert_normalize_subset(MDeformVert *dvert, const bool *vgroup_subset, const int vgroup_tot)
Definition: deform.c:267
void BKE_defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight)
Definition: deform.c:726
void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
Definition: deform.c:977
void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int totvert)
Definition: deform.c:941
void BKE_defvert_normalize_lock_single(MDeformVert *dvert, const bool *vgroup_subset, const int vgroup_tot, const uint def_nr_lock)
Definition: deform.c:336
int * BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const bool use_default)
Definition: deform.c:504
void BKE_defvert_copy_index(MDeformVert *dvert_dst, const int defgroup_dst, const MDeformVert *dvert_src, const int defgroup_src)
Definition: deform.c:172
static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
Definition: deform.c:596
void BKE_defvert_normalize(MDeformVert *dvert)
Definition: deform.c:304
MDeformWeight * BKE_defvert_ensure_index(MDeformVert *dvert, const int defgroup)
Definition: deform.c:688
void BKE_defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const int *flip_map, const int flip_map_len, const bool use_ensure)
Definition: deform.c:223
float BKE_defvert_total_selected_weight(const struct MDeformVert *dv, int defbase_tot, const bool *defbase_sel)
Definition: deform.c:835
bDeformGroup * BKE_object_defgroup_new(Object *ob, const char *name)
Definition: deform.c:57
void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight)
Definition: deform.c:1486
void BKE_defvert_copy_subset(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const bool *vgroup_subset, const int vgroup_tot)
Definition: deform.c:111
void 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)
Definition: deform.c:1015
void BKE_defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
Definition: deform.c:462
int BKE_object_defgroup_flip_index(const Object *ob, int index, const bool use_default)
Definition: deform.c:579
float BKE_defvert_calc_lock_relative_weight(float weight, float locked_weight, float unlocked_weight)
Definition: deform.c:887
float BKE_defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup)
Definition: deform.c:645
float BKE_defvert_find_weight(const struct MDeformVert *dvert, const int defgroup)
Definition: deform.c:632
bool BKE_defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_tot)
Definition: deform.c:818
void BKE_defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const bool use_ensure)
Definition: deform.c:200
float BKE_defvert_lock_relative_weight(float weight, const struct MDeformVert *dv, int defbase_tot, const bool *defbase_locked, const bool *defbase_unlocked)
Definition: deform.c:920
static void vgroups_datatransfer_interp(const CustomDataTransferLayerMap *laymap, void *dest, const void **sources, const float *weights, const int count, const float mix_factor)
Definition: deform.c:1113
void 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)
Definition: deform.c:129
int BKE_defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
Definition: deform.c:799
static bool defgroup_unique_check(void *arg, const char *name)
Definition: deform.c:611
void BKE_object_defgroup_unique_name(bDeformGroup *dg, Object *ob)
Definition: deform.c:620
void 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)
Definition: deform.c:1043
void BKE_defvert_array_free_elems(MDeformVert *dvert, int totvert)
Definition: deform.c:959
void BKE_defvert_blend_write(BlendWriter *writer, int count, MDeformVert *dvlist)
Definition: deform.c:1525
void BKE_defgroup_copy_list(ListBase *outbase, const ListBase *inbase)
Definition: deform.c:75
void BKE_defvert_clear(MDeformVert *dvert)
Definition: deform.c:785
int * BKE_object_defgroup_flip_map_single(const Object *ob, int *flip_map_len, const bool use_default, int defgroup)
Definition: deform.c:545
void BKE_defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
Definition: deform.c:448
void BKE_defvert_normalize_lock_map(MDeformVert *dvert, const bool *vgroup_subset, const int vgroup_tot, const bool *lock_flags, const int defbase_tot)
Definition: deform.c:393
int BKE_object_defgroup_name_index(const Object *ob, const char *name)
Definition: deform.c:494
void BKE_defvert_blend_read(BlendDataReader *reader, int count, MDeformVert *mdverts)
Definition: deform.c:1542
bool 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)
Definition: deform.c:1308
void BKE_defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
Definition: deform.c:144
void 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)
Definition: deform.c:1071
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dvert, const int defgroup)
Definition: deform.c:664
float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv, int defbase_tot, const bool *defbase_sel, int defbase_tot_sel, bool is_normalized)
Definition: deform.c:865
void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
Definition: deform.c:754
void BKE_defvert_remap(MDeformVert *dvert, const int *map, const int map_len)
Definition: deform.c:252
void BKE_defvert_extract_vgroup_to_vertweights(MDeformVert *dvert, const int defgroup, const int num_verts, float *r_weights, const bool invert_vgroup)
Definition: deform.c:992
int count
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
return ret
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
struct MDeformWeight * dw
unsigned int def_nr
unsigned int v1
unsigned int v2
unsigned int v
ListBase defbase
unsigned short actdef
struct bDeformGroup * next
struct bDeformGroup * prev
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)