Blender V2.61 - r43446
|
00001 /* 00002 * BME_customdata.c jan 2007 00003 * 00004 * Custom Data functions for Bmesh 00005 * 00006 * 00007 * ***** BEGIN GPL LICENSE BLOCK ***** 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License 00011 * as published by the Free Software Foundation; either version 2 00012 * of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software Foundation, 00021 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00022 * 00023 * The Original Code is Copyright (C) 2004 Blender Foundation. 00024 * All rights reserved. 00025 * 00026 * The Original Code is: all of this file. 00027 * 00028 * Contributor(s): Geoffrey Bantle, Brecht Van Lommel, Ben Batt 00029 * 00030 * ***** END GPL LICENSE BLOCK ***** 00031 */ 00032 00038 #include <string.h> 00039 00040 #include "MEM_guardedalloc.h" 00041 #include "BKE_bmeshCustomData.h" 00042 #include "bmesh_private.h" 00043 00044 /********************* Layer type information **********************/ 00045 typedef struct BME_LayerTypeInfo { 00046 int size; 00047 const char *defaultname; 00048 void (*copy)(const void *source, void *dest, int count); 00049 void (*free)(void *data, int count, int size); 00050 void (*interp)(void **sources, float *weights, float *sub_weights, int count, void *dest); 00051 void (*set_default)(void *data, int count); 00052 } BME_LayerTypeInfo; 00053 const BME_LayerTypeInfo BMELAYERTYPEINFO[BME_CD_NUMTYPES] = { 00054 {sizeof(BME_facetex), "TexFace", NULL, NULL, NULL, NULL}, 00055 {sizeof(BME_looptex), "UV", NULL, NULL, NULL, NULL}, 00056 {sizeof(BME_loopcol), "VCol", NULL, NULL, NULL, NULL}, 00057 {sizeof(BME_DeformVert), "Group", NULL, NULL, NULL, NULL} 00058 }; 00059 static const BME_LayerTypeInfo *BME_layerType_getInfo(int type) 00060 { 00061 if(type < 0 || type >= CD_NUMTYPES) return NULL; 00062 00063 return &BMELAYERTYPEINFO[type]; 00064 } 00065 void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc) 00066 { 00067 int i, j, offset=0; 00068 const BME_LayerTypeInfo *info; 00069 00070 /*initialize data members*/ 00071 data->layers = NULL; 00072 data->pool = NULL; 00073 data->totlayer = 0; 00074 data->totsize = 0; 00075 00076 /*first count how many layers to alloc*/ 00077 for(i=0; i < BME_CD_NUMTYPES; i++){ 00078 info = BME_layerType_getInfo(i); 00079 data->totlayer += init->layout[i]; 00080 data->totsize += (init->layout[i] * info->size); 00081 } 00082 /*alloc our layers*/ 00083 if(data->totlayer){ 00084 /*alloc memory*/ 00085 data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers"); 00086 data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc, FALSE, FALSE); 00087 /*initialize layer data*/ 00088 for(i=0; i < BME_CD_NUMTYPES; i++){ 00089 if(init->layout[i]){ 00090 info = BME_layerType_getInfo(i); 00091 for(j=0; j < init->layout[i]; j++){ 00092 if(j==0) data->layers[j+i].active = init->active[i]; 00093 data->layers[j+i].type = i; 00094 data->layers[j+i].offset = offset; 00095 strcpy(data->layers[j+i].name, &(init->nametemplate[j+i])); 00096 offset += info->size; 00097 } 00098 } 00099 } 00100 } 00101 } 00102 00103 void BME_CD_Free(BME_CustomData *data) 00104 { 00105 if(data->pool) BLI_mempool_destroy(data->pool); 00106 } 00107 00108 /*Block level ops*/ 00109 void BME_CD_free_block(BME_CustomData *data, void **block) 00110 { 00111 const BME_LayerTypeInfo *typeInfo; 00112 int i; 00113 00114 if(!*block) return; 00115 for(i = 0; i < data->totlayer; ++i) { 00116 typeInfo = BME_layerType_getInfo(data->layers[i].type); 00117 if(typeInfo->free) { 00118 int offset = data->layers[i].offset; 00119 typeInfo->free((char*)*block + offset, 1, typeInfo->size); 00120 } 00121 } 00122 BLI_mempool_free(data->pool, *block); 00123 *block = NULL; 00124 } 00125 00126 00127 static void BME_CD_alloc_block(BME_CustomData *data, void **block) 00128 { 00129 00130 if (*block) BME_CD_free_block(data, block); //if we copy layers that have their own free functions like deformverts 00131 00132 if (data->totsize > 0) 00133 *block = BLI_mempool_alloc(data->pool); 00134 else 00135 *block = NULL; 00136 } 00137 00138 void BME_CD_copy_data(const BME_CustomData *source, BME_CustomData *dest, 00139 void *src_block, void **dest_block) 00140 { 00141 const BME_LayerTypeInfo *typeInfo; 00142 int dest_i, src_i; 00143 00144 if (!*dest_block) /*for addXXXlist functions!*/ 00145 BME_CD_alloc_block(dest, dest_block); 00146 00147 /* copies a layer at a time */ 00148 dest_i = 0; 00149 for(src_i = 0; src_i < source->totlayer; ++src_i) { 00150 00151 /* find the first dest layer with type >= the source type 00152 * (this should work because layers are ordered by type) 00153 */ 00154 while(dest_i < dest->totlayer 00155 && dest->layers[dest_i].type < source->layers[src_i].type) 00156 ++dest_i; 00157 00158 /* if there are no more dest layers, we're done */ 00159 if(dest_i >= dest->totlayer) return; 00160 00161 /* if we found a matching layer, copy the data */ 00162 if(dest->layers[dest_i].type == source->layers[src_i].type && 00163 strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) { 00164 char *src_data = (char*)src_block + source->layers[src_i].offset; 00165 char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset; 00166 00167 typeInfo = BME_layerType_getInfo(source->layers[src_i].type); 00168 00169 if(typeInfo->copy) 00170 typeInfo->copy(src_data, dest_data, 1); 00171 else 00172 memcpy(dest_data, src_data, typeInfo->size); 00173 00174 /* if there are multiple source & dest layers of the same type, 00175 * we don't want to copy all source layers to the same dest, so 00176 * increment dest_i 00177 */ 00178 ++dest_i; 00179 } 00180 } 00181 } 00182 void BME_CD_set_default(BME_CustomData *data, void **block) 00183 { 00184 const BME_LayerTypeInfo *typeInfo; 00185 int i; 00186 00187 if (!*block) 00188 BME_CD_alloc_block(data, block); //for addXXXlist functions... 00189 00190 for(i = 0; i < data->totlayer; ++i) { 00191 int offset = data->layers[i].offset; 00192 00193 typeInfo = BME_layerType_getInfo(data->layers[i].type); 00194 00195 if(typeInfo->set_default) 00196 typeInfo->set_default((char*)*block + offset, 1); 00197 } 00198 }