77068d8ed6647fa729b96966c8edf51ce6ed05e1
[blender.git] / source / blender / blenkernel / intern / customdata.c
1 /*
2 * $Id$
3 *
4 * ***** BEGIN GPL LICENSE BLOCK *****
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software  Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * The Original Code is Copyright (C) 2006 Blender Foundation.
21 * All rights reserved.
22 *
23 * The Original Code is: all of this file.
24 *
25 * Contributor(s): Ben Batt <benbatt@gmail.com>
26 *
27 * ***** END GPL LICENSE BLOCK *****
28 *
29 * Implementation of CustomData.
30 *
31 * BKE_customdata.h contains the function prototypes for this file.
32 *
33 */ 
34
35 #include "BKE_customdata.h"
36
37 #include "BLI_blenlib.h"
38 #include "BLI_linklist.h"
39
40 #include "DNA_customdata_types.h"
41 #include "DNA_listBase.h"
42 #include "DNA_meshdata_types.h"
43
44 #include "MEM_guardedalloc.h"
45
46 #include <string.h>
47
48 /* number of layers to add when growing a CustomData object */
49 #define CUSTOMDATA_GROW 5
50
51 /********************* Layer type information **********************/
52 typedef struct LayerTypeInfo {
53         int size;          /* the memory size of one element of this layer's data */
54         char *structname;  /* name of the struct used, for file writing */
55         int structnum;     /* number of structs per element, for file writing */
56         char *defaultname; /* default layer name */
57
58         /* a function to copy count elements of this layer's data
59          * (deep copy if appropriate)
60          * if NULL, memcpy is used
61          */
62         void (*copy)(const void *source, void *dest, int count);
63
64         /* a function to free any dynamically allocated components of this
65          * layer's data (note the data pointer itself should not be freed)
66          * size should be the size of one element of this layer's data (e.g.
67          * LayerTypeInfo.size)
68          */
69         void (*free)(void *data, int count, int size);
70
71         /* a function to interpolate between count source elements of this
72          * layer's data and store the result in dest
73          * if weights == NULL or sub_weights == NULL, they should default to 1
74          *
75          * weights gives the weight for each element in sources
76          * sub_weights gives the sub-element weights for each element in sources
77          *    (there should be (sub element count)^2 weights per element)
78          * count gives the number of elements in sources
79          */
80         void (*interp)(void **sources, float *weights, float *sub_weights,
81                        int count, void *dest);
82
83     /* a function to swap the data in corners of the element */
84         void (*swap)(void *data, int *corner_indices);
85
86     /* a function to set a layer's data to default values. if NULL, the
87            default is assumed to be all zeros */
88         void (*set_default)(void *data, int count);
89 } LayerTypeInfo;
90
91 static void layerCopy_mdeformvert(const void *source, void *dest,
92                                   int count)
93 {
94         int i, size = sizeof(MDeformVert);
95
96         memcpy(dest, source, count * size);
97
98         for(i = 0; i < count; ++i) {
99                 MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size);
100
101                 if(dvert->totweight) {
102                         MDeformWeight *dw = MEM_callocN(dvert->totweight * sizeof(*dw),
103                                                                                         "layerCopy_mdeformvert dw");
104
105                         memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw));
106                         dvert->dw = dw;
107                 }
108                 else
109                         dvert->dw = NULL;
110         }
111 }
112
113 static void layerFree_mdeformvert(void *data, int count, int size)
114 {
115         int i;
116
117         for(i = 0; i < count; ++i) {
118                 MDeformVert *dvert = (MDeformVert *)((char *)data + i * size);
119
120                 if(dvert->dw) {
121                         MEM_freeN(dvert->dw);
122                         dvert->dw = NULL;
123                         dvert->totweight = 0;
124                 }
125         }
126 }
127
128 static void linklist_free_simple(void *link)
129 {
130         MEM_freeN(link);
131 }
132
133 static void layerInterp_mdeformvert(void **sources, float *weights,
134                                     float *sub_weights, int count, void *dest)
135 {
136         MDeformVert *dvert = dest;
137         LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */
138         LinkNode *node;
139         int i, j, totweight;
140
141         if(count <= 0) return;
142
143         /* build a list of unique def_nrs for dest */
144         totweight = 0;
145         for(i = 0; i < count; ++i) {
146                 MDeformVert *source = sources[i];
147                 float interp_weight = weights ? weights[i] : 1.0f;
148
149                 for(j = 0; j < source->totweight; ++j) {
150                         MDeformWeight *dw = &source->dw[j];
151
152                         for(node = dest_dw; node; node = node->next) {
153                                 MDeformWeight *tmp_dw = (MDeformWeight *)node->link;
154
155                                 if(tmp_dw->def_nr == dw->def_nr) {
156                                         tmp_dw->weight += dw->weight * interp_weight;
157                                         break;
158                                 }
159                         }
160
161                         /* if this def_nr is not in the list, add it */
162                         if(!node) {
163                                 MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw),
164                                                             "layerInterp_mdeformvert tmp_dw");
165                                 tmp_dw->def_nr = dw->def_nr;
166                                 tmp_dw->weight = dw->weight * interp_weight;
167                                 BLI_linklist_prepend(&dest_dw, tmp_dw);
168                                 totweight++;
169                         }
170                 }
171         }
172
173         /* now we know how many unique deform weights there are, so realloc */
174         if(dvert->dw) MEM_freeN(dvert->dw);
175
176         if(totweight) {
177                 dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight,
178                                         "layerInterp_mdeformvert dvert->dw");
179                 dvert->totweight = totweight;
180
181                 for(i = 0, node = dest_dw; node; node = node->next, ++i)
182                         dvert->dw[i] = *((MDeformWeight *)node->link);
183         }
184         else
185                 memset(dvert, 0, sizeof(*dvert));
186
187         BLI_linklist_free(dest_dw, linklist_free_simple);
188 }
189
190
191 static void layerInterp_msticky(void **sources, float *weights,
192                                 float *sub_weights, int count, void *dest)
193 {
194         float co[2], w;
195         MSticky *mst;
196         int i;
197
198         co[0] = co[1] = 0.0f;
199         for(i = 0; i < count; i++) {
200                 w = weights ? weights[i] : 1.0f;
201                 mst = (MSticky*)sources[i];
202
203                 co[0] += w*mst->co[0];
204                 co[1] += w*mst->co[1];
205         }
206
207         mst = (MSticky*)dest;
208         mst->co[0] = co[0];
209         mst->co[1] = co[1];
210 }
211
212
213 static void layerCopy_tface(const void *source, void *dest, int count)
214 {
215         const MTFace *source_tf = (const MTFace*)source;
216         MTFace *dest_tf = (MTFace*)dest;
217         int i;
218
219         for(i = 0; i < count; ++i)
220                 dest_tf[i] = source_tf[i];
221 }
222
223 static void layerInterp_tface(void **sources, float *weights,
224                               float *sub_weights, int count, void *dest)
225 {
226         MTFace *tf = dest;
227         int i, j, k;
228         float uv[4][2];
229         float *sub_weight;
230
231         if(count <= 0) return;
232
233         memset(uv, 0, sizeof(uv));
234
235         sub_weight = sub_weights;
236         for(i = 0; i < count; ++i) {
237                 float weight = weights ? weights[i] : 1;
238                 MTFace *src = sources[i];
239
240                 for(j = 0; j < 4; ++j) {
241                         if(sub_weights) {
242                                 for(k = 0; k < 4; ++k, ++sub_weight) {
243                                         float w = (*sub_weight) * weight;
244                                         float *tmp_uv = src->uv[k];
245
246                                         uv[j][0] += tmp_uv[0] * w;
247                                         uv[j][1] += tmp_uv[1] * w;
248                                 }
249                         } else {
250                                 uv[j][0] += src->uv[j][0] * weight;
251                                 uv[j][1] += src->uv[j][1] * weight;
252                         }
253                 }
254         }
255
256         *tf = *(MTFace *)sources[0];
257         for(j = 0; j < 4; ++j) {
258                 tf->uv[j][0] = uv[j][0];
259                 tf->uv[j][1] = uv[j][1];
260         }
261 }
262
263 static void layerSwap_tface(void *data, int *corner_indices)
264 {
265         MTFace *tf = data;
266         float uv[4][2];
267         int j;
268
269         for(j = 0; j < 4; ++j) {
270                 uv[j][0] = tf->uv[corner_indices[j]][0];
271                 uv[j][1] = tf->uv[corner_indices[j]][1];
272         }
273
274         memcpy(tf->uv, uv, sizeof(tf->uv));
275 }
276
277 static void layerDefault_tface(void *data, int count)
278 {
279         static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL,
280                                    0, 0, TF_DYNAMIC, 0, 0};
281         MTFace *tf = (MTFace*)data;
282         int i;
283
284         for(i = 0; i < count; i++)
285                 tf[i] = default_tf;
286 }
287
288 static void layerCopy_origspace_face(const void *source, void *dest, int count)
289 {
290         const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
291         OrigSpaceFace *dest_tf = (OrigSpaceFace*)dest;
292         int i;
293
294         for(i = 0; i < count; ++i)
295                 dest_tf[i] = source_tf[i];
296 }
297
298 static void layerInterp_origspace_face(void **sources, float *weights,
299                                                           float *sub_weights, int count, void *dest)
300 {
301         OrigSpaceFace *osf = dest;
302         int i, j, k;
303         float uv[4][2];
304         float *sub_weight;
305
306         if(count <= 0) return;
307
308         memset(uv, 0, sizeof(uv));
309
310         sub_weight = sub_weights;
311         for(i = 0; i < count; ++i) {
312                 float weight = weights ? weights[i] : 1;
313                 OrigSpaceFace *src = sources[i];
314
315                 for(j = 0; j < 4; ++j) {
316                         if(sub_weights) {
317                                 for(k = 0; k < 4; ++k, ++sub_weight) {
318                                         float w = (*sub_weight) * weight;
319                                         float *tmp_uv = src->uv[k];
320
321                                         uv[j][0] += tmp_uv[0] * w;
322                                         uv[j][1] += tmp_uv[1] * w;
323                                 }
324                         } else {
325                                 uv[j][0] += src->uv[j][0] * weight;
326                                 uv[j][1] += src->uv[j][1] * weight;
327                         }
328                 }
329         }
330
331         *osf = *(OrigSpaceFace *)sources[0];
332         for(j = 0; j < 4; ++j) {
333                 osf->uv[j][0] = uv[j][0];
334                 osf->uv[j][1] = uv[j][1];
335         }
336 }
337
338 static void layerSwap_origspace_face(void *data, int *corner_indices)
339 {
340         OrigSpaceFace *osf = data;
341         float uv[4][2];
342         int j;
343
344         for(j = 0; j < 4; ++j) {
345                 uv[j][0] = osf->uv[corner_indices[j]][0];
346                 uv[j][1] = osf->uv[corner_indices[j]][1];
347         }
348         memcpy(osf->uv, uv, sizeof(osf->uv));
349 }
350
351 static void layerDefault_origspace_face(void *data, int count)
352 {
353         static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
354         OrigSpaceFace *osf = (OrigSpaceFace*)data;
355         int i;
356
357         for(i = 0; i < count; i++)
358                 osf[i] = default_osf;
359 }
360 /* --------- */
361
362
363
364
365 static void layerInterp_mcol(void **sources, float *weights,
366                              float *sub_weights, int count, void *dest)
367 {
368         MCol *mc = dest;
369         int i, j, k;
370         struct {
371                 float a;
372                 float r;
373                 float g;
374                 float b;
375         } col[4];
376         float *sub_weight;
377
378         if(count <= 0) return;
379
380         memset(col, 0, sizeof(col));
381         
382         sub_weight = sub_weights;
383         for(i = 0; i < count; ++i) {
384                 float weight = weights ? weights[i] : 1;
385
386                 for(j = 0; j < 4; ++j) {
387                         if(sub_weights) {
388                                 MCol *src = sources[i];
389                                 for(k = 0; k < 4; ++k, ++sub_weight, ++src) {
390                                         col[j].a += src->a * (*sub_weight) * weight;
391                                         col[j].r += src->r * (*sub_weight) * weight;
392                                         col[j].g += src->g * (*sub_weight) * weight;
393                                         col[j].b += src->b * (*sub_weight) * weight;
394                                 }
395                         } else {
396                                 MCol *src = sources[i];
397                                 col[j].a += src[j].a * weight;
398                                 col[j].r += src[j].r * weight;
399                                 col[j].g += src[j].g * weight;
400                                 col[j].b += src[j].b * weight;
401                         }
402                 }
403         }
404
405         for(j = 0; j < 4; ++j) {
406                 mc[j].a = (int)col[j].a;
407                 mc[j].r = (int)col[j].r;
408                 mc[j].g = (int)col[j].g;
409                 mc[j].b = (int)col[j].b;
410         }
411 }
412
413 static void layerSwap_mcol(void *data, int *corner_indices)
414 {
415         MCol *mcol = data;
416         MCol col[4];
417         int j;
418
419         for(j = 0; j < 4; ++j)
420                 col[j] = mcol[corner_indices[j]];
421
422         memcpy(mcol, col, sizeof(col));
423 }
424
425 static void layerDefault_mcol(void *data, int count)
426 {
427         static MCol default_mcol = {255, 255, 255, 255};
428         MCol *mcol = (MCol*)data;
429         int i;
430
431         for(i = 0; i < 4*count; i++)
432                 mcol[i] = default_mcol;
433 }
434
435 const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
436         {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
437         {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
438          NULL},
439         {sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert,
440          layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL},
441         {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL},
442         {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
443         {sizeof(MTFace), "MTFace", 1, "UVTex", layerCopy_tface, NULL,
444          layerInterp_tface, layerSwap_tface, layerDefault_tface},
445         /* 4 MCol structs per face */
446         {sizeof(MCol)*4, "MCol", 4, "Col", NULL, NULL, layerInterp_mcol,
447          layerSwap_mcol, layerDefault_mcol},
448         {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
449         /* 3 floats per normal vector */
450         {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
451         {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
452         {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
453         {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
454         {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
455         {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
456          layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
457         {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
458 };
459
460 const char *LAYERTYPENAMES[CD_NUMTYPES] = {
461         "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
462         "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
463         "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco"};
464
465 const CustomDataMask CD_MASK_BAREMESH =
466         CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
467 const CustomDataMask CD_MASK_MESH =
468         CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
469         CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
470         CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
471 const CustomDataMask CD_MASK_EDITMESH =
472         CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
473         CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
474 const CustomDataMask CD_MASK_DERIVEDMESH =
475         CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
476         CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
477         CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO;
478
479 static const LayerTypeInfo *layerType_getInfo(int type)
480 {
481         if(type < 0 || type >= CD_NUMTYPES) return NULL;
482
483         return &LAYERTYPEINFO[type];
484 }
485
486 static const char *layerType_getName(int type)
487 {
488         if(type < 0 || type >= CD_NUMTYPES) return NULL;
489
490         return LAYERTYPENAMES[type];
491 }
492
493 /********************* CustomData functions *********************/
494 static void customData_update_offsets(CustomData *data);
495
496 static CustomDataLayer *customData_add_layer__internal(CustomData *data,
497         int type, int alloctype, void *layerdata, int totelem, const char *name);
498
499 void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
500                       CustomDataMask mask, int alloctype, int totelem)
501 {
502         const LayerTypeInfo *typeInfo;
503         CustomDataLayer *layer, *newlayer;
504         int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0;
505
506         for(i = 0; i < source->totlayer; ++i) {
507                 layer = &source->layers[i];
508                 typeInfo = layerType_getInfo(layer->type);
509
510                 type = layer->type;
511
512                 if (type != lasttype) {
513                         number = 0;
514                         lastactive = layer->active;
515                         lastrender = layer->active_rnd;
516                         lasttype = type;
517                 }
518                 else
519                         number++;
520
521                 if(layer->flag & CD_FLAG_NOCOPY) continue;
522                 else if(!(mask & (1 << type))) continue;
523                 else if(number < CustomData_number_of_layers(dest, type)) continue;
524
525                 if((alloctype == CD_ASSIGN) && (layer->flag & CD_FLAG_NOFREE))
526                         newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE,
527                                 layer->data, totelem, layer->name);
528                 else
529                         newlayer = customData_add_layer__internal(dest, type, alloctype,
530                                 layer->data, totelem, layer->name);
531                 
532                 if(newlayer) {
533                         newlayer->active = lastactive;
534                         newlayer->active_rnd = lastrender;
535                 }
536         }
537 }
538
539 void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
540                      CustomDataMask mask, int alloctype, int totelem)
541 {
542         memset(dest, 0, sizeof(*dest));
543
544         CustomData_merge(source, dest, mask, alloctype, totelem);
545 }
546
547 static void customData_free_layer__internal(CustomDataLayer *layer, int totelem)
548 {
549         const LayerTypeInfo *typeInfo;
550
551         if(!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
552                 typeInfo = layerType_getInfo(layer->type);
553
554                 if(typeInfo->free)
555                         typeInfo->free(layer->data, totelem, typeInfo->size);
556
557                 if(layer->data)
558                         MEM_freeN(layer->data);
559         }
560 }
561
562 void CustomData_free(CustomData *data, int totelem)
563 {
564         int i;
565
566         for(i = 0; i < data->totlayer; ++i)
567                 customData_free_layer__internal(&data->layers[i], totelem);
568
569         if(data->layers)
570                 MEM_freeN(data->layers);
571         
572         memset(data, 0, sizeof(*data));
573 }
574
575 static void customData_update_offsets(CustomData *data)
576 {
577         const LayerTypeInfo *typeInfo;
578         int i, offset = 0;
579
580         for(i = 0; i < data->totlayer; ++i) {
581                 typeInfo = layerType_getInfo(data->layers[i].type);
582
583                 data->layers[i].offset = offset;
584                 offset += typeInfo->size;
585         }
586
587         data->totsize = offset;
588 }
589
590 int CustomData_get_layer_index(const CustomData *data, int type)
591 {
592         int i; 
593
594         for(i=0; i < data->totlayer; ++i)
595                 if(data->layers[i].type == type)
596                         return i;
597
598         return -1;
599 }
600
601 int CustomData_get_named_layer_index(const CustomData *data, int type, char *name)
602 {
603         int i;
604
605         for(i=0; i < data->totlayer; ++i)
606                 if(data->layers[i].type == type && strcmp(data->layers[i].name, name)==0)
607                         return i;
608
609         return -1;
610 }
611
612 int CustomData_get_active_layer_index(const CustomData *data, int type)
613 {
614         int i;
615
616         for(i=0; i < data->totlayer; ++i)
617                 if(data->layers[i].type == type)
618                         return i + data->layers[i].active;
619
620         return -1;
621 }
622
623 int CustomData_get_render_layer_index(const CustomData *data, int type)
624 {
625         int i;
626
627         for(i=0; i < data->totlayer; ++i)
628                 if(data->layers[i].type == type)
629                         return i + data->layers[i].active_rnd;
630
631         return -1;
632 }
633
634 int CustomData_get_active_layer(const CustomData *data, int type)
635 {
636         int i;
637
638         for(i=0; i < data->totlayer; ++i)
639                 if(data->layers[i].type == type)
640                         return data->layers[i].active;
641
642         return -1;
643 }
644
645 int CustomData_get_render_layer(const CustomData *data, int type)
646 {
647         int i;
648
649         for(i=0; i < data->totlayer; ++i)
650                 if(data->layers[i].type == type)
651                         return data->layers[i].active_rnd;
652
653         return -1;
654 }
655
656
657 void CustomData_set_layer_active(CustomData *data, int type, int n)
658 {
659         int i;
660
661         for(i=0; i < data->totlayer; ++i)
662                 if(data->layers[i].type == type)
663                         data->layers[i].active = n;
664 }
665
666 void CustomData_set_layer_render(CustomData *data, int type, int n)
667 {
668         int i;
669
670         for(i=0; i < data->totlayer; ++i)
671                 if(data->layers[i].type == type)
672                         data->layers[i].active_rnd = n;
673 }
674
675 /* for using with an index from CustomData_get_active_layer_index and CustomData_get_render_layer_index */
676 void CustomData_set_layer_active_index(CustomData *data, int type, int n)
677 {
678         int i;
679
680         for(i=0; i < data->totlayer; ++i)
681                 if(data->layers[i].type == type)
682                         data->layers[i].active = n-i;
683 }
684
685 void CustomData_set_layer_render_index(CustomData *data, int type, int n)
686 {
687         int i;
688
689         for(i=0; i < data->totlayer; ++i)
690                 if(data->layers[i].type == type)
691                         data->layers[i].active_rnd = n-i;
692 }
693
694
695 void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
696 {
697         int i;
698
699         for(i=0; i < data->totlayer; ++i)
700                 if(data->layers[i].type == type)
701                         data->layers[i].flag |= flag;
702 }
703
704 static int customData_resize(CustomData *data, int amount)
705 {
706         CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxlayer + amount),
707                                        "CustomData->layers");
708         if(!tmp) return 0;
709
710         data->maxlayer += amount;
711         if (data->layers) {
712                 memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer);
713                 MEM_freeN(data->layers);
714         }
715         data->layers = tmp;
716
717         return 1;
718 }
719
720 static CustomDataLayer *customData_add_layer__internal(CustomData *data,
721         int type, int alloctype, void *layerdata, int totelem, const char *name)
722 {
723         const LayerTypeInfo *typeInfo= layerType_getInfo(type);
724         int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
725         void *newlayerdata;
726
727         if (!typeInfo->defaultname && CustomData_has_layer(data, type))
728                 return &data->layers[CustomData_get_layer_index(data, type)];
729
730         if((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) {
731                 newlayerdata = layerdata;
732         }
733         else {
734                 newlayerdata = MEM_callocN(size, layerType_getName(type));
735                 if(!newlayerdata)
736                         return NULL;
737         }
738
739         if (alloctype == CD_DUPLICATE) {
740                 if(typeInfo->copy)
741                         typeInfo->copy(layerdata, newlayerdata, totelem);
742                 else
743                         memcpy(newlayerdata, layerdata, size);
744         }
745         else if (alloctype == CD_DEFAULT) {
746                 if(typeInfo->set_default)
747                         typeInfo->set_default((char*)newlayerdata, totelem);
748         }
749         else if (alloctype == CD_REFERENCE)
750                 flag |= CD_FLAG_NOFREE;
751
752         if(index >= data->maxlayer) {
753                 if(!customData_resize(data, CUSTOMDATA_GROW)) {
754                         if(newlayerdata != layerdata)
755                                 MEM_freeN(newlayerdata);
756                         return NULL;
757                 }
758         }
759         
760         data->totlayer++;
761
762         /* keep layers ordered by type */
763         for( ; index > 0 && data->layers[index - 1].type > type; --index)
764                 data->layers[index] = data->layers[index - 1];
765
766         data->layers[index].type = type;
767         data->layers[index].flag = flag;
768         data->layers[index].data = newlayerdata;
769
770         if(name) {
771                 strcpy(data->layers[index].name, name);
772                 CustomData_set_layer_unique_name(data, index);
773         }
774         else
775                 data->layers[index].name[0] = '\0';
776
777         if(index > 0 && data->layers[index-1].type == type) {
778                 data->layers[index].active = data->layers[index-1].active;
779                 data->layers[index].active_rnd = data->layers[index-1].active_rnd;
780         } else {
781                 data->layers[index].active = 0;
782                 data->layers[index].active_rnd = 0;
783         }
784         
785         customData_update_offsets(data);
786
787         return &data->layers[index];
788 }
789
790 void *CustomData_add_layer(CustomData *data, int type, int alloctype,
791                            void *layerdata, int totelem)
792 {
793         CustomDataLayer *layer;
794         const LayerTypeInfo *typeInfo= layerType_getInfo(type);
795         
796         layer = customData_add_layer__internal(data, type, alloctype, layerdata,
797                                                totelem, typeInfo->defaultname);
798
799         if(layer)
800                 return layer->data;
801
802         return NULL;
803 }
804
805 /*same as above but accepts a name*/
806 void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
807                            void *layerdata, int totelem, char *name)
808 {
809         CustomDataLayer *layer;
810         
811         layer = customData_add_layer__internal(data, type, alloctype, layerdata,
812                                                totelem, name);
813
814         if(layer)
815                 return layer->data;
816
817         return NULL;
818 }
819
820
821 int CustomData_free_layer(CustomData *data, int type, int totelem, int index)
822 {
823         int i;
824         CustomDataLayer *layer;
825         
826         if (index < 0) return 0;
827
828         layer = &data->layers[index];
829
830         customData_free_layer__internal(&data->layers[index], totelem);
831
832         for (i=index+1; i < data->totlayer; ++i)
833                 data->layers[i-1] = data->layers[i];
834
835         data->totlayer--;
836
837         /* if layer was last of type in array, set new active layer */
838         if ((index >= data->totlayer) || (data->layers[index].type != type)) {
839                 i = CustomData_get_layer_index(data, type);
840                 
841                 if (i >= 0)
842                         for (; i < data->totlayer && data->layers[i].type == type; i++) {
843                                 data->layers[i].active--;
844                                 data->layers[i].active_rnd--;
845                         }
846         }
847
848         if (data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
849                 customData_resize(data, -CUSTOMDATA_GROW);
850
851         customData_update_offsets(data);
852
853         return 1;
854 }
855
856 int CustomData_free_layer_active(CustomData *data, int type, int totelem)
857 {
858         int index = 0;
859         index = CustomData_get_active_layer_index(data, type);
860         if (index < 0) return 0;
861         return CustomData_free_layer(data, type, totelem, index);
862 }
863
864
865 void CustomData_free_layers(CustomData *data, int type, int totelem)
866 {
867         while (CustomData_has_layer(data, type))
868                 CustomData_free_layer_active(data, type, totelem);
869 }
870
871 int CustomData_has_layer(const CustomData *data, int type)
872 {
873         return (CustomData_get_layer_index(data, type) != -1);
874 }
875
876 int CustomData_number_of_layers(const CustomData *data, int type)
877 {
878         int i, number = 0;
879
880         for(i = 0; i < data->totlayer; i++)
881                 if(data->layers[i].type == type)
882                         number++;
883         
884         return number;
885 }
886
887 void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
888 {
889         CustomDataLayer *layer;
890         int layer_index;
891
892         /* get the layer index of the first layer of type */
893         layer_index = CustomData_get_active_layer_index(data, type);
894         if(layer_index < 0) return NULL;
895
896         layer = &data->layers[layer_index];
897
898         if (layer->flag & CD_FLAG_NOFREE) {
899                 layer->data = MEM_dupallocN(layer->data);
900                 layer->flag &= ~CD_FLAG_NOFREE;
901         }
902
903         return layer->data;
904 }
905
906 void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
907                                                   int type, char *name)
908 {
909         CustomDataLayer *layer;
910         int layer_index;
911
912         /* get the layer index of the desired layer */
913         layer_index = CustomData_get_named_layer_index(data, type, name);
914         if(layer_index < 0) return NULL;
915
916         layer = &data->layers[layer_index];
917
918         if (layer->flag & CD_FLAG_NOFREE) {
919                 layer->data = MEM_dupallocN(layer->data);
920                 layer->flag &= ~CD_FLAG_NOFREE;
921         }
922
923         return layer->data;
924 }
925
926 void CustomData_free_temporary(CustomData *data, int totelem)
927 {
928         CustomDataLayer *layer;
929         int i, j;
930
931         for(i = 0, j = 0; i < data->totlayer; ++i) {
932                 layer = &data->layers[i];
933
934                 if (i != j)
935                         data->layers[j] = data->layers[i];
936
937                 if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY)
938                         customData_free_layer__internal(layer, totelem);
939                 else
940                         j++;
941         }
942
943         data->totlayer = j;
944
945         if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
946                 customData_resize(data, -CUSTOMDATA_GROW);
947
948         customData_update_offsets(data);
949 }
950
951 void CustomData_set_only_copy(const struct CustomData *data,
952                               CustomDataMask mask)
953 {
954         int i;
955
956         for(i = 0; i < data->totlayer; ++i)
957                 if(!(mask & (1 << data->layers[i].type)))
958                         data->layers[i].flag |= CD_FLAG_NOCOPY;
959 }
960
961 void CustomData_copy_data(const CustomData *source, CustomData *dest,
962                           int source_index, int dest_index, int count)
963 {
964         const LayerTypeInfo *typeInfo;
965         int src_i, dest_i;
966         int src_offset;
967         int dest_offset;
968
969         /* copies a layer at a time */
970         dest_i = 0;
971         for(src_i = 0; src_i < source->totlayer; ++src_i) {
972
973                 /* find the first dest layer with type >= the source type
974                  * (this should work because layers are ordered by type)
975                  */
976                 while(dest_i < dest->totlayer
977                       && dest->layers[dest_i].type < source->layers[src_i].type)
978                         ++dest_i;
979
980                 /* if there are no more dest layers, we're done */
981                 if(dest_i >= dest->totlayer) return;
982
983                 /* if we found a matching layer, copy the data */
984                 if(dest->layers[dest_i].type == source->layers[src_i].type) {
985                         char *src_data = source->layers[src_i].data;
986                         char *dest_data = dest->layers[dest_i].data;
987
988                         typeInfo = layerType_getInfo(source->layers[src_i].type);
989
990                         src_offset = source_index * typeInfo->size;
991                         dest_offset = dest_index * typeInfo->size;
992
993                         if(typeInfo->copy)
994                                 typeInfo->copy(src_data + src_offset,
995                                                 dest_data + dest_offset,
996                                                 count);
997                         else
998                                 memcpy(dest_data + dest_offset,
999                                        src_data + src_offset,
1000                                        count * typeInfo->size);
1001
1002                         /* if there are multiple source & dest layers of the same type,
1003                          * we don't want to copy all source layers to the same dest, so
1004                          * increment dest_i
1005                          */
1006                         ++dest_i;
1007                 }
1008         }
1009 }
1010
1011 void CustomData_free_elem(CustomData *data, int index, int count)
1012 {
1013         int i;
1014         const LayerTypeInfo *typeInfo;
1015
1016         for(i = 0; i < data->totlayer; ++i) {
1017                 if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
1018                         typeInfo = layerType_getInfo(data->layers[i].type);
1019
1020                         if(typeInfo->free) {
1021                                 int offset = typeInfo->size * index;
1022
1023                                 typeInfo->free((char *)data->layers[i].data + offset,
1024                                                count, typeInfo->size);
1025                         }
1026                 }
1027         }
1028 }
1029
1030 #define SOURCE_BUF_SIZE 100
1031
1032 void CustomData_interp(const CustomData *source, CustomData *dest,
1033                        int *src_indices, float *weights, float *sub_weights,
1034                        int count, int dest_index)
1035 {
1036         int src_i, dest_i;
1037         int dest_offset;
1038         int j;
1039         void *source_buf[SOURCE_BUF_SIZE];
1040         void **sources = source_buf;
1041
1042         /* slow fallback in case we're interpolating a ridiculous number of
1043          * elements
1044          */
1045         if(count > SOURCE_BUF_SIZE)
1046                 sources = MEM_callocN(sizeof(*sources) * count,
1047                                       "CustomData_interp sources");
1048
1049         /* interpolates a layer at a time */
1050         dest_i = 0;
1051         for(src_i = 0; src_i < source->totlayer; ++src_i) {
1052                 const LayerTypeInfo *typeInfo= layerType_getInfo(source->layers[src_i].type);
1053                 if(!typeInfo->interp) continue;
1054
1055                 /* find the first dest layer with type >= the source type
1056                  * (this should work because layers are ordered by type)
1057                  */
1058                 while(dest_i < dest->totlayer
1059                       && dest->layers[dest_i].type < source->layers[src_i].type)
1060                         ++dest_i;
1061
1062                 /* if there are no more dest layers, we're done */
1063                 if(dest_i >= dest->totlayer) return;
1064
1065                 /* if we found a matching layer, copy the data */
1066                 if(dest->layers[dest_i].type == source->layers[src_i].type) {
1067                         void *src_data = source->layers[src_i].data;
1068
1069                         for(j = 0; j < count; ++j)
1070                                 sources[j] = (char *)src_data
1071                                                          + typeInfo->size * src_indices[j];
1072
1073                         dest_offset = dest_index * typeInfo->size;
1074
1075                         typeInfo->interp(sources, weights, sub_weights, count,
1076                                                    (char *)dest->layers[dest_i].data + dest_offset);
1077
1078                         /* if there are multiple source & dest layers of the same type,
1079                          * we don't want to copy all source layers to the same dest, so
1080                          * increment dest_i
1081                          */
1082                         ++dest_i;
1083                 }
1084         }
1085
1086         if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
1087 }
1088
1089 void CustomData_swap(struct CustomData *data, int index, int *corner_indices)
1090 {
1091         const LayerTypeInfo *typeInfo;
1092         int i;
1093
1094         for(i = 0; i < data->totlayer; ++i) {
1095                 typeInfo = layerType_getInfo(data->layers[i].type);
1096
1097                 if(typeInfo->swap) {
1098                         int offset = typeInfo->size * index;
1099
1100                         typeInfo->swap((char *)data->layers[i].data + offset, corner_indices);
1101                 }
1102         }
1103 }
1104
1105 void *CustomData_get(const CustomData *data, int index, int type)
1106 {
1107         int offset;
1108         int layer_index;
1109         
1110         /* get the layer index of the active layer of type */
1111         layer_index = CustomData_get_active_layer_index(data, type);
1112         if(layer_index < 0) return NULL;
1113
1114         /* get the offset of the desired element */
1115         offset = layerType_getInfo(type)->size * index;
1116
1117         return (char *)data->layers[layer_index].data + offset;
1118 }
1119
1120 void *CustomData_get_layer(const CustomData *data, int type)
1121 {
1122         /* get the layer index of the active layer of type */
1123         int layer_index = CustomData_get_active_layer_index(data, type);
1124         if(layer_index < 0) return NULL;
1125
1126         return data->layers[layer_index].data;
1127 }
1128
1129 void *CustomData_get_layer_n(const CustomData *data, int type, int n)
1130 {
1131         /* get the layer index of the active layer of type */
1132         int layer_index = CustomData_get_layer_index(data, type);
1133         if(layer_index < 0) return NULL;
1134
1135         return data->layers[layer_index+n].data;
1136 }
1137
1138 void *CustomData_get_layer_named(const struct CustomData *data, int type,
1139                                  char *name)
1140 {
1141         int layer_index = CustomData_get_named_layer_index(data, type, name);
1142         if(layer_index < 0) return NULL;
1143
1144         return data->layers[layer_index].data;
1145 }
1146
1147 void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
1148 {
1149         /* get the layer index of the first layer of type */
1150         int layer_index = CustomData_get_active_layer_index(data, type);
1151
1152         if(layer_index < 0) return NULL;
1153
1154         data->layers[layer_index].data = ptr;
1155
1156         return ptr;
1157 }
1158
1159 void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr)
1160 {
1161         /* get the layer index of the first layer of type */
1162         int layer_index = CustomData_get_layer_index(data, type);
1163         if(layer_index < 0) return NULL;
1164
1165         data->layers[layer_index+n].data = ptr;
1166
1167         return ptr;
1168 }
1169
1170 void CustomData_set(const CustomData *data, int index, int type, void *source)
1171 {
1172         void *dest = CustomData_get(data, index, type);
1173         const LayerTypeInfo *typeInfo = layerType_getInfo(type);
1174
1175         if(!dest) return;
1176
1177         if(typeInfo->copy)
1178                 typeInfo->copy(source, dest, 1);
1179         else
1180                 memcpy(dest, source, typeInfo->size);
1181 }
1182
1183 /* EditMesh functions */
1184
1185 void CustomData_em_free_block(CustomData *data, void **block)
1186 {
1187     const LayerTypeInfo *typeInfo;
1188     int i;
1189
1190         if(!*block) return;
1191
1192     for(i = 0; i < data->totlayer; ++i) {
1193         if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
1194             typeInfo = layerType_getInfo(data->layers[i].type);
1195
1196             if(typeInfo->free) {
1197                                 int offset = data->layers[i].offset;
1198                 typeInfo->free((char*)*block + offset, 1, typeInfo->size);
1199                         }
1200         }
1201     }
1202
1203         MEM_freeN(*block);
1204         *block = NULL;
1205 }
1206
1207 static void CustomData_em_alloc_block(CustomData *data, void **block)
1208 {
1209         /* TODO: optimize free/alloc */
1210
1211         if (*block)
1212                 CustomData_em_free_block(data, block);
1213
1214         if (data->totsize > 0)
1215                 *block = MEM_callocN(data->totsize, "CustomData EM block");
1216         else
1217                 *block = NULL;
1218 }
1219
1220 void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
1221                             void *src_block, void **dest_block)
1222 {
1223         const LayerTypeInfo *typeInfo;
1224         int dest_i, src_i;
1225
1226         if (!*dest_block)
1227                 CustomData_em_alloc_block(dest, dest_block);
1228         
1229         /* copies a layer at a time */
1230         dest_i = 0;
1231         for(src_i = 0; src_i < source->totlayer; ++src_i) {
1232
1233                 /* find the first dest layer with type >= the source type
1234                  * (this should work because layers are ordered by type)
1235                  */
1236                 while(dest_i < dest->totlayer
1237                       && dest->layers[dest_i].type < source->layers[src_i].type)
1238                         ++dest_i;
1239
1240                 /* if there are no more dest layers, we're done */
1241                 if(dest_i >= dest->totlayer) return;
1242
1243                 /* if we found a matching layer, copy the data */
1244                 if(dest->layers[dest_i].type == source->layers[src_i].type &&
1245                         strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
1246                         char *src_data = (char*)src_block + source->layers[src_i].offset;
1247                         char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
1248
1249                         typeInfo = layerType_getInfo(source->layers[src_i].type);
1250
1251                         if(typeInfo->copy)
1252                                 typeInfo->copy(src_data, dest_data, 1);
1253                         else
1254                                 memcpy(dest_data, src_data, typeInfo->size);
1255
1256                         /* if there are multiple source & dest layers of the same type,
1257                          * we don't want to copy all source layers to the same dest, so
1258                          * increment dest_i
1259                          */
1260                         ++dest_i;
1261                 }
1262         }
1263 }
1264
1265 void *CustomData_em_get(const CustomData *data, void *block, int type)
1266 {
1267         int layer_index;
1268         
1269         /* get the layer index of the first layer of type */
1270         layer_index = CustomData_get_active_layer_index(data, type);
1271         if(layer_index < 0) return NULL;
1272
1273         return (char *)block + data->layers[layer_index].offset;
1274 }
1275
1276 void *CustomData_em_get_n(const CustomData *data, void *block, int type, int n)
1277 {
1278         int layer_index;
1279         
1280         /* get the layer index of the first layer of type */
1281         layer_index = CustomData_get_layer_index(data, type);
1282         if(layer_index < 0) return NULL;
1283
1284         return (char *)block + data->layers[layer_index+n].offset;
1285 }
1286
1287 void CustomData_em_set(CustomData *data, void *block, int type, void *source)
1288 {
1289         void *dest = CustomData_em_get(data, block, type);
1290         const LayerTypeInfo *typeInfo = layerType_getInfo(type);
1291
1292         if(!dest) return;
1293
1294         if(typeInfo->copy)
1295                 typeInfo->copy(source, dest, 1);
1296         else
1297                 memcpy(dest, source, typeInfo->size);
1298 }
1299
1300 void CustomData_em_set_n(CustomData *data, void *block, int type, int n, void *source)
1301 {
1302         void *dest = CustomData_em_get_n(data, block, type, n);
1303         const LayerTypeInfo *typeInfo = layerType_getInfo(type);
1304
1305         if(!dest) return;
1306
1307         if(typeInfo->copy)
1308                 typeInfo->copy(source, dest, 1);
1309         else
1310                 memcpy(dest, source, typeInfo->size);
1311 }
1312
1313 void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
1314                           float *sub_weights, int count, void *dest_block)
1315 {
1316         int i, j;
1317         void *source_buf[SOURCE_BUF_SIZE];
1318         void **sources = source_buf;
1319
1320         /* slow fallback in case we're interpolating a ridiculous number of
1321          * elements
1322          */
1323         if(count > SOURCE_BUF_SIZE)
1324                 sources = MEM_callocN(sizeof(*sources) * count,
1325                                       "CustomData_interp sources");
1326
1327         /* interpolates a layer at a time */
1328         for(i = 0; i < data->totlayer; ++i) {
1329                 CustomDataLayer *layer = &data->layers[i];
1330                 const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
1331
1332                 if(typeInfo->interp) {
1333                         for(j = 0; j < count; ++j)
1334                                 sources[j] = (char *)src_blocks[j] + layer->offset;
1335
1336                         typeInfo->interp(sources, weights, sub_weights, count,
1337                                           (char *)dest_block + layer->offset);
1338                 }
1339         }
1340
1341         if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
1342 }
1343
1344 void CustomData_em_set_default(CustomData *data, void **block)
1345 {
1346         const LayerTypeInfo *typeInfo;
1347         int i;
1348
1349         if (!*block)
1350                 CustomData_em_alloc_block(data, block);
1351
1352         for(i = 0; i < data->totlayer; ++i) {
1353                 int offset = data->layers[i].offset;
1354
1355                 typeInfo = layerType_getInfo(data->layers[i].type);
1356
1357                 if(typeInfo->set_default)
1358                         typeInfo->set_default((char*)*block + offset, 1);
1359         }
1360 }
1361
1362 void CustomData_to_em_block(const CustomData *source, CustomData *dest,
1363                             int src_index, void **dest_block)
1364 {
1365         const LayerTypeInfo *typeInfo;
1366         int dest_i, src_i, src_offset;
1367
1368         if (!*dest_block)
1369                 CustomData_em_alloc_block(dest, dest_block);
1370         
1371         /* copies a layer at a time */
1372         dest_i = 0;
1373         for(src_i = 0; src_i < source->totlayer; ++src_i) {
1374
1375                 /* find the first dest layer with type >= the source type
1376                  * (this should work because layers are ordered by type)
1377                  */
1378                 while(dest_i < dest->totlayer
1379                       && dest->layers[dest_i].type < source->layers[src_i].type)
1380                         ++dest_i;
1381
1382                 /* if there are no more dest layers, we're done */
1383                 if(dest_i >= dest->totlayer) return;
1384
1385                 /* if we found a matching layer, copy the data */
1386                 if(dest->layers[dest_i].type == source->layers[src_i].type) {
1387                         int offset = dest->layers[dest_i].offset;
1388                         char *src_data = source->layers[src_i].data;
1389                         char *dest_data = (char*)*dest_block + offset;
1390
1391                         typeInfo = layerType_getInfo(dest->layers[dest_i].type);
1392                         src_offset = src_index * typeInfo->size;
1393
1394                         if(typeInfo->copy)
1395                                 typeInfo->copy(src_data + src_offset, dest_data, 1);
1396                         else
1397                                 memcpy(dest_data, src_data + src_offset, typeInfo->size);
1398
1399                         /* if there are multiple source & dest layers of the same type,
1400                          * we don't want to copy all source layers to the same dest, so
1401                          * increment dest_i
1402                          */
1403                         ++dest_i;
1404                 }
1405         }
1406 }
1407
1408 void CustomData_from_em_block(const CustomData *source, CustomData *dest,
1409                               void *src_block, int dest_index)
1410 {
1411         const LayerTypeInfo *typeInfo;
1412         int dest_i, src_i, dest_offset;
1413
1414         /* copies a layer at a time */
1415         dest_i = 0;
1416         for(src_i = 0; src_i < source->totlayer; ++src_i) {
1417
1418                 /* find the first dest layer with type >= the source type
1419                  * (this should work because layers are ordered by type)
1420                  */
1421                 while(dest_i < dest->totlayer
1422                       && dest->layers[dest_i].type < source->layers[src_i].type)
1423                         ++dest_i;
1424
1425                 /* if there are no more dest layers, we're done */
1426                 if(dest_i >= dest->totlayer) return;
1427
1428                 /* if we found a matching layer, copy the data */
1429                 if(dest->layers[dest_i].type == source->layers[src_i].type) {
1430                         int offset = source->layers[src_i].offset;
1431                         char *src_data = (char*)src_block + offset;
1432                         char *dest_data = dest->layers[dest_i].data;
1433
1434                         typeInfo = layerType_getInfo(dest->layers[dest_i].type);
1435                         dest_offset = dest_index * typeInfo->size;
1436
1437                         if(typeInfo->copy)
1438                                 typeInfo->copy(src_data, dest_data + dest_offset, 1);
1439                         else
1440                                 memcpy(dest_data + dest_offset, src_data, typeInfo->size);
1441
1442                         /* if there are multiple source & dest layers of the same type,
1443                          * we don't want to copy all source layers to the same dest, so
1444                          * increment dest_i
1445                          */
1446                         ++dest_i;
1447                 }
1448         }
1449
1450 }
1451
1452 void CustomData_file_write_info(int type, char **structname, int *structnum)
1453 {
1454         const LayerTypeInfo *typeInfo = layerType_getInfo(type);
1455
1456         *structname = typeInfo->structname;
1457         *structnum = typeInfo->structnum;
1458 }
1459
1460 int CustomData_sizeof(int type)
1461 {
1462         const LayerTypeInfo *typeInfo = layerType_getInfo(type);
1463
1464         return typeInfo->size;
1465 }
1466
1467 const char *CustomData_layertype_name(int type)
1468 {
1469         return layerType_getName(type);
1470 }
1471
1472 static int  CustomData_is_property_layer(int type)
1473 {
1474         if((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR))
1475                 return 1;
1476         return 0;
1477 }
1478
1479 void CustomData_set_layer_unique_name(CustomData *data, int index)
1480 {
1481         char tempname[64];
1482         int number, i, type;
1483         char *dot, *name;
1484         CustomDataLayer *layer, *nlayer= &data->layers[index];
1485         const LayerTypeInfo *typeInfo= layerType_getInfo(nlayer->type);
1486
1487         if (!typeInfo->defaultname)
1488                 return;
1489
1490         type = nlayer->type;
1491         name = nlayer->name;
1492
1493         if (name[0] == '\0')
1494                 BLI_strncpy(nlayer->name, typeInfo->defaultname, sizeof(nlayer->name));
1495         
1496         /* see if there is a duplicate */
1497         for(i=0; i<data->totlayer; i++) {
1498                 layer = &data->layers[i];
1499                 
1500                 if(CustomData_is_property_layer(type)){
1501                         if(i!=index && CustomData_is_property_layer(layer->type) && 
1502                                 strcmp(layer->name, name)==0)
1503                                         break;  
1504                 
1505                 }
1506                 else{
1507                         if(i!=index && layer->type==type && strcmp(layer->name, name)==0)
1508                                 break;
1509                 }
1510         }
1511
1512         if(i == data->totlayer)
1513                 return;
1514
1515         /* strip off the suffix */
1516         dot = strchr(nlayer->name, '.');
1517         if(dot) *dot=0;
1518         
1519         for(number=1; number <=999; number++) {
1520                 sprintf(tempname, "%s.%03d", nlayer->name, number);
1521
1522                 for(i=0; i<data->totlayer; i++) {
1523                         layer = &data->layers[i];
1524                         
1525                         if(CustomData_is_property_layer(type)){
1526                                 if(i!=index && CustomData_is_property_layer(layer->type) && 
1527                                         strcmp(layer->name, tempname)==0)
1528
1529                                 break;
1530                         }
1531                         else{
1532                                 if(i!=index && layer->type==type && strcmp(layer->name, tempname)==0)
1533                                         break;
1534                         }
1535                 }
1536
1537                 if(i == data->totlayer) {
1538                         BLI_strncpy(nlayer->name, tempname, sizeof(nlayer->name));
1539                         return;
1540                 }
1541         }       
1542 }
1543
1544 int CustomData_verify_versions(struct CustomData *data, int index)
1545 {
1546         const LayerTypeInfo *typeInfo;
1547         CustomDataLayer *layer = &data->layers[index];
1548         int i, keeplayer = 1;
1549
1550         if (layer->type >= CD_NUMTYPES) {
1551                 keeplayer = 0; /* unknown layer type from future version */
1552         }
1553         else {
1554                 typeInfo = layerType_getInfo(layer->type);
1555
1556                 if (!typeInfo->defaultname && (index > 0) &&
1557                         data->layers[index-1].type == layer->type)
1558                         keeplayer = 0; /* multiple layers of which we only support one */
1559         }
1560
1561         if (!keeplayer) {
1562             for (i=index+1; i < data->totlayer; ++i)
1563             data->layers[i-1] = data->layers[i];
1564                 data->totlayer--;
1565         }
1566
1567         return keeplayer;
1568 }
1569