Blender V2.61 - r43446

customdata.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software  Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2006 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): Ben Batt <benbatt@gmail.com>
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  *
00027  * Implementation of CustomData.
00028  *
00029  * BKE_customdata.h contains the function prototypes for this file.
00030  *
00031  */
00032 
00038 #include <math.h>
00039 #include <string.h>
00040 #include <assert.h>
00041 
00042 #include "MEM_guardedalloc.h"
00043 
00044 #include "DNA_meshdata_types.h"
00045 #include "DNA_ID.h"
00046 
00047 #include "BLI_blenlib.h"
00048 #include "BLI_linklist.h"
00049 #include "BLI_math.h"
00050 #include "BLI_mempool.h"
00051 #include "BLI_utildefines.h"
00052 
00053 #include "BKE_customdata.h"
00054 #include "BKE_customdata_file.h"
00055 #include "BKE_global.h"
00056 #include "BKE_main.h"
00057 #include "BKE_utildefines.h"
00058 #include "BKE_multires.h"
00059 
00060 /* number of layers to add when growing a CustomData object */
00061 #define CUSTOMDATA_GROW 5
00062 
00063 /********************* Layer type information **********************/
00064 typedef struct LayerTypeInfo {
00065     int size;          /* the memory size of one element of this layer's data */
00066     const char *structname;  /* name of the struct used, for file writing */
00067     int structnum;     /* number of structs per element, for file writing */
00068     const char *defaultname; /* default layer name */
00069 
00070     /* a function to copy count elements of this layer's data
00071      * (deep copy if appropriate)
00072      * if NULL, memcpy is used
00073      */
00074     void (*copy)(const void *source, void *dest, int count);
00075 
00076     /* a function to free any dynamically allocated components of this
00077      * layer's data (note the data pointer itself should not be freed)
00078      * size should be the size of one element of this layer's data (e.g.
00079      * LayerTypeInfo.size)
00080      */
00081     void (*free)(void *data, int count, int size);
00082 
00083     /* a function to interpolate between count source elements of this
00084      * layer's data and store the result in dest
00085      * if weights == NULL or sub_weights == NULL, they should default to 1
00086      *
00087      * weights gives the weight for each element in sources
00088      * sub_weights gives the sub-element weights for each element in sources
00089      *    (there should be (sub element count)^2 weights per element)
00090      * count gives the number of elements in sources
00091      */
00092     void (*interp)(void **sources, float *weights, float *sub_weights,
00093                    int count, void *dest);
00094 
00095     /* a function to swap the data in corners of the element */
00096     void (*swap)(void *data, const int *corner_indices);
00097 
00098     /* a function to set a layer's data to default values. if NULL, the
00099        default is assumed to be all zeros */
00100     void (*set_default)(void *data, int count);
00101 
00102     /* functions necassary for geometry collapse*/
00103     int (*equal)(void *data1, void *data2);
00104     void (*multiply)(void *data, float fac);
00105     void (*initminmax)(void *min, void *max);
00106     void (*add)(void *data1, void *data2);
00107     void (*dominmax)(void *data1, void *min, void *max);
00108     void (*copyvalue)(void *source, void *dest);
00109 
00110     /* a function to read data from a cdf file */
00111     int (*read)(CDataFile *cdf, void *data, int count);
00112 
00113     /* a function to write data to a cdf file */
00114     int (*write)(CDataFile *cdf, void *data, int count);
00115 
00116     /* a function to determine file size */
00117     size_t (*filesize)(CDataFile *cdf, void *data, int count);
00118 
00119     /* a function to validate layer contents depending on
00120      * sub-elements count
00121      */
00122     void (*validate)(void *source, int sub_elements);
00123 } LayerTypeInfo;
00124 
00125 static void layerCopy_mdeformvert(const void *source, void *dest,
00126                                   int count)
00127 {
00128     int i, size = sizeof(MDeformVert);
00129 
00130     memcpy(dest, source, count * size);
00131 
00132     for(i = 0; i < count; ++i) {
00133         MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size);
00134 
00135         if(dvert->totweight) {
00136             MDeformWeight *dw = MEM_callocN(dvert->totweight * sizeof(*dw),
00137                                             "layerCopy_mdeformvert dw");
00138 
00139             memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw));
00140             dvert->dw = dw;
00141         }
00142         else
00143             dvert->dw = NULL;
00144     }
00145 }
00146 
00147 static void layerFree_mdeformvert(void *data, int count, int size)
00148 {
00149     int i;
00150 
00151     for(i = 0; i < count; ++i) {
00152         MDeformVert *dvert = (MDeformVert *)((char *)data + i * size);
00153 
00154         if(dvert->dw) {
00155             MEM_freeN(dvert->dw);
00156             dvert->dw = NULL;
00157             dvert->totweight = 0;
00158         }
00159     }
00160 }
00161 
00162 static void linklist_free_simple(void *link)
00163 {
00164     MEM_freeN(link);
00165 }
00166 
00167 static void layerInterp_mdeformvert(void **sources, float *weights,
00168                                     float *UNUSED(sub_weights), int count, void *dest)
00169 {
00170     MDeformVert *dvert = dest;
00171     LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */
00172     LinkNode *node;
00173     int i, j, totweight;
00174 
00175     if(count <= 0) return;
00176 
00177     /* build a list of unique def_nrs for dest */
00178     totweight = 0;
00179     for(i = 0; i < count; ++i) {
00180         MDeformVert *source = sources[i];
00181         float interp_weight = weights ? weights[i] : 1.0f;
00182 
00183         for(j = 0; j < source->totweight; ++j) {
00184             MDeformWeight *dw = &source->dw[j];
00185 
00186             for(node = dest_dw; node; node = node->next) {
00187                 MDeformWeight *tmp_dw = (MDeformWeight *)node->link;
00188 
00189                 if(tmp_dw->def_nr == dw->def_nr) {
00190                     tmp_dw->weight += dw->weight * interp_weight;
00191                     break;
00192                 }
00193             }
00194 
00195             /* if this def_nr is not in the list, add it */
00196             if(!node) {
00197                 MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw),
00198                                             "layerInterp_mdeformvert tmp_dw");
00199                 tmp_dw->def_nr = dw->def_nr;
00200                 tmp_dw->weight = dw->weight * interp_weight;
00201                 BLI_linklist_prepend(&dest_dw, tmp_dw);
00202                 totweight++;
00203             }
00204         }
00205     }
00206 
00207     /* now we know how many unique deform weights there are, so realloc */
00208     if(dvert->dw) MEM_freeN(dvert->dw);
00209 
00210     if(totweight) {
00211         dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight,
00212                                 "layerInterp_mdeformvert dvert->dw");
00213         dvert->totweight = totweight;
00214 
00215         for(i = 0, node = dest_dw; node; node = node->next, ++i)
00216             dvert->dw[i] = *((MDeformWeight *)node->link);
00217     }
00218     else
00219         memset(dvert, 0, sizeof(*dvert));
00220 
00221     BLI_linklist_free(dest_dw, linklist_free_simple);
00222 }
00223 
00224 
00225 static void layerInterp_msticky(void **sources, float *weights,
00226                                 float *UNUSED(sub_weights), int count, void *dest)
00227 {
00228     float co[2], w;
00229     MSticky *mst;
00230     int i;
00231 
00232     co[0] = co[1] = 0.0f;
00233     for(i = 0; i < count; i++) {
00234         w = weights ? weights[i] : 1.0f;
00235         mst = (MSticky*)sources[i];
00236 
00237         madd_v2_v2fl(co, mst->co, w);
00238     }
00239 
00240     mst = (MSticky*)dest;
00241     copy_v2_v2(mst->co, co);
00242 }
00243 
00244 
00245 static void layerCopy_tface(const void *source, void *dest, int count)
00246 {
00247     const MTFace *source_tf = (const MTFace*)source;
00248     MTFace *dest_tf = (MTFace*)dest;
00249     int i;
00250 
00251     for(i = 0; i < count; ++i)
00252         dest_tf[i] = source_tf[i];
00253 }
00254 
00255 static void layerInterp_tface(void **sources, float *weights,
00256                               float *sub_weights, int count, void *dest)
00257 {
00258     MTFace *tf = dest;
00259     int i, j, k;
00260     float uv[4][2] = {{0.0f}};
00261     float *sub_weight;
00262 
00263     if(count <= 0) return;
00264 
00265     sub_weight = sub_weights;
00266     for(i = 0; i < count; ++i) {
00267         float weight = weights ? weights[i] : 1;
00268         MTFace *src = sources[i];
00269 
00270         for(j = 0; j < 4; ++j) {
00271             if(sub_weights) {
00272                 for(k = 0; k < 4; ++k, ++sub_weight) {
00273                     madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight);
00274                 }
00275             }
00276             else {
00277                 madd_v2_v2fl(uv[j], src->uv[j], weight);
00278             }
00279         }
00280     }
00281 
00282     *tf = *(MTFace *)(*sources);
00283     memcpy(tf->uv, uv, sizeof(tf->uv));
00284 }
00285 
00286 static void layerSwap_tface(void *data, const int *corner_indices)
00287 {
00288     MTFace *tf = data;
00289     float uv[4][2];
00290     static const short pin_flags[4] =
00291         { TF_PIN1, TF_PIN2, TF_PIN3, TF_PIN4 };
00292     static const char sel_flags[4] =
00293         { TF_SEL1, TF_SEL2, TF_SEL3, TF_SEL4 };
00294     short unwrap = tf->unwrap & ~(TF_PIN1 | TF_PIN2 | TF_PIN3 | TF_PIN4);
00295     char flag = tf->flag & ~(TF_SEL1 | TF_SEL2 | TF_SEL3 | TF_SEL4);
00296     int j;
00297 
00298     for(j = 0; j < 4; ++j) {
00299         const int source_index = corner_indices[j];
00300 
00301         copy_v2_v2(uv[j], tf->uv[source_index]);
00302 
00303         // swap pinning flags around
00304         if(tf->unwrap & pin_flags[source_index]) {
00305             unwrap |= pin_flags[j];
00306         }
00307 
00308         // swap selection flags around
00309         if(tf->flag & sel_flags[source_index]) {
00310             flag |= sel_flags[j];
00311         }
00312     }
00313 
00314     memcpy(tf->uv, uv, sizeof(tf->uv));
00315     tf->unwrap = unwrap;
00316     tf->flag = flag;
00317 }
00318 
00319 static void layerDefault_tface(void *data, int count)
00320 {
00321     static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL,
00322                                0, 0, TF_DYNAMIC|TF_CONVERTED, 0, 0};
00323     MTFace *tf = (MTFace*)data;
00324     int i;
00325 
00326     for(i = 0; i < count; i++)
00327         tf[i] = default_tf;
00328 }
00329 
00330 static void layerCopy_propFloat(const void *source, void *dest,
00331                                   int count)
00332 {
00333     memcpy(dest, source, sizeof(MFloatProperty)*count);
00334 }
00335 
00336 static void layerCopy_propInt(const void *source, void *dest,
00337                                   int count)
00338 {
00339     memcpy(dest, source, sizeof(MIntProperty)*count);
00340 }
00341 
00342 static void layerCopy_propString(const void *source, void *dest,
00343                                   int count)
00344 {
00345     memcpy(dest, source, sizeof(MStringProperty)*count);
00346 }
00347 
00348 static void layerCopy_origspace_face(const void *source, void *dest, int count)
00349 {
00350     const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
00351     OrigSpaceFace *dest_tf = (OrigSpaceFace*)dest;
00352     int i;
00353 
00354     for(i = 0; i < count; ++i)
00355         dest_tf[i] = source_tf[i];
00356 }
00357 
00358 static void layerInterp_origspace_face(void **sources, float *weights,
00359                               float *sub_weights, int count, void *dest)
00360 {
00361     OrigSpaceFace *osf = dest;
00362     int i, j, k;
00363     float uv[4][2] = {{0.0f}};
00364     float *sub_weight;
00365 
00366     if(count <= 0) return;
00367 
00368     sub_weight = sub_weights;
00369     for(i = 0; i < count; ++i) {
00370         float weight = weights ? weights[i] : 1;
00371         OrigSpaceFace *src = sources[i];
00372 
00373         for(j = 0; j < 4; ++j) {
00374             if(sub_weights) {
00375                 for(k = 0; k < 4; ++k, ++sub_weight) {
00376                     madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight);
00377                 }
00378             } else {
00379                 madd_v2_v2fl(uv[j], src->uv[j], weight);
00380             }
00381         }
00382     }
00383 
00384 #if 0 /* no need, this ONLY contains UV's */
00385     *osf = *(OrigSpaceFace *)(*sources);
00386 #endif
00387     memcpy(osf->uv, uv, sizeof(osf->uv));
00388 }
00389 
00390 static void layerSwap_origspace_face(void *data, const int *corner_indices)
00391 {
00392     OrigSpaceFace *osf = data;
00393     float uv[4][2];
00394     int j;
00395 
00396     for(j = 0; j < 4; ++j) {
00397         copy_v2_v2(uv[j], osf->uv[corner_indices[j]]);
00398     }
00399     memcpy(osf->uv, uv, sizeof(osf->uv));
00400 }
00401 
00402 static void layerDefault_origspace_face(void *data, int count)
00403 {
00404     static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
00405     OrigSpaceFace *osf = (OrigSpaceFace*)data;
00406     int i;
00407 
00408     for(i = 0; i < count; i++)
00409         osf[i] = default_osf;
00410 }
00411 
00412 static void layerSwap_mdisps(void *data, const int *ci)
00413 {
00414     MDisps *s = data;
00415     float (*d)[3] = NULL;
00416     int corners, cornersize, S;
00417 
00418     if(s->disps) {
00419         int nverts= (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */
00420         corners= multires_mdisp_corners(s);
00421         cornersize= s->totdisp/corners;
00422 
00423         if(corners!=nverts) {
00424             /* happens when face changed vertex count in edit mode
00425                if it happened, just forgot displacement */
00426 
00427             MEM_freeN(s->disps);
00428             s->totdisp= (s->totdisp/corners)*nverts;
00429             s->disps= MEM_callocN(s->totdisp*sizeof(float)*3, "mdisp swap");
00430             return;
00431         }
00432 
00433         d= MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap");
00434 
00435         for(S = 0; S < corners; S++)
00436             memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float));
00437         
00438         MEM_freeN(s->disps);
00439         s->disps= d;
00440     }
00441 }
00442 
00443 static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
00444                 float *sub_weights, int count, void *dest)
00445 {
00446     MDisps *d = dest;
00447     MDisps *s = NULL;
00448     int st, stl;
00449     int i, x, y;
00450     int side, S, dst_corners, src_corners;
00451     float crn_weight[4][2];
00452     float (*sw)[4] = (void*)sub_weights;
00453     float (*disps)[3], (*out)[3];
00454 
00455     /* happens when flipping normals of newly created mesh */
00456     if(!d->totdisp)
00457         return;
00458 
00459     s = sources[0];
00460     dst_corners = multires_mdisp_corners(d);
00461     src_corners = multires_mdisp_corners(s);
00462 
00463     if(sub_weights && count == 2 && src_corners == 3) {
00464         src_corners = multires_mdisp_corners(sources[1]);
00465 
00466         /* special case -- converting two triangles to quad */
00467         if(src_corners == 3 && dst_corners == 4) {
00468             MDisps tris[2];
00469             int vindex[4] = {0};
00470 
00471             for(i = 0; i < 2; i++)
00472                 for(y = 0; y < 4; y++)
00473                     for(x = 0; x < 4; x++)
00474                         if(sw[x+i*4][y])
00475                             vindex[x] = y;
00476 
00477             for(i = 0; i < 2; i++) {
00478                 float sw_m4[4][4] = {{0}};
00479                 int a = 7 & ~(1 << vindex[i*2] | 1 << vindex[i*2+1]);
00480 
00481                 sw_m4[0][vindex[i*2+1]] = 1;
00482                 sw_m4[1][vindex[i*2]] = 1;
00483 
00484                 for(x = 0; x < 3; x++)
00485                     if(a & (1 << x))
00486                         sw_m4[2][x] = 1;
00487 
00488                 tris[i] = *((MDisps*)sources[i]);
00489                 tris[i].disps = MEM_dupallocN(tris[i].disps);
00490                 layerInterp_mdisps(&sources[i], NULL, (float*)sw_m4, 1, &tris[i]);
00491             }
00492 
00493             mdisp_join_tris(d, &tris[0], &tris[1]);
00494 
00495             for(i = 0; i < 2; i++)
00496                 MEM_freeN(tris[i].disps);
00497 
00498             return;
00499         }
00500     }
00501 
00502     /* For now, some restrictions on the input */
00503     if(count != 1 || !sub_weights) {
00504         for(i = 0; i < d->totdisp; ++i)
00505             zero_v3(d->disps[i]);
00506 
00507         return;
00508     }
00509 
00510     /* Initialize the destination */
00511     disps = MEM_callocN(3*d->totdisp*sizeof(float), "iterp disps");
00512 
00513     side = sqrt(d->totdisp / dst_corners);
00514     st = (side<<1)-1;
00515     stl = st - 1;
00516 
00517     sw= (void*)sub_weights;
00518     for(i = 0; i < 4; ++i) {
00519         crn_weight[i][0] = 0 * sw[i][0] + stl * sw[i][1] + stl * sw[i][2] + 0 * sw[i][3];
00520         crn_weight[i][1] = 0 * sw[i][0] + 0 * sw[i][1] + stl * sw[i][2] + stl * sw[i][3];
00521     }
00522 
00523     multires_mdisp_smooth_bounds(s);
00524 
00525     out = disps;
00526     for(S = 0; S < dst_corners; S++) {
00527         float base[2], axis_x[2], axis_y[2];
00528 
00529         mdisp_apply_weight(S, dst_corners, 0, 0, st, crn_weight, &base[0], &base[1]);
00530         mdisp_apply_weight(S, dst_corners, side-1, 0, st, crn_weight, &axis_x[0], &axis_x[1]);
00531         mdisp_apply_weight(S, dst_corners, 0, side-1, st, crn_weight, &axis_y[0], &axis_y[1]);
00532 
00533         sub_v2_v2(axis_x, base);
00534         sub_v2_v2(axis_y, base);
00535         normalize_v2(axis_x);
00536         normalize_v2(axis_y);
00537 
00538         for(y = 0; y < side; ++y) {
00539             for(x = 0; x < side; ++x, ++out) {
00540                 int crn;
00541                 float face_u, face_v, crn_u, crn_v;
00542 
00543                 mdisp_apply_weight(S, dst_corners, x, y, st, crn_weight, &face_u, &face_v);
00544                 crn = mdisp_rot_face_to_quad_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
00545 
00546                 old_mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
00547                 mdisp_flip_disp(crn, dst_corners, axis_x, axis_y, *out);
00548             }
00549         }
00550     }
00551 
00552     MEM_freeN(d->disps);
00553     d->disps = disps;
00554 }
00555 
00556 static void layerCopy_mdisps(const void *source, void *dest, int count)
00557 {
00558     int i;
00559     const MDisps *s = source;
00560     MDisps *d = dest;
00561 
00562     for(i = 0; i < count; ++i) {
00563         if(s[i].disps) {
00564             d[i].disps = MEM_dupallocN(s[i].disps);
00565             d[i].totdisp = s[i].totdisp;
00566         }
00567         else {
00568             d[i].disps = NULL;
00569             d[i].totdisp = 0;
00570         }
00571         
00572     }
00573 }
00574 
00575 static void layerValidate_mdisps(void *data, int sub_elements)
00576 {
00577     MDisps *disps = data;
00578     if(disps->disps) {
00579         int corners = multires_mdisp_corners(disps);
00580 
00581         if(corners != sub_elements) {
00582             MEM_freeN(disps->disps);
00583             disps->totdisp = disps->totdisp / corners * sub_elements;
00584             disps->disps = MEM_callocN(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
00585         }
00586     }
00587 }
00588 
00589 static void layerFree_mdisps(void *data, int count, int UNUSED(size))
00590 {
00591     int i;
00592     MDisps *d = data;
00593 
00594     for(i = 0; i < count; ++i) {
00595         if(d[i].disps)
00596             MEM_freeN(d[i].disps);
00597         d[i].disps = NULL;
00598         d[i].totdisp = 0;
00599     }
00600 }
00601 
00602 static int layerRead_mdisps(CDataFile *cdf, void *data, int count)
00603 {
00604     MDisps *d = data;
00605     int i;
00606 
00607     for(i = 0; i < count; ++i) {
00608         if(!d[i].disps)
00609             d[i].disps = MEM_callocN(sizeof(float)*3*d[i].totdisp, "mdisps read");
00610 
00611         if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
00612             printf("failed to read multires displacement %d/%d %d\n", i, count, d[i].totdisp);
00613             return 0;
00614         }
00615     }
00616 
00617     return 1;
00618 }
00619 
00620 static int layerWrite_mdisps(CDataFile *cdf, void *data, int count)
00621 {
00622     MDisps *d = data;
00623     int i;
00624 
00625     for(i = 0; i < count; ++i) {
00626         if(!cdf_write_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
00627             printf("failed to write multires displacement %d/%d %d\n", i, count, d[i].totdisp);
00628             return 0;
00629         }
00630     }
00631 
00632     return 1;
00633 }
00634 
00635 static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), void *data, int count)
00636 {
00637     MDisps *d = data;
00638     size_t size = 0;
00639     int i;
00640 
00641     for(i = 0; i < count; ++i)
00642         size += d[i].totdisp*3*sizeof(float);
00643 
00644     return size;
00645 }
00646 
00647 /* --------- */
00648 static void layerCopyValue_mloopcol(void *source, void *dest)
00649 {
00650     MLoopCol *m1 = source, *m2 = dest;
00651     
00652     m2->r = m1->r;
00653     m2->g = m1->g;
00654     m2->b = m1->b;
00655     m2->a = m1->a;
00656 }
00657 
00658 static int layerEqual_mloopcol(void *data1, void *data2)
00659 {
00660     MLoopCol *m1 = data1, *m2 = data2;
00661     float r, g, b, a;
00662 
00663     r = m1->r - m2->r;
00664     g = m1->g - m2->g;
00665     b = m1->b - m2->b;
00666     a = m1->a - m2->a;
00667 
00668     return r*r + g*g + b*b + a*a < 0.001;
00669 }
00670 
00671 static void layerMultiply_mloopcol(void *data, float fac)
00672 {
00673     MLoopCol *m = data;
00674 
00675     m->r = (float)m->r * fac;
00676     m->g = (float)m->g * fac;
00677     m->b = (float)m->b * fac;
00678     m->a = (float)m->a * fac;
00679 }
00680 
00681 static void layerAdd_mloopcol(void *data1, void *data2)
00682 {
00683     MLoopCol *m = data1, *m2 = data2;
00684 
00685     m->r += m2->r;
00686     m->g += m2->g;
00687     m->b += m2->b;
00688     m->a += m2->a;
00689 }
00690 
00691 static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax)
00692 {
00693     MLoopCol *m = data;
00694     MLoopCol *min = vmin, *max = vmax;
00695 
00696     if (m->r < min->r) min->r = m->r;
00697     if (m->g < min->g) min->g = m->g;
00698     if (m->b < min->b) min->b = m->b;
00699     if (m->a < min->a) min->a = m->a;
00700     
00701     if (m->r > max->r) max->r = m->r;
00702     if (m->g > max->g) max->g = m->g;
00703     if (m->b > max->b) max->b = m->b;
00704     if (m->a > max->a) max->a = m->a;
00705 }
00706 
00707 static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
00708 {
00709     MLoopCol *min = vmin, *max = vmax;
00710 
00711     min->r = 255;
00712     min->g = 255;
00713     min->b = 255;
00714     min->a = 255;
00715 
00716     max->r = 0;
00717     max->g = 0;
00718     max->b = 0;
00719     max->a = 0;
00720 }
00721 
00722 static void layerDefault_mloopcol(void *data, int count)
00723 {
00724     MLoopCol default_mloopcol = {255,255,255,255};
00725     MLoopCol *mlcol = (MLoopCol*)data;
00726     int i;
00727     for(i = 0; i < count; i++)
00728         mlcol[i] = default_mloopcol;
00729 
00730 }
00731 
00732 static void layerInterp_mloopcol(void **sources, float *weights,
00733                 float *sub_weights, int count, void *dest)
00734 {
00735     MLoopCol *mc = dest;
00736     int i;
00737     float *sub_weight;
00738     struct {
00739         float a;
00740         float r;
00741         float g;
00742         float b;
00743     } col;
00744     col.a = col.r = col.g = col.b = 0;
00745 
00746     sub_weight = sub_weights;
00747     for(i = 0; i < count; ++i){
00748         float weight = weights ? weights[i] : 1;
00749         MLoopCol *src = sources[i];
00750         if(sub_weights){
00751             col.a += src->a * (*sub_weight) * weight;
00752             col.r += src->r * (*sub_weight) * weight;
00753             col.g += src->g * (*sub_weight) * weight;
00754             col.b += src->b * (*sub_weight) * weight;
00755             sub_weight++;
00756         } else {
00757             col.a += src->a * weight;
00758             col.r += src->r * weight;
00759             col.g += src->g * weight;
00760             col.b += src->b * weight;
00761         }
00762     }
00763     
00764     /* Subdivide smooth or fractal can cause problems without clamping
00765      * although weights should also not cause this situation */
00766     CLAMP(col.a, 0.0f, 255.0f);
00767     CLAMP(col.r, 0.0f, 255.0f);
00768     CLAMP(col.g, 0.0f, 255.0f);
00769     CLAMP(col.b, 0.0f, 255.0f);
00770     
00771     mc->a = (int)col.a;
00772     mc->r = (int)col.r;
00773     mc->g = (int)col.g;
00774     mc->b = (int)col.b;
00775 }
00776 
00777 static void layerCopyValue_mloopuv(void *source, void *dest)
00778 {
00779     MLoopUV *luv1 = source, *luv2 = dest;
00780 
00781     copy_v2_v2(luv2->uv, luv1->uv);
00782 }
00783 
00784 static int layerEqual_mloopuv(void *data1, void *data2)
00785 {
00786     MLoopUV *luv1 = data1, *luv2 = data2;
00787 
00788     return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
00789 }
00790 
00791 static void layerMultiply_mloopuv(void *data, float fac)
00792 {
00793     MLoopUV *luv = data;
00794 
00795     mul_v2_fl(luv->uv, fac);
00796 }
00797 
00798 static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
00799 {
00800     MLoopUV *min = vmin, *max = vmax;
00801 
00802     INIT_MINMAX2(min->uv, max->uv);
00803 }
00804 
00805 static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
00806 {
00807     MLoopUV *min = vmin, *max = vmax, *luv = data;
00808 
00809     DO_MINMAX2(luv->uv, min->uv, max->uv);
00810 }
00811 
00812 static void layerAdd_mloopuv(void *data1, void *data2)
00813 {
00814     MLoopUV *l1 = data1, *l2 = data2;
00815 
00816     add_v2_v2(l1->uv, l2->uv);
00817 }
00818 
00819 static void layerInterp_mloopuv(void **sources, float *weights,
00820                                 float *sub_weights, int count, void *dest)
00821 {
00822     MLoopUV *mluv = dest;
00823     float *uv= mluv->uv;
00824     int i;
00825 
00826     zero_v2(uv);
00827 
00828     if (sub_weights) {
00829         const float *sub_weight = sub_weights;
00830         for(i = 0; i < count; i++) {
00831             float weight = weights ? weights[i] : 1.0f;
00832             MLoopUV *src = sources[i];
00833             madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight);
00834             sub_weight++;
00835         }
00836     }
00837     else {
00838         for(i = 0; i < count; i++) {
00839             float weight = weights ? weights[i] : 1;
00840             MLoopUV *src = sources[i];
00841             madd_v2_v2fl(uv, src->uv, weight);
00842         }
00843     }
00844 }
00845 
00846 static void layerInterp_mcol(void **sources, float *weights,
00847                              float *sub_weights, int count, void *dest)
00848 {
00849     MCol *mc = dest;
00850     int i, j, k;
00851     struct {
00852         float a;
00853         float r;
00854         float g;
00855         float b;
00856     } col[4] = {{0.0f}};
00857 
00858     float *sub_weight;
00859 
00860     if(count <= 0) return;
00861     
00862     sub_weight = sub_weights;
00863     for(i = 0; i < count; ++i) {
00864         float weight = weights ? weights[i] : 1;
00865 
00866         for(j = 0; j < 4; ++j) {
00867             if(sub_weights) {
00868                 MCol *src = sources[i];
00869                 for(k = 0; k < 4; ++k, ++sub_weight, ++src) {
00870                     const float w= (*sub_weight) * weight;
00871                     col[j].a += src->a * w;
00872                     col[j].r += src->r * w;
00873                     col[j].g += src->g * w;
00874                     col[j].b += src->b * w;
00875                 }
00876             } else {
00877                 MCol *src = sources[i];
00878                 col[j].a += src[j].a * weight;
00879                 col[j].r += src[j].r * weight;
00880                 col[j].g += src[j].g * weight;
00881                 col[j].b += src[j].b * weight;
00882             }
00883         }
00884     }
00885 
00886     for(j = 0; j < 4; ++j) {
00887         
00888         /* Subdivide smooth or fractal can cause problems without clamping
00889          * although weights should also not cause this situation */
00890         CLAMP(col[j].a, 0.0f, 255.0f);
00891         CLAMP(col[j].r, 0.0f, 255.0f);
00892         CLAMP(col[j].g, 0.0f, 255.0f);
00893         CLAMP(col[j].b, 0.0f, 255.0f);
00894         
00895         mc[j].a = (int)col[j].a;
00896         mc[j].r = (int)col[j].r;
00897         mc[j].g = (int)col[j].g;
00898         mc[j].b = (int)col[j].b;
00899     }
00900 }
00901 
00902 static void layerSwap_mcol(void *data, const int *corner_indices)
00903 {
00904     MCol *mcol = data;
00905     MCol col[4];
00906     int j;
00907 
00908     for(j = 0; j < 4; ++j)
00909         col[j] = mcol[corner_indices[j]];
00910 
00911     memcpy(mcol, col, sizeof(col));
00912 }
00913 
00914 static void layerDefault_mcol(void *data, int count)
00915 {
00916     static MCol default_mcol = {255, 255, 255, 255};
00917     MCol *mcol = (MCol*)data;
00918     int i;
00919 
00920     for(i = 0; i < 4*count; i++) {
00921         mcol[i] = default_mcol;
00922     }
00923 }
00924 
00925 static void layerInterp_bweight(void **sources, float *weights,
00926                                 float *UNUSED(sub_weights), int count, void *dest)
00927 {
00928     float *f = dest;
00929     float **in = (float **)sources;
00930     int i;
00931     
00932     if(count <= 0) return;
00933 
00934     *f = 0.0f;
00935 
00936     if (weights) {
00937         for(i = 0; i < count; ++i) {
00938             *f += *in[i] * weights[i];
00939         }
00940     }
00941     else {
00942         for(i = 0; i < count; ++i) {
00943             *f += *in[i];
00944         }
00945     }
00946 }
00947 
00948 static void layerInterp_shapekey(void **sources, float *weights,
00949                                  float *UNUSED(sub_weights), int count, void *dest)
00950 {
00951     float *co = dest;
00952     float **in = (float **)sources;
00953     int i;
00954 
00955     if(count <= 0) return;
00956 
00957     zero_v3(co);
00958 
00959     if (weights) {
00960         for(i = 0; i < count; ++i) {
00961             madd_v3_v3fl(co, in[i], weights[i]);
00962         }
00963     }
00964     else {
00965         for(i = 0; i < count; ++i) {
00966             add_v3_v3(co, in[i]);
00967         }
00968     }
00969 }
00970 
00971 static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
00972     /* 0: CD_MVERT */
00973     {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
00974     /* 1: CD_MSTICKY */
00975     {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
00976      NULL},
00977     /* 2: CD_MDEFORMVERT */
00978     {sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert,
00979      layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL},
00980     /* 3: CD_MEDGE */
00981     {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL},
00982     /* 4: CD_MFACE */
00983     {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
00984     /* 5: CD_MTFACE */
00985     {sizeof(MTFace), "MTFace", 1, "UVMap", layerCopy_tface, NULL,
00986      layerInterp_tface, layerSwap_tface, layerDefault_tface},
00987     /* 6: CD_MCOL */
00988     /* 4 MCol structs per face */
00989     {sizeof(MCol)*4, "MCol", 4, "Col", NULL, NULL, layerInterp_mcol,
00990      layerSwap_mcol, layerDefault_mcol},
00991     /* 7: CD_ORIGINDEX */
00992     {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
00993     /* 8: CD_NORMAL */
00994     /* 3 floats per normal vector */
00995     {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
00996     /* 9: CD_POLYINDEX */
00997     {sizeof(int), "MIntProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL},
00998     /* 10: CD_PROP_FLT */
00999     {sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
01000     /* 11: CD_PROP_INT */
01001     {sizeof(MIntProperty), "MIntProperty",1,"Int",layerCopy_propInt,NULL,NULL,NULL},
01002     /* 12: CD_PROP_STR */
01003     {sizeof(MStringProperty), "MStringProperty",1,"String",layerCopy_propString,NULL,NULL,NULL},
01004     /* 13: CD_ORIGSPACE */
01005     {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVMap", layerCopy_origspace_face, NULL,
01006      layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
01007     /* 14: CD_ORCO */
01008     {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
01009     /* 15: CD_MTEXPOLY */
01010     {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
01011     /* 16: CD_MLOOPUV */
01012     {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL,
01013      layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv, 
01014      layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv},
01015     /* 17: CD_MLOOPCOL */
01016     {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, 
01017      layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol, 
01018      layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
01019     /* 18: CD_TANGENT */
01020     {sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
01021     /* 19: CD_MDISPS */
01022     {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
01023      layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL,
01024      NULL, NULL, NULL, NULL, NULL, NULL, 
01025      layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps, layerValidate_mdisps},
01026     /* 20: CD_WEIGHT_MCOL */
01027     {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
01028      layerSwap_mcol, layerDefault_mcol},
01029     /* 21: CD_ID_MCOL */
01030     {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
01031      layerSwap_mcol, layerDefault_mcol},
01032     /* 22: CD_TEXTURE_MCOL */
01033     {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
01034      layerSwap_mcol, layerDefault_mcol},
01035     /* 23: CD_CLOTH_ORCO */
01036     {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
01037     /* 24: CD_RECAST */
01038     {sizeof(MRecast), "MRecast", 1,"Recast",NULL,NULL,NULL,NULL}
01039 
01040 #ifdef USE_BMESH_FORWARD_COMPAT
01041     ,
01042 /* BMESH ONLY */
01043     /* 25: CD_MPOLY */
01044     {sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
01045     /* 26: CD_MLOOP */
01046     {sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL},
01047     /* 27: CD_SHAPE_KEYINDEX */
01048     {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
01049     /* 28: CD_SHAPEKEY */
01050     {sizeof(float)*3, "", 0, "ShapeKey", NULL, NULL, layerInterp_shapekey},
01051     /* 29: CD_BWEIGHT */
01052     {sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
01053     /* 30: CD_CREASE */
01054     {sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
01055     /* 31: CD_WEIGHT_MLOOPCOL */
01056     {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
01057      layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
01058      layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
01059 /* END BMESH ONLY */
01060 
01061 #endif /* USE_BMESH_FORWARD_COMPAT */
01062 
01063 };
01064 
01065 static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
01066     /*   0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace",
01067     /*   5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags",
01068     /* 10-14 */ "CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco",
01069     /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps",
01070     /* 20-24 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco", "CDMRecast"
01071 
01072 #ifdef USE_BMESH_FORWARD_COMPAT
01073     ,
01074     /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
01075     /* 30-31 */ "CDSubSurfCrease", "CDWeightLoopCol"
01076 
01077 #endif /* USE_BMESH_FORWARD_COMPAT */
01078 };
01079 
01080 const CustomDataMask CD_MASK_BAREMESH =
01081     CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
01082 const CustomDataMask CD_MASK_MESH =
01083     CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
01084     CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
01085     CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST;
01086 const CustomDataMask CD_MASK_EDITMESH =
01087     CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
01088     CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST;
01089 const CustomDataMask CD_MASK_DERIVEDMESH =
01090     CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
01091     CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
01092     CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL | CD_MASK_RECAST;
01093 const CustomDataMask CD_MASK_BMESH = 
01094     CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
01095 const CustomDataMask CD_MASK_FACECORNERS =
01096     CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
01097     CD_MASK_MLOOPCOL;
01098 
01099 static const LayerTypeInfo *layerType_getInfo(int type)
01100 {
01101     if(type < 0 || type >= CD_NUMTYPES) return NULL;
01102 
01103     return &LAYERTYPEINFO[type];
01104 }
01105 
01106 static const char *layerType_getName(int type)
01107 {
01108     if(type < 0 || type >= CD_NUMTYPES) return NULL;
01109 
01110     return LAYERTYPENAMES[type];
01111 }
01112 
01113 /********************* CustomData functions *********************/
01114 static void customData_update_offsets(CustomData *data);
01115 
01116 static CustomDataLayer *customData_add_layer__internal(CustomData *data,
01117     int type, int alloctype, void *layerdata, int totelem, const char *name);
01118 
01119 void CustomData_update_typemap(CustomData *data)
01120 {
01121     int i, lasttype = -1;
01122 
01123     /* since we cant do in a pre-processor do here as an assert */
01124     BLI_assert(sizeof(data->typemap) / sizeof(int) >= CD_NUMTYPES);
01125 
01126     for (i=0; i<CD_NUMTYPES; i++) {
01127         data->typemap[i] = -1;
01128     }
01129 
01130     for (i=0; i<data->totlayer; i++) {
01131         if (data->layers[i].type != lasttype) {
01132             data->typemap[data->layers[i].type] = i;
01133         }
01134         lasttype = data->layers[i].type;
01135     }
01136 }
01137 
01138 void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
01139                       CustomDataMask mask, int alloctype, int totelem)
01140 {
01141     /*const LayerTypeInfo *typeInfo;*/
01142     CustomDataLayer *layer, *newlayer;
01143     int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0;
01144 
01145     for(i = 0; i < source->totlayer; ++i) {
01146         layer = &source->layers[i];
01147         /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/
01148 
01149         type = layer->type;
01150 
01151         if (type != lasttype) {
01152             number = 0;
01153             lastactive = layer->active;
01154             lastrender = layer->active_rnd;
01155             lastclone = layer->active_clone;
01156             lastmask = layer->active_mask;
01157             lasttype = type;
01158             lastflag = layer->flag;
01159         }
01160         else
01161             number++;
01162 
01163         if(lastflag & CD_FLAG_NOCOPY) continue;
01164         else if(!(mask & CD_TYPE_AS_MASK(type))) continue;
01165         else if(number < CustomData_number_of_layers(dest, type)) continue;
01166 
01167         if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE))
01168             newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE,
01169                 layer->data, totelem, layer->name);
01170         else
01171             newlayer = customData_add_layer__internal(dest, type, alloctype,
01172                 layer->data, totelem, layer->name);
01173         
01174         if(newlayer) {
01175             newlayer->active = lastactive;
01176             newlayer->active_rnd = lastrender;
01177             newlayer->active_clone = lastclone;
01178             newlayer->active_mask = lastmask;
01179             newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY);
01180         }
01181     }
01182 
01183     CustomData_update_typemap(dest);
01184 }
01185 
01186 void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
01187                      CustomDataMask mask, int alloctype, int totelem)
01188 {
01189     memset(dest, 0, sizeof(*dest));
01190 
01191     if(source->external)
01192         dest->external= MEM_dupallocN(source->external);
01193 
01194     CustomData_merge(source, dest, mask, alloctype, totelem);
01195 }
01196 
01197 static void customData_free_layer__internal(CustomDataLayer *layer, int totelem)
01198 {
01199     const LayerTypeInfo *typeInfo;
01200 
01201     if(!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
01202         typeInfo = layerType_getInfo(layer->type);
01203 
01204         if(typeInfo->free)
01205             typeInfo->free(layer->data, totelem, typeInfo->size);
01206 
01207         if(layer->data)
01208             MEM_freeN(layer->data);
01209     }
01210 }
01211 
01212 static void CustomData_external_free(CustomData *data)
01213 {
01214     if(data->external) {
01215         MEM_freeN(data->external);
01216         data->external= NULL;
01217     }
01218 }
01219 
01220 void CustomData_free(CustomData *data, int totelem)
01221 {
01222     int i;
01223 
01224     for(i = 0; i < data->totlayer; ++i)
01225         customData_free_layer__internal(&data->layers[i], totelem);
01226 
01227     if(data->layers)
01228         MEM_freeN(data->layers);
01229     
01230     CustomData_external_free(data);
01231     
01232     memset(data, 0, sizeof(*data));
01233 }
01234 
01235 static void customData_update_offsets(CustomData *data)
01236 {
01237     const LayerTypeInfo *typeInfo;
01238     int i, offset = 0;
01239 
01240     for(i = 0; i < data->totlayer; ++i) {
01241         typeInfo = layerType_getInfo(data->layers[i].type);
01242 
01243         data->layers[i].offset = offset;
01244         offset += typeInfo->size;
01245     }
01246 
01247     data->totsize = offset;
01248     CustomData_update_typemap(data);
01249 }
01250 
01251 int CustomData_get_layer_index(const CustomData *data, int type)
01252 {
01253     int i; 
01254 
01255     for(i=0; i < data->totlayer; ++i)
01256         if(data->layers[i].type == type)
01257             return i;
01258 
01259     return -1;
01260 }
01261 
01262 int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
01263 {
01264     int i = CustomData_get_layer_index(data, type);
01265 
01266     if (i != -1) {
01267         i = (data->layers[i + n].type == type) ? (i + n) : (-1);
01268     }
01269 
01270     return i;
01271 }
01272 
01273 int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
01274 {
01275     int i;
01276 
01277     for(i=0; i < data->totlayer; ++i)
01278         if(data->layers[i].type == type && strcmp(data->layers[i].name, name)==0)
01279             return i;
01280 
01281     return -1;
01282 }
01283 
01284 int CustomData_get_active_layer_index(const CustomData *data, int type)
01285 {
01286     if (!data->totlayer)
01287         return -1;
01288 
01289     if (data->typemap[type] != -1) {
01290         return data->typemap[type] + data->layers[data->typemap[type]].active;
01291     }
01292 
01293     return -1;
01294 }
01295 
01296 int CustomData_get_render_layer_index(const CustomData *data, int type)
01297 {
01298     int i;
01299 
01300     for(i=0; i < data->totlayer; ++i)
01301         if(data->layers[i].type == type)
01302             return i + data->layers[i].active_rnd;
01303 
01304     return -1;
01305 }
01306 
01307 int CustomData_get_clone_layer_index(const CustomData *data, int type)
01308 {
01309     int i;
01310 
01311     for(i=0; i < data->totlayer; ++i)
01312         if(data->layers[i].type == type)
01313             return i + data->layers[i].active_clone;
01314 
01315     return -1;
01316 }
01317 
01318 int CustomData_get_stencil_layer_index(const CustomData *data, int type)
01319 {
01320     int i;
01321 
01322     for(i=0; i < data->totlayer; ++i)
01323         if(data->layers[i].type == type)
01324             return i + data->layers[i].active_mask;
01325 
01326     return -1;
01327 }
01328 
01329 int CustomData_get_active_layer(const CustomData *data, int type)
01330 {
01331     int i;
01332 
01333     for(i=0; i < data->totlayer; ++i)
01334         if(data->layers[i].type == type)
01335             return data->layers[i].active;
01336 
01337     return -1;
01338 }
01339 
01340 int CustomData_get_render_layer(const CustomData *data, int type)
01341 {
01342     int i;
01343 
01344     for(i=0; i < data->totlayer; ++i)
01345         if(data->layers[i].type == type)
01346             return data->layers[i].active_rnd;
01347 
01348     return -1;
01349 }
01350 
01351 int CustomData_get_clone_layer(const CustomData *data, int type)
01352 {
01353     int i;
01354 
01355     for(i=0; i < data->totlayer; ++i)
01356         if(data->layers[i].type == type)
01357             return data->layers[i].active_clone;
01358 
01359     return -1;
01360 }
01361 
01362 int CustomData_get_stencil_layer(const CustomData *data, int type)
01363 {
01364     int i;
01365 
01366     for(i=0; i < data->totlayer; ++i)
01367         if(data->layers[i].type == type)
01368             return data->layers[i].active_mask;
01369 
01370     return -1;
01371 }
01372 
01373 void CustomData_set_layer_active(CustomData *data, int type, int n)
01374 {
01375     int i;
01376 
01377     for(i=0; i < data->totlayer; ++i)
01378         if(data->layers[i].type == type)
01379             data->layers[i].active = n;
01380 }
01381 
01382 void CustomData_set_layer_render(CustomData *data, int type, int n)
01383 {
01384     int i;
01385 
01386     for(i=0; i < data->totlayer; ++i)
01387         if(data->layers[i].type == type)
01388             data->layers[i].active_rnd = n;
01389 }
01390 
01391 void CustomData_set_layer_clone(CustomData *data, int type, int n)
01392 {
01393     int i;
01394 
01395     for(i=0; i < data->totlayer; ++i)
01396         if(data->layers[i].type == type)
01397             data->layers[i].active_clone = n;
01398 }
01399 
01400 void CustomData_set_layer_stencil(CustomData *data, int type, int n)
01401 {
01402     int i;
01403 
01404     for(i=0; i < data->totlayer; ++i)
01405         if(data->layers[i].type == type)
01406             data->layers[i].active_mask = n;
01407 }
01408 
01409 /* for using with an index from CustomData_get_active_layer_index and CustomData_get_render_layer_index */
01410 void CustomData_set_layer_active_index(CustomData *data, int type, int n)
01411 {
01412     int i;
01413 
01414     for(i=0; i < data->totlayer; ++i)
01415         if(data->layers[i].type == type)
01416             data->layers[i].active = n-i;
01417 }
01418 
01419 void CustomData_set_layer_render_index(CustomData *data, int type, int n)
01420 {
01421     int i;
01422 
01423     for(i=0; i < data->totlayer; ++i)
01424         if(data->layers[i].type == type)
01425             data->layers[i].active_rnd = n-i;
01426 }
01427 
01428 void CustomData_set_layer_clone_index(CustomData *data, int type, int n)
01429 {
01430     int i;
01431 
01432     for(i=0; i < data->totlayer; ++i)
01433         if(data->layers[i].type == type)
01434             data->layers[i].active_clone = n-i;
01435 }
01436 
01437 void CustomData_set_layer_stencil_index(CustomData *data, int type, int n)
01438 {
01439     int i;
01440 
01441     for(i=0; i < data->totlayer; ++i)
01442         if(data->layers[i].type == type)
01443             data->layers[i].active_mask = n-i;
01444 }
01445 
01446 void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
01447 {
01448     int i;
01449 
01450     for(i=0; i < data->totlayer; ++i)
01451         if(data->layers[i].type == type)
01452             data->layers[i].flag |= flag;
01453 }
01454 
01455 static int customData_resize(CustomData *data, int amount)
01456 {
01457     CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxlayer + amount),
01458                                        "CustomData->layers");
01459     if(!tmp) return 0;
01460 
01461     data->maxlayer += amount;
01462     if (data->layers) {
01463         memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer);
01464         MEM_freeN(data->layers);
01465     }
01466     data->layers = tmp;
01467 
01468     return 1;
01469 }
01470 
01471 static CustomDataLayer *customData_add_layer__internal(CustomData *data,
01472     int type, int alloctype, void *layerdata, int totelem, const char *name)
01473 {
01474     const LayerTypeInfo *typeInfo= layerType_getInfo(type);
01475     int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
01476     void *newlayerdata;
01477 
01478     if (!typeInfo->defaultname && CustomData_has_layer(data, type))
01479         return &data->layers[CustomData_get_layer_index(data, type)];
01480 
01481     if((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) {
01482         newlayerdata = layerdata;
01483     }
01484     else {
01485         newlayerdata = MEM_callocN(size, layerType_getName(type));
01486         if(!newlayerdata)
01487             return NULL;
01488     }
01489 
01490     if (alloctype == CD_DUPLICATE) {
01491         if(typeInfo->copy)
01492             typeInfo->copy(layerdata, newlayerdata, totelem);
01493         else
01494             memcpy(newlayerdata, layerdata, size);
01495     }
01496     else if (alloctype == CD_DEFAULT) {
01497         if(typeInfo->set_default)
01498             typeInfo->set_default((char*)newlayerdata, totelem);
01499     }
01500     else if (alloctype == CD_REFERENCE)
01501         flag |= CD_FLAG_NOFREE;
01502 
01503     if(index >= data->maxlayer) {
01504         if(!customData_resize(data, CUSTOMDATA_GROW)) {
01505             if(newlayerdata != layerdata)
01506                 MEM_freeN(newlayerdata);
01507             return NULL;
01508         }
01509     }
01510     
01511     data->totlayer++;
01512 
01513     /* keep layers ordered by type */
01514     for( ; index > 0 && data->layers[index - 1].type > type; --index)
01515         data->layers[index] = data->layers[index - 1];
01516 
01517     data->layers[index].type = type;
01518     data->layers[index].flag = flag;
01519     data->layers[index].data = newlayerdata;
01520 
01521     if(name || (name=typeInfo->defaultname)) {
01522         BLI_strncpy(data->layers[index].name, name, sizeof(data->layers[index].name));
01523         CustomData_set_layer_unique_name(data, index);
01524     }
01525     else
01526         data->layers[index].name[0] = '\0';
01527 
01528     if(index > 0 && data->layers[index-1].type == type) {
01529         data->layers[index].active = data->layers[index-1].active;
01530         data->layers[index].active_rnd = data->layers[index-1].active_rnd;
01531         data->layers[index].active_clone = data->layers[index-1].active_clone;
01532         data->layers[index].active_mask = data->layers[index-1].active_mask;
01533     } else {
01534         data->layers[index].active = 0;
01535         data->layers[index].active_rnd = 0;
01536         data->layers[index].active_clone = 0;
01537         data->layers[index].active_mask = 0;
01538     }
01539     
01540     customData_update_offsets(data);
01541 
01542     return &data->layers[index];
01543 }
01544 
01545 void *CustomData_add_layer(CustomData *data, int type, int alloctype,
01546                            void *layerdata, int totelem)
01547 {
01548     CustomDataLayer *layer;
01549     const LayerTypeInfo *typeInfo= layerType_getInfo(type);
01550     
01551     layer = customData_add_layer__internal(data, type, alloctype, layerdata,
01552                                            totelem, typeInfo->defaultname);
01553     CustomData_update_typemap(data);
01554 
01555     if(layer)
01556         return layer->data;
01557 
01558     return NULL;
01559 }
01560 
01561 /*same as above but accepts a name*/
01562 void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
01563                            void *layerdata, int totelem, const char *name)
01564 {
01565     CustomDataLayer *layer;
01566     
01567     layer = customData_add_layer__internal(data, type, alloctype, layerdata,
01568                                            totelem, name);
01569     CustomData_update_typemap(data);
01570 
01571     if(layer)
01572         return layer->data;
01573 
01574     return NULL;
01575 }
01576 
01577 
01578 int CustomData_free_layer(CustomData *data, int type, int totelem, int index)
01579 {
01580     int i;
01581     
01582     if (index < 0) return 0;
01583 
01584     customData_free_layer__internal(&data->layers[index], totelem);
01585 
01586     for (i=index+1; i < data->totlayer; ++i)
01587         data->layers[i-1] = data->layers[i];
01588 
01589     data->totlayer--;
01590 
01591     /* if layer was last of type in array, set new active layer */
01592     if ((index >= data->totlayer) || (data->layers[index].type != type)) {
01593         i = CustomData_get_layer_index(data, type);
01594         
01595         if (i >= 0)
01596             for (; i < data->totlayer && data->layers[i].type == type; i++) {
01597                 data->layers[i].active--;
01598                 data->layers[i].active_rnd--;
01599                 data->layers[i].active_clone--;
01600                 data->layers[i].active_mask--;
01601             }
01602     }
01603 
01604     if (data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
01605         customData_resize(data, -CUSTOMDATA_GROW);
01606 
01607     customData_update_offsets(data);
01608     CustomData_update_typemap(data);
01609 
01610     return 1;
01611 }
01612 
01613 int CustomData_free_layer_active(CustomData *data, int type, int totelem)
01614 {
01615     int index = 0;
01616     index = CustomData_get_active_layer_index(data, type);
01617     if (index < 0) return 0;
01618     return CustomData_free_layer(data, type, totelem, index);
01619 }
01620 
01621 
01622 void CustomData_free_layers(CustomData *data, int type, int totelem)
01623 {
01624     while (CustomData_has_layer(data, type))
01625         CustomData_free_layer_active(data, type, totelem);
01626 }
01627 
01628 int CustomData_has_layer(const CustomData *data, int type)
01629 {
01630     return (CustomData_get_layer_index(data, type) != -1);
01631 }
01632 
01633 int CustomData_number_of_layers(const CustomData *data, int type)
01634 {
01635     int i, number = 0;
01636 
01637     for(i = 0; i < data->totlayer; i++)
01638         if(data->layers[i].type == type)
01639             number++;
01640     
01641     return number;
01642 }
01643 
01644 void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem)
01645 {
01646     CustomDataLayer *layer;
01647     int layer_index;
01648 
01649     /* get the layer index of the first layer of type */
01650     layer_index = CustomData_get_active_layer_index(data, type);
01651     if(layer_index < 0) return NULL;
01652 
01653     layer = &data->layers[layer_index];
01654 
01655     if (layer->flag & CD_FLAG_NOFREE) {
01656         /* MEM_dupallocN won’t work in case of complex layers, like e.g.
01657          * CD_MDEFORMVERT, which has pointers to allocated data...
01658          * So in case a custom copy function is defined, use it!
01659          */
01660         const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
01661 
01662         if(typeInfo->copy) {
01663             char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
01664             typeInfo->copy(layer->data, dest_data, totelem);
01665             layer->data = dest_data;
01666         }
01667         else
01668             layer->data = MEM_dupallocN(layer->data);
01669 
01670         layer->flag &= ~CD_FLAG_NOFREE;
01671     }
01672 
01673     return layer->data;
01674 }
01675 
01676 void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
01677                                                   const int type, const char *name, const int totelem)
01678 {
01679     CustomDataLayer *layer;
01680     int layer_index;
01681 
01682     /* get the layer index of the desired layer */
01683     layer_index = CustomData_get_named_layer_index(data, type, name);
01684     if(layer_index < 0) return NULL;
01685 
01686     layer = &data->layers[layer_index];
01687 
01688     if (layer->flag & CD_FLAG_NOFREE) {
01689         /* MEM_dupallocN won’t work in case of complex layers, like e.g.
01690          * CD_MDEFORMVERT, which has pointers to allocated data...
01691          * So in case a custom copy function is defined, use it!
01692          */
01693         const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
01694 
01695         if(typeInfo->copy) {
01696             char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
01697             typeInfo->copy(layer->data, dest_data, totelem);
01698             layer->data = dest_data;
01699         }
01700         else
01701             layer->data = MEM_dupallocN(layer->data);
01702 
01703         layer->flag &= ~CD_FLAG_NOFREE;
01704     }
01705 
01706     return layer->data;
01707 }
01708 
01709 int CustomData_is_referenced_layer(struct CustomData *data, int type)
01710 {
01711     CustomDataLayer *layer;
01712     int layer_index;
01713 
01714     /* get the layer index of the first layer of type */
01715     layer_index = CustomData_get_active_layer_index(data, type);
01716     if(layer_index < 0) return 0;
01717 
01718     layer = &data->layers[layer_index];
01719 
01720     return (layer->flag & CD_FLAG_NOFREE) != 0;
01721 }
01722 
01723 void CustomData_free_temporary(CustomData *data, int totelem)
01724 {
01725     CustomDataLayer *layer;
01726     int i, j;
01727 
01728     for(i = 0, j = 0; i < data->totlayer; ++i) {
01729         layer = &data->layers[i];
01730 
01731         if (i != j)
01732             data->layers[j] = data->layers[i];
01733 
01734         if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY)
01735             customData_free_layer__internal(layer, totelem);
01736         else
01737             j++;
01738     }
01739 
01740     data->totlayer = j;
01741 
01742     if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
01743         customData_resize(data, -CUSTOMDATA_GROW);
01744 
01745     customData_update_offsets(data);
01746 }
01747 
01748 void CustomData_set_only_copy(const struct CustomData *data,
01749                               CustomDataMask mask)
01750 {
01751     int i;
01752 
01753     for(i = 0; i < data->totlayer; ++i)
01754         if(!(mask & CD_TYPE_AS_MASK(data->layers[i].type)))
01755             data->layers[i].flag |= CD_FLAG_NOCOPY;
01756 }
01757 
01758 void CustomData_copy_elements(int type, void *source, void *dest, int count)
01759 {
01760     const LayerTypeInfo *typeInfo = layerType_getInfo(type);
01761 
01762     if (typeInfo->copy)
01763         typeInfo->copy(source, dest, count);
01764     else
01765         memcpy(dest, source, typeInfo->size*count);
01766 }
01767 
01768 void CustomData_copy_data(const CustomData *source, CustomData *dest,
01769                           int source_index, int dest_index, int count)
01770 {
01771     const LayerTypeInfo *typeInfo;
01772     int src_i, dest_i;
01773     int src_offset;
01774     int dest_offset;
01775 
01776     /* copies a layer at a time */
01777     dest_i = 0;
01778     for(src_i = 0; src_i < source->totlayer; ++src_i) {
01779 
01780         /* find the first dest layer with type >= the source type
01781          * (this should work because layers are ordered by type)
01782          */
01783         while(dest_i < dest->totlayer
01784               && dest->layers[dest_i].type < source->layers[src_i].type)
01785             ++dest_i;
01786 
01787         /* if there are no more dest layers, we're done */
01788         if(dest_i >= dest->totlayer) return;
01789 
01790         /* if we found a matching layer, copy the data */
01791         if(dest->layers[dest_i].type == source->layers[src_i].type) {
01792             char *src_data = source->layers[src_i].data;
01793             char *dest_data = dest->layers[dest_i].data;
01794 
01795             typeInfo = layerType_getInfo(source->layers[src_i].type);
01796 
01797             src_offset = source_index * typeInfo->size;
01798             dest_offset = dest_index * typeInfo->size;
01799             
01800             if (!src_data || !dest_data) {
01801                 printf("%s: warning null data for %s type (%p --> %p), skipping\n",
01802                        __func__, layerType_getName(source->layers[src_i].type),
01803                        (void *)src_data, (void *)dest_data);
01804                 continue;
01805             }
01806             
01807             if(typeInfo->copy)
01808                 typeInfo->copy(src_data + src_offset,
01809                                 dest_data + dest_offset,
01810                                 count);
01811             else
01812                 memcpy(dest_data + dest_offset,
01813                        src_data + src_offset,
01814                        count * typeInfo->size);
01815 
01816             /* if there are multiple source & dest layers of the same type,
01817              * we don't want to copy all source layers to the same dest, so
01818              * increment dest_i
01819              */
01820             ++dest_i;
01821         }
01822     }
01823 }
01824 
01825 void CustomData_free_elem(CustomData *data, int index, int count)
01826 {
01827     int i;
01828     const LayerTypeInfo *typeInfo;
01829 
01830     for(i = 0; i < data->totlayer; ++i) {
01831         if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
01832             typeInfo = layerType_getInfo(data->layers[i].type);
01833 
01834             if(typeInfo->free) {
01835                 int offset = typeInfo->size * index;
01836 
01837                 typeInfo->free((char *)data->layers[i].data + offset,
01838                                count, typeInfo->size);
01839             }
01840         }
01841     }
01842 }
01843 
01844 #define SOURCE_BUF_SIZE 100
01845 
01846 void CustomData_interp(const CustomData *source, CustomData *dest,
01847                        int *src_indices, float *weights, float *sub_weights,
01848                        int count, int dest_index)
01849 {
01850     int src_i, dest_i;
01851     int dest_offset;
01852     int j;
01853     void *source_buf[SOURCE_BUF_SIZE];
01854     void **sources = source_buf;
01855 
01856     /* slow fallback in case we're interpolating a ridiculous number of
01857      * elements
01858      */
01859     if(count > SOURCE_BUF_SIZE)
01860         sources = MEM_callocN(sizeof(*sources) * count,
01861                               "CustomData_interp sources");
01862 
01863     /* interpolates a layer at a time */
01864     dest_i = 0;
01865     for(src_i = 0; src_i < source->totlayer; ++src_i) {
01866         const LayerTypeInfo *typeInfo= layerType_getInfo(source->layers[src_i].type);
01867         if(!typeInfo->interp) continue;
01868 
01869         /* find the first dest layer with type >= the source type
01870          * (this should work because layers are ordered by type)
01871          */
01872         while(dest_i < dest->totlayer
01873               && dest->layers[dest_i].type < source->layers[src_i].type)
01874             ++dest_i;
01875 
01876         /* if there are no more dest layers, we're done */
01877         if(dest_i >= dest->totlayer) return;
01878 
01879         /* if we found a matching layer, copy the data */
01880         if(dest->layers[dest_i].type == source->layers[src_i].type) {
01881             void *src_data = source->layers[src_i].data;
01882 
01883             for(j = 0; j < count; ++j)
01884                 sources[j] = (char *)src_data
01885                              + typeInfo->size * src_indices[j];
01886 
01887             dest_offset = dest_index * typeInfo->size;
01888 
01889             typeInfo->interp(sources, weights, sub_weights, count,
01890                            (char *)dest->layers[dest_i].data + dest_offset);
01891 
01892             /* if there are multiple source & dest layers of the same type,
01893              * we don't want to copy all source layers to the same dest, so
01894              * increment dest_i
01895              */
01896             ++dest_i;
01897         }
01898     }
01899 
01900     if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
01901 }
01902 
01903 void CustomData_swap(struct CustomData *data, int index, const int *corner_indices)
01904 {
01905     const LayerTypeInfo *typeInfo;
01906     int i;
01907 
01908     for(i = 0; i < data->totlayer; ++i) {
01909         typeInfo = layerType_getInfo(data->layers[i].type);
01910 
01911         if(typeInfo->swap) {
01912             int offset = typeInfo->size * index;
01913 
01914             typeInfo->swap((char *)data->layers[i].data + offset, corner_indices);
01915         }
01916     }
01917 }
01918 
01919 void *CustomData_get(const CustomData *data, int index, int type)
01920 {
01921     int offset;
01922     int layer_index;
01923     
01924     /* get the layer index of the active layer of type */
01925     layer_index = CustomData_get_active_layer_index(data, type);
01926     if(layer_index < 0) return NULL;
01927 
01928     /* get the offset of the desired element */
01929     offset = layerType_getInfo(type)->size * index;
01930 
01931     return (char *)data->layers[layer_index].data + offset;
01932 }
01933 
01934 void *CustomData_get_n(const CustomData *data, int type, int index, int n)
01935 {
01936     int layer_index;
01937     int offset;
01938 
01939     /* get the layer index of the first layer of type */
01940     layer_index = data->typemap[type];
01941     if(layer_index < 0) return NULL;
01942 
01943     offset = layerType_getInfo(type)->size * index;
01944     return (char *)data->layers[layer_index+n].data + offset;
01945 }
01946 
01947 void *CustomData_get_layer(const CustomData *data, int type)
01948 {
01949     /* get the layer index of the active layer of type */
01950     int layer_index = CustomData_get_active_layer_index(data, type);
01951     if(layer_index < 0) return NULL;
01952 
01953     return data->layers[layer_index].data;
01954 }
01955 
01956 void *CustomData_get_layer_n(const CustomData *data, int type, int n)
01957 {
01958     /* get the layer index of the active layer of type */
01959     int layer_index = CustomData_get_layer_index_n(data, type, n);
01960     if(layer_index < 0) return NULL;
01961 
01962     return data->layers[layer_index].data;
01963 }
01964 
01965 void *CustomData_get_layer_named(const struct CustomData *data, int type,
01966                                  const char *name)
01967 {
01968     int layer_index = CustomData_get_named_layer_index(data, type, name);
01969     if(layer_index < 0) return NULL;
01970 
01971     return data->layers[layer_index].data;
01972 }
01973 
01974 
01975 int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
01976 {
01977     /* get the layer index of the first layer of type */
01978     int layer_index = CustomData_get_layer_index_n(data, type, n);
01979 
01980     if(layer_index < 0) return 0;
01981     if (!name) return 0;
01982     
01983     strcpy(data->layers[layer_index].name, name);
01984     
01985     return 1;
01986 }
01987 
01988 void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
01989 {
01990     /* get the layer index of the first layer of type */
01991     int layer_index = CustomData_get_active_layer_index(data, type);
01992 
01993     if(layer_index < 0) return NULL;
01994 
01995     data->layers[layer_index].data = ptr;
01996 
01997     return ptr;
01998 }
01999 
02000 void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr)
02001 {
02002     /* get the layer index of the first layer of type */
02003     int layer_index = CustomData_get_layer_index_n(data, type, n);
02004     if(layer_index < 0) return NULL;
02005 
02006     data->layers[layer_index].data = ptr;
02007 
02008     return ptr;
02009 }
02010 
02011 void CustomData_set(const CustomData *data, int index, int type, void *source)
02012 {
02013     void *dest = CustomData_get(data, index, type);
02014     const LayerTypeInfo *typeInfo = layerType_getInfo(type);
02015 
02016     if(!dest) return;
02017 
02018     if(typeInfo->copy)
02019         typeInfo->copy(source, dest, 1);
02020     else
02021         memcpy(dest, source, typeInfo->size);
02022 }
02023 
02024 /* EditMesh functions */
02025 
02026 void CustomData_em_free_block(CustomData *data, void **block)
02027 {
02028     const LayerTypeInfo *typeInfo;
02029     int i;
02030 
02031     if(!*block) return;
02032 
02033     for(i = 0; i < data->totlayer; ++i) {
02034         if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
02035             typeInfo = layerType_getInfo(data->layers[i].type);
02036 
02037             if(typeInfo->free) {
02038                 int offset = data->layers[i].offset;
02039                 typeInfo->free((char*)*block + offset, 1, typeInfo->size);
02040             }
02041         }
02042     }
02043 
02044     MEM_freeN(*block);
02045     *block = NULL;
02046 }
02047 
02048 static void CustomData_em_alloc_block(CustomData *data, void **block)
02049 {
02050     /* TODO: optimize free/alloc */
02051 
02052     if (*block)
02053         CustomData_em_free_block(data, block);
02054 
02055     if (data->totsize > 0)
02056         *block = MEM_callocN(data->totsize, "CustomData EM block");
02057     else
02058         *block = NULL;
02059 }
02060 
02061 void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
02062                             void *src_block, void **dest_block)
02063 {
02064     const LayerTypeInfo *typeInfo;
02065     int dest_i, src_i;
02066 
02067     if (!*dest_block)
02068         CustomData_em_alloc_block(dest, dest_block);
02069     
02070     /* copies a layer at a time */
02071     dest_i = 0;
02072     for(src_i = 0; src_i < source->totlayer; ++src_i) {
02073 
02074         /* find the first dest layer with type >= the source type
02075          * (this should work because layers are ordered by type)
02076          */
02077         while(dest_i < dest->totlayer
02078               && dest->layers[dest_i].type < source->layers[src_i].type)
02079             ++dest_i;
02080 
02081         /* if there are no more dest layers, we're done */
02082         if(dest_i >= dest->totlayer) return;
02083 
02084         /* if we found a matching layer, copy the data */
02085         if(dest->layers[dest_i].type == source->layers[src_i].type &&
02086             strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
02087             char *src_data = (char*)src_block + source->layers[src_i].offset;
02088             char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
02089 
02090             typeInfo = layerType_getInfo(source->layers[src_i].type);
02091 
02092             if(typeInfo->copy)
02093                 typeInfo->copy(src_data, dest_data, 1);
02094             else
02095                 memcpy(dest_data, src_data, typeInfo->size);
02096 
02097             /* if there are multiple source & dest layers of the same type,
02098              * we don't want to copy all source layers to the same dest, so
02099              * increment dest_i
02100              */
02101             ++dest_i;
02102         }
02103     }
02104 }
02105 
02106 void CustomData_em_validate_data(CustomData *data, void *block, int sub_elements)
02107 {
02108     int i;
02109     for(i = 0; i < data->totlayer; i++) {
02110         const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
02111         char *leayer_data = (char*)block + data->layers[i].offset;
02112 
02113         if(typeInfo->validate)
02114             typeInfo->validate(leayer_data, sub_elements);
02115     }
02116 }
02117 
02118 void *CustomData_em_get(const CustomData *data, void *block, int type)
02119 {
02120     int layer_index;
02121     
02122     /* get the layer index of the first layer of type */
02123     layer_index = CustomData_get_active_layer_index(data, type);
02124     if(layer_index < 0) return NULL;
02125 
02126     return (char *)block + data->layers[layer_index].offset;
02127 }
02128 
02129 void *CustomData_em_get_n(const CustomData *data, void *block, int type, int n)
02130 {
02131     int layer_index;
02132     
02133     /* get the layer index of the first layer of type */
02134     layer_index = CustomData_get_layer_index_n(data, type, n);
02135     if(layer_index < 0) return NULL;
02136 
02137     return (char *)block + data->layers[layer_index].offset;
02138 }
02139 
02140 void CustomData_em_set(CustomData *data, void *block, int type, void *source)
02141 {
02142     void *dest = CustomData_em_get(data, block, type);
02143     const LayerTypeInfo *typeInfo = layerType_getInfo(type);
02144 
02145     if(!dest) return;
02146 
02147     if(typeInfo->copy)
02148         typeInfo->copy(source, dest, 1);
02149     else
02150         memcpy(dest, source, typeInfo->size);
02151 }
02152 
02153 void CustomData_em_set_n(CustomData *data, void *block, int type, int n, void *source)
02154 {
02155     void *dest = CustomData_em_get_n(data, block, type, n);
02156     const LayerTypeInfo *typeInfo = layerType_getInfo(type);
02157 
02158     if(!dest) return;
02159 
02160     if(typeInfo->copy)
02161         typeInfo->copy(source, dest, 1);
02162     else
02163         memcpy(dest, source, typeInfo->size);
02164 }
02165 
02166 void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
02167                           float *sub_weights, int count, void *dest_block)
02168 {
02169     int i, j;
02170     void *source_buf[SOURCE_BUF_SIZE];
02171     void **sources = source_buf;
02172 
02173     /* slow fallback in case we're interpolating a ridiculous number of
02174      * elements
02175      */
02176     if(count > SOURCE_BUF_SIZE)
02177         sources = MEM_callocN(sizeof(*sources) * count,
02178                               "CustomData_interp sources");
02179 
02180     /* interpolates a layer at a time */
02181     for(i = 0; i < data->totlayer; ++i) {
02182         CustomDataLayer *layer = &data->layers[i];
02183         const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
02184 
02185         if(typeInfo->interp) {
02186             for(j = 0; j < count; ++j)
02187                 sources[j] = (char *)src_blocks[j] + layer->offset;
02188 
02189             typeInfo->interp(sources, weights, sub_weights, count,
02190                               (char *)dest_block + layer->offset);
02191         }
02192     }
02193 
02194     if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
02195 }
02196 
02197 void CustomData_em_set_default(CustomData *data, void **block)
02198 {
02199     const LayerTypeInfo *typeInfo;
02200     int i;
02201 
02202     if (!*block)
02203         CustomData_em_alloc_block(data, block);
02204 
02205     for(i = 0; i < data->totlayer; ++i) {
02206         int offset = data->layers[i].offset;
02207 
02208         typeInfo = layerType_getInfo(data->layers[i].type);
02209 
02210         if(typeInfo->set_default)
02211             typeInfo->set_default((char*)*block + offset, 1);
02212     }
02213 }
02214 
02215 void CustomData_to_em_block(const CustomData *source, CustomData *dest,
02216                             int src_index, void **dest_block)
02217 {
02218     const LayerTypeInfo *typeInfo;
02219     int dest_i, src_i, src_offset;
02220 
02221     if (!*dest_block)
02222         CustomData_em_alloc_block(dest, dest_block);
02223     
02224     /* copies a layer at a time */
02225     dest_i = 0;
02226     for(src_i = 0; src_i < source->totlayer; ++src_i) {
02227 
02228         /* find the first dest layer with type >= the source type
02229          * (this should work because layers are ordered by type)
02230          */
02231         while(dest_i < dest->totlayer
02232               && dest->layers[dest_i].type < source->layers[src_i].type)
02233             ++dest_i;
02234 
02235         /* if there are no more dest layers, we're done */
02236         if(dest_i >= dest->totlayer) return;
02237 
02238         /* if we found a matching layer, copy the data */
02239         if(dest->layers[dest_i].type == source->layers[src_i].type) {
02240             int offset = dest->layers[dest_i].offset;
02241             char *src_data = source->layers[src_i].data;
02242             char *dest_data = (char*)*dest_block + offset;
02243 
02244             typeInfo = layerType_getInfo(dest->layers[dest_i].type);
02245             src_offset = src_index * typeInfo->size;
02246 
02247             if(typeInfo->copy)
02248                 typeInfo->copy(src_data + src_offset, dest_data, 1);
02249             else
02250                 memcpy(dest_data, src_data + src_offset, typeInfo->size);
02251 
02252             /* if there are multiple source & dest layers of the same type,
02253              * we don't want to copy all source layers to the same dest, so
02254              * increment dest_i
02255              */
02256             ++dest_i;
02257         }
02258     }
02259 }
02260 
02261 void CustomData_from_em_block(const CustomData *source, CustomData *dest,
02262                               void *src_block, int dest_index)
02263 {
02264     const LayerTypeInfo *typeInfo;
02265     int dest_i, src_i, dest_offset;
02266 
02267     /* copies a layer at a time */
02268     dest_i = 0;
02269     for(src_i = 0; src_i < source->totlayer; ++src_i) {
02270 
02271         /* find the first dest layer with type >= the source type
02272          * (this should work because layers are ordered by type)
02273          */
02274         while(dest_i < dest->totlayer
02275               && dest->layers[dest_i].type < source->layers[src_i].type)
02276             ++dest_i;
02277 
02278         /* if there are no more dest layers, we're done */
02279         if(dest_i >= dest->totlayer) return;
02280 
02281         /* if we found a matching layer, copy the data */
02282         if(dest->layers[dest_i].type == source->layers[src_i].type) {
02283             int offset = source->layers[src_i].offset;
02284             char *src_data = (char*)src_block + offset;
02285             char *dest_data = dest->layers[dest_i].data;
02286 
02287             typeInfo = layerType_getInfo(dest->layers[dest_i].type);
02288             dest_offset = dest_index * typeInfo->size;
02289 
02290             if(typeInfo->copy)
02291                 typeInfo->copy(src_data, dest_data + dest_offset, 1);
02292             else
02293                 memcpy(dest_data + dest_offset, src_data, typeInfo->size);
02294 
02295             /* if there are multiple source & dest layers of the same type,
02296              * we don't want to copy all source layers to the same dest, so
02297              * increment dest_i
02298              */
02299             ++dest_i;
02300         }
02301     }
02302 
02303 }
02304 
02305 /*Bmesh functions*/
02306 /*needed to convert to/from different face reps*/
02307 void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata)
02308 {
02309     int i;
02310     for(i=0; i < fdata->totlayer; i++){
02311         if(fdata->layers[i].type == CD_MTFACE){
02312             CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0);
02313             CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0);
02314         }
02315         else if(fdata->layers[i].type == CD_MCOL)
02316             CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
02317     }       
02318 }
02319 void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total)
02320 {
02321     int i;
02322     for(i=0; i < pdata->totlayer; i++){
02323         if(pdata->layers[i].type == CD_MTEXPOLY)
02324             CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), total);
02325     }
02326     for(i=0; i < ldata->totlayer; i++){
02327         if(ldata->layers[i].type == CD_MLOOPCOL)
02328             CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), total);
02329     }
02330 }
02331 
02332 
02333 void CustomData_bmesh_init_pool(CustomData *data, int allocsize)
02334 {
02335     if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, FALSE, FALSE);
02336 }
02337 
02338 void CustomData_bmesh_free_block(CustomData *data, void **block)
02339 {
02340     const LayerTypeInfo *typeInfo;
02341     int i;
02342 
02343     if(!*block) return;
02344     for(i = 0; i < data->totlayer; ++i) {
02345         if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
02346             typeInfo = layerType_getInfo(data->layers[i].type);
02347 
02348             if(typeInfo->free) {
02349                 int offset = data->layers[i].offset;
02350                 typeInfo->free((char*)*block + offset, 1, typeInfo->size);
02351             }
02352         }
02353     }
02354 
02355     BLI_mempool_free(data->pool, *block);
02356     *block = NULL;
02357 }
02358 
02359 static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
02360 {
02361 
02362     if (*block)
02363         CustomData_bmesh_free_block(data, block);
02364 
02365     if (data->totsize > 0)
02366         *block = BLI_mempool_calloc(data->pool);
02367     else
02368         *block = NULL;
02369 }
02370 
02371 void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
02372                             void *src_block, void **dest_block)
02373 {
02374     const LayerTypeInfo *typeInfo;
02375     int dest_i, src_i;
02376 
02377     if (!*dest_block)
02378         CustomData_bmesh_alloc_block(dest, dest_block);
02379     
02380     /* copies a layer at a time */
02381     dest_i = 0;
02382     for(src_i = 0; src_i < source->totlayer; ++src_i) {
02383 
02384         /* find the first dest layer with type >= the source type
02385          * (this should work because layers are ordered by type)
02386          */
02387         while(dest_i < dest->totlayer
02388               && dest->layers[dest_i].type < source->layers[src_i].type)
02389             ++dest_i;
02390 
02391         /* if there are no more dest layers, we're done */
02392         if(dest_i >= dest->totlayer) return;
02393 
02394         /* if we found a matching layer, copy the data */
02395         if(dest->layers[dest_i].type == source->layers[src_i].type &&
02396             strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
02397             char *src_data = (char*)src_block + source->layers[src_i].offset;
02398             char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
02399 
02400             typeInfo = layerType_getInfo(source->layers[src_i].type);
02401 
02402             if(typeInfo->copy)
02403                 typeInfo->copy(src_data, dest_data, 1);
02404             else
02405                 memcpy(dest_data, src_data, typeInfo->size);
02406 
02407             /* if there are multiple source & dest layers of the same type,
02408              * we don't want to copy all source layers to the same dest, so
02409              * increment dest_i
02410              */
02411             ++dest_i;
02412         }
02413     }
02414 }
02415 
02416 /*Bmesh Custom Data Functions. Should replace editmesh ones with these as well, due to more effecient memory alloc*/
02417 void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
02418 {
02419     int layer_index;
02420     
02421     /* get the layer index of the first layer of type */
02422     layer_index = CustomData_get_active_layer_index(data, type);
02423     if(layer_index < 0) return NULL;
02424 
02425     return (char *)block + data->layers[layer_index].offset;
02426 }
02427 
02428 void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
02429 {
02430     int layer_index;
02431     
02432     /* get the layer index of the first layer of type */
02433     layer_index = CustomData_get_layer_index(data, type);
02434     if(layer_index < 0) return NULL;
02435 
02436     return (char *)block + data->layers[layer_index+n].offset;
02437 }
02438 
02439 /*gets from the layer at physical index n, note: doesn't check type.*/
02440 void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
02441 {
02442     if(n < 0 || n >= data->totlayer) return NULL;
02443 
02444     return (char *)block + data->layers[n].offset;
02445 }
02446 
02447 
02448 void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
02449 {
02450     void *dest = CustomData_bmesh_get(data, block, type);
02451     const LayerTypeInfo *typeInfo = layerType_getInfo(type);
02452 
02453     if(!dest) return;
02454 
02455     if(typeInfo->copy)
02456         typeInfo->copy(source, dest, 1);
02457     else
02458         memcpy(dest, source, typeInfo->size);
02459 }
02460 
02461 void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void *source)
02462 {
02463     void *dest = CustomData_bmesh_get_n(data, block, type, n);
02464     const LayerTypeInfo *typeInfo = layerType_getInfo(type);
02465 
02466     if(!dest) return;
02467 
02468     if(typeInfo->copy)
02469         typeInfo->copy(source, dest, 1);
02470     else
02471         memcpy(dest, source, typeInfo->size);
02472 }
02473 
02474 void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source)
02475 {
02476     void *dest = CustomData_bmesh_get_layer_n(data, block, n);
02477     const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
02478 
02479     if(!dest) return;
02480 
02481     if(typeInfo->copy)
02482         typeInfo->copy(source, dest, 1);
02483     else
02484         memcpy(dest, source, typeInfo->size);
02485 }
02486 
02487 void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
02488                           float *sub_weights, int count, void *dest_block)
02489 {
02490     int i, j;
02491     void *source_buf[SOURCE_BUF_SIZE];
02492     void **sources = source_buf;
02493 
02494     /* slow fallback in case we're interpolating a ridiculous number of
02495      * elements
02496      */
02497     if(count > SOURCE_BUF_SIZE)
02498         sources = MEM_callocN(sizeof(*sources) * count,
02499                               "CustomData_interp sources");
02500 
02501     /* interpolates a layer at a time */
02502     for(i = 0; i < data->totlayer; ++i) {
02503         CustomDataLayer *layer = &data->layers[i];
02504         const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
02505         if(typeInfo->interp) {
02506             for(j = 0; j < count; ++j)
02507                 sources[j] = (char *)src_blocks[j] + layer->offset;
02508 
02509             typeInfo->interp(sources, weights, sub_weights, count,
02510                               (char *)dest_block + layer->offset);
02511         }
02512     }
02513 
02514     if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
02515 }
02516 
02517 void CustomData_bmesh_set_default(CustomData *data, void **block)
02518 {
02519     const LayerTypeInfo *typeInfo;
02520     int i;
02521 
02522     if (!*block)
02523         CustomData_bmesh_alloc_block(data, block);
02524 
02525     for(i = 0; i < data->totlayer; ++i) {
02526         int offset = data->layers[i].offset;
02527 
02528         typeInfo = layerType_getInfo(data->layers[i].type);
02529 
02530         if(typeInfo->set_default)
02531             typeInfo->set_default((char*)*block + offset, 1);
02532         else memset((char*)*block + offset, 0, typeInfo->size);
02533     }
02534 }
02535 
02536 void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
02537                             int src_index, void **dest_block)
02538 {
02539     const LayerTypeInfo *typeInfo;
02540     int dest_i, src_i, src_offset;
02541 
02542     if (!*dest_block)
02543         CustomData_bmesh_alloc_block(dest, dest_block);
02544     
02545     /* copies a layer at a time */
02546     dest_i = 0;
02547     for(src_i = 0; src_i < source->totlayer; ++src_i) {
02548 
02549         /* find the first dest layer with type >= the source type
02550          * (this should work because layers are ordered by type)
02551          */
02552         while(dest_i < dest->totlayer
02553               && dest->layers[dest_i].type < source->layers[src_i].type)
02554             ++dest_i;
02555 
02556         /* if there are no more dest layers, we're done */
02557         if(dest_i >= dest->totlayer) return;
02558 
02559         /* if we found a matching layer, copy the data */
02560         if(dest->layers[dest_i].type == source->layers[src_i].type) {
02561             int offset = dest->layers[dest_i].offset;
02562             char *src_data = source->layers[src_i].data;
02563             char *dest_data = (char*)*dest_block + offset;
02564 
02565             typeInfo = layerType_getInfo(dest->layers[dest_i].type);
02566             src_offset = src_index * typeInfo->size;
02567 
02568             if(typeInfo->copy)
02569                 typeInfo->copy(src_data + src_offset, dest_data, 1);
02570             else
02571                 memcpy(dest_data, src_data + src_offset, typeInfo->size);
02572 
02573             /* if there are multiple source & dest layers of the same type,
02574              * we don't want to copy all source layers to the same dest, so
02575              * increment dest_i
02576              */
02577             ++dest_i;
02578         }
02579     }
02580 }
02581 
02582 void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
02583                               void *src_block, int dest_index)
02584 {
02585     const LayerTypeInfo *typeInfo;
02586     int dest_i, src_i, dest_offset;
02587 
02588     /* copies a layer at a time */
02589     dest_i = 0;
02590     for(src_i = 0; src_i < source->totlayer; ++src_i) {
02591 
02592         /* find the first dest layer with type >= the source type
02593          * (this should work because layers are ordered by type)
02594          */
02595         while(dest_i < dest->totlayer
02596               && dest->layers[dest_i].type < source->layers[src_i].type)
02597             ++dest_i;
02598 
02599         /* if there are no more dest layers, we're done */
02600         if(dest_i >= dest->totlayer) return;
02601 
02602         /* if we found a matching layer, copy the data */
02603         if(dest->layers[dest_i].type == source->layers[src_i].type) {
02604             int offset = source->layers[src_i].offset;
02605             char *src_data = (char*)src_block + offset;
02606             char *dest_data = dest->layers[dest_i].data;
02607 
02608             typeInfo = layerType_getInfo(dest->layers[dest_i].type);
02609             dest_offset = dest_index * typeInfo->size;
02610 
02611             if(typeInfo->copy)
02612                 typeInfo->copy(src_data, dest_data + dest_offset, 1);
02613             else
02614                 memcpy(dest_data + dest_offset, src_data, typeInfo->size);
02615 
02616             /* if there are multiple source & dest layers of the same type,
02617              * we don't want to copy all source layers to the same dest, so
02618              * increment dest_i
02619              */
02620             ++dest_i;
02621         }
02622     }
02623 
02624 }
02625 
02626 void CustomData_file_write_info(int type, const char **structname, int *structnum)
02627 {
02628     const LayerTypeInfo *typeInfo = layerType_getInfo(type);
02629 
02630     *structname = typeInfo->structname;
02631     *structnum = typeInfo->structnum;
02632 }
02633 
02634 int CustomData_sizeof(int type)
02635 {
02636     const LayerTypeInfo *typeInfo = layerType_getInfo(type);
02637 
02638     return typeInfo->size;
02639 }
02640 
02641 const char *CustomData_layertype_name(int type)
02642 {
02643     return layerType_getName(type);
02644 }
02645 
02646 static int  CustomData_is_property_layer(int type)
02647 {
02648     if((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR))
02649         return 1;
02650     return 0;
02651 }
02652 
02653 static int cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
02654 {
02655     int i;
02656     /* see if there is a duplicate */
02657     for(i=0; i<data->totlayer; i++) {
02658         if(i != index) {
02659             CustomDataLayer *layer= &data->layers[i];
02660             
02661             if(CustomData_is_property_layer(type)) {
02662                 if(CustomData_is_property_layer(layer->type) && strcmp(layer->name, name)==0) {
02663                     return 1;
02664                 }
02665             }
02666             else{
02667                 if(i!=index && layer->type==type && strcmp(layer->name, name)==0) {
02668                     return 1;
02669                 }
02670             }
02671         }
02672     }
02673     
02674     return 0;
02675 }
02676 
02677 static int customdata_unique_check(void *arg, const char *name)
02678 {
02679     struct {CustomData *data; int type; int index;} *data_arg= arg;
02680     return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index);
02681 }
02682 
02683 void CustomData_set_layer_unique_name(CustomData *data, int index)
02684 {   
02685     CustomDataLayer *nlayer= &data->layers[index];
02686     const LayerTypeInfo *typeInfo= layerType_getInfo(nlayer->type);
02687 
02688     struct {CustomData *data; int type; int index;} data_arg;
02689     data_arg.data= data;
02690     data_arg.type= nlayer->type;
02691     data_arg.index= index;
02692 
02693     if (!typeInfo->defaultname)
02694         return;
02695     
02696     BLI_uniquename_cb(customdata_unique_check, &data_arg, typeInfo->defaultname, '.', nlayer->name, sizeof(nlayer->name));
02697 }
02698 
02699 void CustomData_validate_layer_name(const CustomData *data, int type, char *name, char *outname)
02700 {
02701     int index = -1;
02702 
02703     /* if a layer name was given, try to find that layer */
02704     if(name[0])
02705         index = CustomData_get_named_layer_index(data, type, name);
02706 
02707     if(index < 0) {
02708         /* either no layer was specified, or the layer we want has been
02709         * deleted, so assign the active layer to name
02710         */
02711         index = CustomData_get_active_layer_index(data, type);
02712         strcpy(outname, data->layers[index].name);
02713     }
02714     else
02715         strcpy(outname, name);
02716 }
02717 
02718 int CustomData_verify_versions(struct CustomData *data, int index)
02719 {
02720     const LayerTypeInfo *typeInfo;
02721     CustomDataLayer *layer = &data->layers[index];
02722     int i, keeplayer = 1;
02723 
02724     if (layer->type >= CD_NUMTYPES) {
02725         keeplayer = 0; /* unknown layer type from future version */
02726     }
02727     else {
02728         typeInfo = layerType_getInfo(layer->type);
02729 
02730         if (!typeInfo->defaultname && (index > 0) &&
02731             data->layers[index-1].type == layer->type)
02732             keeplayer = 0; /* multiple layers of which we only support one */
02733     }
02734 
02735     if (!keeplayer) {
02736         for (i=index+1; i < data->totlayer; ++i)
02737             data->layers[i-1] = data->layers[i];
02738         data->totlayer--;
02739     }
02740 
02741     return keeplayer;
02742 }
02743 
02744 /****************************** External Files *******************************/
02745 
02746 static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external)
02747 {
02748     BLI_strncpy(filename, external->filename, FILE_MAX);
02749     BLI_path_abs(filename, ID_BLEND_PATH(G.main, id));
02750 }
02751 
02752 void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask mask, int totelem)
02753 {
02754     CustomDataLayer *layer;
02755     const LayerTypeInfo *typeInfo;
02756     int i;
02757 
02758     for(i=0; i<data->totlayer; i++) {
02759         layer = &data->layers[i];
02760         typeInfo = layerType_getInfo(layer->type);
02761 
02762         if(!(mask & CD_TYPE_AS_MASK(layer->type)));
02763         else if((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) {
02764             if(typeInfo->free)
02765                 typeInfo->free(layer->data, totelem, typeInfo->size);
02766             layer->flag &= ~CD_FLAG_IN_MEMORY;
02767         }
02768     }
02769 }
02770 
02771 void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem)
02772 {
02773     CustomDataExternal *external= data->external;
02774     CustomDataLayer *layer;
02775     CDataFile *cdf;
02776     CDataFileLayer *blay;
02777     char filename[FILE_MAX];
02778     const LayerTypeInfo *typeInfo;
02779     int i, update = 0;
02780 
02781     if(!external)
02782         return;
02783     
02784     for(i=0; i<data->totlayer; i++) {
02785         layer = &data->layers[i];
02786         typeInfo = layerType_getInfo(layer->type);
02787 
02788         if(!(mask & CD_TYPE_AS_MASK(layer->type)));
02789         else if(layer->flag & CD_FLAG_IN_MEMORY);
02790         else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read)
02791             update= 1;
02792     }
02793 
02794     if(!update)
02795         return;
02796 
02797     customdata_external_filename(filename, id, external);
02798 
02799     cdf= cdf_create(CDF_TYPE_MESH);
02800     if(!cdf_read_open(cdf, filename)) {
02801         fprintf(stderr, "Failed to read %s layer from %s.\n", layerType_getName(layer->type), filename);
02802         return;
02803     }
02804 
02805     for(i=0; i<data->totlayer; i++) {
02806         layer = &data->layers[i];
02807         typeInfo = layerType_getInfo(layer->type);
02808 
02809         if(!(mask & CD_TYPE_AS_MASK(layer->type)));
02810         else if(layer->flag & CD_FLAG_IN_MEMORY);
02811         else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) {
02812             blay= cdf_layer_find(cdf, layer->type, layer->name);
02813 
02814             if(blay) {
02815                 if(cdf_read_layer(cdf, blay)) {
02816                     if(typeInfo->read(cdf, layer->data, totelem));
02817                     else break;
02818                     layer->flag |= CD_FLAG_IN_MEMORY;
02819                 }
02820                 else
02821                     break;
02822             }
02823         }
02824     }
02825 
02826     cdf_read_close(cdf);
02827     cdf_free(cdf);
02828 }
02829 
02830 void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, int totelem, int free)
02831 {
02832     CustomDataExternal *external= data->external;
02833     CustomDataLayer *layer;
02834     CDataFile *cdf;
02835     CDataFileLayer *blay;
02836     const LayerTypeInfo *typeInfo;
02837     int i, update = 0;
02838     char filename[FILE_MAX];
02839 
02840     if(!external)
02841         return;
02842 
02843     /* test if there is anything to write */
02844     for(i=0; i<data->totlayer; i++) {
02845         layer = &data->layers[i];
02846         typeInfo = layerType_getInfo(layer->type);
02847 
02848         if(!(mask & CD_TYPE_AS_MASK(layer->type)));
02849         else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write)
02850             update= 1;
02851     }
02852 
02853     if(!update)
02854         return;
02855 
02856     /* make sure data is read before we try to write */
02857     CustomData_external_read(data, id, mask, totelem);
02858     customdata_external_filename(filename, id, external);
02859 
02860     cdf= cdf_create(CDF_TYPE_MESH);
02861 
02862     for(i=0; i<data->totlayer; i++) {
02863         layer = &data->layers[i];
02864         typeInfo = layerType_getInfo(layer->type);
02865 
02866         if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) {
02867             if(layer->flag & CD_FLAG_IN_MEMORY) {
02868                 cdf_layer_add(cdf, layer->type, layer->name,
02869                     typeInfo->filesize(cdf, layer->data, totelem));
02870             }
02871             else {
02872                 cdf_free(cdf);
02873                 return; /* read failed for a layer! */
02874             }
02875         }
02876     }
02877 
02878     if(!cdf_write_open(cdf, filename)) {
02879         fprintf(stderr, "Failed to open %s for writing.\n", filename);
02880         return;
02881     }
02882 
02883     for(i=0; i<data->totlayer; i++) {
02884         layer = &data->layers[i];
02885         typeInfo = layerType_getInfo(layer->type);
02886 
02887         if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
02888             blay= cdf_layer_find(cdf, layer->type, layer->name);
02889 
02890             if(cdf_write_layer(cdf, blay)) {
02891                 if(typeInfo->write(cdf, layer->data, totelem));
02892                 else break;
02893             }
02894             else
02895                 break;
02896         }
02897     }
02898 
02899     if(i != data->totlayer) {
02900         fprintf(stderr, "Failed to write data to %s.\n", filename);
02901         cdf_free(cdf);
02902         return;
02903     }
02904 
02905     for(i=0; i<data->totlayer; i++) {
02906         layer = &data->layers[i];
02907         typeInfo = layerType_getInfo(layer->type);
02908 
02909         if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
02910             if(free) {
02911                 if(typeInfo->free)
02912                     typeInfo->free(layer->data, totelem, typeInfo->size);
02913                 layer->flag &= ~CD_FLAG_IN_MEMORY;
02914             }
02915         }
02916     }
02917 
02918     cdf_write_close(cdf);
02919     cdf_free(cdf);
02920 }
02921 
02922 void CustomData_external_add(CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename)
02923 {
02924     CustomDataExternal *external= data->external;
02925     CustomDataLayer *layer;
02926     int layer_index;
02927 
02928     layer_index = CustomData_get_active_layer_index(data, type);
02929     if(layer_index < 0) return;
02930 
02931     layer = &data->layers[layer_index];
02932 
02933     if(layer->flag & CD_FLAG_EXTERNAL)
02934         return;
02935 
02936     if(!external) {
02937         external= MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal");
02938         data->external= external;
02939     }
02940     BLI_strncpy(external->filename, filename, sizeof(external->filename));
02941 
02942     layer->flag |= CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY;
02943 }
02944 
02945 void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem)
02946 {
02947     CustomDataExternal *external= data->external;
02948     CustomDataLayer *layer;
02949     //char filename[FILE_MAX];
02950     int layer_index; // i, remove_file;
02951 
02952     layer_index = CustomData_get_active_layer_index(data, type);
02953     if(layer_index < 0) return;
02954 
02955     layer = &data->layers[layer_index];
02956 
02957     if(!external)
02958         return;
02959 
02960     if(layer->flag & CD_FLAG_EXTERNAL) {
02961         if(!(layer->flag & CD_FLAG_IN_MEMORY))
02962             CustomData_external_read(data, id, CD_TYPE_AS_MASK(layer->type), totelem);
02963 
02964         layer->flag &= ~CD_FLAG_EXTERNAL;
02965 
02966 #if 0
02967         remove_file= 1;
02968         for(i=0; i<data->totlayer; i++)
02969             if(data->layers[i].flag & CD_FLAG_EXTERNAL)
02970                 remove_file= 0;
02971 
02972         if(remove_file) {
02973             customdata_external_filename(filename, id, external);
02974             cdf_remove(filename);
02975             CustomData_external_free(data);
02976         }
02977 #endif
02978     }
02979 }
02980 
02981 int CustomData_external_test(CustomData *data, int type)
02982 {
02983     CustomDataLayer *layer;
02984     int layer_index;
02985 
02986     layer_index = CustomData_get_active_layer_index(data, type);
02987     if(layer_index < 0) return 0;
02988 
02989     layer = &data->layers[layer_index];
02990     return (layer->flag & CD_FLAG_EXTERNAL);
02991 }
02992 
02993 #if 0
02994 void CustomData_external_remove_object(CustomData *data, ID *id)
02995 {
02996     CustomDataExternal *external= data->external;
02997     char filename[FILE_MAX];
02998 
02999     if(!external)
03000         return;
03001 
03002     customdata_external_filename(filename, id, external);
03003     cdf_remove(filename);
03004     CustomData_external_free(data);
03005 }
03006 #endif
03007