508021ef74cf1bbe415aae9a4fc1d70df5efd94e
[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_linklist.h"
38
39 #include "DNA_customdata_types.h"
40 #include "DNA_listBase.h"
41 #include "DNA_meshdata_types.h"
42
43 #include "MEM_guardedalloc.h"
44
45 #include <string.h>
46
47 /* number of layers to add when growing a CustomData object */
48 #define CUSTOMDATA_GROW 5
49
50 /********************* Layer type information **********************/
51 typedef struct LayerTypeInfo {
52         int size;          /* the memory size of one element of this layer's data */
53         char *structname;  /* name of the struct used, for file writing */
54         int structnum;     /* number of structs per element, for file writing */
55
56         /* a function to copy count elements of this layer's data
57          * (deep copy if appropriate)
58          * size should be the size of one element of this layer's data (e.g.
59          * LayerTypeInfo.size)
60          * if NULL, memcpy is used
61          */
62         void (*copy)(const void *source, void *dest, int count, int size);
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, int size)
93 {
94         int i;
95
96         memcpy(dest, source, count * size);
97
98         for(i = 0; i < count; ++i) {
99                 MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size);
100                 MDeformWeight *dw = MEM_callocN(dvert->totweight * sizeof(*dw),
101                                                 "layerCopy_mdeformvert dw");
102
103                 memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw));
104                 dvert->dw = dw;
105         }
106 }
107
108 static void layerFree_mdeformvert(void *data, int count, int size)
109 {
110         int i;
111
112         for(i = 0; i < count; ++i) {
113                 MDeformVert *dvert = (MDeformVert *)((char *)data + i * size);
114
115                 if(dvert->dw) {
116                         MEM_freeN(dvert->dw);
117                         dvert->dw = NULL;
118                         dvert->totweight = 0;
119                 }
120         }
121 }
122
123 static void linklist_free_simple(void *link)
124 {
125         MEM_freeN(link);
126 }
127
128 static void layerInterp_mdeformvert(void **sources, float *weights,
129                                     float *sub_weights, int count, void *dest)
130 {
131         MDeformVert *dvert = dest;
132         LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */
133         LinkNode *node;
134         int i, j, totweight;
135
136         if(count <= 0) return;
137
138         /* build a list of unique def_nrs for dest */
139         totweight = 0;
140         for(i = 0; i < count; ++i) {
141                 MDeformVert *source = sources[i];
142                 float interp_weight = weights ? weights[i] : 1.0f;
143
144                 for(j = 0; j < source->totweight; ++j) {
145                         MDeformWeight *dw = &source->dw[j];
146
147                         for(node = dest_dw; node; node = node->next) {
148                                 MDeformWeight *tmp_dw = (MDeformWeight *)node->link;
149
150                                 if(tmp_dw->def_nr == dw->def_nr) {
151                                         tmp_dw->weight += dw->weight * interp_weight;
152                                         break;
153                                 }
154                         }
155
156                         /* if this def_nr is not in the list, add it */
157                         if(!node) {
158                                 MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw),
159                                                             "layerInterp_mdeformvert tmp_dw");
160                                 tmp_dw->def_nr = dw->def_nr;
161                                 tmp_dw->weight = dw->weight * interp_weight;
162                                 BLI_linklist_prepend(&dest_dw, tmp_dw);
163                                 totweight++;
164                         }
165                 }
166         }
167
168         /* now we know how many unique deform weights there are, so realloc */
169         if(dvert->dw) MEM_freeN(dvert->dw);
170
171         if(totweight) {
172                 dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight,
173                                         "layerInterp_mdeformvert dvert->dw");
174                 dvert->totweight = totweight;
175
176                 for(i = 0, node = dest_dw; node; node = node->next, ++i)
177                         dvert->dw[i] = *((MDeformWeight *)node->link);
178         }
179         else
180                 memset(dvert, 0, sizeof(*dvert));
181
182         BLI_linklist_free(dest_dw, linklist_free_simple);
183 }
184
185
186 static void layerInterp_msticky(void **sources, float *weights,
187                                 float *sub_weights, int count, void *dest)
188 {
189         float co[2], w;
190         MSticky *mst;
191         int i;
192
193         co[0] = co[1] = 0.0f;
194         for(i = 0; i < count; i++) {
195                 w = weights ? weights[i] : 1.0f;
196                 mst = (MSticky*)sources[i];
197
198                 co[0] += w*mst->co[0];
199                 co[1] += w*mst->co[1];
200         }
201
202         mst = (MSticky*)dest;
203         mst->co[0] = co[0];
204         mst->co[1] = co[1];
205 }
206
207
208 static void layerCopy_tface(const void *source, void *dest, int count, int size)
209 {
210         const MTFace *source_tf = (const MTFace*)source;
211         MTFace *dest_tf = (MTFace*)dest;
212         int i;
213
214         for(i = 0; i < count; ++i) {
215                 dest_tf[i] = source_tf[i];
216                 dest_tf[i].flag &= ~TF_ACTIVE;
217         }
218 }
219
220 static void layerInterp_tface(void **sources, float *weights,
221                               float *sub_weights, int count, void *dest)
222 {
223         MTFace *tf = dest;
224         int i, j, k;
225         float uv[4][2];
226         float *sub_weight;
227
228         if(count <= 0) return;
229
230         memset(uv, 0, sizeof(uv));
231
232         sub_weight = sub_weights;
233         for(i = 0; i < count; ++i) {
234                 float weight = weights ? weights[i] : 1;
235                 MTFace *src = sources[i];
236
237                 for(j = 0; j < 4; ++j) {
238                         if(sub_weights) {
239                                 for(k = 0; k < 4; ++k, ++sub_weight) {
240                                         float w = (*sub_weight) * weight;
241                                         float *tmp_uv = src->uv[k];
242
243                                         uv[j][0] += tmp_uv[0] * w;
244                                         uv[j][1] += tmp_uv[1] * w;
245                                 }
246                         } else {
247                                 uv[j][0] += src->uv[j][0] * weight;
248                                 uv[j][1] += src->uv[j][1] * weight;
249                         }
250                 }
251         }
252
253         *tf = *(MTFace *)sources[0];
254         for(j = 0; j < 4; ++j) {
255                 tf->uv[j][0] = uv[j][0];
256                 tf->uv[j][1] = uv[j][1];
257         }
258 }
259
260 static void layerSwap_tface(void *data, int *corner_indices)
261 {
262         MTFace *tf = data;
263         float uv[4][2];
264         int j;
265
266         for(j = 0; j < 4; ++j) {
267                 uv[j][0] = tf->uv[corner_indices[j]][0];
268                 uv[j][1] = tf->uv[corner_indices[j]][1];
269         }
270
271         memcpy(tf->uv, uv, sizeof(tf->uv));
272 }
273
274 static void layerDefault_tface(void *data, int count)
275 {
276         static MTFace default_tf = {{{0, 1}, {0, 0}, {1, 0}, {1, 1}}, NULL,
277                                    TF_SELECT, 0, TF_DYNAMIC, 0, 0};
278         MTFace *tf = (MTFace*)data;
279         int i;
280
281         for(i = 0; i < count; i++)
282                 tf[i] = default_tf;
283 }
284
285 static void layerInterp_mcol(void **sources, float *weights,
286                              float *sub_weights, int count, void *dest)
287 {
288         MCol *mc = dest;
289         int i, j, k;
290         struct {
291                 float a;
292                 float r;
293                 float g;
294                 float b;
295         } col[4];
296         float *sub_weight;
297
298         if(count <= 0) return;
299
300         memset(col, 0, sizeof(col));
301         
302         sub_weight = sub_weights;
303         for(i = 0; i < count; ++i) {
304                 float weight = weights ? weights[i] : 1;
305
306                 for(j = 0; j < 4; ++j) {
307                         if(sub_weights) {
308                                 MCol *src = sources[i];
309                                 for(k = 0; k < 4; ++k, ++sub_weight, ++src) {
310                                         col[j].a += src->a * (*sub_weight) * weight;
311                                         col[j].r += src->r * (*sub_weight) * weight;
312                                         col[j].g += src->g * (*sub_weight) * weight;
313                                         col[j].b += src->b * (*sub_weight) * weight;
314                                 }
315                         } else {
316                                 MCol *src = sources[i];
317                                 col[j].a += src[j].a * weight;
318                                 col[j].r += src[j].r * weight;
319                                 col[j].g += src[j].g * weight;
320                                 col[j].b += src[j].b * weight;
321                         }
322                 }
323         }
324
325         for(j = 0; j < 4; ++j) {
326                 mc[j].a = (int)col[j].a;
327                 mc[j].r = (int)col[j].r;
328                 mc[j].g = (int)col[j].g;
329                 mc[j].b = (int)col[j].b;
330         }
331 }
332
333 static void layerSwap_mcol(void *data, int *corner_indices)
334 {
335         MCol *mcol = data;
336         MCol col[4];
337         int j;
338
339         for(j = 0; j < 4; ++j)
340                 col[j] = mcol[corner_indices[j]];
341
342         memcpy(mcol, col, sizeof(col));
343 }
344
345 static void layerDefault_mcol(void *data, int count)
346 {
347         static MCol default_mcol = {255, 255, 255, 255};
348         MCol *mcol = (MCol*)data;
349         int i;
350
351         for(i = 0; i < 4*count; i++)
352                 mcol[i] = default_mcol;
353 }
354
355 const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
356         {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL},
357         {sizeof(MSticky), "MSticky", 1, NULL, NULL, layerInterp_msticky, NULL, NULL},
358         {sizeof(MDeformVert), "MDeformVert", 1, layerCopy_mdeformvert,
359          layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL},
360         {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL},
361         {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL},
362         {sizeof(MTFace), "MTFace", 1, layerCopy_tface, NULL, layerInterp_tface,
363          layerSwap_tface, layerDefault_tface},
364         /* 4 MCol structs per face */
365         {sizeof(MCol)*4, "MCol", 4, NULL, NULL, layerInterp_mcol, layerSwap_mcol,
366          layerDefault_mcol},
367         {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL},
368         /* 3 floats per normal vector */
369         {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL},
370         {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL},
371 };
372
373 const char *LAYERTYPENAMES[CD_NUMTYPES] = {
374         "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
375         "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags"};
376
377 const CustomDataMask CD_MASK_BAREMESH =
378         CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
379 const CustomDataMask CD_MASK_MESH =
380         CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
381         CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL;
382 const CustomDataMask CD_MASK_EDITMESH =
383         CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
384         CD_MASK_MCOL;
385 const CustomDataMask CD_MASK_DERIVEDMESH =
386         CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
387         CD_MASK_MCOL | CD_MASK_ORIGINDEX;
388
389 static const LayerTypeInfo *layerType_getInfo(int type)
390 {
391         if(type < 0 || type >= CD_NUMTYPES) return NULL;
392
393         return &LAYERTYPEINFO[type];
394 }
395
396 static const char *layerType_getName(int type)
397 {
398         if(type < 0 || type >= CD_NUMTYPES) return NULL;
399
400         return LAYERTYPENAMES[type];
401 }
402
403 /********************* CustomData functions *********************/
404 static void CustomData_update_offsets(CustomData *data)
405 {
406         const LayerTypeInfo *typeInfo;
407         int i, offset = 0;
408
409         for(i = 0; i < data->totlayer; ++i) {
410                 typeInfo = layerType_getInfo(data->layers[i].type);
411
412                 data->layers[i].offset = offset;
413                 offset += typeInfo->size;
414         }
415
416         data->totsize = offset;
417 }
418
419 void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
420                       CustomDataMask mask, int alloctype, int totelem)
421 {
422         const LayerTypeInfo *typeInfo;
423         CustomDataLayer *layer;
424         int i, flag, type;
425         void *data;
426
427         for(i = 0; i < source->totlayer; ++i) {
428                 layer = &source->layers[i];
429                 typeInfo = layerType_getInfo(layer->type);
430
431                 if(layer->flag & CD_FLAG_NOCOPY) continue;
432                 else if(!(mask & (1 << layer->type))) continue;
433                 else if(CustomData_has_layer(dest, layer->type)) continue;
434
435                 type = layer->type;
436                 flag = layer->flag & ~CD_FLAG_NOFREE;
437                 data = layer->data;
438
439                 if (alloctype == CD_CALLOC || alloctype == CD_DUPLICATE) {
440                         CustomData_add_layer(dest, type, flag, NULL, totelem);
441                 }
442                 else if (alloctype == CD_REFERENCE) {
443                         CustomData_add_layer(dest, type, flag|CD_FLAG_NOFREE, data, totelem);
444                 }
445                 else if (alloctype == CD_DEFAULT) {
446                         data = CustomData_add_layer(dest, type, flag, NULL, totelem);
447                         if(typeInfo->set_default)
448                                 typeInfo->set_default((char*)data, totelem);
449                 }
450         }
451
452         if (alloctype == CD_DUPLICATE)
453                 CustomData_copy_data(source, dest, 0, 0, totelem);
454
455         CustomData_update_offsets(dest);
456 }
457
458 void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
459                      CustomDataMask mask, int alloctype, int totelem)
460 {
461         memset(dest, 0, sizeof(*dest));
462
463         CustomData_merge(source, dest, mask, alloctype, totelem);
464 }
465
466 static void CustomData_free_layer__internal(CustomDataLayer *layer, int totelem)
467 {
468         const LayerTypeInfo *typeInfo;
469
470         if(!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
471                 typeInfo = layerType_getInfo(layer->type);
472
473                 if(typeInfo->free)
474                         typeInfo->free(layer->data, totelem, typeInfo->size);
475
476                 if(layer->data)
477                         MEM_freeN(layer->data);
478         }
479 }
480
481 void CustomData_free(CustomData *data, int totelem)
482 {
483         int i;
484
485         for(i = 0; i < data->totlayer; ++i)
486                 CustomData_free_layer__internal(&data->layers[i], totelem);
487
488         if(data->layers)
489                 MEM_freeN(data->layers);
490         
491         memset(data, 0, sizeof(*data));
492 }
493
494
495 /* gets index of first layer matching type after start_index
496  * if start_index < 0, starts searching at 0
497  * returns -1 if there is no layer of type
498  */
499 static int CustomData_find_next(const CustomData *data, int type,
500                                 int start_index)
501 {
502         int i = start_index + 1;
503
504         if(i < 0) i = 0;
505
506         for(; i < data->totlayer; ++i)
507                 if(data->layers[i].type == type) return i;
508
509         return -1;
510 }
511
512 static int customData_resize(CustomData *data, int amount)
513 {
514         CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxlayer + amount),
515                                        "CustomData->layers");
516         if(!tmp) return 0;
517
518         data->maxlayer += amount;
519         if (data->layers) {
520                 memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer);
521                 MEM_freeN(data->layers);
522         }
523         data->layers = tmp;
524
525         return 1;
526 }
527
528 static int customData_add_layer__internal(CustomData *data, int type, int flag,
529                                           void *layer)
530 {
531         int index = data->totlayer;
532
533         if(index >= data->maxlayer)
534                 if(!customData_resize(data, CUSTOMDATA_GROW))
535                         return 0;
536         
537         /* keep layers ordered by type */
538         for( ; index > 0 && data->layers[index - 1].type > type; --index)
539                 data->layers[index] = data->layers[index - 1];
540
541         data->layers[index].type = type;
542         data->layers[index].flag = flag;
543         data->layers[index].data = layer;
544
545         data->totlayer++;
546
547         CustomData_update_offsets(data);
548
549         return 1;
550 }
551
552 void *CustomData_add_layer(CustomData *data, int type, int flag,
553                            void *layerdata, int totelem)
554 {
555         int size = layerType_getInfo(type)->size * totelem;
556         void *tmpdata = layerdata;
557
558         if(totelem > 0) {
559                 if(!tmpdata)
560                         tmpdata = MEM_callocN(size, layerType_getName(type));
561                 if(!tmpdata)
562                         return NULL;
563         }
564
565         if(!customData_add_layer__internal(data, type, flag, tmpdata)) {
566                 if(tmpdata)
567                         MEM_freeN(tmpdata);
568                 return NULL;
569         }
570         
571         return tmpdata;
572 }
573
574 int CustomData_free_layer(CustomData *data, int type, int totelem)
575 {
576         int index = CustomData_find_next(data, type, -1);
577
578         if (index < 0) return 0;
579
580         CustomData_free_layer__internal(&data->layers[index], totelem);
581
582         for(++index; index < data->totlayer; ++index)
583                 data->layers[index - 1] = data->layers[index];
584
585         data->totlayer--;
586
587         if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
588                 customData_resize(data, -CUSTOMDATA_GROW);
589
590         CustomData_update_offsets(data);
591
592         return 1;
593 }
594
595 int CustomData_has_layer(const CustomData *data, int type)
596 {
597         return (CustomData_find_next(data, type, -1) != -1);
598 }
599
600 void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
601 {
602         CustomDataLayer *layer;
603         int layer_index;
604
605         /* get the layer index of the first layer of type */
606         layer_index = CustomData_find_next(data, type, -1);
607         if(layer_index < 0) return NULL;
608
609         layer = &data->layers[layer_index];
610
611         if (layer->flag & CD_FLAG_NOFREE) {
612                 layer->data = MEM_dupallocN(layer->data);
613                 layer->flag &= ~CD_FLAG_NOFREE;
614         }
615
616         return layer->data;
617 }
618
619 void CustomData_free_temporary(CustomData *data, int totelem)
620 {
621         CustomDataLayer *layer;
622         int i, j;
623
624         for(i = 0, j = 0; i < data->totlayer; ++i) {
625                 layer = &data->layers[i];
626
627                 if (i != j)
628                         data->layers[j] = data->layers[i];
629
630                 if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY)
631                         CustomData_free_layer__internal(layer, totelem);
632                 else
633                         j++;
634         }
635
636         data->totlayer = j;
637
638         if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
639                 customData_resize(data, -CUSTOMDATA_GROW);
640
641         CustomData_update_offsets(data);
642 }
643
644 int CustomData_compat(const CustomData *data1, const CustomData *data2)
645 {
646         int i;
647
648         if(data1->totlayer != data2->totlayer) return 0;
649
650         for(i = 0; i < data1->totlayer; ++i) {
651                 if(data1->layers[i].type != data2->layers[i].type) return 0;
652                 if(data1->layers[i].flag != data2->layers[i].flag) return 0;
653         }
654
655         return 1;
656 }
657
658 void CustomData_set_only_copy(const struct CustomData *data,
659                               CustomDataMask mask)
660 {
661         int i;
662
663         for(i = 0; i < data->totlayer; ++i)
664                 if(!(mask & (1 << data->layers[i].type)))
665                         data->layers[i].flag |= CD_FLAG_NOCOPY;
666 }
667
668 void CustomData_copy_data(const CustomData *source, CustomData *dest,
669                           int source_index, int dest_index, int count)
670 {
671         const LayerTypeInfo *type_info;
672         int src_i, dest_i;
673         int src_offset;
674         int dest_offset;
675
676         /* copies a layer at a time */
677         dest_i = 0;
678         for(src_i = 0; src_i < source->totlayer; ++src_i) {
679                 if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
680
681                 /* find the first dest layer with type >= the source type
682                  * (this should work because layers are ordered by type)
683                  */
684                 while(dest_i < dest->totlayer
685                       && dest->layers[dest_i].type < source->layers[src_i].type)
686                         ++dest_i;
687
688                 /* if there are no more dest layers, we're done */
689                 if(dest_i >= dest->totlayer) return;
690
691                 /* if we found a matching layer, copy the data */
692                 if(dest->layers[dest_i].type == source->layers[src_i].type) {
693                         char *src_data = source->layers[src_i].data;
694                         char *dest_data = dest->layers[dest_i].data;
695
696                         type_info = layerType_getInfo(source->layers[src_i].type);
697
698                         src_offset = source_index * type_info->size;
699                         dest_offset = dest_index * type_info->size;
700
701                         if(type_info->copy)
702                                 type_info->copy(src_data + src_offset,
703                                                 dest_data + dest_offset,
704                                                 count, type_info->size);
705                         else
706                                 memcpy(dest_data + dest_offset,
707                                        src_data + src_offset,
708                                        count * type_info->size);
709
710                         /* if there are multiple source & dest layers of the same type,
711                          * we don't want to copy all source layers to the same dest, so
712                          * increment dest_i
713                          */
714                         ++dest_i;
715                 }
716         }
717 }
718
719 void CustomData_free_elem(CustomData *data, int index, int count)
720 {
721         int i;
722         const LayerTypeInfo *typeInfo;
723
724         for(i = 0; i < data->totlayer; ++i) {
725                 if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
726                         typeInfo = layerType_getInfo(data->layers[i].type);
727
728                         if(typeInfo->free) {
729                                 int offset = typeInfo->size * index;
730
731                                 typeInfo->free((char *)data->layers[i].data + offset,
732                                                count, typeInfo->size);
733                         }
734                 }
735         }
736 }
737
738 #define SOURCE_BUF_SIZE 100
739
740 void CustomData_interp(const CustomData *source, CustomData *dest,
741                        int *src_indices, float *weights, float *sub_weights,
742                        int count, int dest_index)
743 {
744         int src_i, dest_i;
745         int dest_offset;
746         int j;
747         void *source_buf[SOURCE_BUF_SIZE];
748         void **sources = source_buf;
749
750         /* slow fallback in case we're interpolating a ridiculous number of
751          * elements
752          */
753         if(count > SOURCE_BUF_SIZE)
754                 sources = MEM_callocN(sizeof(*sources) * count,
755                                       "CustomData_interp sources");
756
757         /* interpolates a layer at a time */
758         for(src_i = 0; src_i < source->totlayer; ++src_i) {
759                 CustomDataLayer *source_layer = &source->layers[src_i];
760                 const LayerTypeInfo *type_info =
761                                         layerType_getInfo(source_layer->type);
762
763                 dest_i = CustomData_find_next(dest, source_layer->type, -1);
764
765                 if(dest_i >= 0 && type_info->interp) {
766                         void *src_data = source_layer->data; 
767
768                         for(j = 0; j < count; ++j)
769                                 sources[j] = (char *)src_data
770                                              + type_info->size * src_indices[j];
771
772                         dest_offset = dest_index * type_info->size;
773
774                         type_info->interp(sources, weights, sub_weights, count,
775                                        (char *)dest->layers[dest_i].data + dest_offset);
776                 }
777         }
778
779         if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
780 }
781
782 void CustomData_swap(struct CustomData *data, int index, int *corner_indices)
783 {
784         const LayerTypeInfo *typeInfo;
785         int i;
786
787         for(i = 0; i < data->totlayer; ++i) {
788                 typeInfo = layerType_getInfo(data->layers[i].type);
789
790                 if(typeInfo->swap) {
791                         int offset = typeInfo->size * index;
792
793                         typeInfo->swap((char *)data->layers[i].data + offset, corner_indices);
794                 }
795         }
796 }
797
798 void *CustomData_get(const CustomData *data, int index, int type)
799 {
800         int offset;
801         int layer_index;
802         
803         /* get the layer index of the first layer of type */
804         layer_index = CustomData_find_next(data, type, -1);
805         if(layer_index < 0) return NULL;
806
807         /* get the offset of the desired element */
808         offset = layerType_getInfo(type)->size * index;
809
810         return (char *)data->layers[layer_index].data + offset;
811 }
812
813 void *CustomData_get_layer(const CustomData *data, int type)
814 {
815         /* get the layer index of the first layer of type */
816         int layer_index = CustomData_find_next(data, type, -1);
817
818         if(layer_index < 0) return NULL;
819
820         return data->layers[layer_index].data;
821 }
822
823 void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
824 {
825         /* get the layer index of the first layer of type */
826         int layer_index = CustomData_find_next(data, type, -1);
827
828         if(layer_index < 0) return NULL;
829
830         data->layers[layer_index].data = ptr;
831
832         return ptr;
833 }
834
835 void CustomData_set(const CustomData *data, int index, int type, void *source)
836 {
837         void *dest = CustomData_get(data, index, type);
838         const LayerTypeInfo *type_info = layerType_getInfo(type);
839
840         if(!dest) return;
841
842         if(type_info->copy)
843                 type_info->copy(source, dest, 1, type_info->size);
844         else
845                 memcpy(dest, source, type_info->size);
846 }
847
848 void CustomData_set_default(CustomData *data, int index, int count)
849 {
850         const LayerTypeInfo *typeInfo;
851         int i;
852
853         for(i = 0; i < data->totlayer; ++i) {
854                 typeInfo = layerType_getInfo(data->layers[i].type);
855
856                 if(typeInfo->set_default) {
857                         int offset = typeInfo->size * index;
858
859                         typeInfo->set_default((char *)data->layers[i].data + offset, count);
860                 }
861         }
862 }
863
864 /* EditMesh functions */
865
866 void CustomData_em_free_block(CustomData *data, void **block)
867 {
868     const LayerTypeInfo *typeInfo;
869     int i;
870
871         if(!*block) return;
872
873     for(i = 0; i < data->totlayer; ++i) {
874         if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
875             typeInfo = layerType_getInfo(data->layers[i].type);
876
877             if(typeInfo->free) {
878                                 int offset = data->layers[i].offset;
879                 typeInfo->free((char*)*block + offset, 1, typeInfo->size);
880                         }
881         }
882     }
883
884         MEM_freeN(*block);
885         *block = NULL;
886 }
887
888 static void CustomData_em_alloc_block(CustomData *data, void **block)
889 {
890         /* TODO: optimize free/alloc */
891
892         if (*block)
893                 CustomData_em_free_block(data, block);
894
895         if (data->totsize > 0)
896                 *block = MEM_callocN(data->totsize, "CustomData EM block");
897         else
898                 *block = NULL;
899 }
900
901 void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
902                             void *src_block, void **dest_block)
903 {
904         const LayerTypeInfo *type_info;
905         int dest_i, src_i;
906
907         if (!*dest_block)
908                 CustomData_em_alloc_block(dest, dest_block);
909         
910         /* copies a layer at a time */
911         dest_i = 0;
912         for(src_i = 0; src_i < source->totlayer; ++src_i) {
913                 if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
914
915                 /* find the first dest layer with type >= the source type
916                  * (this should work because layers are ordered by type)
917                  */
918                 while(dest_i < dest->totlayer
919                       && dest->layers[dest_i].type < source->layers[src_i].type)
920                         ++dest_i;
921
922                 /* if there are no more dest layers, we're done */
923                 if(dest_i >= dest->totlayer) return;
924
925                 /* if we found a matching layer, copy the data */
926                 if(dest->layers[dest_i].type == source->layers[src_i].type) {
927                         char *src_data = (char*)src_block + source->layers[src_i].offset;
928                         char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
929
930                         type_info = layerType_getInfo(source->layers[src_i].type);
931
932                         if(type_info->copy)
933                                 type_info->copy(src_data, dest_data, 1, type_info->size);
934                         else
935                                 memcpy(dest_data, src_data, type_info->size);
936
937                         /* if there are multiple source & dest layers of the same type,
938                          * we don't want to copy all source layers to the same dest, so
939                          * increment dest_i
940                          */
941                         ++dest_i;
942                 }
943         }
944 }
945
946 void *CustomData_em_get(const CustomData *data, void *block, int type)
947 {
948         int layer_index;
949         
950         /* get the layer index of the first layer of type */
951         layer_index = CustomData_find_next(data, type, -1);
952         if(layer_index < 0) return NULL;
953
954         return (char *)block + data->layers[layer_index].offset;
955 }
956
957 void CustomData_em_set(CustomData *data, void *block, int type, void *source)
958 {
959         void *dest = CustomData_em_get(data, block, type);
960         const LayerTypeInfo *type_info = layerType_getInfo(type);
961
962         if(!dest) return;
963
964         if(type_info->copy)
965                 type_info->copy(source, dest, 1, type_info->size);
966         else
967                 memcpy(dest, source, type_info->size);
968 }
969
970 void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
971                           float *sub_weights, int count, void *dest_block)
972 {
973         int i, j;
974         void *source_buf[SOURCE_BUF_SIZE];
975         void **sources = source_buf;
976
977         /* slow fallback in case we're interpolating a ridiculous number of
978          * elements
979          */
980         if(count > SOURCE_BUF_SIZE)
981                 sources = MEM_callocN(sizeof(*sources) * count,
982                                       "CustomData_interp sources");
983
984         /* interpolates a layer at a time */
985         for(i = 0; i < data->totlayer; ++i) {
986                 CustomDataLayer *layer = &data->layers[i];
987                 const LayerTypeInfo *type_info = layerType_getInfo(layer->type);
988
989                 if(type_info->interp) {
990                         for(j = 0; j < count; ++j)
991                                 sources[j] = (char *)src_blocks[j] + layer->offset;
992
993                         type_info->interp(sources, weights, sub_weights, count,
994                                           (char *)dest_block + layer->offset);
995                 }
996         }
997
998         if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
999 }
1000
1001 void CustomData_em_set_default(CustomData *data, void **block)
1002 {
1003         const LayerTypeInfo *type_info;
1004         int i;
1005
1006         if (!*block)
1007                 CustomData_em_alloc_block(data, block);
1008
1009         for(i = 0; i < data->totlayer; ++i) {
1010                 int offset = data->layers[i].offset;
1011
1012                 type_info = layerType_getInfo(data->layers[i].type);
1013
1014                 if(type_info->set_default)
1015                         type_info->set_default((char*)*block + offset, 1);
1016         }
1017 }
1018
1019 void CustomData_to_em_block(const CustomData *source, CustomData *dest,
1020                             int src_index, void **dest_block)
1021 {
1022         const LayerTypeInfo *type_info;
1023         int dest_i, src_i, src_offset;
1024
1025         if (!*dest_block)
1026                 CustomData_em_alloc_block(dest, dest_block);
1027         
1028         /* copies a layer at a time */
1029         dest_i = 0;
1030         for(src_i = 0; src_i < source->totlayer; ++src_i) {
1031                 if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
1032
1033                 /* find the first dest layer with type >= the source type
1034                  * (this should work because layers are ordered by type)
1035                  */
1036                 while(dest_i < dest->totlayer
1037                       && dest->layers[dest_i].type < source->layers[src_i].type)
1038                         ++dest_i;
1039
1040                 /* if there are no more dest layers, we're done */
1041                 if(dest_i >= dest->totlayer) return;
1042
1043                 /* if we found a matching layer, copy the data */
1044                 if(dest->layers[dest_i].type == source->layers[src_i].type) {
1045                         int offset = dest->layers[dest_i].offset;
1046                         char *src_data = source->layers[src_i].data;
1047                         char *dest_data = (char*)*dest_block + offset;
1048
1049                         type_info = layerType_getInfo(dest->layers[dest_i].type);
1050                         src_offset = src_index * type_info->size;
1051
1052                         if(type_info->copy)
1053                                 type_info->copy(src_data + src_offset, dest_data, 1,
1054                                                                 type_info->size);
1055                         else
1056                                 memcpy(dest_data, src_data + src_offset, type_info->size);
1057
1058                         /* if there are multiple source & dest layers of the same type,
1059                          * we don't want to copy all source layers to the same dest, so
1060                          * increment dest_i
1061                          */
1062                         ++dest_i;
1063                 }
1064         }
1065 }
1066
1067 void CustomData_from_em_block(const CustomData *source, CustomData *dest,
1068                               void *src_block, int dest_index)
1069 {
1070         const LayerTypeInfo *type_info;
1071         int dest_i, src_i, dest_offset;
1072
1073         /* copies a layer at a time */
1074         dest_i = 0;
1075         for(src_i = 0; src_i < source->totlayer; ++src_i) {
1076                 if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
1077
1078                 /* find the first dest layer with type >= the source type
1079                  * (this should work because layers are ordered by type)
1080                  */
1081                 while(dest_i < dest->totlayer
1082                       && dest->layers[dest_i].type < source->layers[src_i].type)
1083                         ++dest_i;
1084
1085                 /* if there are no more dest layers, we're done */
1086                 if(dest_i >= dest->totlayer) return;
1087
1088                 /* if we found a matching layer, copy the data */
1089                 if(dest->layers[dest_i].type == source->layers[src_i].type) {
1090                         int offset = source->layers[src_i].offset;
1091                         char *src_data = (char*)src_block + offset;
1092                         char *dest_data = dest->layers[dest_i].data;
1093
1094                         type_info = layerType_getInfo(dest->layers[dest_i].type);
1095                         dest_offset = dest_index * type_info->size;
1096
1097                         if(type_info->copy)
1098                                 type_info->copy(src_data, dest_data + dest_offset, 1,
1099                                                                 type_info->size);
1100                         else
1101                                 memcpy(dest_data + dest_offset, src_data, type_info->size);
1102
1103                         /* if there are multiple source & dest layers of the same type,
1104                          * we don't want to copy all source layers to the same dest, so
1105                          * increment dest_i
1106                          */
1107                         ++dest_i;
1108                 }
1109         }
1110
1111 }
1112
1113 void CustomData_file_write_info(int type, char **structname, int *structnum)
1114 {
1115         const LayerTypeInfo *type_info = layerType_getInfo(type);
1116
1117         *structname = type_info->structname;
1118         *structnum = type_info->structnum;
1119 }
1120
1121 int CustomData_sizeof(int type)
1122 {
1123         const LayerTypeInfo *type_info = layerType_getInfo(type);
1124
1125         return type_info->size;
1126 }
1127
1128 const char *CustomData_layertype_name(int type)
1129 {
1130         return layerType_getName(type);
1131 }