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