4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2006 Blender Foundation.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): Ben Batt <benbatt@gmail.com>
27 * ***** END GPL LICENSE BLOCK *****
29 * Implementation of CustomData.
31 * BKE_customdata.h contains the function prototypes for this file.
35 /** \file blender/blenkernel/intern/customdata.c
44 #include "MEM_guardedalloc.h"
46 #include "DNA_meshdata_types.h"
49 #include "BLI_utildefines.h"
50 #include "BLI_blenlib.h"
51 #include "BLI_path_util.h"
52 #include "BLI_linklist.h"
54 #include "BLI_mempool.h"
55 #include "BLI_cellalloc.h"
56 #include "BLI_utildefines.h"
58 #include "BKE_customdata.h"
59 #include "BKE_customdata_file.h"
60 #include "BKE_global.h"
62 #include "BKE_multires.h"
69 /* number of layers to add when growing a CustomData object */
70 #define CUSTOMDATA_GROW 5
72 /********************* Layer type information **********************/
73 typedef struct LayerTypeInfo {
74 int size; /* the memory size of one element of this layer's data */
75 const char *structname; /* name of the struct used, for file writing */
76 int structnum; /* number of structs per element, for file writing */
77 const char *defaultname; /* default layer name */
79 /* a function to copy count elements of this layer's data
80 * (deep copy if appropriate)
81 * if NULL, memcpy is used
83 void (*copy)(const void *source, void *dest, int count);
85 /* a function to free any dynamically allocated components of this
86 * layer's data (note the data pointer itself should not be freed)
87 * size should be the size of one element of this layer's data (e.g.
90 void (*free)(void *data, int count, int size);
92 /* a function to interpolate between count source elements of this
93 * layer's data and store the result in dest
94 * if weights == NULL or sub_weights == NULL, they should default to 1
96 * weights gives the weight for each element in sources
97 * sub_weights gives the sub-element weights for each element in sources
98 * (there should be (sub element count)^2 weights per element)
99 * count gives the number of elements in sources
101 void (*interp)(void **sources, float *weights, float *sub_weights,
102 int count, void *dest);
104 /* a function to swap the data in corners of the element */
105 void (*swap)(void *data, const int *corner_indices);
107 /* a function to set a layer's data to default values. if NULL, the
108 default is assumed to be all zeros */
109 void (*set_default)(void *data, int count);
111 /* functions necassary for geometry collapse*/
112 int (*equal)(void *data1, void *data2);
113 void (*multiply)(void *data, float fac);
114 void (*initminmax)(void *min, void *max);
115 void (*add)(void *data1, void *data2);
116 void (*dominmax)(void *data1, void *min, void *max);
117 void (*copyvalue)(void *source, void *dest);
119 /* a function to read data from a cdf file */
120 int (*read)(CDataFile *cdf, void *data, int count);
122 /* a function to write data to a cdf file */
123 int (*write)(CDataFile *cdf, void *data, int count);
125 /* a function to determine file size */
126 size_t (*filesize)(CDataFile *cdf, void *data, int count);
128 /* a function to validate layer contents depending on
131 void (*validate)(void *source, int sub_elements);
134 static void layerCopy_mdeformvert(const void *source, void *dest,
137 int i, size = sizeof(MDeformVert);
139 memcpy(dest, source, count * size);
141 for(i = 0; i < count; ++i) {
142 MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size);
144 if(dvert->totweight) {
145 MDeformWeight *dw = BLI_cellalloc_calloc(dvert->totweight * sizeof(*dw),
146 "layerCopy_mdeformvert dw");
148 memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw));
156 static void layerFree_mdeformvert(void *data, int count, int size)
160 for(i = 0; i < count; ++i) {
161 MDeformVert *dvert = (MDeformVert *)((char *)data + i * size);
164 BLI_cellalloc_free(dvert->dw);
166 dvert->totweight = 0;
171 static void linklist_free_simple(void *link)
173 BLI_cellalloc_free(link);
176 static void layerInterp_mdeformvert(void **sources, float *weights,
177 float *UNUSED(sub_weights), int count, void *dest)
179 MDeformVert *dvert = dest;
180 LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */
184 if(count <= 0) return;
186 /* build a list of unique def_nrs for dest */
188 for(i = 0; i < count; ++i) {
189 MDeformVert *source = sources[i];
190 float interp_weight = weights ? weights[i] : 1.0f;
192 for(j = 0; j < source->totweight; ++j) {
193 MDeformWeight *dw = &source->dw[j];
195 for(node = dest_dw; node; node = node->next) {
196 MDeformWeight *tmp_dw = (MDeformWeight *)node->link;
198 if(tmp_dw->def_nr == dw->def_nr) {
199 tmp_dw->weight += dw->weight * interp_weight;
204 /* if this def_nr is not in the list, add it */
206 MDeformWeight *tmp_dw = BLI_cellalloc_calloc(sizeof(*tmp_dw),
207 "layerInterp_mdeformvert tmp_dw");
208 tmp_dw->def_nr = dw->def_nr;
209 tmp_dw->weight = dw->weight * interp_weight;
210 BLI_linklist_prepend(&dest_dw, tmp_dw);
216 /* now we know how many unique deform weights there are, so realloc */
217 if(dvert->dw) BLI_cellalloc_free(dvert->dw);
220 dvert->dw = BLI_cellalloc_calloc(sizeof(*dvert->dw) * totweight,
221 "layerInterp_mdeformvert dvert->dw");
222 dvert->totweight = totweight;
224 for(i = 0, node = dest_dw; node; node = node->next, ++i)
225 dvert->dw[i] = *((MDeformWeight *)node->link);
228 memset(dvert, 0, sizeof(*dvert));
230 BLI_linklist_free(dest_dw, linklist_free_simple);
234 static void layerInterp_msticky(void **sources, float *weights,
235 float *UNUSED(sub_weights), int count, void *dest)
241 co[0] = co[1] = 0.0f;
242 for(i = 0; i < count; i++) {
243 w = weights ? weights[i] : 1.0f;
244 mst = (MSticky*)sources[i];
246 co[0] += w*mst->co[0];
247 co[1] += w*mst->co[1];
250 mst = (MSticky*)dest;
256 static void layerCopy_tface(const void *source, void *dest, int count)
258 const MTFace *source_tf = (const MTFace*)source;
259 MTFace *dest_tf = (MTFace*)dest;
262 for(i = 0; i < count; ++i)
263 dest_tf[i] = source_tf[i];
266 static void layerInterp_tface(void **sources, float *weights,
267 float *sub_weights, int count, void *dest)
274 if(count <= 0) return;
276 memset(uv, 0, sizeof(uv));
278 sub_weight = sub_weights;
279 for(i = 0; i < count; ++i) {
280 float weight = weights ? weights[i] : 1;
281 MTFace *src = sources[i];
283 for(j = 0; j < 4; ++j) {
285 for(k = 0; k < 4; ++k, ++sub_weight) {
286 float w = (*sub_weight) * weight;
287 float *tmp_uv = src->uv[k];
289 uv[j][0] += tmp_uv[0] * w;
290 uv[j][1] += tmp_uv[1] * w;
293 uv[j][0] += src->uv[j][0] * weight;
294 uv[j][1] += src->uv[j][1] * weight;
299 *tf = *(MTFace *)sources[0];
300 for(j = 0; j < 4; ++j) {
301 tf->uv[j][0] = uv[j][0];
302 tf->uv[j][1] = uv[j][1];
306 static void layerSwap_tface(void *data, const int *corner_indices)
310 static const short pin_flags[4] =
311 { TF_PIN1, TF_PIN2, TF_PIN3, TF_PIN4 };
312 static const char sel_flags[4] =
313 { TF_SEL1, TF_SEL2, TF_SEL3, TF_SEL4 };
314 short unwrap = tf->unwrap & ~(TF_PIN1 | TF_PIN2 | TF_PIN3 | TF_PIN4);
315 char flag = tf->flag & ~(TF_SEL1 | TF_SEL2 | TF_SEL3 | TF_SEL4);
318 for(j = 0; j < 4; ++j) {
319 int source_index = corner_indices[j];
321 uv[j][0] = tf->uv[source_index][0];
322 uv[j][1] = tf->uv[source_index][1];
324 // swap pinning flags around
325 if(tf->unwrap & pin_flags[source_index]) {
326 unwrap |= pin_flags[j];
329 // swap selection flags around
330 if(tf->flag & sel_flags[source_index]) {
331 flag |= sel_flags[j];
335 memcpy(tf->uv, uv, sizeof(tf->uv));
340 static void layerDefault_tface(void *data, int count)
342 static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL,
343 0, 0, TF_DYNAMIC, 0, 0};
344 MTFace *tf = (MTFace*)data;
347 for(i = 0; i < count; i++)
351 static void layerCopy_propFloat(const void *source, void *dest,
354 memcpy(dest, source, sizeof(MFloatProperty)*count);
357 static void layerCopy_propInt(const void *source, void *dest,
360 memcpy(dest, source, sizeof(MIntProperty)*count);
363 static void layerCopy_propString(const void *source, void *dest,
366 memcpy(dest, source, sizeof(MStringProperty)*count);
369 static void layerCopy_origspace_face(const void *source, void *dest, int count)
371 const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
372 OrigSpaceFace *dest_tf = (OrigSpaceFace*)dest;
375 for(i = 0; i < count; ++i)
376 dest_tf[i] = source_tf[i];
379 static void layerInterp_origspace_face(void **sources, float *weights,
380 float *sub_weights, int count, void *dest)
382 OrigSpaceFace *osf = dest;
387 if(count <= 0) return;
389 memset(uv, 0, sizeof(uv));
391 sub_weight = sub_weights;
392 for(i = 0; i < count; ++i) {
393 float weight = weights ? weights[i] : 1;
394 OrigSpaceFace *src = sources[i];
396 for(j = 0; j < 4; ++j) {
398 for(k = 0; k < 4; ++k, ++sub_weight) {
399 float w = (*sub_weight) * weight;
400 float *tmp_uv = src->uv[k];
402 uv[j][0] += tmp_uv[0] * w;
403 uv[j][1] += tmp_uv[1] * w;
406 uv[j][0] += src->uv[j][0] * weight;
407 uv[j][1] += src->uv[j][1] * weight;
412 *osf = *(OrigSpaceFace *)sources[0];
413 for(j = 0; j < 4; ++j) {
414 osf->uv[j][0] = uv[j][0];
415 osf->uv[j][1] = uv[j][1];
419 static void layerSwap_origspace_face(void *data, const int *corner_indices)
421 OrigSpaceFace *osf = data;
425 for(j = 0; j < 4; ++j) {
426 uv[j][0] = osf->uv[corner_indices[j]][0];
427 uv[j][1] = osf->uv[corner_indices[j]][1];
429 memcpy(osf->uv, uv, sizeof(osf->uv));
432 static void layerDefault_origspace_face(void *data, int count)
434 static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
435 OrigSpaceFace *osf = (OrigSpaceFace*)data;
438 for(i = 0; i < count; i++)
439 osf[i] = default_osf;
442 static void layerSwap_mdisps(void *data, const int *ci)
445 float (*d)[3] = NULL;
446 int corners, cornersize, S;
449 int nverts= (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */
450 corners= multires_mdisp_corners(s);
451 cornersize= s->totdisp/corners;
453 if(corners!=nverts) {
454 /* happens when face changed vertex count in edit mode
455 if it happened, just forgot displacement */
457 BLI_cellalloc_free(s->disps);
458 s->totdisp= (s->totdisp/corners)*nverts;
459 s->disps= BLI_cellalloc_calloc(s->totdisp*sizeof(float)*3, "mdisp swap");
463 d= BLI_cellalloc_calloc(sizeof(float) * 3 * s->totdisp, "mdisps swap");
465 for(S = 0; S < corners; S++)
466 memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float));
468 BLI_cellalloc_free(s->disps);
473 #if 1 /* BMESH_TODO: place holder function, dont actually interp */
474 static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
475 float *UNUSED(sub_weights), int UNUSED(count), void *dest)
479 /* happens when flipping normals of newly created mesh */
481 d->totdisp = ((MDisps*)sources[0])->totdisp;
484 if (!d->disps && d->totdisp)
485 d->disps = BLI_cellalloc_calloc(sizeof(float)*3*d->totdisp, "blank mdisps in layerInterp_mdisps");
490 static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
491 float *sub_weights, int count, void *dest)
497 int side, S, dst_corners, src_corners;
498 float crn_weight[4][2];
499 float (*sw)[4] = (void*)sub_weights;
500 float (*disps)[3], (*out)[3];
502 /* happens when flipping normals of newly created mesh */
507 dst_corners = multires_mdisp_corners(d);
508 src_corners = multires_mdisp_corners(s);
510 if(sub_weights && count == 2 && src_corners == 3) {
511 src_corners = multires_mdisp_corners(sources[1]);
513 /* special case -- converting two triangles to quad */
514 if(src_corners == 3 && dst_corners == 4) {
518 for(i = 0; i < 2; i++)
519 for(y = 0; y < 4; y++)
520 for(x = 0; x < 4; x++)
524 for(i = 0; i < 2; i++) {
525 float sw_m4[4][4] = {{0}};
526 int a = 7 & ~(1 << vindex[i*2] | 1 << vindex[i*2+1]);
528 sw_m4[0][vindex[i*2+1]] = 1;
529 sw_m4[1][vindex[i*2]] = 1;
531 for(x = 0; x < 3; x++)
535 tris[i] = *((MDisps*)sources[i]);
536 tris[i].disps = MEM_dupallocN(tris[i].disps);
537 layerInterp_mdisps(&sources[i], NULL, (float*)sw_m4, 1, &tris[i]);
540 mdisp_join_tris(d, &tris[0], &tris[1]);
542 for(i = 0; i < 2; i++)
543 MEM_freeN(tris[i].disps);
549 /* For now, some restrictions on the input */
550 if(count != 1 || !sub_weights) {
551 for(i = 0; i < d->totdisp; ++i)
552 zero_v3(d->disps[i]);
557 /* Initialize the destination */
558 disps = MEM_callocN(3*d->totdisp*sizeof(float), "iterp disps");
560 side = sqrt(d->totdisp / dst_corners);
564 sw= (void*)sub_weights;
565 for(i = 0; i < 4; ++i) {
566 crn_weight[i][0] = 0 * sw[i][0] + stl * sw[i][1] + stl * sw[i][2] + 0 * sw[i][3];
567 crn_weight[i][1] = 0 * sw[i][0] + 0 * sw[i][1] + stl * sw[i][2] + stl * sw[i][3];
570 multires_mdisp_smooth_bounds(s);
573 for(S = 0; S < dst_corners; S++) {
574 float base[2], axis_x[2], axis_y[2];
576 mdisp_apply_weight(S, dst_corners, 0, 0, st, crn_weight, &base[0], &base[1]);
577 mdisp_apply_weight(S, dst_corners, side-1, 0, st, crn_weight, &axis_x[0], &axis_x[1]);
578 mdisp_apply_weight(S, dst_corners, 0, side-1, st, crn_weight, &axis_y[0], &axis_y[1]);
580 sub_v2_v2(axis_x, base);
581 sub_v2_v2(axis_y, base);
582 normalize_v2(axis_x);
583 normalize_v2(axis_y);
585 for(y = 0; y < side; ++y) {
586 for(x = 0; x < side; ++x, ++out) {
588 float face_u, face_v, crn_u, crn_v;
590 mdisp_apply_weight(S, dst_corners, x, y, st, crn_weight, &face_u, &face_v);
591 crn = mdisp_rot_face_to_quad_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
593 old_mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
594 mdisp_flip_disp(crn, dst_corners, axis_x, axis_y, *out);
604 static void layerCopy_mdisps(const void *source, void *dest, int count)
607 const MDisps *s = source;
610 for(i = 0; i < count; ++i) {
612 d[i].disps = BLI_cellalloc_dupalloc(s[i].disps);
613 d[i].totdisp = s[i].totdisp;
623 static void layerValidate_mdisps(void *data, int sub_elements)
629 MDisps *disps = data;
631 int corners = multires_mdisp_corners(disps);
633 if(corners != sub_elements) {
634 MEM_freeN(disps->disps);
635 disps->totdisp = disps->totdisp / corners * sub_elements;
636 disps->disps = BLI_cellalloc_calloc(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
642 static void layerFree_mdisps(void *data, int count, int UNUSED(size))
647 for(i = 0; i < count; ++i) {
649 BLI_cellalloc_free(d[i].disps);
655 static int layerRead_mdisps(CDataFile *cdf, void *data, int count)
660 for(i = 0; i < count; ++i) {
662 d[i].disps = BLI_cellalloc_calloc(sizeof(float)*3*d[i].totdisp, "mdisps read");
664 if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
665 printf("failed to read multires displacement %d/%d %d\n", i, count, d[i].totdisp);
673 static int layerWrite_mdisps(CDataFile *cdf, void *data, int count)
678 for(i = 0; i < count; ++i) {
679 if(!cdf_write_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
680 printf("failed to write multires displacement %d/%d %d\n", i, count, d[i].totdisp);
688 static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), void *data, int count)
694 for(i = 0; i < count; ++i)
695 size += d[i].totdisp*3*sizeof(float);
701 static void layerCopyValue_mloopcol(void *source, void *dest)
703 MLoopCol *m1 = source, *m2 = dest;
711 static int layerEqual_mloopcol(void *data1, void *data2)
713 MLoopCol *m1 = data1, *m2 = data2;
721 return r*r + g*g + b*b + a*a < 0.001;
724 static void layerMultiply_mloopcol(void *data, float fac)
728 m->r = (float)m->r * fac;
729 m->g = (float)m->g * fac;
730 m->b = (float)m->b * fac;
731 m->a = (float)m->a * fac;
734 static void layerAdd_mloopcol(void *data1, void *data2)
736 MLoopCol *m = data1, *m2 = data2;
744 static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax)
747 MLoopCol *min = vmin, *max = vmax;
749 if (m->r < min->r) min->r = m->r;
750 if (m->g < min->g) min->g = m->g;
751 if (m->b < min->b) min->b = m->b;
752 if (m->a < min->a) min->a = m->a;
754 if (m->r > max->r) max->r = m->r;
755 if (m->g > max->g) max->g = m->g;
756 if (m->b > max->b) max->b = m->b;
757 if (m->a > max->a) max->a = m->a;
760 static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
762 MLoopCol *min = vmin, *max = vmax;
775 static void layerDefault_mloopcol(void *data, int count)
777 MLoopCol default_mloopcol = {255,255,255,255};
778 MLoopCol *mlcol = (MLoopCol*)data;
780 for(i = 0; i < count; i++)
781 mlcol[i] = default_mloopcol;
785 static void layerInterp_mloopcol(void **sources, float *weights,
786 float *sub_weights, int count, void *dest)
797 col.a = col.r = col.g = col.b = 0;
799 sub_weight = sub_weights;
800 for(i = 0; i < count; ++i){
801 float weight = weights ? weights[i] : 1;
802 MLoopCol *src = sources[i];
804 col.a += src->a * (*sub_weight) * weight;
805 col.r += src->r * (*sub_weight) * weight;
806 col.g += src->g * (*sub_weight) * weight;
807 col.b += src->b * (*sub_weight) * weight;
810 col.a += src->a * weight;
811 col.r += src->r * weight;
812 col.g += src->g * weight;
813 col.b += src->b * weight;
817 /* Subdivide smooth or fractal can cause problems without clamping
818 * although weights should also not cause this situation */
819 CLAMP(col.a, 0.0f, 255.0f);
820 CLAMP(col.r, 0.0f, 255.0f);
821 CLAMP(col.g, 0.0f, 255.0f);
822 CLAMP(col.b, 0.0f, 255.0f);
830 static void layerCopyValue_mloopuv(void *source, void *dest)
832 MLoopUV *luv1 = source, *luv2 = dest;
834 luv2->uv[0] = luv1->uv[0];
835 luv2->uv[1] = luv1->uv[1];
838 static int layerEqual_mloopuv(void *data1, void *data2)
840 MLoopUV *luv1 = data1, *luv2 = data2;
843 u = luv1->uv[0] - luv2->uv[0];
844 v = luv1->uv[1] - luv2->uv[1];
846 return u*u + v*v < 0.00001;
849 static void layerMultiply_mloopuv(void *data, float fac)
857 static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
859 MLoopUV *min = vmin, *max = vmax;
861 INIT_MINMAX2(min->uv, max->uv);
864 static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
866 MLoopUV *min = vmin, *max = vmax, *luv = data;
868 DO_MINMAX2(luv->uv, min->uv, max->uv);
871 static void layerAdd_mloopuv(void *data1, void *data2)
873 MLoopUV *l1 = data1, *l2 = data2;
875 l1->uv[0] += l2->uv[0];
876 l1->uv[1] += l2->uv[1];
879 static void layerInterp_mloopuv(void **sources, float *weights,
880 float *sub_weights, int count, void *dest)
882 MLoopUV *mluv = dest;
891 sub_weight = sub_weights;
892 for(i = 0; i < count; ++i){
893 float weight = weights ? weights[i] : 1;
894 MLoopUV *src = sources[i];
896 uv.u += src->uv[0] * (*sub_weight) * weight;
897 uv.v += src->uv[1] * (*sub_weight) * weight;
900 uv.u += src->uv[0] * weight;
901 uv.v += src->uv[1] * weight;
908 static void layerInterp_mcol(void **sources, float *weights,
909 float *sub_weights, int count, void *dest)
921 if(count <= 0) return;
923 memset(col, 0, sizeof(col));
925 sub_weight = sub_weights;
926 for(i = 0; i < count; ++i) {
927 float weight = weights ? weights[i] : 1;
929 for(j = 0; j < 4; ++j) {
931 MCol *src = sources[i];
932 for(k = 0; k < 4; ++k, ++sub_weight, ++src) {
933 col[j].a += src->a * (*sub_weight) * weight;
934 col[j].r += src->r * (*sub_weight) * weight;
935 col[j].g += src->g * (*sub_weight) * weight;
936 col[j].b += src->b * (*sub_weight) * weight;
939 MCol *src = sources[i];
940 col[j].a += src[j].a * weight;
941 col[j].r += src[j].r * weight;
942 col[j].g += src[j].g * weight;
943 col[j].b += src[j].b * weight;
948 for(j = 0; j < 4; ++j) {
950 /* Subdivide smooth or fractal can cause problems without clamping
951 * although weights should also not cause this situation */
952 CLAMP(col[j].a, 0.0f, 255.0f);
953 CLAMP(col[j].r, 0.0f, 255.0f);
954 CLAMP(col[j].g, 0.0f, 255.0f);
955 CLAMP(col[j].b, 0.0f, 255.0f);
957 mc[j].a = (int)col[j].a;
958 mc[j].r = (int)col[j].r;
959 mc[j].g = (int)col[j].g;
960 mc[j].b = (int)col[j].b;
964 static void layerSwap_mcol(void *data, const int *corner_indices)
970 for(j = 0; j < 4; ++j)
971 col[j] = mcol[corner_indices[j]];
973 memcpy(mcol, col, sizeof(col));
976 static void layerDefault_mcol(void *data, int count)
978 static MCol default_mcol = {255, 255, 255, 255};
979 MCol *mcol = (MCol*)data;
982 for(i = 0; i < 4*count; i++)
983 mcol[i] = default_mcol;
986 static void layerInterp_bweight(void **sources, float *weights,
987 float *UNUSED(sub_weights), int count, void *dest)
989 float *f = dest, *src;
990 float **in = (float **)sources;
993 if(count <= 0) return;
997 for(i = 0; i < count; ++i) {
998 float weight = weights ? weights[i] : 1.0f;
1001 *f += *src * weight;
1005 static void layerInterp_shapekey(void **sources, float *weights,
1006 float *UNUSED(sub_weights), int count, void *dest)
1008 float *co = dest, *src;
1009 float **in = (float **)sources;
1012 if(count <= 0) return;
1014 memset(co, 0, sizeof(float)*3);
1016 for(i = 0; i < count; ++i) {
1017 float weight = weights ? weights[i] : 1.0f;
1020 co[0] += src[0] * weight;
1021 co[1] += src[1] * weight;
1022 co[2] += src[2] * weight;
1026 /* note, these numbered comments below are copied from trunk,
1027 * while _most_ match, some at the end need adding and are out of sync */
1029 static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
1031 {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1033 {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
1035 /* 2: CD_MDEFORMVERT */
1036 {sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert,
1037 layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL},
1039 {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1041 {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1043 {sizeof(MTFace), "MTFace", 1, "UVTex", layerCopy_tface, NULL,
1044 layerInterp_tface, layerSwap_tface, layerDefault_tface},
1046 /* 4 MCol structs per face */
1047 {sizeof(MCol)*4, "MCol", 4, "Col", NULL, NULL, layerInterp_mcol,
1048 layerSwap_mcol, layerDefault_mcol},
1049 /* 7: CD_ORIGINDEX */
1050 {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1052 /* 3 floats per normal vector */
1053 {sizeof(float)*3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
1055 {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1056 /* 10: CD_PROP_FLT */
1057 {sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
1058 /* 11: CD_PROP_INT */
1059 {sizeof(MIntProperty), "MIntProperty",1,"Int",layerCopy_propInt,NULL,NULL,NULL},
1060 /* 12: CD_PROP_STR */
1061 {sizeof(MStringProperty), "MStringProperty",1,"String",layerCopy_propString,NULL,NULL,NULL},
1062 /* 13: CD_ORIGSPACE */
1063 {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
1064 layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
1066 {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1067 /* 15: CD_MTEXPOLY */
1068 {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
1069 /* 16: CD_MLOOPUV */
1070 {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL,
1071 layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv,
1072 layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv},
1073 /* 17: CD_MLOOPCOL */
1074 {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL,
1075 layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
1076 layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
1077 {sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1079 {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
1080 layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL,
1081 NULL, NULL, NULL, NULL, NULL, NULL,
1082 layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps, layerValidate_mdisps},
1083 /* 20: CD_WEIGHT_MCOL */
1084 {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
1085 layerSwap_mcol, layerDefault_mcol},
1086 {sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
1087 {sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL},
1088 {sizeof(float)*3, "", 0, "ClothOrco", NULL, NULL, layerInterp_shapekey},
1089 /* 21: CD_ID_MCOL */
1090 {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
1091 layerSwap_mcol, layerDefault_mcol},
1092 {sizeof(MCol)*4, "MCol", 4, "TextureCol", NULL, NULL, layerInterp_mcol,
1093 layerSwap_mcol, layerDefault_mcol},
1094 {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
1095 {sizeof(float)*3, "", 0, "ShapeKey", NULL, NULL, layerInterp_shapekey},
1096 {sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
1097 {sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
1098 {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
1099 layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
1100 layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
1103 static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
1104 "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
1105 "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
1106 "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
1107 "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDMPoly",
1108 "CDMLoop", "CDMClothOrco", "CDMLoopCol", "CDIDCol", "CDTextureCol",
1109 "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", "CDSubSurfCrease"
1113 const CustomDataMask CD_MASK_BAREMESH =
1114 CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MLOOP | CD_MASK_MPOLY | CD_MASK_BWEIGHT;
1115 const CustomDataMask CD_MASK_MESH =
1116 CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
1117 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
1118 CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
1119 CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
1120 CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_MDISPS;
1121 const CustomDataMask CD_MASK_EDITMESH =
1122 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
1123 CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
1124 CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
1125 CD_MASK_MDISPS | CD_MASK_SHAPEKEY;
1126 const CustomDataMask CD_MASK_DERIVEDMESH =
1127 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
1128 CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
1129 CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
1130 CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT |
1131 CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY;
1132 const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
1133 CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
1134 CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS;
1135 const CustomDataMask CD_MASK_FACECORNERS =
1136 CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
1139 static const LayerTypeInfo *layerType_getInfo(int type)
1141 if(type < 0 || type >= CD_NUMTYPES) return NULL;
1143 return &LAYERTYPEINFO[type];
1146 static const char *layerType_getName(int type)
1148 if(type < 0 || type >= CD_NUMTYPES) return NULL;
1150 return LAYERTYPENAMES[type];
1153 /********************* CustomData functions *********************/
1154 static void customData_update_offsets(CustomData *data);
1156 static CustomDataLayer *customData_add_layer__internal(CustomData *data,
1157 int type, int alloctype, void *layerdata, int totelem, const char *name);
1159 void CustomData_update_typemap(CustomData *data)
1161 int i, lasttype = -1;
1163 for (i=0; i<CD_NUMTYPES; i++) {
1164 data->typemap[i] = -1;
1167 for (i=0; i<data->totlayer; i++) {
1168 if (data->layers[i].type != lasttype) {
1169 data->typemap[data->layers[i].type] = i;
1171 lasttype = data->layers[i].type;
1175 void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
1176 CustomDataMask mask, int alloctype, int totelem)
1178 /*const LayerTypeInfo *typeInfo;*/
1179 CustomDataLayer *layer, *newlayer;
1180 int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0;
1182 for(i = 0; i < source->totlayer; ++i) {
1183 layer = &source->layers[i];
1184 /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/
1188 if (type != lasttype) {
1190 lastactive = layer->active;
1191 lastrender = layer->active_rnd;
1192 lastclone = layer->active_clone;
1193 lastmask = layer->active_mask;
1195 lastflag = layer->flag;
1200 if(lastflag & CD_FLAG_NOCOPY) continue;
1201 else if(!((int)mask & (int)(1 << (int)type))) continue;
1202 else if(number < CustomData_number_of_layers(dest, type)) continue;
1204 if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE))
1205 newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE,
1206 layer->data, totelem, layer->name);
1208 newlayer = customData_add_layer__internal(dest, type, alloctype,
1209 layer->data, totelem, layer->name);
1212 newlayer->uid = layer->uid;
1214 newlayer->active = lastactive;
1215 newlayer->active_rnd = lastrender;
1216 newlayer->active_clone = lastclone;
1217 newlayer->active_mask = lastmask;
1218 newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY);
1222 CustomData_update_typemap(dest);
1225 void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
1226 CustomDataMask mask, int alloctype, int totelem)
1228 memset(dest, 0, sizeof(*dest));
1230 if(source->external)
1231 dest->external= MEM_dupallocN(source->external);
1233 CustomData_merge(source, dest, mask, alloctype, totelem);
1236 static void customData_free_layer__internal(CustomDataLayer *layer, int totelem)
1238 const LayerTypeInfo *typeInfo;
1240 if(!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
1241 typeInfo = layerType_getInfo(layer->type);
1244 typeInfo->free(layer->data, totelem, typeInfo->size);
1247 MEM_freeN(layer->data);
1251 static void CustomData_external_free(CustomData *data)
1253 if(data->external) {
1254 MEM_freeN(data->external);
1255 data->external= NULL;
1259 void CustomData_free(CustomData *data, int totelem)
1263 for(i = 0; i < data->totlayer; ++i)
1264 customData_free_layer__internal(&data->layers[i], totelem);
1267 MEM_freeN(data->layers);
1269 CustomData_external_free(data);
1271 memset(data, 0, sizeof(*data));
1274 static void customData_update_offsets(CustomData *data)
1276 const LayerTypeInfo *typeInfo;
1279 for(i = 0; i < data->totlayer; ++i) {
1280 typeInfo = layerType_getInfo(data->layers[i].type);
1282 data->layers[i].offset = offset;
1283 offset += typeInfo->size;
1286 data->totsize = offset;
1287 CustomData_update_typemap(data);
1290 int CustomData_get_layer_index(const CustomData *data, int type)
1294 for(i=0; i < data->totlayer; ++i)
1295 if(data->layers[i].type == type)
1301 int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
1305 for(i=0; i < data->totlayer; ++i)
1306 if(data->layers[i].type == type)
1312 int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
1316 for(i=0; i < data->totlayer; ++i)
1317 if(data->layers[i].type == type && strcmp(data->layers[i].name, name)==0)
1323 int CustomData_get_active_layer_index(const CustomData *data, int type)
1325 if (!data->totlayer)
1328 if (data->typemap[type] != -1) {
1329 return data->typemap[type] + data->layers[data->typemap[type]].active;
1335 int CustomData_get_render_layer_index(const CustomData *data, int type)
1339 for(i=0; i < data->totlayer; ++i)
1340 if(data->layers[i].type == type)
1341 return i + data->layers[i].active_rnd;
1346 int CustomData_get_clone_layer_index(const CustomData *data, int type)
1350 for(i=0; i < data->totlayer; ++i)
1351 if(data->layers[i].type == type)
1352 return i + data->layers[i].active_clone;
1357 int CustomData_get_stencil_layer_index(const CustomData *data, int type)
1361 for(i=0; i < data->totlayer; ++i)
1362 if(data->layers[i].type == type)
1363 return i + data->layers[i].active_mask;
1368 int CustomData_get_active_layer(const CustomData *data, int type)
1372 for(i=0; i < data->totlayer; ++i)
1373 if(data->layers[i].type == type)
1374 return data->layers[i].active;
1379 int CustomData_get_render_layer(const CustomData *data, int type)
1383 for(i=0; i < data->totlayer; ++i)
1384 if(data->layers[i].type == type)
1385 return data->layers[i].active_rnd;
1390 int CustomData_get_clone_layer(const CustomData *data, int type)
1394 for(i=0; i < data->totlayer; ++i)
1395 if(data->layers[i].type == type)
1396 return data->layers[i].active_clone;
1401 int CustomData_get_stencil_layer(const CustomData *data, int type)
1405 for(i=0; i < data->totlayer; ++i)
1406 if(data->layers[i].type == type)
1407 return data->layers[i].active_mask;
1412 void CustomData_set_layer_active(CustomData *data, int type, int n)
1416 for(i=0; i < data->totlayer; ++i)
1417 if(data->layers[i].type == type)
1418 data->layers[i].active = n;
1421 void CustomData_set_layer_render(CustomData *data, int type, int n)
1425 for(i=0; i < data->totlayer; ++i)
1426 if(data->layers[i].type == type)
1427 data->layers[i].active_rnd = n;
1430 void CustomData_set_layer_clone(CustomData *data, int type, int n)
1434 for(i=0; i < data->totlayer; ++i)
1435 if(data->layers[i].type == type)
1436 data->layers[i].active_clone = n;
1439 void CustomData_set_layer_stencil(CustomData *data, int type, int n)
1443 for(i=0; i < data->totlayer; ++i)
1444 if(data->layers[i].type == type)
1445 data->layers[i].active_mask = n;
1448 /* for using with an index from CustomData_get_active_layer_index and CustomData_get_render_layer_index */
1449 void CustomData_set_layer_active_index(CustomData *data, int type, int n)
1453 for(i=0; i < data->totlayer; ++i)
1454 if(data->layers[i].type == type)
1455 data->layers[i].active = n-i;
1458 void CustomData_set_layer_render_index(CustomData *data, int type, int n)
1462 for(i=0; i < data->totlayer; ++i)
1463 if(data->layers[i].type == type)
1464 data->layers[i].active_rnd = n-i;
1467 void CustomData_set_layer_clone_index(CustomData *data, int type, int n)
1471 for(i=0; i < data->totlayer; ++i)
1472 if(data->layers[i].type == type)
1473 data->layers[i].active_clone = n-i;
1476 void CustomData_set_layer_stencil_index(CustomData *data, int type, int n)
1480 for(i=0; i < data->totlayer; ++i)
1481 if(data->layers[i].type == type)
1482 data->layers[i].active_mask = n-i;
1485 void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
1489 for(i=0; i < data->totlayer; ++i)
1490 if(data->layers[i].type == type)
1491 data->layers[i].flag |= flag;
1494 static int customData_resize(CustomData *data, int amount)
1496 CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxlayer + amount),
1497 "CustomData->layers");
1500 data->maxlayer += amount;
1502 memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer);
1503 MEM_freeN(data->layers);
1510 static CustomDataLayer *customData_add_layer__internal(CustomData *data,
1511 int type, int alloctype, void *layerdata, int totelem, const char *name)
1513 const LayerTypeInfo *typeInfo= layerType_getInfo(type);
1514 int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
1517 if (!typeInfo->defaultname && CustomData_has_layer(data, type))
1518 return &data->layers[CustomData_get_layer_index(data, type)];
1520 if((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) {
1521 newlayerdata = layerdata;
1524 newlayerdata = MEM_callocN(size, layerType_getName(type));
1529 if (alloctype == CD_DUPLICATE && layerdata) {
1531 typeInfo->copy(layerdata, newlayerdata, totelem);
1533 memcpy(newlayerdata, layerdata, size);
1535 else if (alloctype == CD_DEFAULT) {
1536 if(typeInfo->set_default)
1537 typeInfo->set_default((char*)newlayerdata, totelem);
1539 else if (alloctype == CD_REFERENCE)
1540 flag |= CD_FLAG_NOFREE;
1542 if(index >= data->maxlayer) {
1543 if(!customData_resize(data, CUSTOMDATA_GROW)) {
1544 if(newlayerdata != layerdata)
1545 MEM_freeN(newlayerdata);
1552 /* keep layers ordered by type */
1553 for( ; index > 0 && data->layers[index - 1].type > type; --index)
1554 data->layers[index] = data->layers[index - 1];
1556 data->layers[index].type = type;
1557 data->layers[index].flag = flag;
1558 data->layers[index].data = newlayerdata;
1560 if(name || (name=typeInfo->defaultname)) {
1561 BLI_strncpy(data->layers[index].name, name, 32);
1562 CustomData_set_layer_unique_name(data, index);
1565 data->layers[index].name[0] = '\0';
1567 if(index > 0 && data->layers[index-1].type == type) {
1568 data->layers[index].active = data->layers[index-1].active;
1569 data->layers[index].active_rnd = data->layers[index-1].active_rnd;
1570 data->layers[index].active_clone = data->layers[index-1].active_clone;
1571 data->layers[index].active_mask = data->layers[index-1].active_mask;
1573 data->layers[index].active = 0;
1574 data->layers[index].active_rnd = 0;
1575 data->layers[index].active_clone = 0;
1576 data->layers[index].active_mask = 0;
1579 customData_update_offsets(data);
1581 return &data->layers[index];
1584 void *CustomData_add_layer(CustomData *data, int type, int alloctype,
1585 void *layerdata, int totelem)
1587 CustomDataLayer *layer;
1588 const LayerTypeInfo *typeInfo= layerType_getInfo(type);
1590 layer = customData_add_layer__internal(data, type, alloctype, layerdata,
1591 totelem, typeInfo->defaultname);
1592 CustomData_update_typemap(data);
1600 /*same as above but accepts a name*/
1601 void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
1602 void *layerdata, int totelem, const char *name)
1604 CustomDataLayer *layer;
1606 layer = customData_add_layer__internal(data, type, alloctype, layerdata,
1608 CustomData_update_typemap(data);
1617 int CustomData_free_layer(CustomData *data, int type, int totelem, int index)
1621 if (index < 0) return 0;
1623 customData_free_layer__internal(&data->layers[index], totelem);
1625 for (i=index+1; i < data->totlayer; ++i)
1626 data->layers[i-1] = data->layers[i];
1630 /* if layer was last of type in array, set new active layer */
1631 if ((index >= data->totlayer) || (data->layers[index].type != type)) {
1632 i = CustomData_get_layer_index(data, type);
1635 for (; i < data->totlayer && data->layers[i].type == type; i++) {
1636 data->layers[i].active--;
1637 data->layers[i].active_rnd--;
1638 data->layers[i].active_clone--;
1639 data->layers[i].active_mask--;
1643 if (data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
1644 customData_resize(data, -CUSTOMDATA_GROW);
1646 customData_update_offsets(data);
1647 CustomData_update_typemap(data);
1652 int CustomData_free_layer_active(CustomData *data, int type, int totelem)
1655 index = CustomData_get_active_layer_index(data, type);
1656 if (index < 0) return 0;
1657 return CustomData_free_layer(data, type, totelem, index);
1661 void CustomData_free_layers(CustomData *data, int type, int totelem)
1663 while (CustomData_has_layer(data, type))
1664 CustomData_free_layer_active(data, type, totelem);
1667 int CustomData_has_layer(const CustomData *data, int type)
1669 return (CustomData_get_layer_index(data, type) != -1);
1672 int CustomData_number_of_layers(const CustomData *data, int type)
1676 for(i = 0; i < data->totlayer; i++)
1677 if(data->layers[i].type == type)
1683 void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
1685 CustomDataLayer *layer;
1688 /* get the layer index of the first layer of type */
1689 layer_index = CustomData_get_active_layer_index(data, type);
1690 if(layer_index < 0) return NULL;
1692 layer = &data->layers[layer_index];
1694 if (layer->flag & CD_FLAG_NOFREE) {
1695 layer->data = MEM_dupallocN(layer->data);
1696 layer->flag &= ~CD_FLAG_NOFREE;
1702 void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
1703 int type, const char *name)
1705 CustomDataLayer *layer;
1708 /* get the layer index of the desired layer */
1709 layer_index = CustomData_get_named_layer_index(data, type, name);
1710 if(layer_index < 0) return NULL;
1712 layer = &data->layers[layer_index];
1714 if (layer->flag & CD_FLAG_NOFREE) {
1715 layer->data = MEM_dupallocN(layer->data);
1716 layer->flag &= ~CD_FLAG_NOFREE;
1722 void CustomData_free_temporary(CustomData *data, int totelem)
1724 CustomDataLayer *layer;
1727 for(i = 0, j = 0; i < data->totlayer; ++i) {
1728 layer = &data->layers[i];
1731 data->layers[j] = data->layers[i];
1733 if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY)
1734 customData_free_layer__internal(layer, totelem);
1741 if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
1742 customData_resize(data, -CUSTOMDATA_GROW);
1744 customData_update_offsets(data);
1747 void CustomData_set_only_copy(const struct CustomData *data,
1748 CustomDataMask mask)
1752 for(i = 0; i < data->totlayer; ++i)
1753 if(!((int)mask & (int)(1 << (int)data->layers[i].type)))
1754 data->layers[i].flag |= CD_FLAG_NOCOPY;
1757 void CustomData_copy_elements(int type, void *source, void *dest, int count)
1759 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
1762 typeInfo->copy(source, dest, count);
1764 memcpy(dest, source, typeInfo->size*count);
1767 void CustomData_copy_data(const CustomData *source, CustomData *dest,
1768 int source_index, int dest_index, int count)
1770 const LayerTypeInfo *typeInfo;
1775 /* copies a layer at a time */
1777 for(src_i = 0; src_i < source->totlayer; ++src_i) {
1779 /* find the first dest layer with type >= the source type
1780 * (this should work because layers are ordered by type)
1782 while(dest_i < dest->totlayer
1783 && dest->layers[dest_i].type < source->layers[src_i].type)
1786 /* if there are no more dest layers, we're done */
1787 if(dest_i >= dest->totlayer) return;
1789 /* if we found a matching layer, copy the data */
1790 if(dest->layers[dest_i].type == source->layers[src_i].type) {
1791 char *src_data = source->layers[src_i].data;
1792 char *dest_data = dest->layers[dest_i].data;
1794 typeInfo = layerType_getInfo(source->layers[src_i].type);
1796 src_offset = source_index * typeInfo->size;
1797 dest_offset = dest_index * typeInfo->size;
1799 if (!src_data || !dest_data) {
1800 printf("eek! null data in CustomData_copy_data!\n");
1805 typeInfo->copy(src_data + src_offset,
1806 dest_data + dest_offset,
1809 memcpy(dest_data + dest_offset,
1810 src_data + src_offset,
1811 count * typeInfo->size);
1813 /* if there are multiple source & dest layers of the same type,
1814 * we don't want to copy all source layers to the same dest, so
1822 void CustomData_free_elem(CustomData *data, int index, int count)
1825 const LayerTypeInfo *typeInfo;
1827 for(i = 0; i < data->totlayer; ++i) {
1828 if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
1829 typeInfo = layerType_getInfo(data->layers[i].type);
1831 if(typeInfo->free) {
1832 int offset = typeInfo->size * index;
1834 typeInfo->free((char *)data->layers[i].data + offset,
1835 count, typeInfo->size);
1841 #define SOURCE_BUF_SIZE 100
1843 void CustomData_interp(const CustomData *source, CustomData *dest,
1844 int *src_indices, float *weights, float *sub_weights,
1845 int count, int dest_index)
1850 void *source_buf[SOURCE_BUF_SIZE];
1851 void **sources = source_buf;
1853 /* slow fallback in case we're interpolating a ridiculous number of
1856 if(count > SOURCE_BUF_SIZE)
1857 sources = MEM_callocN(sizeof(*sources) * count,
1858 "CustomData_interp sources");
1860 /* interpolates a layer at a time */
1862 for(src_i = 0; src_i < source->totlayer; ++src_i) {
1863 const LayerTypeInfo *typeInfo= layerType_getInfo(source->layers[src_i].type);
1864 if(!typeInfo->interp) continue;
1866 /* find the first dest layer with type >= the source type
1867 * (this should work because layers are ordered by type)
1869 while(dest_i < dest->totlayer
1870 && dest->layers[dest_i].type < source->layers[src_i].type)
1873 /* if there are no more dest layers, we're done */
1874 if(dest_i >= dest->totlayer) return;
1876 /* if we found a matching layer, copy the data */
1877 if(dest->layers[dest_i].type == source->layers[src_i].type) {
1878 void *src_data = source->layers[src_i].data;
1880 for(j = 0; j < count; ++j)
1881 sources[j] = (char *)src_data
1882 + typeInfo->size * src_indices[j];
1884 dest_offset = dest_index * typeInfo->size;
1886 typeInfo->interp(sources, weights, sub_weights, count,
1887 (char *)dest->layers[dest_i].data + dest_offset);
1889 /* if there are multiple source & dest layers of the same type,
1890 * we don't want to copy all source layers to the same dest, so
1897 if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
1900 void CustomData_swap(struct CustomData *data, int index, const int *corner_indices)
1902 const LayerTypeInfo *typeInfo;
1905 for(i = 0; i < data->totlayer; ++i) {
1906 typeInfo = layerType_getInfo(data->layers[i].type);
1908 if(typeInfo->swap) {
1909 int offset = typeInfo->size * index;
1911 typeInfo->swap((char *)data->layers[i].data + offset, corner_indices);
1916 void *CustomData_get(const CustomData *data, int index, int type)
1921 /* get the layer index of the active layer of type */
1922 layer_index = CustomData_get_active_layer_index(data, type);
1923 if(layer_index < 0) return NULL;
1925 /* get the offset of the desired element */
1926 offset = layerType_getInfo(type)->size * index;
1928 return (char *)data->layers[layer_index].data + offset;
1931 void *CustomData_get_n(const CustomData *data, int type, int index, int n)
1936 /* get the layer index of the first layer of type */
1937 layer_index = data->typemap[type];
1938 if(layer_index < 0) return NULL;
1940 offset = layerType_getInfo(type)->size * index;
1941 return (char *)data->layers[layer_index+n].data + offset;
1944 void *CustomData_get_layer(const CustomData *data, int type)
1946 /* get the layer index of the active layer of type */
1947 int layer_index = CustomData_get_active_layer_index(data, type);
1948 if(layer_index < 0) return NULL;
1950 return data->layers[layer_index].data;
1953 void *CustomData_get_layer_n(const CustomData *data, int type, int n)
1955 /* get the layer index of the active layer of type */
1956 int layer_index = CustomData_get_layer_index(data, type);
1957 if(layer_index < 0) return NULL;
1959 return data->layers[layer_index+n].data;
1962 void *CustomData_get_layer_named(const struct CustomData *data, int type,
1965 int layer_index = CustomData_get_named_layer_index(data, type, name);
1966 if(layer_index < 0) return NULL;
1968 return data->layers[layer_index].data;
1972 int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
1974 /* get the layer index of the first layer of type */
1975 int layer_index = CustomData_get_layer_index_n(data, type, n);
1977 if(layer_index < 0) return 0;
1978 if (!name) return 0;
1980 strcpy(data->layers[layer_index].name, name);
1985 void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
1987 /* get the layer index of the first layer of type */
1988 int layer_index = CustomData_get_active_layer_index(data, type);
1990 if(layer_index < 0) return NULL;
1992 data->layers[layer_index].data = ptr;
1997 void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr)
1999 /* get the layer index of the first layer of type */
2000 int layer_index = CustomData_get_layer_index(data, type);
2001 if(layer_index < 0) return NULL;
2003 data->layers[layer_index+n].data = ptr;
2008 void CustomData_set(const CustomData *data, int index, int type, void *source)
2010 void *dest = CustomData_get(data, index, type);
2011 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2016 typeInfo->copy(source, dest, 1);
2018 memcpy(dest, source, typeInfo->size);
2021 /* EditMesh functions */
2023 void CustomData_em_free_block(CustomData *data, void **block)
2025 const LayerTypeInfo *typeInfo;
2030 for(i = 0; i < data->totlayer; ++i) {
2031 if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
2032 typeInfo = layerType_getInfo(data->layers[i].type);
2034 if(typeInfo->free) {
2035 int offset = data->layers[i].offset;
2036 typeInfo->free((char*)*block + offset, 1, typeInfo->size);
2045 static void CustomData_em_alloc_block(CustomData *data, void **block)
2047 /* TODO: optimize free/alloc */
2050 CustomData_em_free_block(data, block);
2052 if (data->totsize > 0)
2053 *block = MEM_callocN(data->totsize, "CustomData EM block");
2058 void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
2059 void *src_block, void **dest_block)
2061 const LayerTypeInfo *typeInfo;
2065 CustomData_em_alloc_block(dest, dest_block);
2067 /* copies a layer at a time */
2069 for(src_i = 0; src_i < source->totlayer; ++src_i) {
2071 /* find the first dest layer with type >= the source type
2072 * (this should work because layers are ordered by type)
2074 while(dest_i < dest->totlayer
2075 && dest->layers[dest_i].type < source->layers[src_i].type)
2078 /* if there are no more dest layers, we're done */
2079 if(dest_i >= dest->totlayer) return;
2081 /* if we found a matching layer, copy the data */
2082 if(dest->layers[dest_i].type == source->layers[src_i].type &&
2083 strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
2084 char *src_data = (char*)src_block + source->layers[src_i].offset;
2085 char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
2087 typeInfo = layerType_getInfo(source->layers[src_i].type);
2090 typeInfo->copy(src_data, dest_data, 1);
2092 memcpy(dest_data, src_data, typeInfo->size);
2094 /* if there are multiple source & dest layers of the same type,
2095 * we don't want to copy all source layers to the same dest, so
2103 void CustomData_em_validate_data(CustomData *data, void *block, int sub_elements)
2106 for(i = 0; i < data->totlayer; i++) {
2107 const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
2108 char *leayer_data = (char*)block + data->layers[i].offset;
2110 if(typeInfo->validate)
2111 typeInfo->validate(leayer_data, sub_elements);
2115 void *CustomData_em_get(const CustomData *data, void *block, int type)
2119 /* get the layer index of the first layer of type */
2120 layer_index = CustomData_get_active_layer_index(data, type);
2121 if(layer_index < 0) return NULL;
2123 return (char *)block + data->layers[layer_index].offset;
2126 void *CustomData_em_get_n(const CustomData *data, void *block, int type, int n)
2130 /* get the layer index of the first layer of type */
2131 layer_index = CustomData_get_layer_index(data, type);
2132 if(layer_index < 0) return NULL;
2134 return (char *)block + data->layers[layer_index+n].offset;
2137 void CustomData_em_set(CustomData *data, void *block, int type, void *source)
2139 void *dest = CustomData_em_get(data, block, type);
2140 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2145 typeInfo->copy(source, dest, 1);
2147 memcpy(dest, source, typeInfo->size);
2150 void CustomData_em_set_n(CustomData *data, void *block, int type, int n, void *source)
2152 void *dest = CustomData_em_get_n(data, block, type, n);
2153 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2158 typeInfo->copy(source, dest, 1);
2160 memcpy(dest, source, typeInfo->size);
2163 void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
2164 float *sub_weights, int count, void *dest_block)
2167 void *source_buf[SOURCE_BUF_SIZE];
2168 void **sources = source_buf;
2170 /* slow fallback in case we're interpolating a ridiculous number of
2173 if(count > SOURCE_BUF_SIZE)
2174 sources = MEM_callocN(sizeof(*sources) * count,
2175 "CustomData_interp sources");
2177 /* interpolates a layer at a time */
2178 for(i = 0; i < data->totlayer; ++i) {
2179 CustomDataLayer *layer = &data->layers[i];
2180 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
2182 if(typeInfo->interp) {
2183 for(j = 0; j < count; ++j)
2184 sources[j] = (char *)src_blocks[j] + layer->offset;
2186 typeInfo->interp(sources, weights, sub_weights, count,
2187 (char *)dest_block + layer->offset);
2191 if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
2194 void CustomData_em_set_default(CustomData *data, void **block)
2196 const LayerTypeInfo *typeInfo;
2200 CustomData_em_alloc_block(data, block);
2202 for(i = 0; i < data->totlayer; ++i) {
2203 int offset = data->layers[i].offset;
2205 typeInfo = layerType_getInfo(data->layers[i].type);
2207 if(typeInfo->set_default)
2208 typeInfo->set_default((char*)*block + offset, 1);
2212 void CustomData_to_em_block(const CustomData *source, CustomData *dest,
2213 int src_index, void **dest_block)
2215 const LayerTypeInfo *typeInfo;
2216 int dest_i, src_i, src_offset;
2219 CustomData_em_alloc_block(dest, dest_block);
2221 /* copies a layer at a time */
2223 for(src_i = 0; src_i < source->totlayer; ++src_i) {
2225 /* find the first dest layer with type >= the source type
2226 * (this should work because layers are ordered by type)
2228 while(dest_i < dest->totlayer
2229 && dest->layers[dest_i].type < source->layers[src_i].type)
2232 /* if there are no more dest layers, we're done */
2233 if(dest_i >= dest->totlayer) return;
2235 /* if we found a matching layer, copy the data */
2236 if(dest->layers[dest_i].type == source->layers[src_i].type) {
2237 int offset = dest->layers[dest_i].offset;
2238 char *src_data = source->layers[src_i].data;
2239 char *dest_data = (char*)*dest_block + offset;
2241 typeInfo = layerType_getInfo(dest->layers[dest_i].type);
2242 src_offset = src_index * typeInfo->size;
2245 typeInfo->copy(src_data + src_offset, dest_data, 1);
2247 memcpy(dest_data, src_data + src_offset, typeInfo->size);
2249 /* if there are multiple source & dest layers of the same type,
2250 * we don't want to copy all source layers to the same dest, so
2258 void CustomData_from_em_block(const CustomData *source, CustomData *dest,
2259 void *src_block, int dest_index)
2261 const LayerTypeInfo *typeInfo;
2262 int dest_i, src_i, dest_offset;
2264 /* copies a layer at a time */
2266 for(src_i = 0; src_i < source->totlayer; ++src_i) {
2268 /* find the first dest layer with type >= the source type
2269 * (this should work because layers are ordered by type)
2271 while(dest_i < dest->totlayer
2272 && dest->layers[dest_i].type < source->layers[src_i].type)
2275 /* if there are no more dest layers, we're done */
2276 if(dest_i >= dest->totlayer) return;
2278 /* if we found a matching layer, copy the data */
2279 if(dest->layers[dest_i].type == source->layers[src_i].type) {
2280 int offset = source->layers[src_i].offset;
2281 char *src_data = (char*)src_block + offset;
2282 char *dest_data = dest->layers[dest_i].data;
2284 typeInfo = layerType_getInfo(dest->layers[dest_i].type);
2285 dest_offset = dest_index * typeInfo->size;
2288 typeInfo->copy(src_data, dest_data + dest_offset, 1);
2290 memcpy(dest_data + dest_offset, src_data, typeInfo->size);
2292 /* if there are multiple source & dest layers of the same type,
2293 * we don't want to copy all source layers to the same dest, so
2303 /*needed to convert to/from different face reps*/
2304 void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata,
2305 int totloop, int totpoly)
2308 for(i=0; i < fdata->totlayer; i++){
2309 if(fdata->layers[i].type == CD_MTFACE){
2310 CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), totpoly);
2311 CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), totloop);
2313 else if(fdata->layers[i].type == CD_MCOL)
2314 CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), totloop);
2315 else if(fdata->layers[i].type == CD_MDISPS)
2316 CustomData_add_layer(ldata, CD_MDISPS, CD_CALLOC, &(fdata->layers[i].name), totloop);
2319 void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){
2321 for(i=0; i < pdata->totlayer; i++){
2322 if(pdata->layers[i].type == CD_MTEXPOLY)
2323 CustomData_add_layer_named(fdata, CD_MTFACE, CD_CALLOC, NULL, total, pdata->layers[i].name);
2325 for(i=0; i < ldata->totlayer; i++){
2326 if(ldata->layers[i].type == CD_MLOOPCOL)
2327 CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
2328 if (ldata->layers[i].type == CD_WEIGHT_MLOOPCOL)
2329 CustomData_add_layer_named(fdata, CD_WEIGHT_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
2334 void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
2335 if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 1, 0);
2338 void CustomData_bmesh_merge(CustomData *source, CustomData *dest,
2339 int mask, int alloctype, BMesh *bm, int type)
2343 CustomData destold = *dest;
2347 CustomData_merge(source, dest, mask, alloctype, 0);
2348 CustomData_bmesh_init_pool(dest, 512);
2352 t = BM_VERTS_OF_MESH; break;
2354 t = BM_EDGES_OF_MESH; break;
2356 t = BM_LOOPS_OF_FACE; break;
2358 t = BM_FACES_OF_MESH; break;
2359 default: /* should never happen */
2360 BLI_assert(!"invalid type given");
2361 t = BM_VERTS_OF_MESH;
2364 if (t != BM_LOOPS_OF_FACE) {
2365 /*ensure all current elements follow new customdata layout*/
2366 BM_ITER(h, &iter, bm, t, NULL) {
2367 CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
2368 CustomData_bmesh_free_block(&destold, &h->data);
2376 /*ensure all current elements follow new customdata layout*/
2377 BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
2378 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
2379 CustomData_bmesh_copy_data(&destold, dest, l->head.data, &tmp);
2380 CustomData_bmesh_free_block(&destold, &l->head.data);
2386 if (destold.pool) BLI_mempool_destroy(destold.pool);
2389 void CustomData_bmesh_free_block(CustomData *data, void **block)
2391 const LayerTypeInfo *typeInfo;
2395 for(i = 0; i < data->totlayer; ++i) {
2396 if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
2397 typeInfo = layerType_getInfo(data->layers[i].type);
2399 if(typeInfo->free) {
2400 int offset = data->layers[i].offset;
2401 typeInfo->free((char*)*block + offset, 1, typeInfo->size);
2407 BLI_mempool_free(data->pool, *block);
2412 static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
2416 CustomData_bmesh_free_block(data, block);
2418 if (data->totsize > 0)
2419 *block = BLI_mempool_alloc(data->pool);
2424 void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
2425 void *src_block, void **dest_block)
2427 const LayerTypeInfo *typeInfo;
2431 CustomData_bmesh_alloc_block(dest, dest_block);
2433 /* copies a layer at a time */
2435 for(src_i = 0; src_i < source->totlayer; ++src_i) {
2437 /* find the first dest layer with type >= the source type
2438 * (this should work because layers are ordered by type)
2440 while(dest_i < dest->totlayer
2441 && dest->layers[dest_i].type < source->layers[src_i].type)
2444 /* if there are no more dest layers, we're done */
2445 if(dest_i >= dest->totlayer) return;
2447 /* if we found a matching layer, copy the data */
2448 if(dest->layers[dest_i].type == source->layers[src_i].type &&
2449 strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
2450 char *src_data = (char*)src_block + source->layers[src_i].offset;
2451 char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
2453 typeInfo = layerType_getInfo(source->layers[src_i].type);
2456 typeInfo->copy(src_data, dest_data, 1);
2458 memcpy(dest_data, src_data, typeInfo->size);
2460 /* if there are multiple source & dest layers of the same type,
2461 * we don't want to copy all source layers to the same dest, so
2469 /*Bmesh Custom Data Functions. Should replace editmesh ones with these as well, due to more effecient memory alloc*/
2470 void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
2474 /* get the layer index of the first layer of type */
2475 layer_index = CustomData_get_active_layer_index(data, type);
2476 if(layer_index < 0) return NULL;
2478 return (char *)block + data->layers[layer_index].offset;
2481 void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
2485 /* get the layer index of the first layer of type */
2486 layer_index = CustomData_get_layer_index(data, type);
2487 if(layer_index < 0) return NULL;
2489 return (char *)block + data->layers[layer_index+n].offset;
2492 /*gets from the layer at physical index n, note: doesn't check type.*/
2493 void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
2495 if(n < 0 || n >= data->totlayer) return NULL;
2497 return (char *)block + data->layers[n].offset;
2500 int CustomData_layer_has_math(struct CustomData *data, int layern)
2502 const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layern].type);
2504 if (typeInfo->equal && typeInfo->add && typeInfo->multiply &&
2505 typeInfo->initminmax && typeInfo->dominmax) return 1;
2510 /*copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
2511 another, while not overwriting anything else (e.g. flags)*/
2512 void CustomData_data_copy_value(int type, void *source, void *dest)
2514 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2518 if(typeInfo->copyvalue)
2519 typeInfo->copyvalue(source, dest);
2521 memcpy(dest, source, typeInfo->size);
2524 int CustomData_data_equals(int type, void *data1, void *data2)
2526 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2528 if (typeInfo->equal)
2529 return typeInfo->equal(data1, data2);
2530 else return !memcmp(data1, data2, typeInfo->size);
2533 void CustomData_data_initminmax(int type, void *min, void *max)
2535 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2537 if (typeInfo->initminmax)
2538 typeInfo->initminmax(min, max);
2542 void CustomData_data_dominmax(int type, void *data, void *min, void *max)
2544 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2546 if (typeInfo->dominmax)
2547 typeInfo->dominmax(data, min, max);
2551 void CustomData_data_multiply(int type, void *data, float fac)
2553 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2555 if (typeInfo->multiply)
2556 typeInfo->multiply(data, fac);
2560 void CustomData_data_add(int type, void *data1, void *data2)
2562 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2565 typeInfo->add(data1, data2);
2568 void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
2570 void *dest = CustomData_bmesh_get(data, block, type);
2571 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2576 typeInfo->copy(source, dest, 1);
2578 memcpy(dest, source, typeInfo->size);
2581 void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void *source)
2583 void *dest = CustomData_bmesh_get_n(data, block, type, n);
2584 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2589 typeInfo->copy(source, dest, 1);
2591 memcpy(dest, source, typeInfo->size);
2594 void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source)
2596 void *dest = CustomData_bmesh_get_layer_n(data, block, n);
2597 const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
2602 typeInfo->copy(source, dest, 1);
2604 memcpy(dest, source, typeInfo->size);
2607 void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
2608 float *sub_weights, int count, void *dest_block)
2611 void *source_buf[SOURCE_BUF_SIZE];
2612 void **sources = source_buf;
2614 /* slow fallback in case we're interpolating a ridiculous number of
2617 if(count > SOURCE_BUF_SIZE)
2618 sources = MEM_callocN(sizeof(*sources) * count,
2619 "CustomData_interp sources");
2621 /* interpolates a layer at a time */
2622 for(i = 0; i < data->totlayer; ++i) {
2623 CustomDataLayer *layer = &data->layers[i];
2624 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
2625 if(typeInfo->interp) {
2626 for(j = 0; j < count; ++j)
2627 sources[j] = (char *)src_blocks[j] + layer->offset;
2629 typeInfo->interp(sources, weights, sub_weights, count,
2630 (char *)dest_block + layer->offset);
2634 if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
2637 void CustomData_bmesh_set_default(CustomData *data, void **block)
2639 const LayerTypeInfo *typeInfo;
2643 CustomData_bmesh_alloc_block(data, block);
2645 for(i = 0; i < data->totlayer; ++i) {
2646 int offset = data->layers[i].offset;
2648 typeInfo = layerType_getInfo(data->layers[i].type);
2650 if(typeInfo->set_default)
2651 typeInfo->set_default((char*)*block + offset, 1);
2652 else memset((char*)*block + offset, 0, typeInfo->size);
2656 void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
2657 int src_index, void **dest_block)
2659 const LayerTypeInfo *typeInfo;
2660 int dest_i, src_i, src_offset;
2663 CustomData_bmesh_alloc_block(dest, dest_block);
2665 /* copies a layer at a time */
2667 for(src_i = 0; src_i < source->totlayer; ++src_i) {
2669 /* find the first dest layer with type >= the source type
2670 * (this should work because layers are ordered by type)
2672 while(dest_i < dest->totlayer
2673 && dest->layers[dest_i].type < source->layers[src_i].type)
2676 /* if there are no more dest layers, we're done */
2677 if(dest_i >= dest->totlayer) return;
2679 /* if we found a matching layer, copy the data */
2680 if(dest->layers[dest_i].type == source->layers[src_i].type) {
2681 int offset = dest->layers[dest_i].offset;
2682 char *src_data = source->layers[src_i].data;
2683 char *dest_data = (char*)*dest_block + offset;
2685 typeInfo = layerType_getInfo(dest->layers[dest_i].type);
2686 src_offset = src_index * typeInfo->size;
2689 typeInfo->copy(src_data + src_offset, dest_data, 1);
2691 memcpy(dest_data, src_data + src_offset, typeInfo->size);
2693 /* if there are multiple source & dest layers of the same type,
2694 * we don't want to copy all source layers to the same dest, so
2702 void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
2703 void *src_block, int dest_index)
2705 const LayerTypeInfo *typeInfo;
2706 int dest_i, src_i, dest_offset;
2708 /* copies a layer at a time */
2710 for(src_i = 0; src_i < source->totlayer; ++src_i) {
2712 /* find the first dest layer with type >= the source type
2713 * (this should work because layers are ordered by type)
2715 while(dest_i < dest->totlayer
2716 && dest->layers[dest_i].type < source->layers[src_i].type)
2719 /* if there are no more dest layers, we're done */
2720 if(dest_i >= dest->totlayer) return;
2722 /* if we found a matching layer, copy the data */
2723 if(dest->layers[dest_i].type == source->layers[src_i].type) {
2724 int offset = source->layers[src_i].offset;
2725 char *src_data = (char*)src_block + offset;
2726 char *dest_data = dest->layers[dest_i].data;
2728 typeInfo = layerType_getInfo(dest->layers[dest_i].type);
2729 dest_offset = dest_index * typeInfo->size;
2732 typeInfo->copy(src_data, dest_data + dest_offset, 1);
2734 memcpy(dest_data + dest_offset, src_data, typeInfo->size);
2736 /* if there are multiple source & dest layers of the same type,
2737 * we don't want to copy all source layers to the same dest, so
2746 void CustomData_file_write_info(int type, const char **structname, int *structnum)
2748 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2750 *structname = typeInfo->structname;
2751 *structnum = typeInfo->structnum;
2754 int CustomData_sizeof(int type)
2756 const LayerTypeInfo *typeInfo = layerType_getInfo(type);
2758 return typeInfo->size;
2761 const char *CustomData_layertype_name(int type)
2763 return layerType_getName(type);
2766 static int CustomData_is_property_layer(int type)
2768 if((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR))
2773 static int cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
2776 /* see if there is a duplicate */
2777 for(i=0; i<data->totlayer; i++) {
2779 CustomDataLayer *layer= &data->layers[i];
2781 if(CustomData_is_property_layer(type)) {
2782 if(CustomData_is_property_layer(layer->type) && strcmp(layer->name, name)==0) {
2787 if(i!=index && layer->type==type && strcmp(layer->name, name)==0) {
2797 static int customdata_unique_check(void *arg, const char *name)
2799 struct {CustomData *data; int type; int index;} *data_arg= arg;
2800 return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index);
2803 void CustomData_set_layer_unique_name(CustomData *data, int index)
2805 CustomDataLayer *nlayer= &data->layers[index];
2806 const LayerTypeInfo *typeInfo= layerType_getInfo(nlayer->type);
2808 struct {CustomData *data; int type; int index;} data_arg;
2809 data_arg.data= data;
2810 data_arg.type= nlayer->type;
2811 data_arg.index= index;
2813 if (!typeInfo->defaultname)
2816 BLI_uniquename_cb(customdata_unique_check, &data_arg, typeInfo->defaultname, '.', nlayer->name, sizeof(nlayer->name));
2819 int CustomData_verify_versions(struct CustomData *data, int index)
2821 const LayerTypeInfo *typeInfo;
2822 CustomDataLayer *layer = &data->layers[index];
2823 int i, keeplayer = 1;
2825 if (layer->type >= CD_NUMTYPES) {
2826 keeplayer = 0; /* unknown layer type from future version */
2829 typeInfo = layerType_getInfo(layer->type);
2831 if (!typeInfo->defaultname && (index > 0) &&
2832 data->layers[index-1].type == layer->type)
2833 keeplayer = 0; /* multiple layers of which we only support one */
2837 for (i=index+1; i < data->totlayer; ++i)
2838 data->layers[i-1] = data->layers[i];
2845 /****************************** External Files *******************************/
2847 static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external)
2849 char *path = (id->lib)? id->lib->filepath: G.main->name;
2851 BLI_strncpy(filename, external->filename, FILE_MAX);
2852 BLI_path_abs(filename, path);
2855 void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask mask, int totelem)
2857 CustomDataLayer *layer;
2858 const LayerTypeInfo *typeInfo;
2861 for(i=0; i<data->totlayer; i++) {
2862 layer = &data->layers[i];
2863 typeInfo = layerType_getInfo(layer->type);
2865 if(!(mask & (1<<layer->type)));
2866 else if((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) {
2868 typeInfo->free(layer->data, totelem, typeInfo->size);
2869 layer->flag &= ~CD_FLAG_IN_MEMORY;
2874 void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem)
2876 CustomDataExternal *external= data->external;
2877 CustomDataLayer *layer;
2879 CDataFileLayer *blay;
2880 char filename[FILE_MAX];
2881 const LayerTypeInfo *typeInfo;
2887 for(i=0; i<data->totlayer; i++) {
2888 layer = &data->layers[i];
2889 typeInfo = layerType_getInfo(layer->type);
2891 if(!(mask & (1<<layer->type)));
2892 else if(layer->flag & CD_FLAG_IN_MEMORY);
2893 else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read)
2900 customdata_external_filename(filename, id, external);
2902 cdf= cdf_create(CDF_TYPE_MESH);
2903 if(!cdf_read_open(cdf, filename)) {
2904 fprintf(stderr, "Failed to read %s layer from %s.\n", layerType_getName(layer->type), filename);
2908 for(i=0; i<data->totlayer; i++) {
2909 layer = &data->layers[i];
2910 typeInfo = layerType_getInfo(layer->type);
2912 if(!(mask & (1<<layer->type)));
2913 else if(layer->flag & CD_FLAG_IN_MEMORY);
2914 else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) {
2915 blay= cdf_layer_find(cdf, layer->type, layer->name);
2918 if(cdf_read_layer(cdf, blay)) {
2919 if(typeInfo->read(cdf, layer->data, totelem));
2921 layer->flag |= CD_FLAG_IN_MEMORY;
2929 cdf_read_close(cdf);
2933 void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, int totelem, int free)
2935 CustomDataExternal *external= data->external;
2936 CustomDataLayer *layer;
2938 CDataFileLayer *blay;
2939 const LayerTypeInfo *typeInfo;
2941 char filename[FILE_MAX];
2946 /* test if there is anything to write */
2947 for(i=0; i<data->totlayer; i++) {
2948 layer = &data->layers[i];
2949 typeInfo = layerType_getInfo(layer->type);
2951 if(!(mask & (1<<layer->type)));
2952 else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write)
2959 /* make sure data is read before we try to write */
2960 CustomData_external_read(data, id, mask, totelem);
2961 customdata_external_filename(filename, id, external);
2963 cdf= cdf_create(CDF_TYPE_MESH);
2965 for(i=0; i<data->totlayer; i++) {
2966 layer = &data->layers[i];
2967 typeInfo = layerType_getInfo(layer->type);
2969 if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) {
2970 if(layer->flag & CD_FLAG_IN_MEMORY) {
2971 cdf_layer_add(cdf, layer->type, layer->name,
2972 typeInfo->filesize(cdf, layer->data, totelem));
2976 return; /* read failed for a layer! */
2981 if(!cdf_write_open(cdf, filename)) {
2982 fprintf(stderr, "Failed to open %s for writing.\n", filename);
2986 for(i=0; i<data->totlayer; i++) {
2987 layer = &data->layers[i];
2988 typeInfo = layerType_getInfo(layer->type);
2990 if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
2991 blay= cdf_layer_find(cdf, layer->type, layer->name);
2993 if(cdf_write_layer(cdf, blay)) {
2994 if(typeInfo->write(cdf, layer->data, totelem));
3002 if(i != data->totlayer) {
3003 fprintf(stderr, "Failed to write data to %s.\n", filename);
3008 for(i=0; i<data->totlayer; i++) {
3009 layer = &data->layers[i];
3010 typeInfo = layerType_getInfo(layer->type);
3012 if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
3015 typeInfo->free(layer->data, totelem, typeInfo->size);
3016 layer->flag &= ~CD_FLAG_IN_MEMORY;
3021 cdf_write_close(cdf);
3025 void CustomData_external_add(CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename)
3027 CustomDataExternal *external= data->external;
3028 CustomDataLayer *layer;
3031 layer_index = CustomData_get_active_layer_index(data, type);
3032 if(layer_index < 0) return;
3034 layer = &data->layers[layer_index];
3036 if(layer->flag & CD_FLAG_EXTERNAL)
3040 external= MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal");
3041 data->external= external;
3043 BLI_strncpy(external->filename, filename, sizeof(external->filename));
3045 layer->flag |= CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY;
3048 void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem)
3050 CustomDataExternal *external= data->external;
3051 CustomDataLayer *layer;
3052 //char filename[FILE_MAX];
3053 int layer_index; // i, remove_file;
3055 layer_index = CustomData_get_active_layer_index(data, type);
3056 if(layer_index < 0) return;
3058 layer = &data->layers[layer_index];
3063 if(layer->flag & CD_FLAG_EXTERNAL) {
3064 if(!(layer->flag & CD_FLAG_IN_MEMORY))
3065 CustomData_external_read(data, id, (1<<layer->type), totelem);
3067 layer->flag &= ~CD_FLAG_EXTERNAL;
3071 for(i=0; i<data->totlayer; i++)
3072 if(data->layers[i].flag & CD_FLAG_EXTERNAL)
3076 customdata_external_filename(filename, id, external);
3077 cdf_remove(filename);
3078 CustomData_external_free(data);
3084 int CustomData_external_test(CustomData *data, int type)
3086 CustomDataLayer *layer;
3089 layer_index = CustomData_get_active_layer_index(data, type);
3090 if(layer_index < 0) return 0;
3092 layer = &data->layers[layer_index];
3093 return (layer->flag & CD_FLAG_EXTERNAL);
3097 void CustomData_external_remove_object(CustomData *data, ID *id)
3099 CustomDataExternal *external= data->external;
3100 char filename[FILE_MAX];
3105 customdata_external_filename(filename, id, external);
3106 cdf_remove(filename);
3107 CustomData_external_free(data);