From 337d397d09c8b130f85e0fbd43afb467dd6c5593 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Dec 2011 09:11:11 +0000 Subject: merge in customdata changes from BMesh - biggest change is caching the layer index values in a typemap. --- source/blender/blenkernel/BKE_customdata.h | 22 +++- source/blender/blenkernel/intern/customdata.c | 143 ++++++++++++++++++++++--- source/blender/blenloader/intern/readfile.c | 3 + source/blender/makesdna/DNA_customdata_types.h | 3 + 4 files changed, 157 insertions(+), 14 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index a4cef2d6862..1af2f014ef4 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -75,6 +75,9 @@ extern const CustomDataMask CD_MASK_FACECORNERS; void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem); +/* BMESH_TODO, not really a public function but readfile.c needs it */ +void CustomData_update_typemap(struct CustomData *data); + /* same as the above, except that this will preserve existing layers, and only * add the layers that were not there yet */ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, @@ -128,6 +131,7 @@ int CustomData_number_of_layers(const struct CustomData *data, int type); void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem); void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, const int type, const char *name, const int totelem); +int CustomData_is_referenced_layer(struct CustomData *data, int type); /* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is * zero for the layer type, so only layer types specified by the mask @@ -144,12 +148,13 @@ void CustomData_set_only_copy(const struct CustomData *data, void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count); +void CustomData_copy_elements(int type, void *source, void *dest, int count); void CustomData_em_copy_data(const struct CustomData *source, struct CustomData *dest, void *src_block, void **dest_block); void CustomData_bmesh_copy_data(const struct CustomData *source, - struct CustomData *dest,void *src_block, - void **dest_block); + struct CustomData *dest, void *src_block, + void **dest_block); void CustomData_em_validate_data(struct CustomData *data, void *block, int sub_elements); /* frees data in a CustomData object @@ -191,11 +196,18 @@ void CustomData_swap(struct CustomData *data, int index, const int *corner_indic * returns NULL if there is no layer of type */ void *CustomData_get(const struct CustomData *data, int index, int type); +void *CustomData_get_n(const struct CustomData *data, int type, int index, int n); void *CustomData_em_get(const struct CustomData *data, void *block, int type); void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n); void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type); void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n); +/* gets the layer at physical index n, with no type checking. + */ +void *CustomData_bmesh_get_layer_n(const struct CustomData *data, void *block, int n); + +int CustomData_set_layer_name(const struct CustomData *data, int type, int n, const char *name); + /* gets a pointer to the active or first layer of type * returns NULL if there is no layer of type */ @@ -205,6 +217,7 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name); int CustomData_get_layer_index(const struct CustomData *data, int type); +int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); int CustomData_get_render_layer_index(const struct CustomData *data, int type); @@ -231,6 +244,11 @@ void CustomData_bmesh_set(const struct CustomData *data, void *block, int type, void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n, void *source); +/*sets the data of the block at physical layer n. no real type checking + *is performed. + */ +void CustomData_bmesh_set_layer_n(struct CustomData *data, void *block, int n, + void *source); /* set the pointer of to the first layer of type. the old data is not freed. * returns the value of ptr if the layer is found, NULL otherwise diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 289faaa0095..0363ba459a7 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -917,6 +917,25 @@ static void customData_update_offsets(CustomData *data); static CustomDataLayer *customData_add_layer__internal(CustomData *data, int type, int alloctype, void *layerdata, int totelem, const char *name); +void CustomData_update_typemap(CustomData *data) +{ + int i, lasttype = -1; + + /* since we cant do in a pre-processor do here as an assert */ + BLI_assert(sizeof(data->typemap) / sizeof(int) >= CD_NUMTYPES); + + for (i=0; itypemap[i] = -1; + } + + for (i=0; itotlayer; i++) { + if (data->layers[i].type != lasttype) { + data->typemap[data->layers[i].type] = i; + } + lasttype = data->layers[i].type; + } +} + void CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { @@ -961,6 +980,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY); } } + + CustomData_update_typemap(dest); } void CustomData_copy(const struct CustomData *source, struct CustomData *dest, @@ -1025,6 +1046,7 @@ static void customData_update_offsets(CustomData *data) } data->totsize = offset; + CustomData_update_typemap(data); } int CustomData_get_layer_index(const CustomData *data, int type) @@ -1038,6 +1060,17 @@ int CustomData_get_layer_index(const CustomData *data, int type) return -1; } +int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n) +{ + int i = CustomData_get_layer_index(data, type); + + if (i != -1) { + i = (data->layers[i + n].type == type) ? (i + n) : (-1); + } + + return i; +} + int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name) { int i; @@ -1051,11 +1084,12 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha int CustomData_get_active_layer_index(const CustomData *data, int type) { - int i; + if (!data->totlayer) + return -1; - for(i=0; i < data->totlayer; ++i) - if(data->layers[i].type == type) - return i + data->layers[i].active; + if (data->typemap[type] != -1) { + return data->typemap[type] + data->layers[data->typemap[type]].active; + } return -1; } @@ -1284,6 +1318,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, data->layers[index].type = type; data->layers[index].flag = flag; data->layers[index].data = newlayerdata; + if(name || (name=typeInfo->defaultname)) { BLI_strncpy(data->layers[index].name, name, 32); CustomData_set_layer_unique_name(data, index); @@ -1316,6 +1351,7 @@ void *CustomData_add_layer(CustomData *data, int type, int alloctype, layer = customData_add_layer__internal(data, type, alloctype, layerdata, totelem, typeInfo->defaultname); + CustomData_update_typemap(data); if(layer) return layer->data; @@ -1331,6 +1367,7 @@ void *CustomData_add_layer_named(CustomData *data, int type, int alloctype, layer = customData_add_layer__internal(data, type, alloctype, layerdata, totelem, name); + CustomData_update_typemap(data); if(layer) return layer->data; @@ -1369,6 +1406,7 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) customData_resize(data, -CUSTOMDATA_GROW); customData_update_offsets(data); + CustomData_update_typemap(data); return 1; } @@ -1469,6 +1507,20 @@ void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, return layer->data; } +int CustomData_is_referenced_layer(struct CustomData *data, int type) +{ + CustomDataLayer *layer; + int layer_index; + + /* get the layer index of the first layer of type */ + layer_index = CustomData_get_active_layer_index(data, type); + if(layer_index < 0) return 0; + + layer = &data->layers[layer_index]; + + return (layer->flag & CD_FLAG_NOFREE) != 0; +} + void CustomData_free_temporary(CustomData *data, int totelem) { CustomDataLayer *layer; @@ -1495,7 +1547,7 @@ void CustomData_free_temporary(CustomData *data, int totelem) } void CustomData_set_only_copy(const struct CustomData *data, - CustomDataMask mask) + CustomDataMask mask) { int i; @@ -1504,6 +1556,16 @@ void CustomData_set_only_copy(const struct CustomData *data, data->layers[i].flag |= CD_FLAG_NOCOPY; } +void CustomData_copy_elements(int type, void *source, void *dest, int count) +{ + const LayerTypeInfo *typeInfo = layerType_getInfo(type); + + if (typeInfo->copy) + typeInfo->copy(source, dest, count); + else + memcpy(dest, source, typeInfo->size*count); +} + void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count) { @@ -1535,7 +1597,14 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest, src_offset = source_index * typeInfo->size; dest_offset = dest_index * typeInfo->size; - + + if (!src_data || !dest_data) { + printf("%s: warning null data for %s type (%p --> %p), skipping\n", + __func__, layerType_getName(source->layers[src_i].type), + (void *)src_data, (void *)dest_data); + continue; + } + if(typeInfo->copy) typeInfo->copy(src_data + src_offset, dest_data + dest_offset, @@ -1663,6 +1732,19 @@ void *CustomData_get(const CustomData *data, int index, int type) return (char *)data->layers[layer_index].data + offset; } +void *CustomData_get_n(const CustomData *data, int type, int index, int n) +{ + int layer_index; + int offset; + + /* get the layer index of the first layer of type */ + layer_index = data->typemap[type]; + if(layer_index < 0) return NULL; + + offset = layerType_getInfo(type)->size * index; + return (char *)data->layers[layer_index+n].data + offset; +} + void *CustomData_get_layer(const CustomData *data, int type) { /* get the layer index of the active layer of type */ @@ -1675,10 +1757,10 @@ void *CustomData_get_layer(const CustomData *data, int type) void *CustomData_get_layer_n(const CustomData *data, int type, int n) { /* get the layer index of the active layer of type */ - int layer_index = CustomData_get_layer_index(data, type); + int layer_index = CustomData_get_layer_index_n(data, type, n); if(layer_index < 0) return NULL; - return data->layers[layer_index+n].data; + return data->layers[layer_index].data; } void *CustomData_get_layer_named(const struct CustomData *data, int type, @@ -1690,6 +1772,20 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type, return data->layers[layer_index].data; } + +int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name) +{ + /* get the layer index of the first layer of type */ + int layer_index = CustomData_get_layer_index_n(data, type, n); + + if(layer_index < 0) return 0; + if (!name) return 0; + + strcpy(data->layers[layer_index].name, name); + + return 1; +} + void *CustomData_set_layer(const CustomData *data, int type, void *ptr) { /* get the layer index of the first layer of type */ @@ -1705,10 +1801,10 @@ void *CustomData_set_layer(const CustomData *data, int type, void *ptr) void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, void *ptr) { /* get the layer index of the first layer of type */ - int layer_index = CustomData_get_layer_index(data, type); + int layer_index = CustomData_get_layer_index_n(data, type, n); if(layer_index < 0) return NULL; - data->layers[layer_index+n].data = ptr; + data->layers[layer_index].data = ptr; return ptr; } @@ -1836,10 +1932,10 @@ void *CustomData_em_get_n(const CustomData *data, void *block, int type, int n) int layer_index; /* get the layer index of the first layer of type */ - layer_index = CustomData_get_layer_index(data, type); + layer_index = CustomData_get_layer_index_n(data, type, n); if(layer_index < 0) return NULL; - return (char *)block + data->layers[layer_index+n].offset; + return (char *)block + data->layers[layer_index].offset; } void CustomData_em_set(CustomData *data, void *block, int type, void *source) @@ -2141,6 +2237,15 @@ void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int return (char *)block + data->layers[layer_index+n].offset; } +/*gets from the layer at physical index n, note: doesn't check type.*/ +void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n) +{ + if(n < 0 || n >= data->totlayer) return NULL; + + return (char *)block + data->layers[n].offset; +} + + void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source) { void *dest = CustomData_bmesh_get(data, block, type); @@ -2167,6 +2272,19 @@ void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void memcpy(dest, source, typeInfo->size); } +void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source) +{ + void *dest = CustomData_bmesh_get_layer_n(data, block, n); + const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type); + + if(!dest) return; + + if(typeInfo->copy) + typeInfo->copy(source, dest, 1); + else + memcpy(dest, source, typeInfo->size); +} + void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights, float *sub_weights, int count, void *dest_block) { @@ -2212,6 +2330,7 @@ void CustomData_bmesh_set_default(CustomData *data, void **block) if(typeInfo->set_default) typeInfo->set_default((char*)*block + offset, 1); + else memset((char*)*block + offset, 0, typeInfo->size); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2f3d14da4c2..bdd9ba65ac5 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3680,6 +3680,7 @@ static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps, int exte } } +/*this isn't really a public api function, so prototyped here*/ static void direct_link_customdata(FileData *fd, CustomData *data, int count) { int i = 0; @@ -3700,6 +3701,8 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count) i++; } } + + CustomData_update_typemap(data); } static void direct_link_mesh(FileData *fd, Mesh *mesh) diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 128bd6b6653..a3b735f0fe1 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -59,6 +59,9 @@ typedef struct CustomDataExternal { * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */ typedef struct CustomData { CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ + int typemap[32]; /* runtime only! - maps types to indices of first layer of that type, + * MUST be >= CD_NUMTYPES, but we cant use a define here. + * Correct size is ensured in CustomData_update_typemap assert() */ int totlayer, maxlayer; /* number of layers, size of layers array */ int totsize, pad; /* in editmode, total size of all data layers */ void *pool; /* Bmesh: Memory pool for allocation of blocks */ -- cgit v1.2.3