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