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