2
* BME_customdata.c jan 2007
4
* Custom Data functions for Bmesh
6
* $Id: BME_Customdata.c 27655 2010-03-22 09:30:00Z campbellbarton $
8
* ***** BEGIN GPL LICENSE BLOCK *****
10
* This program is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU General Public License
12
* as published by the Free Software Foundation; either version 2
13
* of the License, or (at your option) any later version. The Blender
14
* Foundation also sells licenses for use in proprietary software under
15
* the Blender License. See http://www.blender.org/BL/ for information
18
* This program is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU General Public License for more details.
23
* You should have received a copy of the GNU General Public License
24
* along with this program; if not, write to the Free Software Foundation,
25
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27
* The Original Code is Copyright (C) 2004 Blender Foundation.
28
* All rights reserved.
30
* The Original Code is: all of this file.
32
* Contributor(s): Geoffrey Bantle, Brecht Van Lommel, Ben Batt
34
* ***** END GPL LICENSE BLOCK *****
39
#include "BKE_bmeshCustomData.h"
40
#include "bmesh_private.h"
41
#include "MEM_guardedalloc.h"
43
/********************* Layer type information **********************/
44
typedef struct BME_LayerTypeInfo {
47
void (*copy)(const void *source, void *dest, int count);
48
void (*free)(void *data, int count, int size);
49
void (*interp)(void **sources, float *weights, float *sub_weights, int count, void *dest);
50
void (*set_default)(void *data, int count);
52
const BME_LayerTypeInfo BMELAYERTYPEINFO[BME_CD_NUMTYPES] = {
53
{sizeof(BME_facetex), "TexFace", NULL, NULL, NULL, NULL},
54
{sizeof(BME_looptex), "UV", NULL, NULL, NULL, NULL},
55
{sizeof(BME_loopcol), "VCol", NULL, NULL, NULL, NULL},
56
{sizeof(BME_DeformVert), "Group", NULL, NULL, NULL, NULL}
58
static const BME_LayerTypeInfo *BME_layerType_getInfo(int type)
60
if(type < 0 || type >= CD_NUMTYPES) return NULL;
62
return &BMELAYERTYPEINFO[type];
64
void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc)
67
const BME_LayerTypeInfo *info;
69
/*initialize data members*/
75
/*first count how many layers to alloc*/
76
for(i=0; i < BME_CD_NUMTYPES; i++){
77
info = BME_layerType_getInfo(i);
78
data->totlayer += init->layout[i];
79
data->totsize += (init->layout[i] * info->size);
84
data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
85
data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc, 0);
86
/*initialize layer data*/
87
for(i=0; i < BME_CD_NUMTYPES; i++){
89
info = BME_layerType_getInfo(i);
90
for(j=0; j < init->layout[i]; j++){
91
if(j==0) data->layers[j+i].active = init->active[i];
92
data->layers[j+i].type = i;
93
data->layers[j+i].offset = offset;
94
strcpy(data->layers[j+i].name, &(init->nametemplate[j+i]));
102
void BME_CD_Free(BME_CustomData *data)
104
if(data->pool) BLI_mempool_destroy(data->pool);
108
void BME_CD_free_block(BME_CustomData *data, void **block)
110
const BME_LayerTypeInfo *typeInfo;
114
for(i = 0; i < data->totlayer; ++i) {
115
typeInfo = BME_layerType_getInfo(data->layers[i].type);
117
int offset = data->layers[i].offset;
118
typeInfo->free((char*)*block + offset, 1, typeInfo->size);
121
BLI_mempool_free(data->pool, *block);
126
static void BME_CD_alloc_block(BME_CustomData *data, void **block)
129
if (*block) BME_CD_free_block(data, block); //if we copy layers that have their own free functions like deformverts
131
if (data->totsize > 0)
132
*block = BLI_mempool_alloc(data->pool);
137
void BME_CD_copy_data(const BME_CustomData *source, BME_CustomData *dest,
138
void *src_block, void **dest_block)
140
const BME_LayerTypeInfo *typeInfo;
143
if (!*dest_block) /*for addXXXlist functions!*/
144
BME_CD_alloc_block(dest, dest_block);
146
/* copies a layer at a time */
148
for(src_i = 0; src_i < source->totlayer; ++src_i) {
150
/* find the first dest layer with type >= the source type
151
* (this should work because layers are ordered by type)
153
while(dest_i < dest->totlayer
154
&& dest->layers[dest_i].type < source->layers[src_i].type)
157
/* if there are no more dest layers, we're done */
158
if(dest_i >= dest->totlayer) return;
160
/* if we found a matching layer, copy the data */
161
if(dest->layers[dest_i].type == source->layers[src_i].type &&
162
strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
163
char *src_data = (char*)src_block + source->layers[src_i].offset;
164
char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
166
typeInfo = BME_layerType_getInfo(source->layers[src_i].type);
169
typeInfo->copy(src_data, dest_data, 1);
171
memcpy(dest_data, src_data, typeInfo->size);
173
/* if there are multiple source & dest layers of the same type,
174
* we don't want to copy all source layers to the same dest, so
181
void BME_CD_set_default(BME_CustomData *data, void **block)
183
const BME_LayerTypeInfo *typeInfo;
187
BME_CD_alloc_block(data, block); //for addXXXlist functions...
189
for(i = 0; i < data->totlayer; ++i) {
190
int offset = data->layers[i].offset;
192
typeInfo = BME_layerType_getInfo(data->layers[i].type);
194
if(typeInfo->set_default)
195
typeInfo->set_default((char*)*block + offset, 1);