Blender  V2.93
customdata.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) 2006 Blender Foundation.
17  * All rights reserved.
18  * Implementation of CustomData.
19  *
20  * BKE_customdata.h contains the function prototypes for this file.
21  */
22 
27 #include "MEM_guardedalloc.h"
28 
29 /* Since we have versioning code here (CustomData_verify_versions()). */
30 #define DNA_DEPRECATED_ALLOW
31 
32 #include "DNA_ID.h"
33 #include "DNA_customdata_types.h"
34 #include "DNA_hair_types.h"
35 #include "DNA_meshdata_types.h"
36 
37 #include "BLI_bitmap.h"
38 #include "BLI_endian_switch.h"
39 #include "BLI_math.h"
40 #include "BLI_math_color_blend.h"
41 #include "BLI_mempool.h"
42 #include "BLI_path_util.h"
43 #include "BLI_string.h"
44 #include "BLI_string_utils.h"
45 #include "BLI_utildefines.h"
46 
47 #include "BLT_translation.h"
48 
49 #include "BKE_customdata.h"
50 #include "BKE_customdata_file.h"
51 #include "BKE_deform.h"
52 #include "BKE_main.h"
53 #include "BKE_mesh_mapping.h"
54 #include "BKE_mesh_remap.h"
55 #include "BKE_multires.h"
56 #include "BKE_subsurf.h"
57 
58 #include "BLO_read_write.h"
59 
60 #include "bmesh.h"
61 
62 #include "CLG_log.h"
63 
64 /* only for customdata_data_transfer_interp_normal_normals */
65 #include "data_transfer_intern.h"
66 
67 /* number of layers to add when growing a CustomData object */
68 #define CUSTOMDATA_GROW 5
69 
70 /* ensure typemap size is ok */
72 
73 static CLG_LogRef LOG = {"bke.customdata"};
74 
77  const CustomData_MeshMasks *mask_src)
78 {
79  mask_dst->vmask |= mask_src->vmask;
80  mask_dst->emask |= mask_src->emask;
81  mask_dst->fmask |= mask_src->fmask;
82  mask_dst->pmask |= mask_src->pmask;
83  mask_dst->lmask |= mask_src->lmask;
84 }
85 
88  const CustomData_MeshMasks *mask_required)
89 {
90  return (((mask_required->vmask & mask_ref->vmask) == mask_required->vmask) &&
91  ((mask_required->emask & mask_ref->emask) == mask_required->emask) &&
92  ((mask_required->fmask & mask_ref->fmask) == mask_required->fmask) &&
93  ((mask_required->pmask & mask_ref->pmask) == mask_required->pmask) &&
94  ((mask_required->lmask & mask_ref->lmask) == mask_required->lmask));
95 }
96 
97 /********************* Layer type information **********************/
98 typedef struct LayerTypeInfo {
99  int size; /* the memory size of one element of this layer's data */
100 
102  const char *structname;
105 
110  const char *defaultname;
111 
118 
125  void (*free)(void *data, int count, int size);
126 
143 
145  void (*swap)(void *data, const int *corner_indices);
146 
150  void (*set_default)(void *data, int count);
151 
154 
156  bool (*equal)(const void *data1, const void *data2);
157  void (*multiply)(void *data, float fac);
158  void (*initminmax)(void *min, void *max);
159  void (*add)(void *data1, const void *data2);
160  void (*dominmax)(const void *data1, void *min, void *max);
161  void (*copyvalue)(const void *source, void *dest, const int mixmode, const float mixfactor);
162 
164  bool (*read)(CDataFile *cdf, void *data, int count);
165 
167  bool (*write)(CDataFile *cdf, const void *data, int count);
168 
170  size_t (*filesize)(CDataFile *cdf, const void *data, int count);
171 
174  int (*layers_max)(void);
176 
177 static void layerCopy_mdeformvert(const void *source, void *dest, int count)
178 {
179  int i, size = sizeof(MDeformVert);
180 
181  memcpy(dest, source, count * size);
182 
183  for (i = 0; i < count; i++) {
184  MDeformVert *dvert = POINTER_OFFSET(dest, i * size);
185 
186  if (dvert->totweight) {
188  dvert->totweight, sizeof(*dw), "layerCopy_mdeformvert dw");
189 
190  memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw));
191  dvert->dw = dw;
192  }
193  else {
194  dvert->dw = NULL;
195  }
196  }
197 }
198 
199 static void layerFree_mdeformvert(void *data, int count, int size)
200 {
201  for (int i = 0; i < count; i++) {
202  MDeformVert *dvert = POINTER_OFFSET(data, i * size);
203 
204  if (dvert->dw) {
205  MEM_freeN(dvert->dw);
206  dvert->dw = NULL;
207  dvert->totweight = 0;
208  }
209  }
210 }
211 
212 /* copy just zeros in this case */
213 static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest, int count)
214 {
215  const int size = sizeof(void *);
216 
217  for (int i = 0; i < count; i++) {
218  void **ptr = POINTER_OFFSET(dest, i * size);
219  *ptr = NULL;
220  }
221 }
222 
223 #ifndef WITH_PYTHON
225 {
226  /* dummy */
227 }
228 #endif
229 
230 static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
231 {
232  for (int i = 0; i < count; i++) {
233  void **ptr = POINTER_OFFSET(data, i * size);
234  if (*ptr) {
236  }
237  }
238 }
239 
240 static void layerInterp_mdeformvert(const void **sources,
241  const float *weights,
242  const float *UNUSED(sub_weights),
243  int count,
244  void *dest)
245 {
246  /* a single linked list of MDeformWeight's
247  * use this to avoid double allocs (which LinkNode would do) */
248  struct MDeformWeight_Link {
249  struct MDeformWeight_Link *next;
250  MDeformWeight dw;
251  };
252 
253  MDeformVert *dvert = dest;
254  struct MDeformWeight_Link *dest_dwlink = NULL;
255  struct MDeformWeight_Link *node;
256 
257  /* build a list of unique def_nrs for dest */
258  int totweight = 0;
259  for (int i = 0; i < count; i++) {
260  const MDeformVert *source = sources[i];
261  float interp_weight = weights[i];
262 
263  for (int j = 0; j < source->totweight; j++) {
264  MDeformWeight *dw = &source->dw[j];
265  float weight = dw->weight * interp_weight;
266 
267  if (weight == 0.0f) {
268  continue;
269  }
270 
271  for (node = dest_dwlink; node; node = node->next) {
272  MDeformWeight *tmp_dw = &node->dw;
273 
274  if (tmp_dw->def_nr == dw->def_nr) {
275  tmp_dw->weight += weight;
276  break;
277  }
278  }
279 
280  /* if this def_nr is not in the list, add it */
281  if (!node) {
282  struct MDeformWeight_Link *tmp_dwlink = alloca(sizeof(*tmp_dwlink));
283  tmp_dwlink->dw.def_nr = dw->def_nr;
284  tmp_dwlink->dw.weight = weight;
285 
286  /* inline linklist */
287  tmp_dwlink->next = dest_dwlink;
288  dest_dwlink = tmp_dwlink;
289 
290  totweight++;
291  }
292  }
293  }
294 
295  /* Delay writing to the destination in case dest is in sources. */
296 
297  /* now we know how many unique deform weights there are, so realloc */
298  if (dvert->dw && (dvert->totweight == totweight)) {
299  /* pass (fast-path if we don't need to realloc). */
300  }
301  else {
302  if (dvert->dw) {
303  MEM_freeN(dvert->dw);
304  }
305 
306  if (totweight) {
307  dvert->dw = MEM_malloc_arrayN(totweight, sizeof(*dvert->dw), __func__);
308  }
309  }
310 
311  if (totweight) {
312  dvert->totweight = totweight;
313  int i = 0;
314  for (node = dest_dwlink; node; node = node->next, i++) {
315  if (node->dw.weight > 1.0f) {
316  node->dw.weight = 1.0f;
317  }
318  dvert->dw[i] = node->dw;
319  }
320  }
321  else {
322  memset(dvert, 0, sizeof(*dvert));
323  }
324 }
325 
326 static void layerInterp_normal(const void **sources,
327  const float *weights,
328  const float *UNUSED(sub_weights),
329  int count,
330  void *dest)
331 {
332  /* Note: This is linear interpolation, which is not optimal for vectors.
333  * Unfortunately, spherical interpolation of more than two values is hairy,
334  * so for now it will do... */
335  float no[3] = {0.0f};
336 
337  while (count--) {
338  madd_v3_v3fl(no, (const float *)sources[count], weights[count]);
339  }
340 
341  /* Weighted sum of normalized vectors will **not** be normalized, even if weights are. */
342  normalize_v3_v3((float *)dest, no);
343 }
344 
345 static bool layerValidate_normal(void *data, const uint totitems, const bool do_fixes)
346 {
347  static const float no_default[3] = {0.0f, 0.0f, 1.0f}; /* Z-up default normal... */
348  float(*no)[3] = data;
349  bool has_errors = false;
350 
351  for (int i = 0; i < totitems; i++, no++) {
352  if (!is_finite_v3((float *)no)) {
353  has_errors = true;
354  if (do_fixes) {
355  copy_v3_v3((float *)no, no_default);
356  }
357  }
358  else if (!compare_ff(len_squared_v3((float *)no), 1.0f, 1e-6f)) {
359  has_errors = true;
360  if (do_fixes) {
361  normalize_v3((float *)no);
362  }
363  }
364  }
365 
366  return has_errors;
367 }
368 
369 static void layerCopyValue_normal(const void *source,
370  void *dest,
371  const int mixmode,
372  const float mixfactor)
373 {
374  const float *no_src = source;
375  float *no_dst = dest;
376  float no_tmp[3];
377 
378  if (ELEM(mixmode,
382  /* Above/below threshold modes are not supported here, fallback to nomix (just in case). */
383  copy_v3_v3(no_dst, no_src);
384  }
385  else { /* Modes that support 'real' mix factor. */
386  /* Since we normalize in the end, MIX and ADD are the same op here. */
387  if (ELEM(mixmode, CDT_MIX_MIX, CDT_MIX_ADD)) {
388  add_v3_v3v3(no_tmp, no_dst, no_src);
389  normalize_v3(no_tmp);
390  }
391  else if (mixmode == CDT_MIX_SUB) {
392  sub_v3_v3v3(no_tmp, no_dst, no_src);
393  normalize_v3(no_tmp);
394  }
395  else if (mixmode == CDT_MIX_MUL) {
396  mul_v3_v3v3(no_tmp, no_dst, no_src);
397  normalize_v3(no_tmp);
398  }
399  else {
400  copy_v3_v3(no_tmp, no_src);
401  }
402  interp_v3_v3v3_slerp_safe(no_dst, no_dst, no_tmp, mixfactor);
403  }
404 }
405 
406 static void layerCopy_tface(const void *source, void *dest, int count)
407 {
408  const MTFace *source_tf = (const MTFace *)source;
409  MTFace *dest_tf = (MTFace *)dest;
410  for (int i = 0; i < count; i++) {
411  dest_tf[i] = source_tf[i];
412  }
413 }
414 
415 static void layerInterp_tface(
416  const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
417 {
418  MTFace *tf = dest;
419  float uv[4][2] = {{0.0f}};
420 
421  const float *sub_weight = sub_weights;
422  for (int i = 0; i < count; i++) {
423  const float interp_weight = weights[i];
424  const MTFace *src = sources[i];
425 
426  for (int j = 0; j < 4; j++) {
427  if (sub_weights) {
428  for (int k = 0; k < 4; k++, sub_weight++) {
429  madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight);
430  }
431  }
432  else {
433  madd_v2_v2fl(uv[j], src->uv[j], interp_weight);
434  }
435  }
436  }
437 
438  /* Delay writing to the destination in case dest is in sources. */
439  *tf = *(MTFace *)(*sources);
440  memcpy(tf->uv, uv, sizeof(tf->uv));
441 }
442 
443 static void layerSwap_tface(void *data, const int *corner_indices)
444 {
445  MTFace *tf = data;
446  float uv[4][2];
447 
448  for (int j = 0; j < 4; j++) {
449  const int source_index = corner_indices[j];
450  copy_v2_v2(uv[j], tf->uv[source_index]);
451  }
452 
453  memcpy(tf->uv, uv, sizeof(tf->uv));
454 }
455 
456 static void layerDefault_tface(void *data, int count)
457 {
458  static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
459  MTFace *tf = (MTFace *)data;
460 
461  for (int i = 0; i < count; i++) {
462  tf[i] = default_tf;
463  }
464 }
465 
466 static int layerMaxNum_tface(void)
467 {
468  return MAX_MTFACE;
469 }
470 
471 static void layerCopy_propFloat(const void *source, void *dest, int count)
472 {
473  memcpy(dest, source, sizeof(MFloatProperty) * count);
474 }
475 
476 static void layerInterp_propFloat(const void **sources,
477  const float *weights,
478  const float *UNUSED(sub_weights),
479  int count,
480  void *dest)
481 {
482  float result = 0.0f;
483  for (int i = 0; i < count; i++) {
484  const float interp_weight = weights[i];
485  const float src = *(const float *)sources[i];
486  result += src * interp_weight;
487  }
488  *(float *)dest = result;
489 }
490 
491 static bool layerValidate_propFloat(void *data, const uint totitems, const bool do_fixes)
492 {
493  MFloatProperty *fp = data;
494  bool has_errors = false;
495 
496  for (int i = 0; i < totitems; i++, fp++) {
497  if (!isfinite(fp->f)) {
498  if (do_fixes) {
499  fp->f = 0.0f;
500  }
501  has_errors = true;
502  }
503  }
504 
505  return has_errors;
506 }
507 
508 static void layerCopy_propInt(const void *source, void *dest, int count)
509 {
510  memcpy(dest, source, sizeof(MIntProperty) * count);
511 }
512 
513 static void layerCopy_propString(const void *source, void *dest, int count)
514 {
515  memcpy(dest, source, sizeof(MStringProperty) * count);
516 }
517 
518 static void layerCopy_origspace_face(const void *source, void *dest, int count)
519 {
520  const OrigSpaceFace *source_tf = (const OrigSpaceFace *)source;
521  OrigSpaceFace *dest_tf = (OrigSpaceFace *)dest;
522 
523  for (int i = 0; i < count; i++) {
524  dest_tf[i] = source_tf[i];
525  }
526 }
527 
529  const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
530 {
531  OrigSpaceFace *osf = dest;
532  float uv[4][2] = {{0.0f}};
533 
534  const float *sub_weight = sub_weights;
535  for (int i = 0; i < count; i++) {
536  const float interp_weight = weights[i];
537  const OrigSpaceFace *src = sources[i];
538 
539  for (int j = 0; j < 4; j++) {
540  if (sub_weights) {
541  for (int k = 0; k < 4; k++, sub_weight++) {
542  madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight);
543  }
544  }
545  else {
546  madd_v2_v2fl(uv[j], src->uv[j], interp_weight);
547  }
548  }
549  }
550 
551  /* Delay writing to the destination in case dest is in sources. */
552  memcpy(osf->uv, uv, sizeof(osf->uv));
553 }
554 
555 static void layerSwap_origspace_face(void *data, const int *corner_indices)
556 {
557  OrigSpaceFace *osf = data;
558  float uv[4][2];
559 
560  for (int j = 0; j < 4; j++) {
561  copy_v2_v2(uv[j], osf->uv[corner_indices[j]]);
562  }
563  memcpy(osf->uv, uv, sizeof(osf->uv));
564 }
565 
566 static void layerDefault_origspace_face(void *data, int count)
567 {
568  static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
569  OrigSpaceFace *osf = (OrigSpaceFace *)data;
570 
571  for (int i = 0; i < count; i++) {
572  osf[i] = default_osf;
573  }
574 }
575 
576 static void layerSwap_mdisps(void *data, const int *ci)
577 {
578  MDisps *s = data;
579 
580  if (s->disps) {
581  int nverts = (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */
582  int corners = multires_mdisp_corners(s);
583  int cornersize = s->totdisp / corners;
584 
585  if (corners != nverts) {
586  /* happens when face changed vertex count in edit mode
587  * if it happened, just forgot displacement */
588 
589  MEM_freeN(s->disps);
590  s->totdisp = (s->totdisp / corners) * nverts;
591  s->disps = MEM_calloc_arrayN(s->totdisp, sizeof(float[3]), "mdisp swap");
592  return;
593  }
594 
595  float(*d)[3] = MEM_calloc_arrayN(s->totdisp, sizeof(float[3]), "mdisps swap");
596 
597  for (int S = 0; S < corners; S++) {
598  memcpy(d + cornersize * S, s->disps + cornersize * ci[S], sizeof(float[3]) * cornersize);
599  }
600 
601  MEM_freeN(s->disps);
602  s->disps = d;
603  }
604 }
605 
606 static void layerCopy_mdisps(const void *source, void *dest, int count)
607 {
608  const MDisps *s = source;
609  MDisps *d = dest;
610 
611  for (int i = 0; i < count; i++) {
612  if (s[i].disps) {
613  d[i].disps = MEM_dupallocN(s[i].disps);
614  d[i].hidden = MEM_dupallocN(s[i].hidden);
615  }
616  else {
617  d[i].disps = NULL;
618  d[i].hidden = NULL;
619  }
620 
621  /* still copy even if not in memory, displacement can be external */
622  d[i].totdisp = s[i].totdisp;
623  d[i].level = s[i].level;
624  }
625 }
626 
627 static void layerFree_mdisps(void *data, int count, int UNUSED(size))
628 {
629  MDisps *d = data;
630 
631  for (int i = 0; i < count; i++) {
632  if (d[i].disps) {
633  MEM_freeN(d[i].disps);
634  }
635  if (d[i].hidden) {
636  MEM_freeN(d[i].hidden);
637  }
638  d[i].disps = NULL;
639  d[i].hidden = NULL;
640  d[i].totdisp = 0;
641  d[i].level = 0;
642  }
643 }
644 
645 static bool layerRead_mdisps(CDataFile *cdf, void *data, int count)
646 {
647  MDisps *d = data;
648 
649  for (int i = 0; i < count; i++) {
650  if (!d[i].disps) {
651  d[i].disps = MEM_calloc_arrayN(d[i].totdisp, sizeof(float[3]), "mdisps read");
652  }
653 
654  if (!cdf_read_data(cdf, sizeof(float[3]) * d[i].totdisp, d[i].disps)) {
655  CLOG_ERROR(&LOG, "failed to read multires displacement %d/%d %d", i, count, d[i].totdisp);
656  return 0;
657  }
658  }
659 
660  return true;
661 }
662 
663 static bool layerWrite_mdisps(CDataFile *cdf, const void *data, int count)
664 {
665  const MDisps *d = data;
666 
667  for (int i = 0; i < count; i++) {
668  if (!cdf_write_data(cdf, sizeof(float[3]) * d[i].totdisp, d[i].disps)) {
669  CLOG_ERROR(&LOG, "failed to write multires displacement %d/%d %d", i, count, d[i].totdisp);
670  return 0;
671  }
672  }
673 
674  return true;
675 }
676 
677 static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int count)
678 {
679  const MDisps *d = data;
680  size_t size = 0;
681 
682  for (int i = 0; i < count; i++) {
683  size += sizeof(float[3]) * d[i].totdisp;
684  }
685 
686  return size;
687 }
688 static void layerInterp_paint_mask(const void **sources,
689  const float *weights,
690  const float *UNUSED(sub_weights),
691  int count,
692  void *dest)
693 {
694  float mask = 0.0f;
695  for (int i = 0; i < count; i++) {
696  const float interp_weight = weights[i];
697  const float *src = sources[i];
698  mask += (*src) * interp_weight;
699  }
700  *(float *)dest = mask;
701 }
702 
703 static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
704 {
705  const GridPaintMask *s = source;
706  GridPaintMask *d = dest;
707 
708  for (int i = 0; i < count; i++) {
709  if (s[i].data) {
710  d[i].data = MEM_dupallocN(s[i].data);
711  d[i].level = s[i].level;
712  }
713  else {
714  d[i].data = NULL;
715  d[i].level = 0;
716  }
717  }
718 }
719 
720 static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size))
721 {
722  GridPaintMask *gpm = data;
723 
724  for (int i = 0; i < count; i++) {
725  if (gpm[i].data) {
726  MEM_freeN(gpm[i].data);
727  }
728  gpm[i].data = NULL;
729  gpm[i].level = 0;
730  }
731 }
732 
733 /* --------- */
734 static void layerCopyValue_mloopcol(const void *source,
735  void *dest,
736  const int mixmode,
737  const float mixfactor)
738 {
739  const MLoopCol *m1 = source;
740  MLoopCol *m2 = dest;
741  unsigned char tmp_col[4];
742 
743  if (ELEM(mixmode,
747  /* Modes that do a full copy or nothing. */
749  /* TODO: Check for a real valid way to get 'factor' value of our dest color? */
750  const float f = ((float)m2->r + (float)m2->g + (float)m2->b) / 3.0f;
751  if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) {
752  return; /* Do Nothing! */
753  }
754  if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) {
755  return; /* Do Nothing! */
756  }
757  }
758  m2->r = m1->r;
759  m2->g = m1->g;
760  m2->b = m1->b;
761  m2->a = m1->a;
762  }
763  else { /* Modes that support 'real' mix factor. */
764  unsigned char src[4] = {m1->r, m1->g, m1->b, m1->a};
765  unsigned char dst[4] = {m2->r, m2->g, m2->b, m2->a};
766 
767  if (mixmode == CDT_MIX_MIX) {
768  blend_color_mix_byte(tmp_col, dst, src);
769  }
770  else if (mixmode == CDT_MIX_ADD) {
771  blend_color_add_byte(tmp_col, dst, src);
772  }
773  else if (mixmode == CDT_MIX_SUB) {
774  blend_color_sub_byte(tmp_col, dst, src);
775  }
776  else if (mixmode == CDT_MIX_MUL) {
777  blend_color_mul_byte(tmp_col, dst, src);
778  }
779  else {
780  memcpy(tmp_col, src, sizeof(tmp_col));
781  }
782 
783  blend_color_interpolate_byte(dst, dst, tmp_col, mixfactor);
784 
785  m2->r = (char)dst[0];
786  m2->g = (char)dst[1];
787  m2->b = (char)dst[2];
788  m2->a = (char)dst[3];
789  }
790 }
791 
792 static bool layerEqual_mloopcol(const void *data1, const void *data2)
793 {
794  const MLoopCol *m1 = data1, *m2 = data2;
795  float r, g, b, a;
796 
797  r = m1->r - m2->r;
798  g = m1->g - m2->g;
799  b = m1->b - m2->b;
800  a = m1->a - m2->a;
801 
802  return r * r + g * g + b * b + a * a < 0.001f;
803 }
804 
805 static void layerMultiply_mloopcol(void *data, float fac)
806 {
807  MLoopCol *m = data;
808 
809  m->r = (float)m->r * fac;
810  m->g = (float)m->g * fac;
811  m->b = (float)m->b * fac;
812  m->a = (float)m->a * fac;
813 }
814 
815 static void layerAdd_mloopcol(void *data1, const void *data2)
816 {
817  MLoopCol *m = data1;
818  const MLoopCol *m2 = data2;
819 
820  m->r += m2->r;
821  m->g += m2->g;
822  m->b += m2->b;
823  m->a += m2->a;
824 }
825 
826 static void layerDoMinMax_mloopcol(const void *data, void *vmin, void *vmax)
827 {
828  const MLoopCol *m = data;
829  MLoopCol *min = vmin, *max = vmax;
830 
831  if (m->r < min->r) {
832  min->r = m->r;
833  }
834  if (m->g < min->g) {
835  min->g = m->g;
836  }
837  if (m->b < min->b) {
838  min->b = m->b;
839  }
840  if (m->a < min->a) {
841  min->a = m->a;
842  }
843  if (m->r > max->r) {
844  max->r = m->r;
845  }
846  if (m->g > max->g) {
847  max->g = m->g;
848  }
849  if (m->b > max->b) {
850  max->b = m->b;
851  }
852  if (m->a > max->a) {
853  max->a = m->a;
854  }
855 }
856 
857 static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
858 {
859  MLoopCol *min = vmin, *max = vmax;
860 
861  min->r = 255;
862  min->g = 255;
863  min->b = 255;
864  min->a = 255;
865 
866  max->r = 0;
867  max->g = 0;
868  max->b = 0;
869  max->a = 0;
870 }
871 
872 static void layerDefault_mloopcol(void *data, int count)
873 {
874  MLoopCol default_mloopcol = {255, 255, 255, 255};
875  MLoopCol *mlcol = (MLoopCol *)data;
876  for (int i = 0; i < count; i++) {
877  mlcol[i] = default_mloopcol;
878  }
879 }
880 
881 static void layerInterp_mloopcol(const void **sources,
882  const float *weights,
883  const float *UNUSED(sub_weights),
884  int count,
885  void *dest)
886 {
887  MLoopCol *mc = dest;
888  struct {
889  float a;
890  float r;
891  float g;
892  float b;
893  } col = {0};
894 
895  for (int i = 0; i < count; i++) {
896  const float interp_weight = weights[i];
897  const MLoopCol *src = sources[i];
898  col.r += src->r * interp_weight;
899  col.g += src->g * interp_weight;
900  col.b += src->b * interp_weight;
901  col.a += src->a * interp_weight;
902  }
903 
904  /* Subdivide smooth or fractal can cause problems without clamping
905  * although weights should also not cause this situation */
906 
907  /* Also delay writing to the destination in case dest is in sources. */
908  mc->r = round_fl_to_uchar_clamp(col.r);
909  mc->g = round_fl_to_uchar_clamp(col.g);
910  mc->b = round_fl_to_uchar_clamp(col.b);
911  mc->a = round_fl_to_uchar_clamp(col.a);
912 }
913 
914 static int layerMaxNum_mloopcol(void)
915 {
916  return MAX_MCOL;
917 }
918 
919 static void layerCopyValue_mloopuv(const void *source,
920  void *dest,
921  const int mixmode,
922  const float mixfactor)
923 {
924  const MLoopUV *luv1 = source;
925  MLoopUV *luv2 = dest;
926 
927  /* We only support a limited subset of advanced mixing here -
928  * namely the mixfactor interpolation. */
929 
930  if (mixmode == CDT_MIX_NOMIX) {
931  copy_v2_v2(luv2->uv, luv1->uv);
932  }
933  else {
934  interp_v2_v2v2(luv2->uv, luv2->uv, luv1->uv, mixfactor);
935  }
936 }
937 
938 static bool layerEqual_mloopuv(const void *data1, const void *data2)
939 {
940  const MLoopUV *luv1 = data1, *luv2 = data2;
941 
942  return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
943 }
944 
945 static void layerMultiply_mloopuv(void *data, float fac)
946 {
947  MLoopUV *luv = data;
948 
949  mul_v2_fl(luv->uv, fac);
950 }
951 
952 static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
953 {
954  MLoopUV *min = vmin, *max = vmax;
955 
956  INIT_MINMAX2(min->uv, max->uv);
957 }
958 
959 static void layerDoMinMax_mloopuv(const void *data, void *vmin, void *vmax)
960 {
961  const MLoopUV *luv = data;
962  MLoopUV *min = vmin, *max = vmax;
963 
964  minmax_v2v2_v2(min->uv, max->uv, luv->uv);
965 }
966 
967 static void layerAdd_mloopuv(void *data1, const void *data2)
968 {
969  MLoopUV *l1 = data1;
970  const MLoopUV *l2 = data2;
971 
972  add_v2_v2(l1->uv, l2->uv);
973 }
974 
975 static void layerInterp_mloopuv(const void **sources,
976  const float *weights,
977  const float *UNUSED(sub_weights),
978  int count,
979  void *dest)
980 {
981  float uv[2];
982  int flag = 0;
983 
984  zero_v2(uv);
985 
986  for (int i = 0; i < count; i++) {
987  const float interp_weight = weights[i];
988  const MLoopUV *src = sources[i];
989  madd_v2_v2fl(uv, src->uv, interp_weight);
990  if (interp_weight > 0.0f) {
991  flag |= src->flag;
992  }
993  }
994 
995  /* Delay writing to the destination in case dest is in sources. */
996  copy_v2_v2(((MLoopUV *)dest)->uv, uv);
997  ((MLoopUV *)dest)->flag = flag;
998 }
999 
1000 static bool layerValidate_mloopuv(void *data, const uint totitems, const bool do_fixes)
1001 {
1002  MLoopUV *uv = data;
1003  bool has_errors = false;
1004 
1005  for (int i = 0; i < totitems; i++, uv++) {
1006  if (!is_finite_v2(uv->uv)) {
1007  if (do_fixes) {
1008  zero_v2(uv->uv);
1009  }
1010  has_errors = true;
1011  }
1012  }
1013 
1014  return has_errors;
1015 }
1016 
1017 /* origspace is almost exact copy of mloopuv's, keep in sync */
1018 static void layerCopyValue_mloop_origspace(const void *source,
1019  void *dest,
1020  const int UNUSED(mixmode),
1021  const float UNUSED(mixfactor))
1022 {
1023  const OrigSpaceLoop *luv1 = source;
1024  OrigSpaceLoop *luv2 = dest;
1025 
1026  copy_v2_v2(luv2->uv, luv1->uv);
1027 }
1028 
1029 static bool layerEqual_mloop_origspace(const void *data1, const void *data2)
1030 {
1031  const OrigSpaceLoop *luv1 = data1, *luv2 = data2;
1032 
1033  return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
1034 }
1035 
1036 static void layerMultiply_mloop_origspace(void *data, float fac)
1037 {
1038  OrigSpaceLoop *luv = data;
1039 
1040  mul_v2_fl(luv->uv, fac);
1041 }
1042 
1043 static void layerInitMinMax_mloop_origspace(void *vmin, void *vmax)
1044 {
1045  OrigSpaceLoop *min = vmin, *max = vmax;
1046 
1047  INIT_MINMAX2(min->uv, max->uv);
1048 }
1049 
1050 static void layerDoMinMax_mloop_origspace(const void *data, void *vmin, void *vmax)
1051 {
1052  const OrigSpaceLoop *luv = data;
1053  OrigSpaceLoop *min = vmin, *max = vmax;
1054 
1055  minmax_v2v2_v2(min->uv, max->uv, luv->uv);
1056 }
1057 
1058 static void layerAdd_mloop_origspace(void *data1, const void *data2)
1059 {
1060  OrigSpaceLoop *l1 = data1;
1061  const OrigSpaceLoop *l2 = data2;
1062 
1063  add_v2_v2(l1->uv, l2->uv);
1064 }
1065 
1066 static void layerInterp_mloop_origspace(const void **sources,
1067  const float *weights,
1068  const float *UNUSED(sub_weights),
1069  int count,
1070  void *dest)
1071 {
1072  float uv[2];
1073  zero_v2(uv);
1074 
1075  for (int i = 0; i < count; i++) {
1076  const float interp_weight = weights[i];
1077  const OrigSpaceLoop *src = sources[i];
1078  madd_v2_v2fl(uv, src->uv, interp_weight);
1079  }
1080 
1081  /* Delay writing to the destination in case dest is in sources. */
1082  copy_v2_v2(((OrigSpaceLoop *)dest)->uv, uv);
1083 }
1084 /* --- end copy */
1085 
1086 static void layerInterp_mcol(
1087  const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
1088 {
1089  MCol *mc = dest;
1090  struct {
1091  float a;
1092  float r;
1093  float g;
1094  float b;
1095  } col[4] = {{0.0f}};
1096 
1097  const float *sub_weight = sub_weights;
1098  for (int i = 0; i < count; i++) {
1099  const float interp_weight = weights[i];
1100 
1101  for (int j = 0; j < 4; j++) {
1102  if (sub_weights) {
1103  const MCol *src = sources[i];
1104  for (int k = 0; k < 4; k++, sub_weight++, src++) {
1105  const float w = (*sub_weight) * interp_weight;
1106  col[j].a += src->a * w;
1107  col[j].r += src->r * w;
1108  col[j].g += src->g * w;
1109  col[j].b += src->b * w;
1110  }
1111  }
1112  else {
1113  const MCol *src = sources[i];
1114  col[j].a += src[j].a * interp_weight;
1115  col[j].r += src[j].r * interp_weight;
1116  col[j].g += src[j].g * interp_weight;
1117  col[j].b += src[j].b * interp_weight;
1118  }
1119  }
1120  }
1121 
1122  /* Delay writing to the destination in case dest is in sources. */
1123  for (int j = 0; j < 4; j++) {
1124 
1125  /* Subdivide smooth or fractal can cause problems without clamping
1126  * although weights should also not cause this situation */
1127  mc[j].a = round_fl_to_uchar_clamp(col[j].a);
1128  mc[j].r = round_fl_to_uchar_clamp(col[j].r);
1129  mc[j].g = round_fl_to_uchar_clamp(col[j].g);
1130  mc[j].b = round_fl_to_uchar_clamp(col[j].b);
1131  }
1132 }
1133 
1134 static void layerSwap_mcol(void *data, const int *corner_indices)
1135 {
1136  MCol *mcol = data;
1137  MCol col[4];
1138 
1139  for (int j = 0; j < 4; j++) {
1140  col[j] = mcol[corner_indices[j]];
1141  }
1142 
1143  memcpy(mcol, col, sizeof(col));
1144 }
1145 
1146 static void layerDefault_mcol(void *data, int count)
1147 {
1148  static MCol default_mcol = {255, 255, 255, 255};
1149  MCol *mcol = (MCol *)data;
1150 
1151  for (int i = 0; i < 4 * count; i++) {
1152  mcol[i] = default_mcol;
1153  }
1154 }
1155 
1156 static void layerDefault_origindex(void *data, int count)
1157 {
1158  copy_vn_i((int *)data, count, ORIGINDEX_NONE);
1159 }
1160 
1161 static void layerInterp_bweight(const void **sources,
1162  const float *weights,
1163  const float *UNUSED(sub_weights),
1164  int count,
1165  void *dest)
1166 {
1167  float **in = (float **)sources;
1168 
1169  if (count <= 0) {
1170  return;
1171  }
1172 
1173  float f = 0.0f;
1174 
1175  for (int i = 0; i < count; i++) {
1176  const float interp_weight = weights[i];
1177  f += *in[i] * interp_weight;
1178  }
1179 
1180  /* Delay writing to the destination in case dest is in sources. */
1181  *((float *)dest) = f;
1182 }
1183 
1184 static void layerInterp_shapekey(const void **sources,
1185  const float *weights,
1186  const float *UNUSED(sub_weights),
1187  int count,
1188  void *dest)
1189 {
1190  float **in = (float **)sources;
1191 
1192  if (count <= 0) {
1193  return;
1194  }
1195 
1196  float co[3];
1197  zero_v3(co);
1198 
1199  for (int i = 0; i < count; i++) {
1200  const float interp_weight = weights[i];
1201  madd_v3_v3fl(co, in[i], interp_weight);
1202  }
1203 
1204  /* Delay writing to the destination in case dest is in sources. */
1205  copy_v3_v3((float *)dest, co);
1206 }
1207 
1208 static void layerDefault_mvert_skin(void *data, int count)
1209 {
1210  MVertSkin *vs = data;
1211 
1212  for (int i = 0; i < count; i++) {
1213  copy_v3_fl(vs[i].radius, 0.25f);
1214  vs[i].flag = 0;
1215  }
1216 }
1217 
1218 static void layerCopy_mvert_skin(const void *source, void *dest, int count)
1219 {
1220  memcpy(dest, source, sizeof(MVertSkin) * count);
1221 }
1222 
1223 static void layerInterp_mvert_skin(const void **sources,
1224  const float *weights,
1225  const float *UNUSED(sub_weights),
1226  int count,
1227  void *dest)
1228 {
1229  MVertSkin *vs_dst = dest;
1230 
1231  float radius[3];
1232  zero_v3(radius);
1233 
1234  for (int i = 0; i < count; i++) {
1235  const float interp_weight = weights[i];
1236  const MVertSkin *vs_src = sources[i];
1237 
1238  madd_v3_v3fl(radius, vs_src->radius, interp_weight);
1239  }
1240 
1241  /* Delay writing to the destination in case dest is in sources. */
1242  vs_dst = dest;
1243  copy_v3_v3(vs_dst->radius, radius);
1244  vs_dst->flag &= ~MVERT_SKIN_ROOT;
1245 }
1246 
1247 static void layerSwap_flnor(void *data, const int *corner_indices)
1248 {
1249  short(*flnors)[4][3] = data;
1250  short nors[4][3];
1251  int i = 4;
1252 
1253  while (i--) {
1254  copy_v3_v3_short(nors[i], (*flnors)[corner_indices[i]]);
1255  }
1256 
1257  memcpy(flnors, nors, sizeof(nors));
1258 }
1259 
1260 static void layerDefault_fmap(void *data, int count)
1261 {
1262  int *fmap_num = (int *)data;
1263  for (int i = 0; i < count; i++) {
1264  fmap_num[i] = -1;
1265  }
1266 }
1267 
1268 static void layerCopyValue_propcol(const void *source,
1269  void *dest,
1270  const int mixmode,
1271  const float mixfactor)
1272 {
1273  const MPropCol *m1 = source;
1274  MPropCol *m2 = dest;
1275  float tmp_col[4];
1276 
1277  if (ELEM(mixmode,
1278  CDT_MIX_NOMIX,
1281  /* Modes that do a full copy or nothing. */
1283  /* TODO: Check for a real valid way to get 'factor' value of our dest color? */
1284  const float f = (m2->color[0] + m2->color[1] + m2->color[2]) / 3.0f;
1285  if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) {
1286  return; /* Do Nothing! */
1287  }
1288  if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) {
1289  return; /* Do Nothing! */
1290  }
1291  }
1292  copy_v4_v4(m2->color, m1->color);
1293  }
1294  else { /* Modes that support 'real' mix factor. */
1295  if (mixmode == CDT_MIX_MIX) {
1296  blend_color_mix_float(tmp_col, m2->color, m1->color);
1297  }
1298  else if (mixmode == CDT_MIX_ADD) {
1299  blend_color_add_float(tmp_col, m2->color, m1->color);
1300  }
1301  else if (mixmode == CDT_MIX_SUB) {
1302  blend_color_sub_float(tmp_col, m2->color, m1->color);
1303  }
1304  else if (mixmode == CDT_MIX_MUL) {
1305  blend_color_mul_float(tmp_col, m2->color, m1->color);
1306  }
1307  else {
1308  memcpy(tmp_col, m1->color, sizeof(tmp_col));
1309  }
1310  blend_color_interpolate_float(m2->color, m2->color, tmp_col, mixfactor);
1311 
1312  copy_v4_v4(m2->color, m1->color);
1313  }
1314 }
1315 
1316 static bool layerEqual_propcol(const void *data1, const void *data2)
1317 {
1318  const MPropCol *m1 = data1, *m2 = data2;
1319  float tot = 0;
1320 
1321  for (int i = 0; i < 4; i++) {
1322  float c = (m1->color[i] - m2->color[i]);
1323  tot += c * c;
1324  }
1325 
1326  return tot < 0.001f;
1327 }
1328 
1329 static void layerMultiply_propcol(void *data, float fac)
1330 {
1331  MPropCol *m = data;
1332  mul_v4_fl(m->color, fac);
1333 }
1334 
1335 static void layerAdd_propcol(void *data1, const void *data2)
1336 {
1337  MPropCol *m = data1;
1338  const MPropCol *m2 = data2;
1339  add_v4_v4(m->color, m2->color);
1340 }
1341 
1342 static void layerDoMinMax_propcol(const void *data, void *vmin, void *vmax)
1343 {
1344  const MPropCol *m = data;
1345  MPropCol *min = vmin, *max = vmax;
1346  minmax_v4v4_v4(min->color, max->color, m->color);
1347 }
1348 
1349 static void layerInitMinMax_propcol(void *vmin, void *vmax)
1350 {
1351  MPropCol *min = vmin, *max = vmax;
1352 
1353  copy_v4_fl(min->color, FLT_MAX);
1354  copy_v4_fl(max->color, FLT_MIN);
1355 }
1356 
1357 static void layerDefault_propcol(void *data, int count)
1358 {
1359  /* Default to white, full alpha. */
1360  MPropCol default_propcol = {{1.0f, 1.0f, 1.0f, 1.0f}};
1361  MPropCol *pcol = (MPropCol *)data;
1362  for (int i = 0; i < count; i++) {
1363  copy_v4_v4(pcol[i].color, default_propcol.color);
1364  }
1365 }
1366 
1367 static void layerInterp_propcol(const void **sources,
1368  const float *weights,
1369  const float *UNUSED(sub_weights),
1370  int count,
1371  void *dest)
1372 {
1373  MPropCol *mc = dest;
1374  float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1375  for (int i = 0; i < count; i++) {
1376  const float interp_weight = weights[i];
1377  const MPropCol *src = sources[i];
1378  madd_v4_v4fl(col, src->color, interp_weight);
1379  }
1380  copy_v4_v4(mc->color, col);
1381 }
1382 
1383 static int layerMaxNum_propcol(void)
1384 {
1385  return MAX_MCOL;
1386 }
1387 
1388 static void layerInterp_propfloat3(const void **sources,
1389  const float *weights,
1390  const float *UNUSED(sub_weights),
1391  int count,
1392  void *dest)
1393 {
1394  vec3f result = {0.0f, 0.0f, 0.0f};
1395  for (int i = 0; i < count; i++) {
1396  const float interp_weight = weights[i];
1397  const vec3f *src = sources[i];
1398  madd_v3_v3fl(&result.x, &src->x, interp_weight);
1399  }
1400  copy_v3_v3((float *)dest, &result.x);
1401 }
1402 
1403 static void layerMultiply_propfloat3(void *data, float fac)
1404 {
1405  vec3f *vec = data;
1406  vec->x *= fac;
1407  vec->y *= fac;
1408  vec->z *= fac;
1409 }
1410 
1411 static void layerAdd_propfloat3(void *data1, const void *data2)
1412 {
1413  vec3f *vec1 = data1;
1414  const vec3f *vec2 = data2;
1415  vec1->x += vec2->x;
1416  vec1->y += vec2->y;
1417  vec1->z += vec2->z;
1418 }
1419 
1420 static bool layerValidate_propfloat3(void *data, const uint totitems, const bool do_fixes)
1421 {
1422  float *values = data;
1423  bool has_errors = false;
1424  for (int i = 0; i < totitems * 3; i++) {
1425  if (!isfinite(values[i])) {
1426  if (do_fixes) {
1427  values[i] = 0.0f;
1428  }
1429  has_errors = true;
1430  }
1431  }
1432  return has_errors;
1433 }
1434 
1435 static void layerInterp_propfloat2(const void **sources,
1436  const float *weights,
1437  const float *UNUSED(sub_weights),
1438  int count,
1439  void *dest)
1440 {
1441  vec2f result = {0.0f, 0.0f};
1442  for (int i = 0; i < count; i++) {
1443  const float interp_weight = weights[i];
1444  const vec2f *src = sources[i];
1445  madd_v2_v2fl(&result.x, &src->x, interp_weight);
1446  }
1447  copy_v2_v2((float *)dest, &result.x);
1448 }
1449 
1450 static void layerMultiply_propfloat2(void *data, float fac)
1451 {
1452  vec2f *vec = data;
1453  vec->x *= fac;
1454  vec->y *= fac;
1455 }
1456 
1457 static void layerAdd_propfloat2(void *data1, const void *data2)
1458 {
1459  vec2f *vec1 = data1;
1460  const vec2f *vec2 = data2;
1461  vec1->x += vec2->x;
1462  vec1->y += vec2->y;
1463 }
1464 
1465 static bool layerValidate_propfloat2(void *data, const uint totitems, const bool do_fixes)
1466 {
1467  float *values = data;
1468  bool has_errors = false;
1469  for (int i = 0; i < totitems * 2; i++) {
1470  if (!isfinite(values[i])) {
1471  if (do_fixes) {
1472  values[i] = 0.0f;
1473  }
1474  has_errors = true;
1475  }
1476  }
1477  return has_errors;
1478 }
1479 
1481  /* 0: CD_MVERT */
1482  {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1483  /* 1: CD_MSTICKY */ /* DEPRECATED */
1484  {sizeof(float[2]), "", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1485  /* 2: CD_MDEFORMVERT */
1486  {sizeof(MDeformVert),
1487  "MDeformVert",
1488  1,
1489  NULL,
1493  NULL,
1494  NULL},
1495  /* 3: CD_MEDGE */
1496  {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1497  /* 4: CD_MFACE */
1498  {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1499  /* 5: CD_MTFACE */
1500  {sizeof(MTFace),
1501  "MTFace",
1502  1,
1503  N_("UVMap"),
1505  NULL,
1509  NULL,
1510  NULL,
1511  NULL,
1512  NULL,
1513  NULL,
1514  NULL,
1515  NULL,
1516  NULL,
1517  NULL,
1518  NULL,
1520  /* 6: CD_MCOL */
1521  /* 4 MCol structs per face */
1522  {sizeof(MCol[4]),
1523  "MCol",
1524  4,
1525  N_("Col"),
1526  NULL,
1527  NULL,
1531  NULL,
1532  NULL,
1533  NULL,
1534  NULL,
1535  NULL,
1536  NULL,
1537  NULL,
1538  NULL,
1539  NULL,
1540  NULL,
1542  /* 7: CD_ORIGINDEX */
1543  {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_origindex},
1544  /* 8: CD_NORMAL */
1545  /* 3 floats per normal vector */
1546  {sizeof(float[3]),
1547  "vec3f",
1548  1,
1549  NULL,
1550  NULL,
1551  NULL,
1553  NULL,
1554  NULL,
1556  NULL,
1557  NULL,
1558  NULL,
1559  NULL,
1560  NULL,
1562  /* 9: CD_FACEMAP */
1563  {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_fmap, NULL},
1564  /* 10: CD_PROP_FLOAT */
1565  {sizeof(MFloatProperty),
1566  "MFloatProperty",
1567  1,
1568  N_("Float"),
1570  NULL,
1572  NULL,
1573  NULL,
1575  /* 11: CD_PROP_INT32 */
1576  {sizeof(MIntProperty), "MIntProperty", 1, N_("Int"), layerCopy_propInt, NULL, NULL, NULL},
1577  /* 12: CD_PROP_STRING */
1578  {sizeof(MStringProperty),
1579  "MStringProperty",
1580  1,
1581  N_("String"),
1583  NULL,
1584  NULL,
1585  NULL},
1586  /* 13: CD_ORIGSPACE */
1587  {sizeof(OrigSpaceFace),
1588  "OrigSpaceFace",
1589  1,
1590  N_("UVMap"),
1592  NULL,
1596  /* 14: CD_ORCO */
1597  {sizeof(float[3]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1598  /* 15: CD_MTEXPOLY */ /* DEPRECATED */
1599  /* note, when we expose the UV Map / TexFace split to the user,
1600  * change this back to face Texture. */
1601  {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1602  /* 16: CD_MLOOPUV */
1603  {sizeof(MLoopUV),
1604  "MLoopUV",
1605  1,
1606  N_("UVMap"),
1607  NULL,
1608  NULL,
1610  NULL,
1611  NULL,
1619  NULL,
1620  NULL,
1621  NULL,
1623  /* 17: CD_MLOOPCOL */
1624  {sizeof(MLoopCol),
1625  "MLoopCol",
1626  1,
1627  N_("Col"),
1628  NULL,
1629  NULL,
1631  NULL,
1633  NULL,
1640  NULL,
1641  NULL,
1642  NULL,
1644  /* 18: CD_TANGENT */
1645  {sizeof(float[4][4]), "", 0, N_("Tangent"), NULL, NULL, NULL, NULL, NULL},
1646  /* 19: CD_MDISPS */
1647  {sizeof(MDisps),
1648  "MDisps",
1649  1,
1650  NULL,
1653  NULL,
1655  NULL,
1656  NULL,
1657  NULL,
1658  NULL,
1659  NULL,
1660  NULL,
1661  NULL,
1662  NULL,
1666  /* 20: CD_PREVIEW_MCOL */
1667  {sizeof(MCol[4]),
1668  "MCol",
1669  4,
1670  N_("PreviewCol"),
1671  NULL,
1672  NULL,
1676  /* 21: CD_ID_MCOL */ /* DEPRECATED */
1677  {sizeof(MCol[4]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1678  /* 22: CD_TEXTURE_MCOL */
1679  {sizeof(MCol[4]),
1680  "MCol",
1681  4,
1682  N_("TexturedCol"),
1683  NULL,
1684  NULL,
1688  /* 23: CD_CLOTH_ORCO */
1689  {sizeof(float[3]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1690  /* 24: CD_RECAST */
1691  {sizeof(MRecast), "MRecast", 1, N_("Recast"), NULL, NULL, NULL, NULL},
1692 
1693  /* BMESH ONLY */
1694  /* 25: CD_MPOLY */
1695  {sizeof(MPoly), "MPoly", 1, N_("NGon Face"), NULL, NULL, NULL, NULL, NULL},
1696  /* 26: CD_MLOOP */
1697  {sizeof(MLoop), "MLoop", 1, N_("NGon Face-Vertex"), NULL, NULL, NULL, NULL, NULL},
1698  /* 27: CD_SHAPE_KEYINDEX */
1699  {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1700  /* 28: CD_SHAPEKEY */
1701  {sizeof(float[3]), "", 0, N_("ShapeKey"), NULL, NULL, layerInterp_shapekey},
1702  /* 29: CD_BWEIGHT */
1703  {sizeof(float), "", 0, N_("BevelWeight"), NULL, NULL, layerInterp_bweight},
1704  /* 30: CD_CREASE */
1705  {sizeof(float), "", 0, N_("SubSurfCrease"), NULL, NULL, layerInterp_bweight},
1706  /* 31: CD_ORIGSPACE_MLOOP */
1707  {sizeof(OrigSpaceLoop),
1708  "OrigSpaceLoop",
1709  1,
1710  N_("OS Loop"),
1711  NULL,
1712  NULL,
1714  NULL,
1715  NULL,
1716  NULL,
1723  /* 32: CD_PREVIEW_MLOOPCOL */
1724  {sizeof(MLoopCol),
1725  "MLoopCol",
1726  1,
1727  N_("PreviewLoopCol"),
1728  NULL,
1729  NULL,
1731  NULL,
1733  NULL,
1740  /* 33: CD_BM_ELEM_PYPTR */
1741  {sizeof(void *),
1742  "",
1743  1,
1744  NULL,
1747  NULL,
1748  NULL,
1749  NULL},
1750 
1751  /* END BMESH ONLY */
1752 
1753  /* 34: CD_PAINT_MASK */
1754  {sizeof(float), "", 0, NULL, NULL, NULL, layerInterp_paint_mask, NULL, NULL},
1755  /* 35: CD_GRID_PAINT_MASK */
1756  {sizeof(GridPaintMask),
1757  "GridPaintMask",
1758  1,
1759  NULL,
1762  NULL,
1763  NULL,
1764  NULL},
1765  /* 36: CD_MVERT_SKIN */
1766  {sizeof(MVertSkin),
1767  "MVertSkin",
1768  1,
1769  NULL,
1771  NULL,
1773  NULL,
1775  /* 37: CD_FREESTYLE_EDGE */
1776  {sizeof(FreestyleEdge), "FreestyleEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1777  /* 38: CD_FREESTYLE_FACE */
1778  {sizeof(FreestyleFace), "FreestyleFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1779  /* 39: CD_MLOOPTANGENT */
1780  {sizeof(float[4]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1781  /* 40: CD_TESSLOOPNORMAL */
1782  {sizeof(short[4][3]), "", 0, NULL, NULL, NULL, NULL, layerSwap_flnor, NULL},
1783  /* 41: CD_CUSTOMLOOPNORMAL */
1784  {sizeof(short[2]), "vec2s", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1785  /* 42: CD_SCULPT_FACE_SETS */
1786  {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1787  /* 43: CD_LOCATION */
1788  {sizeof(float[3]), "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1789  /* 44: CD_RADIUS */
1790  {sizeof(float), "MFloatProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1791  /* 45: CD_HAIRCURVE */
1792  {sizeof(HairCurve), "HairCurve", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1793  /* 46: CD_HAIRMAPPING */
1794  {sizeof(HairMapping), "HairMapping", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1795  /* 47: CD_PROP_COLOR */
1796  {sizeof(MPropCol),
1797  "MPropCol",
1798  1,
1799  N_("Color"),
1800  NULL,
1801  NULL,
1803  NULL,
1805  NULL,
1812  NULL,
1813  NULL,
1814  NULL,
1816  /* 48: CD_PROP_FLOAT3 */
1817  {sizeof(float[3]),
1818  "vec3f",
1819  1,
1820  N_("Float3"),
1821  NULL,
1822  NULL,
1824  NULL,
1825  NULL,
1827  NULL,
1829  NULL,
1831  /* 49: CD_PROP_FLOAT2 */
1832  {sizeof(float[2]),
1833  "vec2f",
1834  1,
1835  N_("Float2"),
1836  NULL,
1837  NULL,
1839  NULL,
1840  NULL,
1842  NULL,
1844  NULL,
1846  /* 50: CD_PROP_BOOL */
1847  {sizeof(bool),
1848  "bool",
1849  1,
1850  N_("Boolean"),
1851  NULL,
1852  NULL,
1853  NULL,
1854  NULL,
1855  NULL,
1856  NULL,
1857  NULL,
1858  NULL,
1859  NULL,
1860  NULL},
1861 };
1862 
1863 static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
1864  /* 0-4 */ "CDMVert",
1865  "CDMSticky",
1866  "CDMDeformVert",
1867  "CDMEdge",
1868  "CDMFace",
1869  /* 5-9 */ "CDMTFace",
1870  "CDMCol",
1871  "CDOrigIndex",
1872  "CDNormal",
1873  "CDFaceMap",
1874  /* 10-14 */ "CDMFloatProperty",
1875  "CDMIntProperty",
1876  "CDMStringProperty",
1877  "CDOrigSpace",
1878  "CDOrco",
1879  /* 15-19 */ "CDMTexPoly",
1880  "CDMLoopUV",
1881  "CDMloopCol",
1882  "CDTangent",
1883  "CDMDisps",
1884  /* 20-24 */ "CDPreviewMCol",
1885  "CDIDMCol",
1886  "CDTextureMCol",
1887  "CDClothOrco",
1888  "CDMRecast",
1889 
1890  /* BMESH ONLY */
1891  /* 25-29 */ "CDMPoly",
1892  "CDMLoop",
1893  "CDShapeKeyIndex",
1894  "CDShapeKey",
1895  "CDBevelWeight",
1896  /* 30-34 */ "CDSubSurfCrease",
1897  "CDOrigSpaceLoop",
1898  "CDPreviewLoopCol",
1899  "CDBMElemPyPtr",
1900  "CDPaintMask",
1901  /* 35-36 */ "CDGridPaintMask",
1902  "CDMVertSkin",
1903  /* 37-38 */ "CDFreestyleEdge",
1904  "CDFreestyleFace",
1905  /* 39-42 */ "CDMLoopTangent",
1906  "CDTessLoopNormal",
1907  "CDCustomLoopNormal",
1908  "CDSculptFaceGroups",
1909  /* 43-46 */ "CDHairPoint",
1910  "CDHairCurve",
1911  "CDHairMapping",
1912  "CDPoint",
1913  "CDPropCol",
1914  "CDPropFloat3",
1915  "CDPropFloat2",
1916  "CDPropBoolean",
1917 };
1918 
1921  .emask = CD_MASK_MEDGE | CD_MASK_BWEIGHT,
1922  .fmask = 0,
1923  .lmask = CD_MASK_MLOOP,
1924  .pmask = CD_MASK_MPOLY | CD_MASK_FACEMAP,
1925 };
1929  .fmask = 0,
1930  .lmask = CD_MASK_MLOOP,
1932 };
1937  .fmask = 0,
1942 };
1946  .emask = (CD_MASK_PROP_ALL),
1947  .fmask = 0,
1951 };
1960  CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */
1963 };
1968  .fmask = 0,
1973 };
1978  .vmask = 0,
1979  .emask = 0,
1984  .pmask = 0,
1985 };
2003 };
2004 
2006 {
2007  if (type < 0 || type >= CD_NUMTYPES) {
2008  return NULL;
2009  }
2010 
2011  return &LAYERTYPEINFO[type];
2012 }
2013 
2014 static const char *layerType_getName(int type)
2015 {
2016  if (type < 0 || type >= CD_NUMTYPES) {
2017  return NULL;
2018  }
2019 
2020  return LAYERTYPENAMES[type];
2021 }
2022 
2024 {
2025  printf("verts mask=0x%lx:\n", (long unsigned int)mask->vmask);
2026  for (int i = 0; i < CD_NUMTYPES; i++) {
2027  if (mask->vmask & CD_TYPE_AS_MASK(i)) {
2028  printf(" %s\n", layerType_getName(i));
2029  }
2030  }
2031 
2032  printf("edges mask=0x%lx:\n", (long unsigned int)mask->emask);
2033  for (int i = 0; i < CD_NUMTYPES; i++) {
2034  if (mask->emask & CD_TYPE_AS_MASK(i)) {
2035  printf(" %s\n", layerType_getName(i));
2036  }
2037  }
2038 
2039  printf("faces mask=0x%lx:\n", (long unsigned int)mask->fmask);
2040  for (int i = 0; i < CD_NUMTYPES; i++) {
2041  if (mask->fmask & CD_TYPE_AS_MASK(i)) {
2042  printf(" %s\n", layerType_getName(i));
2043  }
2044  }
2045 
2046  printf("loops mask=0x%lx:\n", (long unsigned int)mask->lmask);
2047  for (int i = 0; i < CD_NUMTYPES; i++) {
2048  if (mask->lmask & CD_TYPE_AS_MASK(i)) {
2049  printf(" %s\n", layerType_getName(i));
2050  }
2051  }
2052 
2053  printf("polys mask=0x%lx:\n", (long unsigned int)mask->pmask);
2054  for (int i = 0; i < CD_NUMTYPES; i++) {
2055  if (mask->pmask & CD_TYPE_AS_MASK(i)) {
2056  printf(" %s\n", layerType_getName(i));
2057  }
2058  }
2059 }
2060 
2061 /********************* CustomData functions *********************/
2063 
2065  int type,
2066  eCDAllocType alloctype,
2067  void *layerdata,
2068  int totelem,
2069  const char *name);
2070 
2072 {
2073  int lasttype = -1;
2074 
2075  for (int i = 0; i < CD_NUMTYPES; i++) {
2076  data->typemap[i] = -1;
2077  }
2078 
2079  for (int i = 0; i < data->totlayer; i++) {
2080  const int type = data->layers[i].type;
2081  if (type != lasttype) {
2082  data->typemap[type] = i;
2083  lasttype = type;
2084  }
2085  }
2086 }
2087 
2088 /* currently only used in BLI_assert */
2089 #ifndef NDEBUG
2091 {
2092  CustomData data_copy = *data;
2093  CustomData_update_typemap(&data_copy);
2094  return (memcmp(data->typemap, data_copy.typemap, sizeof(data->typemap)) == 0);
2095 }
2096 #endif
2097 
2098 bool CustomData_merge(const struct CustomData *source,
2099  struct CustomData *dest,
2101  eCDAllocType alloctype,
2102  int totelem)
2103 {
2104  /*const LayerTypeInfo *typeInfo;*/
2105  CustomDataLayer *layer, *newlayer;
2106  int lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
2107  int number = 0, maxnumber = -1;
2108  bool changed = false;
2109 
2110  for (int i = 0; i < source->totlayer; i++) {
2111  layer = &source->layers[i];
2112  /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/
2113 
2114  int type = layer->type;
2115  int flag = layer->flag;
2116 
2117  if (type != lasttype) {
2118  number = 0;
2120  lastactive = layer->active;
2121  lastrender = layer->active_rnd;
2122  lastclone = layer->active_clone;
2123  lastmask = layer->active_mask;
2124  lasttype = type;
2125  }
2126  else {
2127  number++;
2128  }
2129 
2130  if (flag & CD_FLAG_NOCOPY) {
2131  continue;
2132  }
2133  if (!(mask & CD_TYPE_AS_MASK(type))) {
2134  continue;
2135  }
2136  if ((maxnumber != -1) && (number >= maxnumber)) {
2137  continue;
2138  }
2139  if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) {
2140  continue;
2141  }
2142 
2143  void *data;
2144  switch (alloctype) {
2145  case CD_ASSIGN:
2146  case CD_REFERENCE:
2147  case CD_DUPLICATE:
2148  data = layer->data;
2149  break;
2150  default:
2151  data = NULL;
2152  break;
2153  }
2154 
2155  if ((alloctype == CD_ASSIGN) && (flag & CD_FLAG_NOFREE)) {
2156  newlayer = customData_add_layer__internal(
2157  dest, type, CD_REFERENCE, data, totelem, layer->name);
2158  }
2159  else {
2160  newlayer = customData_add_layer__internal(dest, type, alloctype, data, totelem, layer->name);
2161  }
2162 
2163  if (newlayer) {
2164  newlayer->uid = layer->uid;
2165 
2166  newlayer->active = lastactive;
2167  newlayer->active_rnd = lastrender;
2168  newlayer->active_clone = lastclone;
2169  newlayer->active_mask = lastmask;
2170  newlayer->flag |= flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY);
2171  changed = true;
2172  }
2173  }
2174 
2176  return changed;
2177 }
2178 
2179 /* NOTE: Take care of referenced layers by yourself! */
2181 {
2182  for (int i = 0; i < data->totlayer; i++) {
2183  CustomDataLayer *layer = &data->layers[i];
2184  const LayerTypeInfo *typeInfo;
2185  if (layer->flag & CD_FLAG_NOFREE) {
2186  continue;
2187  }
2188  typeInfo = layerType_getInfo(layer->type);
2189  layer->data = MEM_reallocN(layer->data, (size_t)totelem * typeInfo->size);
2190  }
2191 }
2192 
2193 void CustomData_copy(const struct CustomData *source,
2194  struct CustomData *dest,
2196  eCDAllocType alloctype,
2197  int totelem)
2198 {
2199  CustomData_reset(dest);
2200 
2201  if (source->external) {
2202  dest->external = MEM_dupallocN(source->external);
2203  }
2204 
2205  CustomData_merge(source, dest, mask, alloctype, totelem);
2206 }
2207 
2208 static void customData_free_layer__internal(CustomDataLayer *layer, int totelem)
2209 {
2210  const LayerTypeInfo *typeInfo;
2211 
2212  if (!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
2213  typeInfo = layerType_getInfo(layer->type);
2214 
2215  if (typeInfo->free) {
2216  typeInfo->free(layer->data, totelem, typeInfo->size);
2217  }
2218 
2219  if (layer->data) {
2220  MEM_freeN(layer->data);
2221  }
2222  }
2223 }
2224 
2226 {
2227  if (data->external) {
2228  MEM_freeN(data->external);
2229  data->external = NULL;
2230  }
2231 }
2232 
2234 {
2235  memset(data, 0, sizeof(*data));
2236  copy_vn_i(data->typemap, CD_NUMTYPES, -1);
2237 }
2238 
2239 void CustomData_free(CustomData *data, int totelem)
2240 {
2241  for (int i = 0; i < data->totlayer; i++) {
2242  customData_free_layer__internal(&data->layers[i], totelem);
2243  }
2244 
2245  if (data->layers) {
2246  MEM_freeN(data->layers);
2247  }
2248 
2251 }
2252 
2254 {
2255  for (int i = 0; i < data->totlayer; i++) {
2256  CustomDataLayer *layer = &data->layers[i];
2257  if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
2258  continue;
2259  }
2260  customData_free_layer__internal(layer, totelem);
2261  }
2262 
2263  if (data->layers) {
2264  MEM_freeN(data->layers);
2265  }
2266 
2269 }
2270 
2272 {
2273  const LayerTypeInfo *typeInfo;
2274  int offset = 0;
2275 
2276  for (int i = 0; i < data->totlayer; i++) {
2277  typeInfo = layerType_getInfo(data->layers[i].type);
2278 
2279  data->layers[i].offset = offset;
2280  offset += typeInfo->size;
2281  }
2282 
2283  data->totsize = offset;
2285 }
2286 
2287 /* to use when we're in the middle of modifying layers */
2289 {
2290  for (int i = 0; i < data->totlayer; i++) {
2291  if (data->layers[i].type == type) {
2292  return i;
2293  }
2294  }
2295 
2296  return -1;
2297 }
2298 
2299 /* -------------------------------------------------------------------- */
2300 /* index values to access the layers (offset from the layer start) */
2301 
2303 {
2305  return data->typemap[type];
2306 }
2307 
2308 int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
2309 {
2310  BLI_assert(n >= 0);
2312 
2313  if (i != -1) {
2314  BLI_assert(i + n < data->totlayer);
2315  i = (data->layers[i + n].type == type) ? (i + n) : (-1);
2316  }
2317 
2318  return i;
2319 }
2320 
2321 int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
2322 {
2323  for (int i = 0; i < data->totlayer; i++) {
2324  if (data->layers[i].type == type) {
2325  if (STREQ(data->layers[i].name, name)) {
2326  return i;
2327  }
2328  }
2329  }
2330 
2331  return -1;
2332 }
2333 
2335 {
2336  const int layer_index = data->typemap[type];
2338  return (layer_index != -1) ? layer_index + data->layers[layer_index].active : -1;
2339 }
2340 
2342 {
2343  const int layer_index = data->typemap[type];
2345  return (layer_index != -1) ? layer_index + data->layers[layer_index].active_rnd : -1;
2346 }
2347 
2349 {
2350  const int layer_index = data->typemap[type];
2352  return (layer_index != -1) ? layer_index + data->layers[layer_index].active_clone : -1;
2353 }
2354 
2356 {
2357  const int layer_index = data->typemap[type];
2359  return (layer_index != -1) ? layer_index + data->layers[layer_index].active_mask : -1;
2360 }
2361 
2362 /* -------------------------------------------------------------------- */
2363 /* index values per layer type */
2364 
2365 int CustomData_get_named_layer(const struct CustomData *data, int type, const char *name)
2366 {
2367  const int named_index = CustomData_get_named_layer_index(data, type, name);
2368  const int layer_index = data->typemap[type];
2370  return (named_index != -1) ? named_index - layer_index : -1;
2371 }
2372 
2374 {
2375  const int layer_index = data->typemap[type];
2377  return (layer_index != -1) ? data->layers[layer_index].active : -1;
2378 }
2379 
2381 {
2382  const int layer_index = data->typemap[type];
2384  return (layer_index != -1) ? data->layers[layer_index].active_rnd : -1;
2385 }
2386 
2388 {
2389  const int layer_index = data->typemap[type];
2391  return (layer_index != -1) ? data->layers[layer_index].active_clone : -1;
2392 }
2393 
2395 {
2396  const int layer_index = data->typemap[type];
2398  return (layer_index != -1) ? data->layers[layer_index].active_mask : -1;
2399 }
2400 
2402 {
2403  for (int i = 0; i < data->totlayer; i++) {
2404  if (data->layers[i].type == type) {
2405  data->layers[i].active = n;
2406  }
2407  }
2408 }
2409 
2411 {
2412  for (int i = 0; i < data->totlayer; i++) {
2413  if (data->layers[i].type == type) {
2414  data->layers[i].active_rnd = n;
2415  }
2416  }
2417 }
2418 
2420 {
2421  for (int i = 0; i < data->totlayer; i++) {
2422  if (data->layers[i].type == type) {
2423  data->layers[i].active_clone = n;
2424  }
2425  }
2426 }
2427 
2429 {
2430  for (int i = 0; i < data->totlayer; i++) {
2431  if (data->layers[i].type == type) {
2432  data->layers[i].active_mask = n;
2433  }
2434  }
2435 }
2436 
2437 /* For using with an index from CustomData_get_active_layer_index and
2438  * CustomData_get_render_layer_index. */
2440 {
2441  for (int i = 0; i < data->totlayer; i++) {
2442  if (data->layers[i].type == type) {
2443  data->layers[i].active = n - i;
2444  }
2445  }
2446 }
2447 
2449 {
2450  for (int i = 0; i < data->totlayer; i++) {
2451  if (data->layers[i].type == type) {
2452  data->layers[i].active_rnd = n - i;
2453  }
2454  }
2455 }
2456 
2458 {
2459  for (int i = 0; i < data->totlayer; i++) {
2460  if (data->layers[i].type == type) {
2461  data->layers[i].active_clone = n - i;
2462  }
2463  }
2464 }
2465 
2467 {
2468  for (int i = 0; i < data->totlayer; i++) {
2469  if (data->layers[i].type == type) {
2470  data->layers[i].active_mask = n - i;
2471  }
2472  }
2473 }
2474 
2475 void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
2476 {
2477  for (int i = 0; i < data->totlayer; i++) {
2478  if (data->layers[i].type == type) {
2479  data->layers[i].flag |= flag;
2480  }
2481  }
2482 }
2483 
2484 void CustomData_clear_layer_flag(struct CustomData *data, int type, int flag)
2485 {
2486  const int nflag = ~flag;
2487 
2488  for (int i = 0; i < data->totlayer; i++) {
2489  if (data->layers[i].type == type) {
2490  data->layers[i].flag &= nflag;
2491  }
2492  }
2493 }
2494 
2495 static bool customData_resize(CustomData *data, int amount)
2496 {
2498  (data->maxlayer + amount), sizeof(*tmp), "CustomData->layers");
2499  if (!tmp) {
2500  return false;
2501  }
2502 
2503  data->maxlayer += amount;
2504  if (data->layers) {
2505  memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer);
2506  MEM_freeN(data->layers);
2507  }
2508  data->layers = tmp;
2509 
2510  return true;
2511 }
2512 
2514  int type,
2515  eCDAllocType alloctype,
2516  void *layerdata,
2517  int totelem,
2518  const char *name)
2519 {
2520  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2521  int flag = 0, index = data->totlayer;
2522  void *newlayerdata = NULL;
2523 
2524  /* Passing a layer-data to copy from with an alloctype that won't copy is
2525  * most likely a bug */
2526  BLI_assert(!layerdata || ELEM(alloctype, CD_ASSIGN, CD_DUPLICATE, CD_REFERENCE));
2527 
2528  if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
2529  return &data->layers[CustomData_get_layer_index(data, type)];
2530  }
2531 
2532  if (ELEM(alloctype, CD_ASSIGN, CD_REFERENCE)) {
2533  newlayerdata = layerdata;
2534  }
2535  else if (totelem > 0 && typeInfo->size > 0) {
2536  if (alloctype == CD_DUPLICATE && layerdata) {
2537  newlayerdata = MEM_malloc_arrayN((size_t)totelem, typeInfo->size, layerType_getName(type));
2538  }
2539  else {
2540  newlayerdata = MEM_calloc_arrayN((size_t)totelem, typeInfo->size, layerType_getName(type));
2541  }
2542 
2543  if (!newlayerdata) {
2544  return NULL;
2545  }
2546  }
2547 
2548  if (alloctype == CD_DUPLICATE && layerdata) {
2549  if (totelem > 0) {
2550  if (typeInfo->copy) {
2551  typeInfo->copy(layerdata, newlayerdata, totelem);
2552  }
2553  else {
2554  memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size);
2555  }
2556  }
2557  }
2558  else if (alloctype == CD_DEFAULT) {
2559  if (typeInfo->set_default) {
2560  typeInfo->set_default(newlayerdata, totelem);
2561  }
2562  }
2563  else if (alloctype == CD_REFERENCE) {
2564  flag |= CD_FLAG_NOFREE;
2565  }
2566 
2567  if (index >= data->maxlayer) {
2569  if (newlayerdata != layerdata) {
2570  MEM_freeN(newlayerdata);
2571  }
2572  return NULL;
2573  }
2574  }
2575 
2576  data->totlayer++;
2577 
2578  /* keep layers ordered by type */
2579  for (; index > 0 && data->layers[index - 1].type > type; index--) {
2580  data->layers[index] = data->layers[index - 1];
2581  }
2582 
2583  data->layers[index].type = type;
2584  data->layers[index].flag = flag;
2585  data->layers[index].data = newlayerdata;
2586 
2587  /* Set default name if none exists. Note we only call DATA_() once
2588  * we know there is a default name, to avoid overhead of locale lookups
2589  * in the depsgraph. */
2590  if (!name && typeInfo->defaultname) {
2591  name = DATA_(typeInfo->defaultname);
2592  }
2593 
2594  if (name) {
2595  BLI_strncpy(data->layers[index].name, name, sizeof(data->layers[index].name));
2597  }
2598  else {
2599  data->layers[index].name[0] = '\0';
2600  }
2601 
2602  if (index > 0 && data->layers[index - 1].type == type) {
2603  data->layers[index].active = data->layers[index - 1].active;
2604  data->layers[index].active_rnd = data->layers[index - 1].active_rnd;
2605  data->layers[index].active_clone = data->layers[index - 1].active_clone;
2606  data->layers[index].active_mask = data->layers[index - 1].active_mask;
2607  }
2608  else {
2609  data->layers[index].active = 0;
2610  data->layers[index].active_rnd = 0;
2611  data->layers[index].active_clone = 0;
2612  data->layers[index].active_mask = 0;
2613  }
2614 
2616 
2617  return &data->layers[index];
2618 }
2619 
2621  CustomData *data, int type, eCDAllocType alloctype, void *layerdata, int totelem)
2622 {
2623  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2624 
2626  data, type, alloctype, layerdata, totelem, typeInfo->defaultname);
2628 
2629  if (layer) {
2630  return layer->data;
2631  }
2632 
2633  return NULL;
2634 }
2635 
2636 /*same as above but accepts a name*/
2638  int type,
2639  eCDAllocType alloctype,
2640  void *layerdata,
2641  int totelem,
2642  const char *name)
2643 {
2645  data, type, alloctype, layerdata, totelem, name);
2647 
2648  if (layer) {
2649  return layer->data;
2650  }
2651 
2652  return NULL;
2653 }
2654 
2655 bool CustomData_free_layer(CustomData *data, int type, int totelem, int index)
2656 {
2657  const int index_first = CustomData_get_layer_index(data, type);
2658  const int n = index - index_first;
2659 
2660  BLI_assert(index >= index_first);
2661  if ((index_first == -1) || (n < 0)) {
2662  return false;
2663  }
2664  BLI_assert(data->layers[index].type == type);
2665 
2666  customData_free_layer__internal(&data->layers[index], totelem);
2667 
2668  for (int i = index + 1; i < data->totlayer; i++) {
2669  data->layers[i - 1] = data->layers[i];
2670  }
2671 
2672  data->totlayer--;
2673 
2674  /* if layer was last of type in array, set new active layer */
2676 
2677  if (i != -1) {
2678  /* don't decrement zero index */
2679  const int index_nonzero = n ? n : 1;
2680  CustomDataLayer *layer;
2681 
2682  for (layer = &data->layers[i]; i < data->totlayer && layer->type == type; i++, layer++) {
2683  if (layer->active >= index_nonzero) {
2684  layer->active--;
2685  }
2686  if (layer->active_rnd >= index_nonzero) {
2687  layer->active_rnd--;
2688  }
2689  if (layer->active_clone >= index_nonzero) {
2690  layer->active_clone--;
2691  }
2692  if (layer->active_mask >= index_nonzero) {
2693  layer->active_mask--;
2694  }
2695  }
2696  }
2697 
2698  if (data->totlayer <= data->maxlayer - CUSTOMDATA_GROW) {
2700  }
2701 
2703 
2704  return true;
2705 }
2706 
2708 {
2709  const int index = CustomData_get_active_layer_index(data, type);
2710  if (index == -1) {
2711  return false;
2712  }
2713  return CustomData_free_layer(data, type, totelem, index);
2714 }
2715 
2716 void CustomData_free_layers(CustomData *data, int type, int totelem)
2717 {
2718  const int index = CustomData_get_layer_index(data, type);
2719  while (CustomData_free_layer(data, type, totelem, index)) {
2720  /* pass */
2721  }
2722 }
2723 
2725 {
2726  return (CustomData_get_layer_index(data, type) != -1);
2727 }
2728 
2730 {
2731  int number = 0;
2732 
2733  for (int i = 0; i < data->totlayer; i++) {
2734  if (data->layers[i].type == type) {
2735  number++;
2736  }
2737  }
2738 
2739  return number;
2740 }
2741 
2743 {
2744  int number = 0;
2745 
2746  for (int i = 0; i < data->totlayer; i++) {
2747  if (mask & CD_TYPE_AS_MASK(data->layers[i].type)) {
2748  number++;
2749  }
2750  }
2751 
2752  return number;
2753 }
2754 
2756  const int layer_index,
2757  const int totelem)
2758 {
2759  if (layer_index == -1) {
2760  return NULL;
2761  }
2762 
2763  CustomDataLayer *layer = &data->layers[layer_index];
2764 
2765  if (layer->flag & CD_FLAG_NOFREE) {
2766  /* MEM_dupallocN won't work in case of complex layers, like e.g.
2767  * CD_MDEFORMVERT, which has pointers to allocated data...
2768  * So in case a custom copy function is defined, use it!
2769  */
2770  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
2771 
2772  if (typeInfo->copy) {
2773  void *dst_data = MEM_malloc_arrayN(
2774  (size_t)totelem, typeInfo->size, "CD duplicate ref layer");
2775  typeInfo->copy(layer->data, dst_data, totelem);
2776  layer->data = dst_data;
2777  }
2778  else {
2779  layer->data = MEM_dupallocN(layer->data);
2780  }
2781 
2782  layer->flag &= ~CD_FLAG_NOFREE;
2783  }
2784 
2785  return layer->data;
2786 }
2787 
2788 void *CustomData_duplicate_referenced_layer(CustomData *data, const int type, const int totelem)
2789 {
2790  /* get the layer index of the first layer of type */
2791  int layer_index = CustomData_get_active_layer_index(data, type);
2792 
2793  return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
2794 }
2795 
2797  const int type,
2798  const int n,
2799  const int totelem)
2800 {
2801  /* get the layer index of the desired layer */
2802  int layer_index = CustomData_get_layer_index_n(data, type, n);
2803 
2804  return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
2805 }
2806 
2808  const int type,
2809  const char *name,
2810  const int totelem)
2811 {
2812  /* get the layer index of the desired layer */
2813  int layer_index = CustomData_get_named_layer_index(data, type, name);
2814 
2815  return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
2816 }
2817 
2819 {
2820  for (int i = 0; i < data->totlayer; i++) {
2821  CustomDataLayer *layer = &data->layers[i];
2823  }
2824 }
2825 
2827 {
2828  /* get the layer index of the first layer of type */
2829  int layer_index = CustomData_get_active_layer_index(data, type);
2830  if (layer_index == -1) {
2831  return false;
2832  }
2833 
2834  CustomDataLayer *layer = &data->layers[layer_index];
2835 
2836  return (layer->flag & CD_FLAG_NOFREE) != 0;
2837 }
2838 
2840 {
2841  int i, j;
2842  bool changed = false;
2843  for (i = 0, j = 0; i < data->totlayer; i++) {
2844  CustomDataLayer *layer = &data->layers[i];
2845 
2846  if (i != j) {
2847  data->layers[j] = data->layers[i];
2848  }
2849 
2850  if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY) {
2851  customData_free_layer__internal(layer, totelem);
2852  changed = true;
2853  }
2854  else {
2855  j++;
2856  }
2857  }
2858 
2859  data->totlayer = j;
2860 
2861  if (data->totlayer <= data->maxlayer - CUSTOMDATA_GROW) {
2863  changed = true;
2864  }
2865 
2866  if (changed) {
2868  }
2869 }
2870 
2872 {
2873  for (int i = 0; i < data->totlayer; i++) {
2874  if (!(mask & CD_TYPE_AS_MASK(data->layers[i].type))) {
2875  data->layers[i].flag |= CD_FLAG_NOCOPY;
2876  }
2877  }
2878 }
2879 
2880 void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs, int count)
2881 {
2882  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2883 
2884  if (typeInfo->copy) {
2885  typeInfo->copy(src_data_ofs, dst_data_ofs, count);
2886  }
2887  else {
2888  memcpy(dst_data_ofs, src_data_ofs, (size_t)count * typeInfo->size);
2889  }
2890 }
2891 
2893  CustomData *dest,
2894  int src_layer_index,
2895  int dst_layer_index,
2896  int src_index,
2897  int dst_index,
2898  int count)
2899 {
2900  const LayerTypeInfo *typeInfo;
2901 
2902  const void *src_data = source->layers[src_layer_index].data;
2903  void *dst_data = dest->layers[dst_layer_index].data;
2904 
2905  typeInfo = layerType_getInfo(source->layers[src_layer_index].type);
2906 
2907  const size_t src_offset = (size_t)src_index * typeInfo->size;
2908  const size_t dst_offset = (size_t)dst_index * typeInfo->size;
2909 
2910  if (!count || !src_data || !dst_data) {
2911  if (count && !(src_data == NULL && dst_data == NULL)) {
2912  CLOG_WARN(&LOG,
2913  "null data for %s type (%p --> %p), skipping",
2914  layerType_getName(source->layers[src_layer_index].type),
2915  (void *)src_data,
2916  (void *)dst_data);
2917  }
2918  return;
2919  }
2920 
2921  if (typeInfo->copy) {
2922  typeInfo->copy(
2923  POINTER_OFFSET(src_data, src_offset), POINTER_OFFSET(dst_data, dst_offset), count);
2924  }
2925  else {
2926  memcpy(POINTER_OFFSET(dst_data, dst_offset),
2927  POINTER_OFFSET(src_data, src_offset),
2928  (size_t)count * typeInfo->size);
2929  }
2930 }
2931 
2933  const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
2934 {
2935  /* copies a layer at a time */
2936  for (int src_i = 0; src_i < source->totlayer; src_i++) {
2937 
2938  int dest_i = CustomData_get_named_layer_index(
2939  dest, source->layers[src_i].type, source->layers[src_i].name);
2940 
2941  /* if we found a matching layer, copy the data */
2942  if (dest_i != -1) {
2943  CustomData_copy_data_layer(source, dest, src_i, dest_i, source_index, dest_index, count);
2944  }
2945  }
2946 }
2947 
2949  const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
2950 {
2951  /* copies a layer at a time */
2952  int dest_i = 0;
2953  for (int src_i = 0; src_i < source->totlayer; src_i++) {
2954 
2955  /* find the first dest layer with type >= the source type
2956  * (this should work because layers are ordered by type)
2957  */
2958  while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
2959  dest_i++;
2960  }
2961 
2962  /* if there are no more dest layers, we're done */
2963  if (dest_i >= dest->totlayer) {
2964  return;
2965  }
2966 
2967  /* if we found a matching layer, copy the data */
2968  if (dest->layers[dest_i].type == source->layers[src_i].type) {
2969  CustomData_copy_data_layer(source, dest, src_i, dest_i, source_index, dest_index, count);
2970 
2971  /* if there are multiple source & dest layers of the same type,
2972  * we don't want to copy all source layers to the same dest, so
2973  * increment dest_i
2974  */
2975  dest_i++;
2976  }
2977  }
2978 }
2979 
2981  CustomData *destination,
2982  int type,
2983  int source_index,
2984  int destination_index,
2985  int count)
2986 {
2987  const int source_layer_index = CustomData_get_layer_index(source, type);
2988  if (source_layer_index == -1) {
2989  return;
2990  }
2991  const int destinaiton_layer_index = CustomData_get_layer_index(destination, type);
2992  if (destinaiton_layer_index == -1) {
2993  return;
2994  }
2996  destination,
2997  source_layer_index,
2998  destinaiton_layer_index,
2999  source_index,
3000  destination_index,
3001  count);
3002 }
3003 
3005 {
3006  for (int i = 0; i < data->totlayer; i++) {
3007  if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
3008  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
3009 
3010  if (typeInfo->free) {
3011  size_t offset = (size_t)index * typeInfo->size;
3012 
3013  typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
3014  }
3015  }
3016  }
3017 }
3018 
3019 #define SOURCE_BUF_SIZE 100
3020 
3033 void CustomData_interp(const CustomData *source,
3034  CustomData *dest,
3035  const int *src_indices,
3036  const float *weights,
3037  const float *sub_weights,
3038  int count,
3039  int dest_index)
3040 {
3041  if (count <= 0) {
3042  return;
3043  }
3044 
3045  const void *source_buf[SOURCE_BUF_SIZE];
3046  const void **sources = source_buf;
3047 
3048  /* Slow fallback in case we're interpolating a ridiculous number of elements. */
3049  if (count > SOURCE_BUF_SIZE) {
3050  sources = MEM_malloc_arrayN(count, sizeof(*sources), __func__);
3051  }
3052 
3053  /* If no weights are given, generate default ones to produce an average result. */
3054  float default_weights_buf[SOURCE_BUF_SIZE];
3055  float *default_weights = NULL;
3056  if (weights == NULL) {
3057  default_weights = (count > SOURCE_BUF_SIZE) ?
3058  MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) :
3059  default_weights_buf;
3060  copy_vn_fl(default_weights, count, 1.0f / count);
3061  weights = default_weights;
3062  }
3063 
3064  /* interpolates a layer at a time */
3065  int dest_i = 0;
3066  for (int src_i = 0; src_i < source->totlayer; src_i++) {
3067  const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers[src_i].type);
3068  if (!typeInfo->interp) {
3069  continue;
3070  }
3071 
3072  /* find the first dest layer with type >= the source type
3073  * (this should work because layers are ordered by type)
3074  */
3075  while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
3076  dest_i++;
3077  }
3078 
3079  /* if there are no more dest layers, we're done */
3080  if (dest_i >= dest->totlayer) {
3081  break;
3082  }
3083 
3084  /* if we found a matching layer, copy the data */
3085  if (dest->layers[dest_i].type == source->layers[src_i].type) {
3086  void *src_data = source->layers[src_i].data;
3087 
3088  for (int j = 0; j < count; j++) {
3089  sources[j] = POINTER_OFFSET(src_data, (size_t)src_indices[j] * typeInfo->size);
3090  }
3091 
3092  typeInfo->interp(
3093  sources,
3094  weights,
3095  sub_weights,
3096  count,
3097  POINTER_OFFSET(dest->layers[dest_i].data, (size_t)dest_index * typeInfo->size));
3098 
3099  /* if there are multiple source & dest layers of the same type,
3100  * we don't want to copy all source layers to the same dest, so
3101  * increment dest_i
3102  */
3103  dest_i++;
3104  }
3105  }
3106 
3107  if (count > SOURCE_BUF_SIZE) {
3108  MEM_freeN((void *)sources);
3109  }
3110  if (!ELEM(default_weights, NULL, default_weights_buf)) {
3111  MEM_freeN(default_weights);
3112  }
3113 }
3114 
3122 void CustomData_swap_corners(struct CustomData *data, int index, const int *corner_indices)
3123 {
3124  for (int i = 0; i < data->totlayer; i++) {
3125  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
3126 
3127  if (typeInfo->swap) {
3128  const size_t offset = (size_t)index * typeInfo->size;
3129 
3130  typeInfo->swap(POINTER_OFFSET(data->layers[i].data, offset), corner_indices);
3131  }
3132  }
3133 }
3134 
3138 void CustomData_swap(struct CustomData *data, const int index_a, const int index_b)
3139 {
3140  char buff_static[256];
3141 
3142  if (index_a == index_b) {
3143  return;
3144  }
3145 
3146  for (int i = 0; i < data->totlayer; i++) {
3147  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
3148  const size_t size = typeInfo->size;
3149  const size_t offset_a = size * index_a;
3150  const size_t offset_b = size * index_b;
3151 
3152  void *buff = size <= sizeof(buff_static) ? buff_static : MEM_mallocN(size, __func__);
3153  memcpy(buff, POINTER_OFFSET(data->layers[i].data, offset_a), size);
3154  memcpy(POINTER_OFFSET(data->layers[i].data, offset_a),
3155  POINTER_OFFSET(data->layers[i].data, offset_b),
3156  size);
3157  memcpy(POINTER_OFFSET(data->layers[i].data, offset_b), buff, size);
3158 
3159  if (buff != buff_static) {
3160  MEM_freeN(buff);
3161  }
3162  }
3163 }
3164 
3165 void *CustomData_get(const CustomData *data, int index, int type)
3166 {
3167  BLI_assert(index >= 0);
3168 
3169  /* get the layer index of the active layer of type */
3170  int layer_index = CustomData_get_active_layer_index(data, type);
3171  if (layer_index == -1) {
3172  return NULL;
3173  }
3174 
3175  /* get the offset of the desired element */
3176  const size_t offset = (size_t)index * layerType_getInfo(type)->size;
3177 
3178  return POINTER_OFFSET(data->layers[layer_index].data, offset);
3179 }
3180 
3181 void *CustomData_get_n(const CustomData *data, int type, int index, int n)
3182 {
3183  BLI_assert(index >= 0 && n >= 0);
3184 
3185  /* get the layer index of the first layer of type */
3186  int layer_index = data->typemap[type];
3187  if (layer_index == -1) {
3188  return NULL;
3189  }
3190 
3191  const size_t offset = (size_t)index * layerType_getInfo(type)->size;
3192  return POINTER_OFFSET(data->layers[layer_index + n].data, offset);
3193 }
3194 
3196 {
3197  /* get the layer index of the active layer of type */
3198  int layer_index = CustomData_get_active_layer_index(data, type);
3199  if (layer_index == -1) {
3200  return NULL;
3201  }
3202 
3203  return data->layers[layer_index].data;
3204 }
3205 
3206 void *CustomData_get_layer_n(const CustomData *data, int type, int n)
3207 {
3208  /* get the layer index of the active layer of type */
3209  int layer_index = CustomData_get_layer_index_n(data, type, n);
3210  if (layer_index == -1) {
3211  return NULL;
3212  }
3213 
3214  return data->layers[layer_index].data;
3215 }
3216 
3217 void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
3218 {
3219  int layer_index = CustomData_get_named_layer_index(data, type, name);
3220  if (layer_index == -1) {
3221  return NULL;
3222  }
3223 
3224  return data->layers[layer_index].data;
3225 }
3226 
3228 {
3229  /* get the layer index of the active layer of type */
3230  int layer_index = CustomData_get_active_layer_index(data, type);
3231  if (layer_index == -1) {
3232  return -1;
3233  }
3234 
3235  return data->layers[layer_index].offset;
3236 }
3237 
3239 {
3240  /* get the layer index of the active layer of type */
3241  int layer_index = CustomData_get_layer_index_n(data, type, n);
3242  if (layer_index == -1) {
3243  return -1;
3244  }
3245 
3246  return data->layers[layer_index].offset;
3247 }
3248 
3249 bool CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
3250 {
3251  /* get the layer index of the first layer of type */
3252  const int layer_index = CustomData_get_layer_index_n(data, type, n);
3253 
3254  if ((layer_index == -1) || !name) {
3255  return false;
3256  }
3257 
3258  BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[layer_index].name));
3259 
3260  return true;
3261 }
3262 
3263 const char *CustomData_get_layer_name(const CustomData *data, int type, int n)
3264 {
3265  const int layer_index = CustomData_get_layer_index_n(data, type, n);
3266 
3267  return (layer_index == -1) ? NULL : data->layers[layer_index].name;
3268 }
3269 
3270 void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
3271 {
3272  /* get the layer index of the first layer of type */
3273  int layer_index = CustomData_get_active_layer_index(data, type);
3274 
3275  if (layer_index == -1) {
3276  return NULL;
3277  }
3278 
3279  data->layers[layer_index].data = ptr;
3280 
3281  return ptr;
3282 }
3283 
3284 void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr)
3285 {
3286  /* get the layer index of the first layer of type */
3287  int layer_index = CustomData_get_layer_index_n(data, type, n);
3288  if (layer_index == -1) {
3289  return NULL;
3290  }
3291 
3292  data->layers[layer_index].data = ptr;
3293 
3294  return ptr;
3295 }
3296 
3297 void CustomData_set(const CustomData *data, int index, int type, const void *source)
3298 {
3299  void *dest = CustomData_get(data, index, type);
3300  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3301 
3302  if (!dest) {
3303  return;
3304  }
3305 
3306  if (typeInfo->copy) {
3307  typeInfo->copy(source, dest, 1);
3308  }
3309  else {
3310  memcpy(dest, source, typeInfo->size);
3311  }
3312 }
3313 
3314 /* BMesh functions */
3315 /* needed to convert to/from different face reps */
3316 void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *ldata, int totloop)
3317 {
3318  for (int i = 0; i < fdata->totlayer; i++) {
3319  if (fdata->layers[i].type == CD_MTFACE) {
3321  ldata, CD_MLOOPUV, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
3322  }
3323  else if (fdata->layers[i].type == CD_MCOL) {
3325  ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
3326  }
3327  else if (fdata->layers[i].type == CD_MDISPS) {
3329  ldata, CD_MDISPS, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
3330  }
3331  else if (fdata->layers[i].type == CD_TESSLOOPNORMAL) {
3333  ldata, CD_NORMAL, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
3334  }
3335  }
3336 }
3337 
3338 void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *ldata, int total)
3339 {
3340  /* avoid accumulating extra layers */
3341  BLI_assert(!CustomData_from_bmeshpoly_test(fdata, ldata, false));
3342 
3343  for (int i = 0; i < ldata->totlayer; i++) {
3344  if (ldata->layers[i].type == CD_MLOOPUV) {
3345  CustomData_add_layer_named(fdata, CD_MTFACE, CD_CALLOC, NULL, total, ldata->layers[i].name);
3346  }
3347  if (ldata->layers[i].type == CD_MLOOPCOL) {
3348  CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
3349  }
3350  else if (ldata->layers[i].type == CD_PREVIEW_MLOOPCOL) {
3352  fdata, CD_PREVIEW_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
3353  }
3354  else if (ldata->layers[i].type == CD_ORIGSPACE_MLOOP) {
3356  fdata, CD_ORIGSPACE, CD_CALLOC, NULL, total, ldata->layers[i].name);
3357  }
3358  else if (ldata->layers[i].type == CD_NORMAL) {
3360  fdata, CD_TESSLOOPNORMAL, CD_CALLOC, NULL, total, ldata->layers[i].name);
3361  }
3362  else if (ldata->layers[i].type == CD_TANGENT) {
3363  CustomData_add_layer_named(fdata, CD_TANGENT, CD_CALLOC, NULL, total, ldata->layers[i].name);
3364  }
3365  }
3366 
3368 }
3369 
3370 #ifndef NDEBUG
3377 bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *ldata, bool fallback)
3378 {
3379  int a_num = 0, b_num = 0;
3380 # define LAYER_CMP(l_a, t_a, l_b, t_b) \
3381  ((a_num += CustomData_number_of_layers(l_a, t_a)) == \
3382  (b_num += CustomData_number_of_layers(l_b, t_b)))
3383 
3384  if (!LAYER_CMP(ldata, CD_MLOOPUV, fdata, CD_MTFACE)) {
3385  return false;
3386  }
3387  if (!LAYER_CMP(ldata, CD_MLOOPCOL, fdata, CD_MCOL)) {
3388  return false;
3389  }
3390  if (!LAYER_CMP(ldata, CD_PREVIEW_MLOOPCOL, fdata, CD_PREVIEW_MCOL)) {
3391  return false;
3392  }
3393  if (!LAYER_CMP(ldata, CD_ORIGSPACE_MLOOP, fdata, CD_ORIGSPACE)) {
3394  return false;
3395  }
3396  if (!LAYER_CMP(ldata, CD_NORMAL, fdata, CD_TESSLOOPNORMAL)) {
3397  return false;
3398  }
3399  if (!LAYER_CMP(ldata, CD_TANGENT, fdata, CD_TANGENT)) {
3400  return false;
3401  }
3402 
3403 # undef LAYER_CMP
3404 
3405  /* if no layers are on either CustomData's,
3406  * then there was nothing to do... */
3407  return a_num ? true : fallback;
3408 }
3409 #endif
3410 
3412 {
3413  int act;
3414 
3415  if (CustomData_has_layer(ldata, CD_MLOOPUV)) {
3418 
3421 
3422  act = CustomData_get_clone_layer(ldata, CD_MLOOPUV);
3424 
3427  }
3428 
3429  if (CustomData_has_layer(ldata, CD_MLOOPCOL)) {
3431  CustomData_set_layer_active(fdata, CD_MCOL, act);
3432 
3434  CustomData_set_layer_render(fdata, CD_MCOL, act);
3435 
3437  CustomData_set_layer_clone(fdata, CD_MCOL, act);
3438 
3441  }
3442 }
3443 
3444 /* update active indices for active/render/clone/stencil custom data layers
3445  * based on indices from fdata layers
3446  * used by do_versions in readfile.c when creating pdata and ldata for pre-bmesh
3447  * meshes and needed to preserve active/render/clone/stencil flags set in pre-bmesh files
3448  */
3450 {
3451  int act;
3452 
3453  if (CustomData_has_layer(fdata, CD_MTFACE)) {
3454  act = CustomData_get_active_layer(fdata, CD_MTFACE);
3456 
3457  act = CustomData_get_render_layer(fdata, CD_MTFACE);
3459 
3460  act = CustomData_get_clone_layer(fdata, CD_MTFACE);
3462 
3465  }
3466 
3467  if (CustomData_has_layer(fdata, CD_MCOL)) {
3468  act = CustomData_get_active_layer(fdata, CD_MCOL);
3470 
3471  act = CustomData_get_render_layer(fdata, CD_MCOL);
3473 
3474  act = CustomData_get_clone_layer(fdata, CD_MCOL);
3476 
3477  act = CustomData_get_stencil_layer(fdata, CD_MCOL);
3479  }
3480 }
3481 
3482 void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype)
3483 {
3484  int chunksize;
3485 
3486  /* Dispose old pools before calling here to avoid leaks */
3487  BLI_assert(data->pool == NULL);
3488 
3489  switch (htype) {
3490  case BM_VERT:
3491  chunksize = bm_mesh_chunksize_default.totvert;
3492  break;
3493  case BM_EDGE:
3494  chunksize = bm_mesh_chunksize_default.totedge;
3495  break;
3496  case BM_LOOP:
3497  chunksize = bm_mesh_chunksize_default.totloop;
3498  break;
3499  case BM_FACE:
3500  chunksize = bm_mesh_chunksize_default.totface;
3501  break;
3502  default:
3503  BLI_assert(0);
3504  chunksize = 512;
3505  break;
3506  }
3507 
3508  /* If there are no layers, no pool is needed just yet */
3509  if (data->totlayer) {
3510  data->pool = BLI_mempool_create(data->totsize, totelem, chunksize, BLI_MEMPOOL_NOP);
3511  }
3512 }
3513 
3515  CustomData *dest,
3517  eCDAllocType alloctype,
3518  BMesh *bm,
3519  const char htype)
3520 {
3521 
3522  if (CustomData_number_of_layers_typemask(source, mask) == 0) {
3523  return false;
3524  }
3525 
3526  /* copy old layer description so that old data can be copied into
3527  * the new allocation */
3528  CustomData destold = *dest;
3529  if (destold.layers) {
3530  destold.layers = MEM_dupallocN(destold.layers);
3531  }
3532 
3533  if (CustomData_merge(source, dest, mask, alloctype, 0) == false) {
3534  if (destold.layers) {
3535  MEM_freeN(destold.layers);
3536  }
3537  return false;
3538  }
3539 
3540  int iter_type;
3541  int totelem;
3542  switch (htype) {
3543  case BM_VERT:
3544  iter_type = BM_VERTS_OF_MESH;
3545  totelem = bm->totvert;
3546  break;
3547  case BM_EDGE:
3548  iter_type = BM_EDGES_OF_MESH;
3549  totelem = bm->totedge;
3550  break;
3551  case BM_LOOP:
3552  iter_type = BM_LOOPS_OF_FACE;
3553  totelem = bm->totloop;
3554  break;
3555  case BM_FACE:
3556  iter_type = BM_FACES_OF_MESH;
3557  totelem = bm->totface;
3558  break;
3559  default: /* should never happen */
3560  BLI_assert(!"invalid type given");
3561  iter_type = BM_VERTS_OF_MESH;
3562  totelem = bm->totvert;
3563  break;
3564  }
3565 
3566  dest->pool = NULL;
3567  CustomData_bmesh_init_pool(dest, totelem, htype);
3568 
3569  if (iter_type != BM_LOOPS_OF_FACE) {
3570  BMHeader *h;
3571  BMIter iter;
3572  /*ensure all current elements follow new customdata layout*/
3573  BM_ITER_MESH (h, &iter, bm, iter_type) {
3574  void *tmp = NULL;
3575  CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
3576  CustomData_bmesh_free_block(&destold, &h->data);
3577  h->data = tmp;
3578  }
3579  }
3580  else {
3581  BMFace *f;
3582  BMLoop *l;
3583  BMIter iter;
3584  BMIter liter;
3585 
3586  /*ensure all current elements follow new customdata layout*/
3587  BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
3588  BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
3589  void *tmp = NULL;
3590  CustomData_bmesh_copy_data(&destold, dest, l->head.data, &tmp);
3591  CustomData_bmesh_free_block(&destold, &l->head.data);
3592  l->head.data = tmp;
3593  }
3594  }
3595  }
3596 
3597  if (destold.pool) {
3598  BLI_mempool_destroy(destold.pool);
3599  }
3600  if (destold.layers) {
3601  MEM_freeN(destold.layers);
3602  }
3603  return true;
3604 }
3605 
3607 {
3608  if (*block == NULL) {
3609  return;
3610  }
3611 
3612  for (int i = 0; i < data->totlayer; i++) {
3613  if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
3614  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
3615 
3616  if (typeInfo->free) {
3617  int offset = data->layers[i].offset;
3618  typeInfo->free(POINTER_OFFSET(*block, offset), 1, typeInfo->size);
3619  }
3620  }
3621  }
3622 
3623  if (data->totsize) {
3624  BLI_mempool_free(data->pool, *block);
3625  }
3626 
3627  *block = NULL;
3628 }
3629 
3634 {
3635  if (block == NULL) {
3636  return;
3637  }
3638  for (int i = 0; i < data->totlayer; i++) {
3639  if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
3640  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
3641  if (typeInfo->free) {
3642  const size_t offset = data->layers[i].offset;
3643  typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
3644  }
3645  }
3646  }
3647  if (data->totsize) {
3648  memset(block, 0, data->totsize);
3649  }
3650 }
3651 
3652 static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
3653 {
3654  if (*block) {
3656  }
3657 
3658  if (data->totsize > 0) {
3659  *block = BLI_mempool_alloc(data->pool);
3660  }
3661  else {
3662  *block = NULL;
3663  }
3664 }
3665 
3670  void *block,
3671  const CustomDataMask mask_exclude)
3672 {
3673  if (block == NULL) {
3674  return;
3675  }
3676  for (int i = 0; i < data->totlayer; i++) {
3677  if ((CD_TYPE_AS_MASK(data->layers[i].type) & mask_exclude) == 0) {
3678  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
3679  const size_t offset = data->layers[i].offset;
3680  if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
3681  if (typeInfo->free) {
3682  typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
3683  }
3684  }
3685  memset(POINTER_OFFSET(block, offset), 0, typeInfo->size);
3686  }
3687  }
3688 }
3689 
3690 static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
3691 {
3692  int offset = data->layers[n].offset;
3693  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
3694 
3695  if (typeInfo->set_default) {
3696  typeInfo->set_default(POINTER_OFFSET(*block, offset), 1);
3697  }
3698  else {
3699  memset(POINTER_OFFSET(*block, offset), 0, typeInfo->size);
3700  }
3701 }
3702 
3704 {
3705  if (*block == NULL) {
3707  }
3708 
3709  for (int i = 0; i < data->totlayer; i++) {
3711  }
3712 }
3713 
3715  CustomData *dest,
3716  void *src_block,
3717  void **dest_block,
3718  const CustomDataMask mask_exclude)
3719 {
3720  /* Note that having a version of this function without a 'mask_exclude'
3721  * would cause too much duplicate code, so add a check instead. */
3722  const bool no_mask = (mask_exclude == 0);
3723 
3724  if (*dest_block == NULL) {
3725  CustomData_bmesh_alloc_block(dest, dest_block);
3726  if (*dest_block) {
3727  memset(*dest_block, 0, dest->totsize);
3728  }
3729  }
3730 
3731  /* copies a layer at a time */
3732  int dest_i = 0;
3733  for (int src_i = 0; src_i < source->totlayer; src_i++) {
3734 
3735  /* find the first dest layer with type >= the source type
3736  * (this should work because layers are ordered by type)
3737  */
3738  while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
3739  CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
3740  dest_i++;
3741  }
3742 
3743  /* if there are no more dest layers, we're done */
3744  if (dest_i >= dest->totlayer) {
3745  return;
3746  }
3747 
3748  /* if we found a matching layer, copy the data */
3749  if (dest->layers[dest_i].type == source->layers[src_i].type &&
3750  STREQ(dest->layers[dest_i].name, source->layers[src_i].name)) {
3751  if (no_mask || ((CD_TYPE_AS_MASK(dest->layers[dest_i].type) & mask_exclude) == 0)) {
3752  const void *src_data = POINTER_OFFSET(src_block, source->layers[src_i].offset);
3753  void *dest_data = POINTER_OFFSET(*dest_block, dest->layers[dest_i].offset);
3754  const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers[src_i].type);
3755  if (typeInfo->copy) {
3756  typeInfo->copy(src_data, dest_data, 1);
3757  }
3758  else {
3759  memcpy(dest_data, src_data, typeInfo->size);
3760  }
3761  }
3762 
3763  /* if there are multiple source & dest layers of the same type,
3764  * we don't want to copy all source layers to the same dest, so
3765  * increment dest_i
3766  */
3767  dest_i++;
3768  }
3769  }
3770 
3771  while (dest_i < dest->totlayer) {
3772  CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
3773  dest_i++;
3774  }
3775 }
3776 
3778  CustomData *dest,
3779  void *src_block,
3780  void **dest_block)
3781 {
3782  CustomData_bmesh_copy_data_exclude_by_type(source, dest, src_block, dest_block, 0);
3783 }
3784 
3785 /* BMesh Custom Data Functions.
3786  * Should replace edit-mesh ones with these as well, due to more efficient memory alloc.
3787  */
3788 void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
3789 {
3790  /* get the layer index of the first layer of type */
3791  int layer_index = CustomData_get_active_layer_index(data, type);
3792  if (layer_index == -1) {
3793  return NULL;
3794  }
3795 
3796  return POINTER_OFFSET(block, data->layers[layer_index].offset);
3797 }
3798 
3799 void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
3800 {
3801  /* get the layer index of the first layer of type */
3802  int layer_index = CustomData_get_layer_index(data, type);
3803  if (layer_index == -1) {
3804  return NULL;
3805  }
3806 
3807  return POINTER_OFFSET(block, data->layers[layer_index + n].offset);
3808 }
3809 
3810 /*gets from the layer at physical index n, note: doesn't check type.*/
3811 void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
3812 {
3813  if (n < 0 || n >= data->totlayer) {
3814  return NULL;
3815  }
3816 
3817  return POINTER_OFFSET(block, data->layers[n].offset);
3818 }
3819 
3820 bool CustomData_layer_has_math(const struct CustomData *data, int layer_n)
3821 {
3822  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layer_n].type);
3823 
3824  if (typeInfo->equal && typeInfo->add && typeInfo->multiply && typeInfo->initminmax &&
3825  typeInfo->dominmax) {
3826  return true;
3827  }
3828 
3829  return false;
3830 }
3831 
3832 bool CustomData_layer_has_interp(const struct CustomData *data, int layer_n)
3833 {
3834  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layer_n].type);
3835 
3836  if (typeInfo->interp) {
3837  return true;
3838  }
3839 
3840  return false;
3841 }
3842 
3844 {
3845  /* interpolates a layer at a time */
3846  for (int i = 0; i < data->totlayer; i++) {
3847  if (CustomData_layer_has_math(data, i)) {
3848  return true;
3849  }
3850  }
3851 
3852  return false;
3853 }
3854 
3855 /* a non bmesh version would have to check layer->data */
3857 {
3858  for (int i = 0; i < data->totlayer; i++) {
3859  if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
3860  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
3861  if (typeInfo->free) {
3862  return true;
3863  }
3864  }
3865  }
3866  return false;
3867 }
3868 
3870 {
3871  /* interpolates a layer at a time */
3872  for (int i = 0; i < data->totlayer; i++) {
3874  return true;
3875  }
3876  }
3877 
3878  return false;
3879 }
3880 
3882 {
3883  for (int i = 0; i < data->totlayer; i++) {
3884  if (data->layers[i].flag & CD_FLAG_NOFREE) {
3885  return true;
3886  }
3887  }
3888  return false;
3889 }
3890 
3891 /* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
3892  * another, while not overwriting anything else (e.g. flags)*/
3893 void CustomData_data_copy_value(int type, const void *source, void *dest)
3894 {
3895  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3896 
3897  if (!dest) {
3898  return;
3899  }
3900 
3901  if (typeInfo->copyvalue) {
3902  typeInfo->copyvalue(source, dest, CDT_MIX_NOMIX, 0.0f);
3903  }
3904  else {
3905  memcpy(dest, source, typeInfo->size);
3906  }
3907 }
3908 
3909 /* Mixes the "value" (e.g. mloopuv uv or mloopcol colors) from one block into
3910  * another, while not overwriting anything else (e.g. flags)*/
3912  int type, const void *source, void *dest, const int mixmode, const float mixfactor)
3913 {
3914  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3915 
3916  if (!dest) {
3917  return;
3918  }
3919 
3920  if (typeInfo->copyvalue) {
3921  typeInfo->copyvalue(source, dest, mixmode, mixfactor);
3922  }
3923  else {
3924  /* Mere copy if no advanced interpolation is supported. */
3925  memcpy(dest, source, typeInfo->size);
3926  }
3927 }
3928 
3929 bool CustomData_data_equals(int type, const void *data1, const void *data2)
3930 {
3931  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3932 
3933  if (typeInfo->equal) {
3934  return typeInfo->equal(data1, data2);
3935  }
3936 
3937  return !memcmp(data1, data2, typeInfo->size);
3938 }
3939 
3940 void CustomData_data_initminmax(int type, void *min, void *max)
3941 {
3942  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3943 
3944  if (typeInfo->initminmax) {
3945  typeInfo->initminmax(min, max);
3946  }
3947 }
3948 
3949 void CustomData_data_dominmax(int type, const void *data, void *min, void *max)
3950 {
3951  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3952 
3953  if (typeInfo->dominmax) {
3954  typeInfo->dominmax(data, min, max);
3955  }
3956 }
3957 
3958 void CustomData_data_multiply(int type, void *data, float fac)
3959 {
3960  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3961 
3962  if (typeInfo->multiply) {
3963  typeInfo->multiply(data, fac);
3964  }
3965 }
3966 
3967 void CustomData_data_add(int type, void *data1, const void *data2)
3968 {
3969  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3970 
3971  if (typeInfo->add) {
3972  typeInfo->add(data1, data2);
3973  }
3974 }
3975 
3976 void CustomData_bmesh_set(const CustomData *data, void *block, int type, const void *source)
3977 {
3978  void *dest = CustomData_bmesh_get(data, block, type);
3979  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3980 
3981  if (!dest) {
3982  return;
3983  }
3984 
3985  if (typeInfo->copy) {
3986  typeInfo->copy(source, dest, 1);
3987  }
3988  else {
3989  memcpy(dest, source, typeInfo->size);
3990  }
3991 }
3992 
3993 void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, const void *source)
3994 {
3995  void *dest = CustomData_bmesh_get_n(data, block, type, n);
3996  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
3997 
3998  if (!dest) {
3999  return;
4000  }
4001 
4002  if (typeInfo->copy) {
4003  typeInfo->copy(source, dest, 1);
4004  }
4005  else {
4006  memcpy(dest, source, typeInfo->size);
4007  }
4008 }
4009 
4010 void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, const void *source)
4011 {
4012  void *dest = CustomData_bmesh_get_layer_n(data, block, n);
4013  const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
4014 
4015  if (!dest) {
4016  return;
4017  }
4018 
4019  if (typeInfo->copy) {
4020  typeInfo->copy(source, dest, 1);
4021  }
4022  else {
4023  memcpy(dest, source, typeInfo->size);
4024  }
4025 }
4026 
4032  const void **src_blocks_ofs,
4033  const float *weights,
4034  const float *sub_weights,
4035  int count,
4036  void *dst_block_ofs,
4037  int n)
4038 {
4039  BLI_assert(weights != NULL);
4040  BLI_assert(count > 0);
4041 
4042  CustomDataLayer *layer = &data->layers[n];
4043  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4044 
4045  typeInfo->interp(src_blocks_ofs, weights, sub_weights, count, dst_block_ofs);
4046 }
4047 
4049  const void **src_blocks,
4050  const float *weights,
4051  const float *sub_weights,
4052  int count,
4053  void *dst_block)
4054 {
4055  if (count <= 0) {
4056  return;
4057  }
4058 
4059  void *source_buf[SOURCE_BUF_SIZE];
4060  const void **sources = (const void **)source_buf;
4061 
4062  /* Slow fallback in case we're interpolating a ridiculous number of elements. */
4063  if (count > SOURCE_BUF_SIZE) {
4064  sources = MEM_malloc_arrayN(count, sizeof(*sources), __func__);
4065  }
4066 
4067  /* If no weights are given, generate default ones to produce an average result. */
4068  float default_weights_buf[SOURCE_BUF_SIZE];
4069  float *default_weights = NULL;
4070  if (weights == NULL) {
4071  default_weights = (count > SOURCE_BUF_SIZE) ?
4072  MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) :
4073  default_weights_buf;
4074  copy_vn_fl(default_weights, count, 1.0f / count);
4075  weights = default_weights;
4076  }
4077 
4078  /* interpolates a layer at a time */
4079  for (int i = 0; i < data->totlayer; i++) {
4080  CustomDataLayer *layer = &data->layers[i];
4081  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4082  if (typeInfo->interp) {
4083  for (int j = 0; j < count; j++) {
4084  sources[j] = POINTER_OFFSET(src_blocks[j], layer->offset);
4085  }
4087  data, sources, weights, sub_weights, count, POINTER_OFFSET(dst_block, layer->offset), i);
4088  }
4089  }
4090 
4091  if (count > SOURCE_BUF_SIZE) {
4092  MEM_freeN((void *)sources);
4093  }
4094  if (!ELEM(default_weights, NULL, default_weights_buf)) {
4095  MEM_freeN(default_weights);
4096  }
4097 }
4098 
4105  CustomData *dest,
4106  int src_index,
4107  void **dest_block,
4108  bool use_default_init)
4109 {
4110  if (*dest_block == NULL) {
4111  CustomData_bmesh_alloc_block(dest, dest_block);
4112  }
4113 
4114  /* copies a layer at a time */
4115  int dest_i = 0;
4116  for (int src_i = 0; src_i < source->totlayer; src_i++) {
4117 
4118  /* find the first dest layer with type >= the source type
4119  * (this should work because layers are ordered by type)
4120  */
4121  while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
4122  if (use_default_init) {
4123  CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
4124  }
4125  dest_i++;
4126  }
4127 
4128  /* if there are no more dest layers, we're done */
4129  if (dest_i >= dest->totlayer) {
4130  break;
4131  }
4132 
4133  /* if we found a matching layer, copy the data */
4134  if (dest->layers[dest_i].type == source->layers[src_i].type) {
4135  int offset = dest->layers[dest_i].offset;
4136  const void *src_data = source->layers[src_i].data;
4137  void *dest_data = POINTER_OFFSET(*dest_block, offset);
4138 
4139  const LayerTypeInfo *typeInfo = layerType_getInfo(dest->layers[dest_i].type);
4140  const size_t src_offset = (size_t)src_index * typeInfo->size;
4141 
4142  if (typeInfo->copy) {
4143  typeInfo->copy(POINTER_OFFSET(src_data, src_offset), dest_data, 1);
4144  }
4145  else {
4146  memcpy(dest_data, POINTER_OFFSET(src_data, src_offset), typeInfo->size);
4147  }
4148 
4149  /* if there are multiple source & dest layers of the same type,
4150  * we don't want to copy all source layers to the same dest, so
4151  * increment dest_i
4152  */
4153  dest_i++;
4154  }
4155  }
4156 
4157  if (use_default_init) {
4158  while (dest_i < dest->totlayer) {
4159  CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
4160  dest_i++;
4161  }
4162  }
4163 }
4164 
4166  CustomData *dest,
4167  void *src_block,
4168  int dest_index)
4169 {
4170  /* copies a layer at a time */
4171  int dest_i = 0;
4172  for (int src_i = 0; src_i < source->totlayer; src_i++) {
4173 
4174  /* find the first dest layer with type >= the source type
4175  * (this should work because layers are ordered by type)
4176  */
4177  while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
4178  dest_i++;
4179  }
4180 
4181  /* if there are no more dest layers, we're done */
4182  if (dest_i >= dest->totlayer) {
4183  return;
4184  }
4185 
4186  /* if we found a matching layer, copy the data */
4187  if (dest->layers[dest_i].type == source->layers[src_i].type) {
4188  const LayerTypeInfo *typeInfo = layerType_getInfo(dest->layers[dest_i].type);
4189  int offset = source->layers[src_i].offset;
4190  const void *src_data = POINTER_OFFSET(src_block, offset);
4191  void *dst_data = POINTER_OFFSET(dest->layers[dest_i].data,
4192  (size_t)dest_index * typeInfo->size);
4193 
4194  if (typeInfo->copy) {
4195  typeInfo->copy(src_data, dst_data, 1);
4196  }
4197  else {
4198  memcpy(dst_data, src_data, typeInfo->size);
4199  }
4200 
4201  /* if there are multiple source & dest layers of the same type,
4202  * we don't want to copy all source layers to the same dest, so
4203  * increment dest_i
4204  */
4205  dest_i++;
4206  }
4207  }
4208 }
4209 
4210 void CustomData_file_write_info(int type, const char **r_struct_name, int *r_struct_num)
4211 {
4212  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
4213 
4214  *r_struct_name = typeInfo->structname;
4215  *r_struct_num = typeInfo->structnum;
4216 }
4217 
4238  CustomDataLayer **r_write_layers,
4239  CustomDataLayer *write_layers_buff,
4240  size_t write_layers_size)
4241 {
4242  CustomDataLayer *write_layers = write_layers_buff;
4243  const size_t chunk_size = (write_layers_size > 0) ? write_layers_size : CD_TEMP_CHUNK_SIZE;
4244 
4245  const int totlayer = data->totlayer;
4246  int i, j;
4247 
4248  for (i = 0, j = 0; i < totlayer; i++) {
4249  CustomDataLayer *layer = &data->layers[i];
4250  if (layer->flag & CD_FLAG_NOCOPY) { /* Layers with this flag set are not written to file. */
4251  data->totlayer--;
4252  /* CLOG_WARN(&LOG, "skipping layer %p (%s)", layer, layer->name); */
4253  }
4254  else {
4255  if (UNLIKELY((size_t)j >= write_layers_size)) {
4256  if (write_layers == write_layers_buff) {
4257  write_layers = MEM_malloc_arrayN(
4258  (write_layers_size + chunk_size), sizeof(*write_layers), __func__);
4259  if (write_layers_buff) {
4260  memcpy(write_layers, write_layers_buff, sizeof(*write_layers) * write_layers_size);
4261  }
4262  }
4263  else {
4264  write_layers = MEM_reallocN(write_layers,
4265  sizeof(*write_layers) * (write_layers_size + chunk_size));
4266  }
4267  write_layers_size += chunk_size;
4268  }
4269  write_layers[j++] = *layer;
4270  }
4271  }
4272  BLI_assert(j == data->totlayer);
4273  data->maxlayer = data->totlayer; /* We only write that much of data! */
4274  *r_write_layers = write_layers;
4275 }
4276 
4278 {
4279  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
4280 
4281  return typeInfo->size;
4282 }
4283 
4285 {
4286  return layerType_getName(type);
4287 }
4288 
4293 {
4294  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
4295  return typeInfo->defaultname == NULL;
4296 }
4297 
4304 {
4305  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
4306 
4307  return (typeInfo->free != NULL);
4308 }
4309 
4314 {
4315  const LayerTypeInfo *typeInfo = layerType_getInfo(type);
4316 
4317  /* Same test as for singleton above. */
4318  if (typeInfo->defaultname == NULL) {
4319  return 1;
4320  }
4321  if (typeInfo->layers_max == NULL) {
4322  return -1;
4323  }
4324 
4325  return typeInfo->layers_max();
4326 }
4327 
4328 static bool cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
4329 {
4330  /* see if there is a duplicate */
4331  for (int i = 0; i < data->totlayer; i++) {
4332  if (i != index) {
4333  CustomDataLayer *layer = &data->layers[i];
4334 
4336  if ((CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) && STREQ(layer->name, name)) {
4337  return true;
4338  }
4339  }
4340  else {
4341  if (i != index && layer->type == type && STREQ(layer->name, name)) {
4342  return true;
4343  }
4344  }
4345  }
4346  }
4347 
4348  return false;
4349 }
4350 
4351 static bool customdata_unique_check(void *arg, const char *name)
4352 {
4353  struct {
4354  CustomData *data;
4355  int type;
4356  int index;
4357  } *data_arg = arg;
4358  return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index);
4359 }
4360 
4362 {
4363  CustomDataLayer *nlayer = &data->layers[index];
4364  const LayerTypeInfo *typeInfo = layerType_getInfo(nlayer->type);
4365 
4366  struct {
4367  CustomData *data;
4368  int type;
4369  int index;
4370  } data_arg;
4371  data_arg.data = data;
4372  data_arg.type = nlayer->type;
4373  data_arg.index = index;
4374 
4375  if (!typeInfo->defaultname) {
4376  return;
4377  }
4378 
4379  /* Set default name if none specified. Note we only call DATA_() when
4380  * needed to avoid overhead of locale lookups in the depsgraph. */
4381  if (nlayer->name[0] == '\0') {
4382  STRNCPY(nlayer->name, DATA_(typeInfo->defaultname));
4383  }
4384 
4386  customdata_unique_check, &data_arg, NULL, '.', nlayer->name, sizeof(nlayer->name));
4387 }
4388 
4390  int type,
4391  const char *name,
4392  char *outname)
4393 {
4394  int index = -1;
4395 
4396  /* if a layer name was given, try to find that layer */
4397  if (name[0]) {
4398  index = CustomData_get_named_layer_index(data, type, name);
4399  }
4400 
4401  if (index == -1) {
4402  /* either no layer was specified, or the layer we want has been
4403  * deleted, so assign the active layer to name
4404  */
4406  BLI_strncpy(outname, data->layers[index].name, MAX_CUSTOMDATA_LAYER_NAME);
4407  }
4408  else {
4409  BLI_strncpy(outname, name, MAX_CUSTOMDATA_LAYER_NAME);
4410  }
4411 }
4412 
4414 {
4415  const LayerTypeInfo *typeInfo;
4416  CustomDataLayer *layer = &data->layers[index];
4417  bool keeplayer = true;
4418 
4419  if (layer->type >= CD_NUMTYPES) {
4420  keeplayer = false; /* unknown layer type from future version */
4421  }
4422  else {
4423  typeInfo = layerType_getInfo(layer->type);
4424 
4425  if (!typeInfo->defaultname && (index > 0) && data->layers[index - 1].type == layer->type) {
4426  keeplayer = false; /* multiple layers of which we only support one */
4427  }
4428  /* This is a preemptive fix for cases that should not happen
4429  * (layers that should not be written in .blend files),
4430  * but can happen due to bugs (see e.g. T62318).
4431  * Also for forward compatibility, in future,
4432  * we may put into `.blend` file some currently un-written data types,
4433  * this should cover that case as well.
4434  * Better to be safe here, and fix issue on the fly rather than crash... */
4435  /* 0 structnum is used in writing code to tag layer types that should not be written. */
4436  else if (typeInfo->structnum == 0 &&
4437  /* XXX Not sure why those three are exception, maybe that should be fixed? */
4438  !ELEM(layer->type, CD_PAINT_MASK, CD_FACEMAP, CD_MTEXPOLY, CD_SCULPT_FACE_SETS)) {
4439  keeplayer = false;
4440  CLOG_WARN(&LOG, ".blend file read: removing a data layer that should not have been written");
4441  }
4442  }
4443 
4444  if (!keeplayer) {
4445  for (int i = index + 1; i < data->totlayer; i++) {
4446  data->layers[i - 1] = data->layers[i];
4447  }
4448  data->totlayer--;
4449  }
4450 
4451  return keeplayer;
4452 }
4453 
4460 bool CustomData_layer_validate(CustomDataLayer *layer, const uint totitems, const bool do_fixes)
4461 {
4462  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4463 
4464  if (typeInfo->validate != NULL) {
4465  return typeInfo->validate(layer->data, totitems, do_fixes);
4466  }
4467 
4468  return false;
4469 }
4470 
4472 {
4473  printf("{\n");
4474 
4475  int i;
4476  const CustomDataLayer *layer;
4477  for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
4478  const char *name = CustomData_layertype_name(layer->type);
4479  const int size = CustomData_sizeof(layer->type);
4480  const char *structname;
4481  int structnum;
4482  CustomData_file_write_info(layer->type, &structname, &structnum);
4483  printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
4484  name,
4485  structname,
4486  layer->type,
4487  (const void *)layer->data,
4488  size,
4489  (int)(MEM_allocN_len(layer->data) / size));
4490  }
4491 
4492  printf("}\n");
4493 }
4494 
4495 /****************************** External Files *******************************/
4496 
4497 static void customdata_external_filename(char filename[FILE_MAX],
4498  ID *id,
4499  CustomDataExternal *external)
4500 {
4501  BLI_strncpy(filename, external->filename, FILE_MAX);
4502  BLI_path_abs(filename, ID_BLEND_PATH_FROM_GLOBAL(id));
4503 }
4504 
4506 {
4507  for (int i = 0; i < data->totlayer; i++) {
4508  CustomDataLayer *layer = &data->layers[i];
4509  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4510 
4511  if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
4512  /* pass */
4513  }
4514  else if ((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) {
4515  if (typeInfo->free) {
4516  typeInfo->free(layer->data, totelem, typeInfo->size);
4517  }
4518  layer->flag &= ~CD_FLAG_IN_MEMORY;
4519  }
4520  }
4521 }
4522 
4524 {
4525  CustomDataExternal *external = data->external;
4526  CustomDataLayer *layer;
4527  char filename[FILE_MAX];
4528  int update = 0;
4529 
4530  if (!external) {
4531  return;
4532  }
4533 
4534  for (int i = 0; i < data->totlayer; i++) {
4535  layer = &data->layers[i];
4536  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4537 
4538  if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
4539  /* pass */
4540  }
4541  else if (layer->flag & CD_FLAG_IN_MEMORY) {
4542  /* pass */
4543  }
4544  else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) {
4545  update = 1;
4546  }
4547  }
4548 
4549  if (!update) {
4550  return;
4551  }
4552 
4553  customdata_external_filename(filename, id, external);
4554 
4556  if (!cdf_read_open(cdf, filename)) {
4557  cdf_free(cdf);
4558  CLOG_ERROR(&LOG, "Failed to read %s layer from %s.", layerType_getName(layer->type), filename);
4559  return;
4560  }
4561 
4562  for (int i = 0; i < data->totlayer; i++) {
4563  layer = &data->layers[i];
4564  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4565 
4566  if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
4567  /* pass */
4568  }
4569  else if (layer->flag & CD_FLAG_IN_MEMORY) {
4570  /* pass */
4571  }
4572  else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) {
4573  CDataFileLayer *blay = cdf_layer_find(cdf, layer->type, layer->name);
4574 
4575  if (blay) {
4576  if (cdf_read_layer(cdf, blay)) {
4577  if (typeInfo->read(cdf, layer->data, totelem)) {
4578  /* pass */
4579  }
4580  else {
4581  break;
4582  }
4583  layer->flag |= CD_FLAG_IN_MEMORY;
4584  }
4585  else {
4586  break;
4587  }
4588  }
4589  }
4590  }
4591 
4592  cdf_read_close(cdf);
4593  cdf_free(cdf);
4594 }
4595 
4597  CustomData *data, ID *id, CustomDataMask mask, int totelem, int free)
4598 {
4599  CustomDataExternal *external = data->external;
4600  int update = 0;
4601  char filename[FILE_MAX];
4602 
4603  if (!external) {
4604  return;
4605  }
4606 
4607  /* test if there is anything to write */
4608  for (int i = 0; i < data->totlayer; i++) {
4609  CustomDataLayer *layer = &data->layers[i];
4610  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4611 
4612  if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
4613  /* pass */
4614  }
4615  else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
4616  update = 1;
4617  }
4618  }
4619 
4620  if (!update) {
4621  return;
4622  }
4623 
4624  /* make sure data is read before we try to write */
4625  CustomData_external_read(data, id, mask, totelem);
4626  customdata_external_filename(filename, id, external);
4627 
4629 
4630  for (int i = 0; i < data->totlayer; i++) {
4631  CustomDataLayer *layer = &data->layers[i];
4632  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4633 
4634  if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) {
4635  if (layer->flag & CD_FLAG_IN_MEMORY) {
4636  cdf_layer_add(
4637  cdf, layer->type, layer->name, typeInfo->filesize(cdf, layer->data, totelem));
4638  }
4639  else {
4640  cdf_free(cdf);
4641  return; /* read failed for a layer! */
4642  }
4643  }
4644  }
4645 
4646  if (!cdf_write_open(cdf, filename)) {
4647  CLOG_ERROR(&LOG, "Failed to open %s for writing.", filename);
4648  cdf_free(cdf);
4649  return;
4650  }
4651 
4652  int i;
4653  for (i = 0; i < data->totlayer; i++) {
4654  CustomDataLayer *layer = &data->layers[i];
4655  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4656 
4657  if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
4658  CDataFileLayer *blay = cdf_layer_find(cdf, layer->type, layer->name);
4659 
4660  if (cdf_write_layer(cdf, blay)) {
4661  if (typeInfo->write(cdf, layer->data, totelem)) {
4662  /* pass */
4663  }
4664  else {
4665  break;
4666  }
4667  }
4668  else {
4669  break;
4670  }
4671  }
4672  }
4673 
4674  if (i != data->totlayer) {
4675  CLOG_ERROR(&LOG, "Failed to write data to %s.", filename);
4676  cdf_write_close(cdf);
4677  cdf_free(cdf);
4678  return;
4679  }
4680 
4681  for (i = 0; i < data->totlayer; i++) {
4682  CustomDataLayer *layer = &data->layers[i];
4683  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
4684 
4685  if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
4686  if (free) {
4687  if (typeInfo->free) {
4688  typeInfo->free(layer->data, totelem, typeInfo->size);
4689  }
4690  layer->flag &= ~CD_FLAG_IN_MEMORY;
4691  }
4692  }
4693  }
4694 
4695  cdf_write_close(cdf);
4696  cdf_free(cdf);
4697 }
4698 
4700  CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename)
4701 {
4702  CustomDataExternal *external = data->external;
4703 
4704  int layer_index = CustomData_get_active_layer_index(data, type);
4705  if (layer_index == -1) {
4706  return;
4707  }
4708 
4709  CustomDataLayer *layer = &data->layers[layer_index];
4710 
4711  if (layer->flag & CD_FLAG_EXTERNAL) {
4712  return;
4713  }
4714 
4715  if (!external) {
4716  external = MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal");
4717  data->external = external;
4718  }
4719  BLI_strncpy(external->filename, filename, sizeof(external->filename));
4720 
4722 }
4723 
4724 void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem)
4725 {
4726  CustomDataExternal *external = data->external;
4727 
4728  int layer_index = CustomData_get_active_layer_index(data, type);
4729  if (layer_index == -1) {
4730  return;
4731  }
4732 
4733  CustomDataLayer *layer = &data->layers[layer_index];
4734 
4735  if (!external) {
4736  return;
4737  }
4738 
4739  if (layer->flag & CD_FLAG_EXTERNAL) {
4740  if (!(layer->flag & CD_FLAG_IN_MEMORY)) {
4741  CustomData_external_read(data, id, CD_TYPE_AS_MASK(layer->type), totelem);
4742  }
4743 
4744  layer->flag &= ~CD_FLAG_EXTERNAL;
4745  }
4746 }
4747 
4749 {
4750  int layer_index = CustomData_get_active_layer_index(data, type);
4751  if (layer_index == -1) {
4752  return false;
4753  }
4754 
4755  CustomDataLayer *layer = &data->layers[layer_index];
4756  return (layer->flag & CD_FLAG_EXTERNAL) != 0;
4757 }
4758 
4759 /* ********** Mesh-to-mesh data transfer ********** */
4760 static void copy_bit_flag(void *dst, const void *src, const size_t data_size, const uint64_t flag)
4761 {
4762 #define COPY_BIT_FLAG(_type, _dst, _src, _f) \
4763  { \
4764  const _type _val = *((_type *)(_src)) & ((_type)(_f)); \
4765  *((_type *)(_dst)) &= ~((_type)(_f)); \
4766  *((_type *)(_dst)) |= _val; \
4767  } \
4768  (void)0
4769 
4770  switch (data_size) {
4771  case 1:
4772  COPY_BIT_FLAG(uint8_t, dst, src, flag);
4773  break;
4774  case 2:
4775  COPY_BIT_FLAG(uint16_t, dst, src, flag);
4776  break;
4777  case 4:
4778  COPY_BIT_FLAG(uint32_t, dst, src, flag);
4779  break;
4780  case 8:
4781  COPY_BIT_FLAG(uint64_t, dst, src, flag);
4782  break;
4783  default:
4784  // CLOG_ERROR(&LOG, "Unknown flags-container size (%zu)", datasize);
4785  break;
4786  }
4787 
4788 #undef COPY_BIT_FLAG
4789 }
4790 
4791 static bool check_bit_flag(const void *data, const size_t data_size, const uint64_t flag)
4792 {
4793  switch (data_size) {
4794  case 1:
4795  return ((*((uint8_t *)data) & ((uint8_t)flag)) != 0);
4796  case 2:
4797  return ((*((uint16_t *)data) & ((uint16_t)flag)) != 0);
4798  case 4:
4799  return ((*((uint32_t *)data) & ((uint32_t)flag)) != 0);
4800  case 8:
4801  return ((*((uint64_t *)data) & ((uint64_t)flag)) != 0);
4802  default:
4803  // CLOG_ERROR(&LOG, "Unknown flags-container size (%zu)", datasize);
4804  return false;
4805  }
4806 }
4807 
4809  void *data_dst,
4810  const void **sources,
4811  const float *weights,
4812  const int count,
4813  const float mix_factor)
4814 {
4815  BLI_assert(weights != NULL);
4816  BLI_assert(count > 0);
4817 
4818  /* Fake interpolation, we actually copy highest weighted source to dest.
4819  * Note we also handle bitflags here,
4820  * in which case we rather choose to transfer value of elements totaling
4821  * more than 0.5 of weight. */
4822  int best_src_idx = 0;
4823 
4824  const int data_type = laymap->data_type;
4825  const int mix_mode = laymap->mix_mode;
4826 
4827  size_t data_size;
4828  const uint64_t data_flag = laymap->data_flag;
4829 
4830  cd_interp interp_cd = NULL;
4831  cd_copy copy_cd = NULL;
4832 
4833  if (!sources) {
4834  /* Not supported here, abort. */
4835  return;
4836  }
4837 
4838  if (data_type & CD_FAKE) {
4839  data_size = laymap->data_size;
4840  }
4841  else {
4842  const LayerTypeInfo *type_info = layerType_getInfo(data_type);
4843 
4844  data_size = (size_t)type_info->size;
4845  interp_cd = type_info->interp;
4846  copy_cd = type_info->copy;
4847  }
4848 
4849  void *tmp_dst = MEM_mallocN(data_size, __func__);
4850 
4851  if (count > 1 && !interp_cd) {
4852  if (data_flag) {
4853  /* Boolean case, we can 'interpolate' in two groups,
4854  * and choose value from highest weighted group. */
4855  float tot_weight_true = 0.0f;
4856  int item_true_idx = -1, item_false_idx = -1;
4857 
4858  for (int i = 0; i < count; i++) {
4859  if (check_bit_flag(sources[i], data_size, data_flag)) {
4860  tot_weight_true += weights[i];
4861  item_true_idx = i;
4862  }
4863  else {
4864  item_false_idx = i;
4865  }
4866  }
4867  best_src_idx = (tot_weight_true >= 0.5f) ? item_true_idx : item_false_idx;
4868  }
4869  else {
4870  /* We just choose highest weighted source. */
4871  float max_weight = 0.0f;
4872 
4873  for (int i = 0; i < count; i++) {
4874  if (weights[i] > max_weight) {
4875  max_weight = weights[i];
4876  best_src_idx = i;
4877  }
4878  }
4879  }
4880  }
4881 
4882  BLI_assert(best_src_idx >= 0);
4883 
4884  if (interp_cd) {
4885  interp_cd(sources, weights, NULL, count, tmp_dst);
4886  }
4887  else if (data_flag) {
4888  copy_bit_flag(tmp_dst, sources[best_src_idx], data_size, data_flag);
4889  }
4890  /* No interpolation, just copy highest weight source element's data. */
4891  else if (copy_cd) {
4892  copy_cd(sources[best_src_idx], tmp_dst, 1);
4893  }
4894  else {
4895  memcpy(tmp_dst, sources[best_src_idx], data_size);
4896  }
4897 
4898  if (data_flag) {
4899  /* Bool flags, only copy if dest data is set (resp. unset) -
4900  * only 'advanced' modes we can support here! */
4901  if (mix_factor >= 0.5f && ((mix_mode == CDT_MIX_TRANSFER) ||
4902  (mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD &&
4903  check_bit_flag(data_dst, data_size, data_flag)) ||
4904  (mix_mode == CDT_MIX_REPLACE_BELOW_THRESHOLD &&
4905  !check_bit_flag(data_dst, data_size, data_flag)))) {
4906  copy_bit_flag(data_dst, tmp_dst, data_size, data_flag);
4907  }
4908  }
4909  else if (!(data_type & CD_FAKE)) {
4910  CustomData_data_mix_value(data_type, tmp_dst, data_dst, mix_mode, mix_factor);
4911  }
4912  /* Else we can do nothing by default, needs custom interp func!
4913  * Note this is here only for sake of consistency, not expected to be used much actually? */
4914  else {
4915  if (mix_factor >= 0.5f) {
4916  memcpy(data_dst, tmp_dst, data_size);
4917  }
4918  }
4919 
4920  MEM_freeN(tmp_dst);
4921 }
4922 
4923 /* Normals are special, we need to take care of source & destination spaces... */
4925  void *data_dst,
4926  const void **sources,
4927  const float *weights,
4928  const int count,
4929  const float mix_factor)
4930 {
4931  BLI_assert(weights != NULL);
4932  BLI_assert(count > 0);
4933 
4934  const int data_type = laymap->data_type;
4935  const int mix_mode = laymap->mix_mode;
4936 
4937  SpaceTransform *space_transform = laymap->interp_data;
4938 
4939  const LayerTypeInfo *type_info = layerType_getInfo(data_type);
4940  cd_interp interp_cd = type_info->interp;
4941 
4942  float tmp_dst[3];
4943 
4944  BLI_assert(data_type == CD_NORMAL);
4945 
4946  if (!sources) {
4947  /* Not supported here, abort. */
4948  return;
4949  }
4950 
4951  interp_cd(sources, weights, NULL, count, tmp_dst);
4952  if (space_transform) {
4953  /* tmp_dst is in source space so far, bring it back in destination space. */
4954  BLI_space_transform_invert_normal(space_transform, tmp_dst);
4955  }
4956 
4957  CustomData_data_mix_value(data_type, tmp_dst, data_dst, mix_mode, mix_factor);
4958 }
4959 
4961  const CustomDataTransferLayerMap *laymap)
4962 {
4963  MeshPairRemapItem *mapit = me_remap->items;
4964  const int totelem = me_remap->items_num;
4965 
4966  const int data_type = laymap->data_type;
4967  const void *data_src = laymap->data_src;
4968  void *data_dst = laymap->data_dst;
4969 
4970  size_t data_step;
4971  size_t data_size;
4972  size_t data_offset;
4973 
4975 
4976  size_t tmp_buff_size = 32;
4977  const void **tmp_data_src = NULL;
4978 
4979  /* Note: NULL data_src may happen and be valid (see vgroups...). */
4980  if (!data_dst) {
4981  return;
4982  }
4983 
4984  if (data_src) {
4985  tmp_data_src = MEM_malloc_arrayN(tmp_buff_size, sizeof(*tmp_data_src), __func__);
4986  }
4987 
4988  if (data_type & CD_FAKE) {
4989  data_step = laymap->elem_size;
4990  data_size = laymap->data_size;
4991  data_offset = laymap->data_offset;
4992  }
4993  else {
4994  const LayerTypeInfo *type_info = layerType_getInfo(data_type);
4995 
4996  /* Note: we can use 'fake' CDLayers, like e.g. for crease, bweight, etc. :/ */
4997  data_size = (size_t)type_info->size;
4998  data_step = laymap->elem_size ? laymap->elem_size : data_size;
4999  data_offset = laymap->data_offset;
5000  }
5001 
5003 
5004  for (int i = 0; i < totelem; i++, data_dst = POINTER_OFFSET(data_dst, data_step), mapit++) {
5005  const int sources_num = mapit->sources_num;
5006  const float mix_factor = laymap->mix_factor *
5007  (laymap->mix_weights ? laymap->mix_weights[i] : 1.0f);
5008 
5009  if (!sources_num) {
5010  /* No sources for this element, skip it. */
5011  continue;
5012  }
5013 
5014  if (tmp_data_src) {
5015  if (UNLIKELY(sources_num > tmp_buff_size)) {
5016  tmp_buff_size = (size_t)sources_num;
5017  tmp_data_src = MEM_reallocN((void *)tmp_data_src, sizeof(*tmp_data_src) * tmp_buff_size);
5018  }
5019 
5020  for (int j = 0; j < sources_num; j++) {
5021  const size_t src_idx = (size_t)mapit->indices_src[j];
5022  tmp_data_src[j] = POINTER_OFFSET(data_src, (data_step * src_idx) + data_offset);
5023  }
5024  }
5025 
5026  interp(laymap,
5027  POINTER_OFFSET(data_dst, data_offset),
5028  tmp_data_src,
5029  mapit->weights_src,
5030  sources_num,
5031  mix_factor);
5032  }
5033 
5034  MEM_SAFE_FREE(tmp_data_src);
5035 }
5036 
5037 static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external)
5038 {
5039  if (mdlist) {
5040  BLO_write_struct_array(writer, MDisps, count, mdlist);
5041  for (int i = 0; i < count; i++) {
5042  MDisps *md = &mdlist[i];
5043  if (md->disps) {
5044  if (!external) {
5045  BLO_write_float3_array(writer, md->totdisp, &md->disps[0][0]);
5046  }
5047  }
5048 
5049  if (md->hidden) {
5050  BLO_write_raw(writer, BLI_BITMAP_SIZE(md->totdisp), md->hidden);
5051  }
5052  }
5053  }
5054 }
5055 
5056 static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask *grid_paint_mask)
5057 {
5058  if (grid_paint_mask) {
5059  BLO_write_struct_array(writer, GridPaintMask, count, grid_paint_mask);
5060  for (int i = 0; i < count; i++) {
5061  GridPaintMask *gpm = &grid_paint_mask[i];
5062  if (gpm->data) {
5063  const int gridsize = BKE_ccg_gridsize(gpm->level);
5064  BLO_write_raw(writer, sizeof(*gpm->data) * gridsize * gridsize, gpm->data);
5065  }
5066  }
5067  }
5068 }
5069 
5074  CustomData *data,
5075  CustomDataLayer *layers,
5076  int count,
5077  CustomDataMask cddata_mask,
5078  ID *id)
5079 {
5080  /* write external customdata (not for undo) */
5081  if (data->external && !BLO_write_is_undo(writer)) {
5082  CustomData_external_write(data, id, cddata_mask, count, 0);
5083  }
5084 
5085  BLO_write_struct_array_at_address(writer, CustomDataLayer, data->totlayer, data->layers, layers);
5086 
5087  for (int i = 0; i < data->totlayer; i++) {
5088  CustomDataLayer *layer = &layers[i];
5089 
5090  if (layer->type == CD_MDEFORMVERT) {
5091  /* layer types that allocate own memory need special handling */
5092  BKE_defvert_blend_write(writer, count, layer->data);
5093  }
5094  else if (layer->type == CD_MDISPS) {
5095  write_mdisps(writer, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
5096  }
5097  else if (layer->type == CD_PAINT_MASK) {
5098  const float *layer_data = layer->data;
5099  BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
5100  }
5101  else if (layer->type == CD_SCULPT_FACE_SETS) {
5102  const float *layer_data = layer->data;
5103  BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
5104  }
5105  else if (layer->type == CD_GRID_PAINT_MASK) {
5106  write_grid_paint_mask(writer, count, layer->data);
5107  }
5108  else if (layer->type == CD_FACEMAP) {
5109  const int *layer_data = layer->data;
5110  BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
5111  }
5112  else if (layer->type == CD_PROP_BOOL) {
5113  const bool *layer_data = layer->data;
5114  BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
5115  }
5116  else {
5117  const char *structname;
5118  int structnum;
5119  CustomData_file_write_info(layer->type, &structname, &structnum);
5120  if (structnum) {
5121  int datasize = structnum * count;
5122  BLO_write_struct_array_by_name(writer, structname, datasize, layer->data);
5123  }
5124  else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */
5125  printf("%s error: layer '%s':%d - can't be written to file\n",
5126  __func__,
5127  structname,
5128  layer->type);
5129  }
5130  }
5131  }
5132 
5133  if (data->external) {
5134  BLO_write_struct(writer, CustomDataExternal, data->external);
5135  }
5136 }
5137 
5138 static void blend_read_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external)
5139 {
5140  if (mdisps) {
5141  for (int i = 0; i < count; i++) {
5142  BLO_read_data_address(reader, &mdisps[i].disps);
5143  BLO_read_data_address(reader, &mdisps[i].hidden);
5144 
5145  if (mdisps[i].totdisp && !mdisps[i].level) {
5146  /* this calculation is only correct for loop mdisps;
5147  * if loading pre-BMesh face mdisps this will be
5148  * overwritten with the correct value in
5149  * bm_corners_to_loops() */
5150  float gridsize = sqrtf(mdisps[i].totdisp);
5151  mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1;
5152  }
5153 
5154  if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) {
5155  /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */
5156  /* this does swap for data written at write_mdisps() - readfile.c */
5157  BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3);
5158  }
5159  if (!external && !mdisps[i].disps) {
5160  mdisps[i].totdisp = 0;
5161  }
5162  }
5163  }
5164 }
5165 
5167  int count,
5168  GridPaintMask *grid_paint_mask)
5169 {
5170  if (grid_paint_mask) {
5171  for (int i = 0; i < count; i++) {
5172  GridPaintMask *gpm = &grid_paint_mask[i];
5173  if (gpm->data) {
5174  BLO_read_data_address(reader, &gpm->data);
5175  }
5176  }
5177  }
5178 }
5179 
5181 {
5182  BLO_read_data_address(reader, &data->layers);
5183 
5184  /* Annoying workaround for bug T31079 loading legacy files with
5185  * no polygons _but_ have stale custom-data. */
5186  if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) {
5188  return;
5189  }
5190 
5191  BLO_read_data_address(reader, &data->external);
5192 
5193  int i = 0;
5194  while (i < data->totlayer) {
5195  CustomDataLayer *layer = &data->layers[i];
5196 
5197  if (layer->flag & CD_FLAG_EXTERNAL) {
5198  layer->flag &= ~CD_FLAG_IN_MEMORY;
5199  }
5200 
5201  layer->flag &= ~CD_FLAG_NOFREE;
5202 
5203  if (CustomData_verify_versions(data, i)) {
5204  BLO_read_data_address(reader, &layer->data);
5205  if (layer->data == NULL && count > 0 && layer->type == CD_PROP_BOOL) {
5206  /* Usually this should never happen, except when a custom data layer has not been written
5207  * to a file correctly. */
5208  CLOG_WARN(&LOG, "Reallocating custom data layer that was not saved correctly.");
5209  const LayerTypeInfo *info = layerType_getInfo(layer->type);
5210  layer->data = MEM_calloc_arrayN((size_t)count, info->size, layerType_getName(layer->type));
5211  if (info->set_default) {
5212  info->set_default(layer->data, count);
5213  }
5214  }
5215  if (layer->type == CD_MDISPS) {
5216  blend_read_mdisps(reader, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
5217  }
5218  else if (layer->type == CD_GRID_PAINT_MASK) {
5219  blend_read_paint_mask(reader, count, layer->data);
5220  }
5221  i++;
5222  }
5223  }
5224 
5226 }
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
eCDAllocType
@ CD_REFERENCE
@ CD_ASSIGN
@ CD_CALLOC
@ CD_DUPLICATE
@ CD_DEFAULT
uint64_t CustomDataMask
@ CDT_MIX_SUB
@ CDT_MIX_REPLACE_BELOW_THRESHOLD
@ CDT_MIX_REPLACE_ABOVE_THRESHOLD
@ CDT_MIX_ADD
@ CDT_MIX_MUL
@ CDT_MIX_TRANSFER
@ CDT_MIX_MIX
@ CDT_MIX_NOMIX
void(* cd_datatransfer_interp)(const struct CustomDataTransferLayerMap *laymap, void *dest, const void **sources, const float *weights, const int count, const float mix_factor)
#define ORIGINDEX_NONE
bool(* cd_validate)(void *item, const uint totitems, const bool do_fixes)
@ CD_FAKE
void(* cd_copy)(const void *source, void *dest, int count)
#define CD_TYPE_AS_MASK(_type)
void(* cd_interp)(const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
bool cdf_read_open(CDataFile *cdf, const char *filename)
bool cdf_read_data(CDataFile *cdf, unsigned int size, void *data)
#define CDF_TYPE_MESH
void cdf_read_close(CDataFile *cdf)
bool cdf_write_open(CDataFile *cdf, const char *filename)
CDataFile * cdf_create(int type)
void cdf_write_close(CDataFile *cdf)
void cdf_free(CDataFile *cdf)
bool cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
CDataFileLayer * cdf_layer_add(CDataFile *cdf, int type, const char *name, size_t datasize)
CDataFileLayer * cdf_layer_find(CDataFile *cdf, int type, const char *name)
bool cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay)
bool cdf_write_data(CDataFile *cdf, unsigned int size, void *data)
support for deformation groups and hooks.
void BKE_defvert_blend_write(struct BlendWriter *writer, int count, struct MDeformVert *dvlist)
Definition: deform.c:1525
int multires_mdisp_corners(struct MDisps *s)
Definition: multires.c:1436
int BKE_ccg_gridsize(int level)
Definition: CCGSubSurf.c:37
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_BITMAP_SIZE(_tot)
Definition: BLI_bitmap.h:47
void BLI_endian_switch_float_array(float *val, const int size) ATTR_NONNULL(1)
Definition: endian_switch.c:65
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:116
MINLINE int compare_ff(float a, float b, const float max_diff)
#define M_LN2
Definition: BLI_math_base.h:71
MINLINE unsigned char round_fl_to_uchar_clamp(float a)
MINLINE void blend_color_add_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_interpolate_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4], float t)
MINLINE void blend_color_sub_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_mul_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mul_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_sub_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_add_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_mix_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], const float src2[4], float t)
void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float no[3])
void copy_vn_fl(float *array_tar, const int size, const float val)
Definition: math_vector.c:1410
MINLINE void mul_v4_fl(float r[4], float f)
MINLINE void add_v4_v4(float r[4], const float a[4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t)
Definition: math_vector.c:32
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
void copy_vn_i(int *array_tar, const int size, const int val)
Definition: math_vector.c:1374
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
Definition: math_vector.c:1043
MINLINE void add_v2_v2(float r[2], const float a[2])
void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:121
bool is_finite_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:398
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
bool is_finite_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:393
MINLINE void copy_v3_v3_short(short r[3], const short a[3])
void minmax_v4v4_v4(float min[4], float max[4], const float vec[4])
Definition: math_vector.c:991
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void zero_v2(float r[2])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
MINLINE void zero_v3(float r[3])
MINLINE void copy_v4_fl(float r[4], float f)
@ BLI_MEMPOOL_NOP
Definition: BLI_mempool.h:77
void BLI_mempool_free(BLI_mempool *pool, void *addr) ATTR_NONNULL(1
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int totelem, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_mempool.c:268
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: BLI_mempool.c:334
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:757
#define FILE_MAX
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
#define STRNCPY(dst, src)
Definition: BLI_string.h:163
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
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 INIT_MINMAX2(min, max)
#define ARRAY_SIZE(arr)
#define UNUSED(x)
#define UNLIKELY(x)
#define ELEM(...)
#define POINTER_OFFSET(v, ofs)
#define STREQ(a, b)
#define BLO_read_data_address(reader, ptr_p)
void BLO_write_float3_array(BlendWriter *writer, uint num, const float *data_ptr)
Definition: writefile.c:1393
#define BLO_write_struct_array_at_address(writer, struct_name, array_size, address, data_ptr)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
void BLO_write_struct_array_by_name(BlendWriter *writer, const char *struct_name, int array_size, const void *data_ptr)
Definition: writefile.c:1296
bool BLO_read_requires_endian_switch(BlendDataReader *reader)
Definition: readfile.c:5620
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr)
Definition: writefile.c:1286
bool BLO_write_is_undo(BlendWriter *writer)
Definition: writefile.c:1412
#define N_(msgid)
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:204
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:203
ID and Library types, which are fundamental for sdna.
#define ID_BLEND_PATH_FROM_GLOBAL(_id)
Definition: DNA_ID.h:421
#define CD_MASK_SCULPT_FACE_SETS
#define CD_MASK_BM_ELEM_PYPTR
#define MAX_CUSTOMDATA_LAYER_NAME
#define CD_MASK_MLOOP
#define CD_MASK_NORMAL
#define CD_MASK_PROP_COLOR
#define CD_MASK_BWEIGHT
#define CD_MASK_ORIGINDEX
#define CD_MASK_MCOL
#define CD_MASK_ORCO
#define CD_MASK_MDEFORMVERT
#define CD_MASK_MLOOPCOL
#define CD_MASK_TESSLOOPNORMAL
#define CD_MASK_MVERT_SKIN
#define MAX_MCOL
#define CD_MASK_PROP_ALL
#define CD_MASK_PREVIEW_MCOL
#define CD_MASK_TANGENT
@ CD_FACEMAP
@ CD_PAINT_MASK
@ CD_TESSLOOPNORMAL
@ CD_PREVIEW_MCOL
@ CD_MDEFORMVERT
@ CD_NUMTYPES
@ CD_ORIGSPACE_MLOOP
@ CD_PROP_BOOL
@ CD_MLOOPCOL
@ CD_ORIGSPACE
@ CD_SCULPT_FACE_SETS
@ CD_GRID_PAINT_MASK
@ CD_PREVIEW_MLOOPCOL
@ CD_MLOOPUV
@ CD_TANGENT
#define CD_MASK_FREESTYLE_FACE
#define CD_MASK_MEDGE
#define CD_MASK_SHAPE_KEYINDEX
#define CD_MASK_MTFACE
#define CD_MASK_ORIGSPACE_MLOOP
#define CD_MASK_MPOLY
#define CD_MASK_CLOTH_ORCO
#define CD_TEMP_CHUNK_SIZE
#define CD_MASK_PREVIEW_MLOOPCOL
#define CD_MASK_GRID_PAINT_MASK
#define CD_MASK_CUSTOMLOOPNORMAL
#define CD_MASK_MVERT
#define CD_MASK_CREASE
#define CD_MASK_SHAPEKEY
#define CD_MASK_FACEMAP
#define CD_MASK_MLOOPUV
#define CD_MASK_MFACE
@ CD_FLAG_NOCOPY
@ CD_FLAG_IN_MEMORY
@ CD_FLAG_TEMPORARY
@ CD_FLAG_NOFREE
@ CD_FLAG_EXTERNAL
#define MAX_MTFACE
#define CD_MASK_MDISPS
#define CD_MASK_FREESTYLE_EDGE
#define CD_MASK_ORIGSPACE
#define CD_MASK_MLOOPTANGENT
#define CD_MASK_PAINT_MASK
struct HairMapping HairMapping
struct HairCurve HairCurve
struct MLoop MLoop
struct FreestyleEdge FreestyleEdge
struct MDisps MDisps
struct MEdge MEdge
struct MVertSkin MVertSkin
struct MStringProperty MStringProperty
struct GridPaintMask GridPaintMask
struct MRecast MRecast
struct MDeformVert MDeformVert
struct MTFace MTFace
struct OrigSpaceFace OrigSpaceFace
struct OrigSpaceLoop OrigSpaceLoop
struct MIntProperty MIntProperty
@ MVERT_SKIN_ROOT
struct MLoopCol MLoopCol
struct MPoly MPoly
struct MFloatProperty MFloatProperty
struct MPropCol MPropCol
struct MFace MFace
struct MLoopUV MLoopUV
struct FreestyleFace FreestyleFace
struct MVert MVert
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
@ BM_LOOP
Definition: bmesh_class.h:385
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_FACE
ATTR_WARN_UNUSED_RESULT BMesh * bm
const BMAllocTemplate bm_mesh_chunksize_default
Definition: bmesh_mesh.c:47
ATTR_WARN_UNUSED_RESULT const BMLoop * l
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static void layerDefault_origindex(void *data, int count)
Definition: customdata.c:1156
bool CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
Definition: customdata.c:3249
static void customData_free_layer__internal(CustomDataLayer *layer, int totelem)
Definition: customdata.c:2208
static void layerInterp_mdeformvert(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:240
void CustomData_swap(struct CustomData *data, const int index_a, const int index_b)
Definition: customdata.c:3138
static void layerAdd_mloopuv(void *data1, const void *data2)
Definition: customdata.c:967
static void layerDoMinMax_propcol(const void *data, void *vmin, void *vmax)
Definition: customdata.c:1342
void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem)
Definition: customdata.c:4523
const CustomData_MeshMasks CD_MASK_EVERYTHING
Definition: customdata.c:1986
static void layerInitMinMax_mloop_origspace(void *vmin, void *vmax)
Definition: customdata.c:1043
bool CustomData_has_math(const struct CustomData *data)
Definition: customdata.c:3843
void CustomData_bmesh_set(const CustomData *data, void *block, int type, const void *source)
Definition: customdata.c:3976
void CustomData_set(const CustomData *data, int index, int type, const void *source)
Definition: customdata.c:3297
static bool layerValidate_normal(void *data, const uint totitems, const bool do_fixes)
Definition: customdata.c:345
static void layerSwap_flnor(void *data, const int *corner_indices)
Definition: customdata.c:1247
static bool layerValidate_mloopuv(void *data, const uint totitems, const bool do_fixes)
Definition: customdata.c:1000
void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, const void *source)
Definition: customdata.c:3993
void * CustomData_duplicate_referenced_layer(CustomData *data, const int type, const int totelem)
Definition: customdata.c:2788
bool CustomData_free_layer_active(CustomData *data, int type, int totelem)
Definition: customdata.c:2707
void * CustomData_add_layer(CustomData *data, int type, eCDAllocType alloctype, void *layerdata, int totelem)
Definition: customdata.c:2620
static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
Definition: customdata.c:3652
static int layerMaxNum_propcol(void)
Definition: customdata.c:1383
static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
Definition: customdata.c:857
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX
Definition: customdata.c:1926
void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *ldata, int totloop)
Definition: customdata.c:3316
void * CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr)
Definition: customdata.c:3284
void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, void *src_block, void **dest_block)
Definition: customdata.c:3777
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES]
Definition: customdata.c:1480
void CustomData_free_layers(CustomData *data, int type, int totelem)
Definition: customdata.c:2716
static bool layerRead_mdisps(CDataFile *cdf, void *data, int count)
Definition: customdata.c:645
static void layerMultiply_mloopuv(void *data, float fac)
Definition: customdata.c:945
static bool layerEqual_mloopuv(const void *data1, const void *data2)
Definition: customdata.c:938
void customdata_data_transfer_interp_normal_normals(const CustomDataTransferLayerMap *laymap, void *data_dst, const void **sources, const float *weights, const int count, const float mix_factor)
Definition: customdata.c:4924
static bool check_bit_flag(const void *data, const size_t data_size, const uint64_t flag)
Definition: customdata.c:4791
static void layerInterp_mcol(const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
Definition: customdata.c:1086
void CustomData_interp(const CustomData *source, CustomData *dest, const int *src_indices, const float *weights, const float *sub_weights, int count, int dest_index)
Definition: customdata.c:3033
static bool layerEqual_mloop_origspace(const void *data1, const void *data2)
Definition: customdata.c:1029
bool CustomData_free_layer(CustomData *data, int type, int totelem, int index)
Definition: customdata.c:2655
static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external)
Definition: customdata.c:5037
int CustomData_number_of_layers_typemask(const CustomData *data, CustomDataMask mask)
Definition: customdata.c:2742
static void layerCopy_propString(const void *source, void *dest, int count)
Definition: customdata.c:513
static void blend_read_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external)
Definition: customdata.c:5138
static void layerInterp_paint_mask(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:688
static void layerDoMinMax_mloopuv(const void *data, void *vmin, void *vmax)
Definition: customdata.c:959
void * CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
Definition: customdata.c:3799
static int CustomData_get_layer_index__notypemap(const CustomData *data, int type)
Definition: customdata.c:2288
void bpy_bm_generic_invalidate(struct BPy_BMGeneric *UNUSED(self))
Definition: customdata.c:224
void CustomData_data_mix_value(int type, const void *source, void *dest, const int mixmode, const float mixfactor)
Definition: customdata.c:3911
void CustomData_bmesh_free_block(CustomData *data, void **block)
Definition: customdata.c:3606
static void layerDefault_mvert_skin(void *data, int count)
Definition: customdata.c:1208
void CustomData_set_layer_render(CustomData *data, int type, int n)
Definition: customdata.c:2410
int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
Definition: customdata.c:2321
static void layerDefault_tface(void *data, int count)
Definition: customdata.c:456
static void customdata_data_transfer_interp_generic(const CustomDataTransferLayerMap *laymap, void *data_dst, const void **sources, const float *weights, const int count, const float mix_factor)
Definition: customdata.c:4808
void CustomData_clear_layer_flag(struct CustomData *data, int type, int flag)
Definition: customdata.c:2484
static const LayerTypeInfo * layerType_getInfo(int type)
Definition: customdata.c:2005
static void * customData_duplicate_referenced_layer_index(CustomData *data, const int layer_index, const int totelem)
Definition: customdata.c:2755
int CustomData_get_layer_index(const CustomData *data, int type)
Definition: customdata.c:2302
bool CustomData_bmesh_merge(const CustomData *source, CustomData *dest, CustomDataMask mask, eCDAllocType alloctype, BMesh *bm, const char htype)
Definition: customdata.c:3514
const char * CustomData_get_layer_name(const CustomData *data, int type, int n)
Definition: customdata.c:3263
bool CustomData_layer_has_interp(const struct CustomData *data, int layer_n)
Definition: customdata.c:3832
int CustomData_get_stencil_layer_index(const CustomData *data, int type)
Definition: customdata.c:2355
bool CustomData_layertype_is_singleton(int type)
Definition: customdata.c:4292
void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst, const CustomData_MeshMasks *mask_src)
Definition: customdata.c:76
void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype)
Definition: customdata.c:3482
void CustomData_set_layer_stencil_index(CustomData *data, int type, int n)
Definition: customdata.c:2466
void CustomData_set_only_copy(const struct CustomData *data, CustomDataMask mask)
Definition: customdata.c:2871
static void layerCopy_propInt(const void *source, void *dest, int count)
Definition: customdata.c:508
static bool layerWrite_mdisps(CDataFile *cdf, const void *data, int count)
Definition: customdata.c:663
static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
Definition: customdata.c:3690
int CustomData_get_active_layer(const CustomData *data, int type)
Definition: customdata.c:2373
bool CustomData_data_equals(int type, const void *data1, const void *data2)
Definition: customdata.c:3929
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
Definition: customdata.c:2308
static void layerCopy_mvert_skin(const void *source, void *dest, int count)
Definition: customdata.c:1218
void customData_mask_layers__print(const CustomData_MeshMasks *mask)
Definition: customdata.c:2023
void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, const void *source)
Definition: customdata.c:4010
BLI_STATIC_ASSERT(ARRAY_SIZE(((CustomData *) NULL) ->typemap)==CD_NUMTYPES, "size mismatch")
void CustomData_reset(CustomData *data)
Definition: customdata.c:2233
void * CustomData_get_n(const CustomData *data, int type, int index, int n)
Definition: customdata.c:3181
void * CustomData_bmesh_get(const CustomData *data, void *block, int type)
Definition: customdata.c:3788
#define SOURCE_BUF_SIZE
Definition: customdata.c:3019
static bool customdata_unique_check(void *arg, const char *name)
Definition: customdata.c:4351
static void layerDoMinMax_mloop_origspace(const void *data, void *vmin, void *vmax)
Definition: customdata.c:1050
static void layerSwap_tface(void *data, const int *corner_indices)
Definition: customdata.c:443
bool CustomData_MeshMasks_are_matching(const CustomData_MeshMasks *mask_ref, const CustomData_MeshMasks *mask_required)
Definition: customdata.c:87
void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *ldata, int total)
Definition: customdata.c:3338
void CustomData_data_add(int type, void *data1, const void *data2)
Definition: customdata.c:3967
bool CustomData_has_referenced(const struct CustomData *data)
Definition: customdata.c:3881
void CustomData_copy_data_layer(const CustomData *source, CustomData *dest, int src_layer_index, int dst_layer_index, int src_index, int dst_index, int count)
Definition: customdata.c:2892
static void layerCopy_tface(const void *source, void *dest, int count)
Definition: customdata.c:406
void * CustomData_duplicate_referenced_layer_n(CustomData *data, const int type, const int n, const int totelem)
Definition: customdata.c:2796
static const char * layerType_getName(int type)
Definition: customdata.c:2014
bool CustomData_layer_validate(CustomDataLayer *layer, const uint totitems, const bool do_fixes)
Definition: customdata.c:4460
void CustomData_bmesh_interp(CustomData *data, const void **src_blocks, const float *weights, const float *sub_weights, int count, void *dst_block)
Definition: customdata.c:4048
const CustomData_MeshMasks CD_MASK_BAREMESH
Definition: customdata.c:1919
static void layerFree_mdisps(void *data, int count, int UNUSED(size))
Definition: customdata.c:627
bool CustomData_has_layer(const CustomData *data, int type)
Definition: customdata.c:2724
static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
Definition: customdata.c:952
static void customData_update_offsets(CustomData *data)
Definition: customdata.c:2271
static void layerInterp_shapekey(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:1184
static void layerAdd_mloopcol(void *data1, const void *data2)
Definition: customdata.c:815
static void copy_bit_flag(void *dst, const void *src, const size_t data_size, const uint64_t flag)
Definition: customdata.c:4760
#define LAYER_CMP(l_a, t_a, l_b, t_b)
static bool customData_resize(CustomData *data, int amount)
Definition: customdata.c:2495
void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem)
Definition: customdata.c:4724
static void layerDefault_propcol(void *data, int count)
Definition: customdata.c:1357
static void layerCopy_propFloat(const void *source, void *dest, int count)
Definition: customdata.c:471
static void layerAdd_mloop_origspace(void *data1, const void *data2)
Definition: customdata.c:1058
void CustomData_set_layer_render_index(CustomData *data, int type, int n)
Definition: customdata.c:2448
static void layerSwap_origspace_face(void *data, const int *corner_indices)
Definition: customdata.c:555
void CustomData_set_layer_active(CustomData *data, int type, int n)
Definition: customdata.c:2401
static void layerMultiply_propfloat3(void *data, float fac)
Definition: customdata.c:1403
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
Definition: customdata.c:3217
static void layerInterp_propfloat2(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:1435
bool CustomData_layertype_is_dynamic(int type)
Definition: customdata.c:4303
void * CustomData_get_layer(const CustomData *data, int type)
Definition: customdata.c:3195
static void layerCopy_mdeformvert(const void *source, void *dest, int count)
Definition: customdata.c:177
bool CustomData_is_referenced_layer(struct CustomData *data, int type)
Definition: customdata.c:2826
static void layerMultiply_mloop_origspace(void *data, float fac)
Definition: customdata.c:1036
static bool layerEqual_propcol(const void *data1, const void *data2)
Definition: customdata.c:1316
int CustomData_layertype_layers_max(const int type)
Definition: customdata.c:4313
static void layerInitMinMax_propcol(void *vmin, void *vmax)
Definition: customdata.c:1349
void CustomData_free(CustomData *data, int totelem)
Definition: customdata.c:2239
static void layerFree_mdeformvert(void *data, int count, int size)
Definition: customdata.c:199
void CustomData_bmesh_interp_n(CustomData *data, const void **src_blocks_ofs, const float *weights, const float *sub_weights, int count, void *dst_block_ofs, int n)
Definition: customdata.c:4031
static void layerCopy_mdisps(const void *source, void *dest, int count)
Definition: customdata.c:606
static void layerCopyValue_mloopuv(const void *source, void *dest, const int mixmode, const float mixfactor)
Definition: customdata.c:919
struct LayerTypeInfo LayerTypeInfo
void CustomData_data_copy_value(int type, const void *source, void *dest)
Definition: customdata.c:3893
static void layerAdd_propfloat3(void *data1, const void *data2)
Definition: customdata.c:1411
static bool layerValidate_propfloat3(void *data, const uint totitems, const bool do_fixes)
Definition: customdata.c:1420
int CustomData_get_n_offset(const CustomData *data, int type, int n)
Definition: customdata.c:3238
void CustomData_blend_write(BlendWriter *writer, CustomData *data, CustomDataLayer *layers, int count, CustomDataMask cddata_mask, ID *id)
Definition: customdata.c:5073
void CustomData_free_temporary(CustomData *data, int totelem)
Definition: customdata.c:2839
int CustomData_get_stencil_layer(const CustomData *data, int type)
Definition: customdata.c:2394
static void layerInterp_mloopuv(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:975
int CustomData_get_clone_layer(const CustomData *data, int type)
Definition: customdata.c:2387
static void blend_read_paint_mask(BlendDataReader *reader, int count, GridPaintMask *grid_paint_mask)
Definition: customdata.c:5166
static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
Definition: customdata.c:703
const CustomData_MeshMasks CD_MASK_BMESH
Definition: customdata.c:1964
static void layerCopy_origspace_face(const void *source, void *dest, int count)
Definition: customdata.c:518
static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external)
Definition: customdata.c:4497
bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *ldata, bool fallback)
Definition: customdata.c:3377
void CustomData_update_typemap(CustomData *data)
Definition: customdata.c:2071
void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
Definition: customdata.c:5180
void CustomData_data_multiply(int type, void *data, float fac)
Definition: customdata.c:3958
void CustomData_bmesh_set_default(CustomData *data, void **block)
Definition: customdata.c:3703
const char * CustomData_layertype_name(int type)
Definition: customdata.c:4284
static void layerAdd_propcol(void *data1, const void *data2)
Definition: customdata.c:1335
void * CustomData_get(const CustomData *data, int index, int type)
Definition: customdata.c:3165
static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int count)
Definition: customdata.c:677
static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest, int count)
Definition: customdata.c:213
static void CustomData_external_free(CustomData *data)
Definition: customdata.c:2225
void CustomData_layers__print(CustomData *data)
Definition: customdata.c:4471
static void layerAdd_propfloat2(void *data1, const void *data2)
Definition: customdata.c:1457
static CustomDataLayer * customData_add_layer__internal(CustomData *data, int type, eCDAllocType alloctype, void *layerdata, int totelem, const char *name)
Definition: customdata.c:2513
static bool customdata_typemap_is_valid(const CustomData *data)
Definition: customdata.c:2090
void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, int totelem, int free)
Definition: customdata.c:4596
static bool layerEqual_mloopcol(const void *data1, const void *data2)
Definition: customdata.c:792
void CustomData_validate_layer_name(const CustomData *data, int type, const char *name, char *outname)
Definition: customdata.c:4389
void * CustomData_add_layer_named(CustomData *data, int type, eCDAllocType alloctype, void *layerdata, int totelem, const char *name)
Definition: customdata.c:2637
void * CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
Definition: customdata.c:3811
void CustomData_data_transfer(const MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap)
Definition: customdata.c:4960
void CustomData_data_initminmax(int type, void *min, void *max)
Definition: customdata.c:3940
static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
Definition: customdata.c:230
int CustomData_number_of_layers(const CustomData *data, int type)
Definition: customdata.c:2729
int CustomData_get_active_layer_index(const CustomData *data, int type)
Definition: customdata.c:2334
void * CustomData_get_layer_n(const CustomData *data, int type, int n)
Definition: customdata.c:3206
void CustomData_set_layer_clone(CustomData *data, int type, int n)
Definition: customdata.c:2419
int CustomData_sizeof(int type)
Definition: customdata.c:4277
void CustomData_set_layer_unique_name(CustomData *data, int index)
Definition: customdata.c:4361
static void layerInterp_propfloat3(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:1388
void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask mask, int totelem)
Definition: customdata.c:4505
static int layerMaxNum_tface(void)
Definition: customdata.c:466
void CustomData_set_layer_active_index(CustomData *data, int type, int n)
Definition: customdata.c:2439
static void layerDefault_mcol(void *data, int count)
Definition: customdata.c:1146
static void layerMultiply_propcol(void *data, float fac)
Definition: customdata.c:1329
void CustomData_file_write_info(int type, const char **r_struct_name, int *r_struct_num)
Definition: customdata.c:4210
void CustomData_free_elem(CustomData *data, int index, int count)
Definition: customdata.c:3004
static int layerMaxNum_mloopcol(void)
Definition: customdata.c:914
static void layerInterp_origspace_face(const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
Definition: customdata.c:528
int CustomData_get_named_layer(const struct CustomData *data, int type, const char *name)
Definition: customdata.c:2365
void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
Definition: customdata.c:2948
static void layerInterp_mvert_skin(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:1223
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
Definition: customdata.c:2475
int CustomData_get_offset(const CustomData *data, int type)
Definition: customdata.c:3227
bool CustomData_external_test(CustomData *data, int type)
Definition: customdata.c:4748
void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, CustomData *ldata)
Definition: customdata.c:3449
static void layerCopyValue_propcol(const void *source, void *dest, const int mixmode, const float mixfactor)
Definition: customdata.c:1268
static void layerDefault_origspace_face(void *data, int count)
Definition: customdata.c:566
void CustomData_realloc(CustomData *data, int totelem)
Definition: customdata.c:2180
void * CustomData_set_layer(const CustomData *data, int type, void *ptr)
Definition: customdata.c:3270
bool CustomData_has_interp(const struct CustomData *data)
Definition: customdata.c:3869
static void layerInterp_propcol(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:1367
const CustomData_MeshMasks CD_MASK_EDITMESH
Definition: customdata.c:1943
void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source, CustomData *dest, void *src_block, void **dest_block, const CustomDataMask mask_exclude)
Definition: customdata.c:3714
static void layerSwap_mcol(void *data, const int *corner_indices)
Definition: customdata.c:1134
static void layerMultiply_propfloat2(void *data, float fac)
Definition: customdata.c:1450
static bool layerValidate_propFloat(void *data, const uint totitems, const bool do_fixes)
Definition: customdata.c:491
static CLG_LogRef LOG
Definition: customdata.c:73
static void layerInterp_propFloat(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:476
int CustomData_get_render_layer(const CustomData *data, int type)
Definition: customdata.c:2380
const CustomData_MeshMasks CD_MASK_DERIVEDMESH
Definition: customdata.c:1952
bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, eCDAllocType alloctype, int totelem)
Definition: customdata.c:2098
static void layerInterp_normal(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:326
static void layerInterp_mloopcol(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:881
static void layerCopyValue_normal(const void *source, void *dest, const int mixmode, const float mixfactor)
Definition: customdata.c:369
bool CustomData_layer_has_math(const struct CustomData *data, int layer_n)
Definition: customdata.c:3820
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, eCDAllocType alloctype, int totelem)
Definition: customdata.c:2193
static bool cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
Definition: customdata.c:4328
static void layerDefault_fmap(void *data, int count)
Definition: customdata.c:1260
static void layerCopyValue_mloop_origspace(const void *source, void *dest, const int UNUSED(mixmode), const float UNUSED(mixfactor))
Definition: customdata.c:1018
static void layerDoMinMax_mloopcol(const void *data, void *vmin, void *vmax)
Definition: customdata.c:826
static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask *grid_paint_mask)
Definition: customdata.c:5056
void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask)
Definition: customdata.c:2253
void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest, void *src_block, int dest_index)
Definition: customdata.c:4165
int CustomData_get_clone_layer_index(const CustomData *data, int type)
Definition: customdata.c:2348
static void layerInterp_bweight(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:1161
static const char * LAYERTYPENAMES[CD_NUMTYPES]
Definition: customdata.c:1863
int CustomData_get_render_layer_index(const CustomData *data, int type)
Definition: customdata.c:2341
void CustomData_set_layer_clone_index(CustomData *data, int type, int n)
Definition: customdata.c:2457
void CustomData_copy_data_named(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
Definition: customdata.c:2932
void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs, int count)
Definition: customdata.c:2880
void CustomData_swap_corners(struct CustomData *data, int index, const int *corner_indices)
Definition: customdata.c:3122
void CustomData_duplicate_referenced_layers(CustomData *data, int totelem)
Definition: customdata.c:2818
void CustomData_data_dominmax(int type, const void *data, void *min, void *max)
Definition: customdata.c:3949
void * CustomData_duplicate_referenced_layer_named(CustomData *data, const int type, const char *name, const int totelem)
Definition: customdata.c:2807
static void layerInterp_mloop_origspace(const void **sources, const float *weights, const float *UNUSED(sub_weights), int count, void *dest)
Definition: customdata.c:1066
static void layerDefault_mloopcol(void *data, int count)
Definition: customdata.c:872
void CustomData_external_add(CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename)
Definition: customdata.c:4699
bool CustomData_bmesh_has_free(const struct CustomData *data)
Definition: customdata.c:3856
void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, int src_index, void **dest_block, bool use_default_init)
Definition: customdata.c:4104
#define CUSTOMDATA_GROW
Definition: customdata.c:68
static bool layerValidate_propfloat2(void *data, const uint totitems, const bool do_fixes)
Definition: customdata.c:1465
void CustomData_copy_layer_type_data(const CustomData *source, CustomData *destination, int type, int source_index, int destination_index, int count)
Definition: customdata.c:2980
const CustomData_MeshMasks CD_MASK_MESH
Definition: customdata.c:1933
void CustomData_bmesh_free_block_data(CustomData *data, void *block)
Definition: customdata.c:3633
#define COPY_BIT_FLAG(_type, _dst, _src, _f)
void CustomData_set_layer_stencil(CustomData *data, int type, int n)
Definition: customdata.c:2428
static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size))
Definition: customdata.c:720
const CustomData_MeshMasks CD_MASK_FACECORNERS
Definition: customdata.c:1977
static void layerCopyValue_mloopcol(const void *source, void *dest, const int mixmode, const float mixfactor)
Definition: customdata.c:734
static void layerSwap_mdisps(void *data, const int *ci)
Definition: customdata.c:576
void CustomData_blend_write_prepare(CustomData *data, CustomDataLayer **r_write_layers, CustomDataLayer *write_layers_buff, size_t write_layers_size)
Definition: customdata.c:4237
static void layerMultiply_mloopcol(void *data, float fac)
Definition: customdata.c:805
static void layerInterp_tface(const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
Definition: customdata.c:415
bool CustomData_verify_versions(struct CustomData *data, int index)
Definition: customdata.c:4413
void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data, void *block, const CustomDataMask mask_exclude)
Definition: customdata.c:3669
void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *ldata)
Definition: customdata.c:3411
OperationNode * node
static const float data2[18 *GP_PRIM_DATABUF_SIZE]
static const float data1[33 *GP_PRIM_DATABUF_SIZE]
uint col
int count
#define logf(x)
#define sqrtf(x)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:40
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
static ulong * next
bool isfinite(uchar)
Definition: image.cpp:44
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
static void update(bNodeTree *ntree)
static PropertyRNA * typemap[IDP_NUMTYPES]
Definition: rna_access.c:522
#define min(a, b)
Definition: sort.c:51
unsigned short uint16_t
Definition: stdint.h:82
unsigned int uint32_t
Definition: stdint.h:83
unsigned char uint8_t
Definition: stdint.h:81
unsigned __int64 uint64_t
Definition: stdint.h:93
void * data
Definition: bmesh_class.h:63
BMHeader head
Definition: bmesh_class.h:157
int totvert
Definition: bmesh_class.h:297
int totedge
Definition: bmesh_class.h:297
int totloop
Definition: bmesh_class.h:297
int totface
Definition: bmesh_class.h:297
cd_datatransfer_interp interp
struct BLI_mempool * pool
CustomDataLayer * layers
CustomDataExternal * external
unsigned int level
Definition: DNA_ID.h:273
bool(* write)(CDataFile *cdf, const void *data, int count)
Definition: customdata.c:167
void(* set_default)(void *data, int count)
Definition: customdata.c:150
void(* dominmax)(const void *data1, void *min, void *max)
Definition: customdata.c:160
const char * defaultname
Definition: customdata.c:110
cd_interp interp
Definition: customdata.c:142
void(* free)(void *data, int count, int size)
Definition: customdata.c:125
void(* add)(void *data1, const void *data2)
Definition: customdata.c:159
int(* layers_max)(void)
Definition: customdata.c:174
size_t(* filesize)(CDataFile *cdf, const void *data, int count)
Definition: customdata.c:170
const char * structname
Definition: customdata.c:102
void(* copyvalue)(const void *source, void *dest, const int mixmode, const float mixfactor)
Definition: customdata.c:161
cd_copy copy
Definition: customdata.c:117
bool(* read)(CDataFile *cdf, void *data, int count)
Definition: customdata.c:164
void(* initminmax)(void *min, void *max)
Definition: customdata.c:158
cd_validate validate
Definition: customdata.c:153
void(* swap)(void *data, const int *corner_indices)
Definition: customdata.c:145
bool(* equal)(const void *data1, const void *data2)
Definition: customdata.c:156
void(* multiply)(void *data, float fac)
Definition: customdata.c:157
unsigned char r
unsigned char a
unsigned char g
unsigned char b
struct MDeformWeight * dw
unsigned int def_nr
float(* disps)[3]
unsigned int * hidden
unsigned char a
unsigned char b
unsigned char r
unsigned char g
float color[4]
float uv[4][2]
MeshPairRemapItem * items
float x
Definition: DNA_vec_types.h:39
float y
Definition: DNA_vec_types.h:39
float x
Definition: DNA_vec_types.h:57
float z
Definition: DNA_vec_types.h:57
float y
Definition: DNA_vec_types.h:57
float max
ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
PointerRNA * ptr
Definition: wm_files.c:3157