Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2006-11-20 07:28:02 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2006-11-20 07:28:02 +0300
commite435fbc3c5a00e5b63c1cd2609ab6828187660d3 (patch)
tree3f1da9c51451dee55a203cd001d37f8774d2582f /source/blender/blenkernel/intern/customdata.c
parent0a7c43c6e5fc7d5d75a4645eca1164cede2d03a6 (diff)
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
Diffstat (limited to 'source/blender/blenkernel/intern/customdata.c')
-rw-r--r--source/blender/blenkernel/intern/customdata.c593
1 files changed, 397 insertions, 196 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index c626c79bdcc..21b77f671e4 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -37,7 +37,7 @@
#include "BLI_linklist.h"
#include "DNA_customdata_types.h"
-#include "DNA_mesh_types.h"
+#include "DNA_listbase.h"
#include "DNA_meshdata_types.h"
#include "MEM_guardedalloc.h"
@@ -49,7 +49,9 @@
/********************* Layer type information **********************/
typedef struct LayerTypeInfo {
- int size; /* the memory size of one element of this layer's data */
+ int size; /* the memory size of one element of this layer's data */
+ char *structname; /* name of the struct used, for file writing */
+ int structnum; /* number of structs per element, for file writing */
/* a function to copy count elements of this layer's data
* (deep copy if appropriate)
@@ -78,9 +80,12 @@ typedef struct LayerTypeInfo {
void (*interp)(void **sources, float *weights, float *sub_weights,
int count, void *dest);
+ /* a function to swap the data in corners of the element */
+ void (*swap)(void *data, int *corner_indices);
+
/* a function to set a layer's data to default values. if NULL, the
default is assumed to be all zeros */
- void (*set_default)(void *data);
+ void (*set_default)(void *data, int count);
} LayerTypeInfo;
static void layerCopy_mdeformvert(const void *source, void *dest,
@@ -110,6 +115,7 @@ static void layerFree_mdeformvert(void *data, int count, int size)
if(dvert->dw) {
MEM_freeN(dvert->dw);
dvert->dw = NULL;
+ dvert->totweight = 0;
}
}
}
@@ -176,10 +182,33 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
BLI_linklist_free(dest_dw, linklist_free_simple);
}
+
+static void layerInterp_msticky(void **sources, float *weights,
+ float *sub_weights, int count, void *dest)
+{
+ float co[2], w;
+ MSticky *mst;
+ int i;
+
+ co[0] = co[1] = 0.0f;
+ for(i = 0; i < count; i++) {
+ w = weights ? weights[i] : 1.0f;
+ mst = (MSticky*)sources[i];
+
+ co[0] += w*mst->co[0];
+ co[1] += w*mst->co[1];
+ }
+
+ mst = (MSticky*)dest;
+ mst->co[0] = co[0];
+ mst->co[1] = co[1];
+}
+
+
static void layerCopy_tface(const void *source, void *dest, int count, int size)
{
- const TFace *source_tf = (const TFace*)source;
- TFace *dest_tf = (TFace*)dest;
+ const MTFace *source_tf = (const MTFace*)source;
+ MTFace *dest_tf = (MTFace*)dest;
int i;
for(i = 0; i < count; ++i) {
@@ -191,70 +220,66 @@ static void layerCopy_tface(const void *source, void *dest, int count, int size)
static void layerInterp_tface(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
- TFace *tf = dest;
+ MTFace *tf = dest;
int i, j, k;
float uv[4][2];
- float col[4][4];
float *sub_weight;
if(count <= 0) return;
memset(uv, 0, sizeof(uv));
- memset(col, 0, sizeof(col));
sub_weight = sub_weights;
for(i = 0; i < count; ++i) {
float weight = weights ? weights[i] : 1;
- TFace *src = sources[i];
+ MTFace *src = sources[i];
for(j = 0; j < 4; ++j) {
if(sub_weights) {
for(k = 0; k < 4; ++k, ++sub_weight) {
float w = (*sub_weight) * weight;
- char *tmp_col = (char *)&src->col[k];
float *tmp_uv = src->uv[k];
uv[j][0] += tmp_uv[0] * w;
uv[j][1] += tmp_uv[1] * w;
-
- col[j][0] += tmp_col[0] * w;
- col[j][1] += tmp_col[1] * w;
- col[j][2] += tmp_col[2] * w;
- col[j][3] += tmp_col[3] * w;
}
} else {
- char *tmp_col = (char *)&src->col[j];
uv[j][0] += src->uv[j][0] * weight;
uv[j][1] += src->uv[j][1] * weight;
-
- col[j][0] += tmp_col[0] * weight;
- col[j][1] += tmp_col[1] * weight;
- col[j][2] += tmp_col[2] * weight;
- col[j][3] += tmp_col[3] * weight;
}
}
}
- *tf = *(TFace *)sources[0];
+ *tf = *(MTFace *)sources[0];
for(j = 0; j < 4; ++j) {
- char *tmp_col = (char *)&tf->col[j];
-
tf->uv[j][0] = uv[j][0];
tf->uv[j][1] = uv[j][1];
+ }
+}
+
+static void layerSwap_tface(void *data, int *corner_indices)
+{
+ MTFace *tf = data;
+ float uv[4][2];
+ int j;
- tmp_col[0] = (int)col[j][0];
- tmp_col[1] = (int)col[j][1];
- tmp_col[2] = (int)col[j][2];
- tmp_col[3] = (int)col[j][3];
+ for(j = 0; j < 4; ++j) {
+ uv[j][0] = tf->uv[corner_indices[j]][0];
+ uv[j][1] = tf->uv[corner_indices[j]][1];
}
+
+ memcpy(tf->uv, uv, sizeof(tf->uv));
}
-static void layerDefault_tface(void *data)
+static void layerDefault_tface(void *data, int count)
{
- static TFace default_tf = {NULL, {{0, 1}, {0, 0}, {1, 0}, {1, 1}},
- {~0, ~0, ~0, ~0}, TF_SELECT, 0, TF_DYNAMIC, 0, 0};
+ static MTFace default_tf = {{{0, 1}, {0, 0}, {1, 0}, {1, 1}}, NULL,
+ TF_SELECT, 0, TF_DYNAMIC, 0, 0};
+ MTFace *tf = (MTFace*)data;
+ int i;
- *((TFace*)data) = default_tf;
+ for(i = 0; i < count; i++)
+ tf[i] = default_tf;
}
static void layerInterp_mcol(void **sources, float *weights,
@@ -305,111 +330,164 @@ static void layerInterp_mcol(void **sources, float *weights,
}
}
-static void layerDefault_mcol(void *data)
+static void layerSwap_mcol(void *data, int *corner_indices)
+{
+ MCol *mcol = data;
+ MCol col[4];
+ int j;
+
+ for(j = 0; j < 4; ++j)
+ col[j] = mcol[corner_indices[j]];
+
+ memcpy(mcol, col, sizeof(col));
+}
+
+static void layerDefault_mcol(void *data, int count)
{
static MCol default_mcol = {255, 255, 255, 255};
MCol *mcol = (MCol*)data;
+ int i;
+
+ for(i = 0; i < 4*count; i++)
+ mcol[i] = default_mcol;
+}
- mcol[0]= default_mcol;
- mcol[1]= default_mcol;
- mcol[2]= default_mcol;
- mcol[3]= default_mcol;
-}
-
-const LayerTypeInfo LAYERTYPEINFO[LAYERTYPE_NUMTYPES] = {
- {sizeof(MVert), NULL, NULL, NULL, NULL},
- {sizeof(MSticky), NULL, NULL, NULL, NULL},
- {sizeof(MDeformVert), layerCopy_mdeformvert,
- layerFree_mdeformvert, layerInterp_mdeformvert, NULL},
- {sizeof(MEdge), NULL, NULL, NULL, NULL},
- {sizeof(MFace), NULL, NULL, NULL, NULL},
- {sizeof(TFace), layerCopy_tface, NULL, layerInterp_tface,
- layerDefault_tface},
+const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
+ {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MSticky), "MSticky", 1, NULL, NULL, layerInterp_msticky, NULL, NULL},
+ {sizeof(MDeformVert), "MDeformVert", 1, layerCopy_mdeformvert,
+ layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL},
+ {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MTFace), "MTFace", 1, layerCopy_tface, NULL, layerInterp_tface,
+ layerSwap_tface, layerDefault_tface},
/* 4 MCol structs per face */
- {sizeof(MCol) * 4, NULL, NULL, layerInterp_mcol, layerDefault_mcol},
- {sizeof(int), NULL, NULL, NULL, NULL},
+ {sizeof(MCol)*4, "MCol", 4, NULL, NULL, layerInterp_mcol, layerSwap_mcol,
+ layerDefault_mcol},
+ {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL},
/* 3 floats per normal vector */
- {sizeof(float) * 3, NULL, NULL, NULL, NULL},
- {sizeof(int), NULL, NULL, NULL, NULL},
+ {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL},
};
+const char *LAYERTYPENAMES[CD_NUMTYPES] = {
+ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
+ "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags"};
+
+CustomDataMask CD_MASK_MESH[CD_NUMTYPES] = {
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0};
+CustomDataMask CD_MASK_EDITMESH[CD_NUMTYPES] = {
+ 0, 1, 1, 0, 0, 1, 1, 0, 0, 0};
+CustomDataMask CD_MASK_DERIVEDMESH[CD_NUMTYPES] = {
+ 0, 1, 1, 0, 0, 1, 1, 1, 0, 0};
+
static const LayerTypeInfo *layerType_getInfo(int type)
{
- if(type < 0 || type >= LAYERTYPE_NUMTYPES) return NULL;
+ if(type < 0 || type >= CD_NUMTYPES) return NULL;
return &LAYERTYPEINFO[type];
}
-/********************* CustomData functions *********************/
-void CustomData_init(CustomData *data,
- int maxLayers, int maxElems, int subElems)
+static const char *layerType_getName(int type)
{
- data->layers = MEM_callocN(maxLayers * sizeof(*data->layers),
- "CustomData->layers");
- data->numLayers = 0;
- data->maxLayers = maxLayers;
- data->numElems = maxElems;
- data->maxElems = maxElems;
- data->subElems = subElems;
+ if(type < 0 || type >= CD_NUMTYPES) return NULL;
+
+ return LAYERTYPENAMES[type];
}
+/********************* CustomData functions *********************/
static void CustomData_update_offsets(CustomData *data)
{
const LayerTypeInfo *typeInfo;
int i, offset = 0;
- for(i = 0; i < data->numLayers; ++i) {
+ for(i = 0; i < data->totlayer; ++i) {
typeInfo = layerType_getInfo(data->layers[i].type);
data->layers[i].offset = offset;
offset += typeInfo->size;
}
- data->totSize = offset;
+ data->totsize = offset;
}
-void CustomData_from_template(const CustomData *source, CustomData *dest,
- int flag, int maxElems)
+void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
+ CustomDataMask *mask, int alloctype, int totelem)
{
- int i, layerflag;
+ const LayerTypeInfo *typeInfo;
+ CustomDataLayer *layer;
+ int i, flag, type;
+ void *data;
- CustomData_init(dest, source->maxLayers, maxElems, source->subElems);
+ for(i = 0; i < source->totlayer; ++i) {
+ layer = &source->layers[i];
+ typeInfo = layerType_getInfo(layer->type);
- for(i = 0; i < source->numLayers; ++i) {
- if(source->layers[i].flag & LAYERFLAG_NOCOPY) continue;
+ if(layer->flag & CD_FLAG_NOCOPY) continue;
+ else if(mask && !mask[layer->type]) continue;
+ else if(CustomData_has_layer(dest, layer->type)) continue;
- layerflag = (source->layers[i].flag & ~LAYERFLAG_NOFREE) | flag;
- CustomData_add_layer(dest, source->layers[i].type, layerflag, NULL);
+ type = layer->type;
+ flag = layer->flag & ~CD_FLAG_NOFREE;
+ data = layer->data;
+
+ if (alloctype == CD_CALLOC) {
+ CustomData_add_layer(dest, type, flag, NULL, totelem);
+ }
+ else if (alloctype == CD_REFERENCE) {
+ CustomData_add_layer(dest, type, flag|CD_FLAG_NOFREE, data, totelem);
+ }
+ else if (alloctype == CD_DUPLICATE) {
+ CustomData_add_layer(dest, type, flag, MEM_dupallocN(data), totelem);
+ }
+ else if (alloctype == CD_DEFAULT) {
+ data = CustomData_add_layer(dest, type, flag, NULL, totelem);
+ if(typeInfo->set_default)
+ typeInfo->set_default((char*)data, totelem);
+ }
}
CustomData_update_offsets(dest);
+
}
-void CustomData_free(CustomData *data)
+void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
+ CustomDataMask *mask, int alloctype, int totelem)
+{
+ memset(dest, 0, sizeof(*dest));
+
+ CustomData_merge(source, dest, mask, alloctype, totelem);
+}
+
+static void CustomData_free_layer__internal(CustomDataLayer *layer, int totelem)
{
- int i;
const LayerTypeInfo *typeInfo;
- for(i = 0; i < data->numLayers; ++i) {
- if(!(data->layers[i].flag & LAYERFLAG_NOFREE)) {
- typeInfo = layerType_getInfo(data->layers[i].type);
- if(typeInfo->free)
- typeInfo->free(data->layers[i].data, data->numElems,
- typeInfo->size);
+ if(!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
+ typeInfo = layerType_getInfo(layer->type);
- if(data->layers[i].data)
- MEM_freeN(data->layers[i].data);
- }
+ if(typeInfo->free)
+ typeInfo->free(layer->data, totelem, typeInfo->size);
+
+ if(layer->data)
+ MEM_freeN(layer->data);
}
+}
- data->numLayers = 0;
+void CustomData_free(CustomData *data, int totelem)
+{
+ int i;
+
+ for(i = 0; i < data->totlayer; ++i)
+ CustomData_free_layer__internal(&data->layers[i], totelem);
- if(data->layers) {
+ if(data->layers)
MEM_freeN(data->layers);
- data->layers = NULL;
- }
+
+ memset(data, 0, sizeof(*data));
}
+
/* gets index of first layer matching type after start_index
* if start_index < 0, starts searching at 0
* returns -1 if there is no layer of type
@@ -421,7 +499,7 @@ static int CustomData_find_next(const CustomData *data, int type,
if(i < 0) i = 0;
- for(; i < data->numLayers; ++i)
+ for(; i < data->totlayer; ++i)
if(data->layers[i].type == type) return i;
return -1;
@@ -429,26 +507,28 @@ static int CustomData_find_next(const CustomData *data, int type,
static int customData_resize(CustomData *data, int amount)
{
- CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxLayers + amount),
+ CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxlayer + amount),
"CustomData->layers");
if(!tmp) return 0;
- data->maxLayers += amount;
- memcpy(tmp, data->layers, sizeof(*tmp) * data->numLayers);
-
- MEM_freeN(data->layers);
+ data->maxlayer += amount;
+ if (data->layers) {
+ memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer);
+ MEM_freeN(data->layers);
+ }
data->layers = tmp;
return 1;
}
-static int customData_add_layer__internal(CustomData *data, int type,
- int flag, void *layer)
+static int customData_add_layer__internal(CustomData *data, int type, int flag,
+ void *layer)
{
- int index = data->numLayers;
+ int index = data->totlayer;
- if(index >= data->maxLayers)
- if(!customData_resize(data, CUSTOMDATA_GROW)) return 0;
+ if(index >= data->maxlayer)
+ if(!customData_resize(data, CUSTOMDATA_GROW))
+ return 0;
/* keep layers ordered by type */
for( ; index > 0 && data->layers[index - 1].type > type; --index)
@@ -458,42 +538,46 @@ static int customData_add_layer__internal(CustomData *data, int type,
data->layers[index].flag = flag;
data->layers[index].data = layer;
- data->numLayers++;
+ data->totlayer++;
CustomData_update_offsets(data);
return 1;
}
-int CustomData_add_layer(CustomData *data, int type, int flag, void *layer)
+void *CustomData_add_layer(CustomData *data, int type, int flag,
+ void *layerdata, int totelem)
{
- int size = layerType_getInfo(type)->size * data->numElems;
- void *tmp_layer = layer;
+ int size = layerType_getInfo(type)->size * totelem;
+ void *tmpdata = layerdata;
- if(!layer) tmp_layer = MEM_callocN(size, "CustomDataLayer.data");
+ if(!tmpdata)
+ tmpdata = MEM_callocN(size, layerType_getName(type));
+ if(!tmpdata)
+ return NULL;
- if(!tmp_layer) return 0;
-
- if(customData_add_layer__internal(data, type, flag, tmp_layer))
- return 1;
- else {
- MEM_freeN(tmp_layer);
- return 0;
+ if(!customData_add_layer__internal(data, type, flag, tmpdata)) {
+ MEM_freeN(tmpdata);
+ return NULL;
}
+
+ return tmpdata;
}
-int CustomData_free_layer(CustomData *data, int type)
+int CustomData_free_layer(CustomData *data, int type, int totelem)
{
int index = CustomData_find_next(data, type, -1);
if (index < 0) return 0;
- for(++index; index < data->numLayers; ++index)
+ CustomData_free_layer__internal(&data->layers[index], totelem);
+
+ for(++index; index < data->totlayer; ++index)
data->layers[index - 1] = data->layers[index];
- data->numLayers--;
+ data->totlayer--;
- if(data->numLayers <= data->maxLayers-CUSTOMDATA_GROW)
+ if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
customData_resize(data, -CUSTOMDATA_GROW);
CustomData_update_offsets(data);
@@ -501,18 +585,62 @@ int CustomData_free_layer(CustomData *data, int type)
return 1;
}
-int CustomData_has_layer(const struct CustomData *data, int type)
+int CustomData_has_layer(const CustomData *data, int type)
{
return (CustomData_find_next(data, type, -1) != -1);
}
+void *CustomData_duplicate_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_find_next(data, type, -1);
+ if(layer_index < 0) return NULL;
+
+ layer = &data->layers[layer_index];
+
+ if (layer->flag & CD_FLAG_NOFREE) {
+ layer->data = MEM_dupallocN(layer->data);
+ layer->flag &= ~CD_FLAG_NOFREE;
+ }
+
+ return layer->data;
+}
+
+void CustomData_free_temporary(CustomData *data, int totelem)
+{
+ CustomDataLayer *layer;
+ int i, j;
+
+ for(i = 0, j = 0; i < data->totlayer; ++i) {
+ layer = &data->layers[i];
+
+ if (i != j)
+ data->layers[j] = data->layers[i];
+
+ if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY)
+ CustomData_free_layer__internal(layer, totelem);
+ else
+ j++;
+ }
+
+ data->totlayer = j;
+
+ if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
+ customData_resize(data, -CUSTOMDATA_GROW);
+
+ CustomData_update_offsets(data);
+}
+
int CustomData_compat(const CustomData *data1, const CustomData *data2)
{
int i;
- if(data1->numLayers != data2->numLayers) return 0;
+ if(data1->totlayer != data2->totlayer) return 0;
- for(i = 0; i < data1->numLayers; ++i) {
+ for(i = 0; i < data1->totlayer; ++i) {
if(data1->layers[i].type != data2->layers[i].type) return 0;
if(data1->layers[i].flag != data2->layers[i].flag) return 0;
}
@@ -520,34 +648,28 @@ int CustomData_compat(const CustomData *data1, const CustomData *data2)
return 1;
}
-int CustomData_copy_data(const CustomData *source, CustomData *dest,
- int source_index, int dest_index, int count)
+void CustomData_copy_data(const CustomData *source, CustomData *dest,
+ int source_index, int dest_index, int count)
{
const LayerTypeInfo *type_info;
int src_i, dest_i;
int src_offset;
int dest_offset;
- if(count < 0) return 0;
- if(source_index < 0 || (source_index + count) > source->numElems)
- return 0;
- if(dest_index < 0 || (dest_index + count) > dest->numElems)
- return 0;
-
/* copies a layer at a time */
dest_i = 0;
- for(src_i = 0; src_i < source->numLayers; ++src_i) {
- if(source->layers[src_i].flag & LAYERFLAG_NOCOPY) continue;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+ if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
- while(dest_i < dest->numLayers
+ while(dest_i < dest->totlayer
&& dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
- if(dest_i >= dest->numLayers) return 1;
+ if(dest_i >= dest->totlayer) return;
/* if we found a matching layer, copy the data */
if(dest->layers[dest_i].type == source->layers[src_i].type) {
@@ -575,19 +697,15 @@ int CustomData_copy_data(const CustomData *source, CustomData *dest,
++dest_i;
}
}
-
- return 1;
}
-int CustomData_free_elem(CustomData *data, int index, int count)
+void CustomData_free_elem(CustomData *data, int index, int count)
{
int i;
const LayerTypeInfo *typeInfo;
- if(index < 0 || count <= 0 || index + count > data->numElems) return 0;
-
- for(i = 0; i < data->numLayers; ++i) {
- if(!(data->layers[i].flag & LAYERFLAG_NOFREE)) {
+ for(i = 0; i < data->totlayer; ++i) {
+ if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
typeInfo = layerType_getInfo(data->layers[i].type);
if(typeInfo->free) {
@@ -598,15 +716,13 @@ int CustomData_free_elem(CustomData *data, int index, int count)
}
}
}
-
- return 1;
}
#define SOURCE_BUF_SIZE 100
-int CustomData_interp(const CustomData *source, CustomData *dest,
- int *src_indices, float *weights, float *sub_weights,
- int count, int dest_index)
+void CustomData_interp(const CustomData *source, CustomData *dest,
+ int *src_indices, float *weights, float *sub_weights,
+ int count, int dest_index)
{
int src_i, dest_i;
int dest_offset;
@@ -614,9 +730,6 @@ int CustomData_interp(const CustomData *source, CustomData *dest,
void *source_buf[SOURCE_BUF_SIZE];
void **sources = source_buf;
- if(count <= 0) return 0;
- if(dest_index < 0 || dest_index >= dest->numElems) return 0;
-
/* slow fallback in case we're interpolating a ridiculous number of
* elements
*/
@@ -625,7 +738,7 @@ int CustomData_interp(const CustomData *source, CustomData *dest,
"CustomData_interp sources");
/* interpolates a layer at a time */
- for(src_i = 0; src_i < source->numLayers; ++src_i) {
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
CustomDataLayer *source_layer = &source->layers[src_i];
const LayerTypeInfo *type_info =
layerType_getInfo(source_layer->type);
@@ -647,7 +760,22 @@ int CustomData_interp(const CustomData *source, CustomData *dest,
}
if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
- return 1;
+}
+
+void CustomData_swap(struct CustomData *data, int index, int *corner_indices)
+{
+ const LayerTypeInfo *typeInfo;
+ int i;
+
+ for(i = 0; i < data->totlayer; ++i) {
+ typeInfo = layerType_getInfo(data->layers[i].type);
+
+ if(typeInfo->swap) {
+ int offset = typeInfo->size * index;
+
+ typeInfo->swap((char *)data->layers[i].data + offset, corner_indices);
+ }
+ }
}
void *CustomData_get(const CustomData *data, int index, int type)
@@ -655,8 +783,6 @@ void *CustomData_get(const CustomData *data, int index, int type)
int offset;
int layer_index;
- if(index < 0 || index > data->numElems) return NULL;
-
/* get the layer index of the first layer of type */
layer_index = CustomData_find_next(data, type, -1);
if(layer_index < 0) return NULL;
@@ -677,6 +803,18 @@ void *CustomData_get_layer(const CustomData *data, int type)
return data->layers[layer_index].data;
}
+void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
+{
+ /* get the layer index of the first layer of type */
+ int layer_index = CustomData_find_next(data, type, -1);
+
+ if(layer_index < 0) return NULL;
+
+ data->layers[layer_index].data = ptr;
+
+ return ptr;
+}
+
void CustomData_set(const CustomData *data, int index, int type, void *source)
{
void *dest = CustomData_get(data, index, type);
@@ -690,11 +828,20 @@ void CustomData_set(const CustomData *data, int index, int type, void *source)
memcpy(dest, source, type_info->size);
}
-void CustomData_set_num_elems(CustomData *data, int numElems)
+void CustomData_set_default(CustomData *data, int index, int count)
{
- if(numElems < 0) return;
- if(numElems < data->maxElems) data->numElems = numElems;
- else data->numElems = data->maxElems;
+ const LayerTypeInfo *typeInfo;
+ int i;
+
+ for(i = 0; i < data->totlayer; ++i) {
+ typeInfo = layerType_getInfo(data->layers[i].type);
+
+ if(typeInfo->set_default) {
+ int offset = typeInfo->size * index;
+
+ typeInfo->set_default((char *)data->layers[i].data + offset, count);
+ }
+ }
}
/* EditMesh functions */
@@ -706,8 +853,8 @@ void CustomData_em_free_block(CustomData *data, void **block)
if(!*block) return;
- for(i = 0; i < data->numLayers; ++i) {
- if(!(data->layers[i].flag & LAYERFLAG_NOFREE)) {
+ for(i = 0; i < data->totlayer; ++i) {
+ if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
typeInfo = layerType_getInfo(data->layers[i].type);
if(typeInfo->free) {
@@ -728,13 +875,13 @@ static void CustomData_em_alloc_block(CustomData *data, void **block)
if (*block)
CustomData_em_free_block(data, block);
- if (data->totSize > 0)
- *block = MEM_callocN(data->totSize, "CustomData EM block");
+ if (data->totsize > 0)
+ *block = MEM_callocN(data->totsize, "CustomData EM block");
else
*block = NULL;
}
-int CustomData_em_copy_data(const CustomData *source, CustomData *dest,
+void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
void *src_block, void **dest_block)
{
const LayerTypeInfo *type_info;
@@ -745,18 +892,18 @@ int CustomData_em_copy_data(const CustomData *source, CustomData *dest,
/* copies a layer at a time */
dest_i = 0;
- for(src_i = 0; src_i < source->numLayers; ++src_i) {
- if(source->layers[src_i].flag & LAYERFLAG_NOCOPY) continue;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+ if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
- while(dest_i < dest->numLayers
+ while(dest_i < dest->totlayer
&& dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
- if(dest_i >= dest->numLayers) return 1;
+ if(dest_i >= dest->totlayer) return;
/* if we found a matching layer, copy the data */
if(dest->layers[dest_i].type == source->layers[src_i].type) {
@@ -777,8 +924,6 @@ int CustomData_em_copy_data(const CustomData *source, CustomData *dest,
++dest_i;
}
}
-
- return 1;
}
void *CustomData_em_get(const CustomData *data, void *block, int type)
@@ -805,15 +950,13 @@ void CustomData_em_set(CustomData *data, void *block, int type, void *source)
memcpy(dest, source, type_info->size);
}
-int CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
- float *sub_weights, int count, void *dest_block)
+void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
+ float *sub_weights, int count, void *dest_block)
{
int i, j;
void *source_buf[SOURCE_BUF_SIZE];
void **sources = source_buf;
- if(count <= 0) return 0;
-
/* slow fallback in case we're interpolating a ridiculous number of
* elements
*/
@@ -822,7 +965,7 @@ int CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
"CustomData_interp sources");
/* interpolates a layer at a time */
- for(i = 0; i < data->numLayers; ++i) {
+ for(i = 0; i < data->totlayer; ++i) {
CustomDataLayer *layer = &data->layers[i];
const LayerTypeInfo *type_info = layerType_getInfo(layer->type);
@@ -836,7 +979,6 @@ int CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
}
if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
- return 1;
}
void CustomData_em_set_default(CustomData *data, void **block)
@@ -847,13 +989,13 @@ void CustomData_em_set_default(CustomData *data, void **block)
if (!*block)
CustomData_em_alloc_block(data, block);
- for(i = 0; i < data->numLayers; ++i) {
+ for(i = 0; i < data->totlayer; ++i) {
int offset = data->layers[i].offset;
type_info = layerType_getInfo(data->layers[i].type);
if(type_info->set_default)
- type_info->set_default((char*)*block + offset);
+ type_info->set_default((char*)*block + offset, 1);
}
}
@@ -861,25 +1003,47 @@ void CustomData_to_em_block(const CustomData *source, CustomData *dest,
int src_index, void **dest_block)
{
const LayerTypeInfo *type_info;
- int i, src_offset;
+ int dest_i, src_i, src_offset;
if (!*dest_block)
CustomData_em_alloc_block(dest, dest_block);
/* copies a layer at a time */
- for(i = 0; i < dest->numLayers; ++i) {
- int offset = dest->layers[i].offset;
- char *src_data = source->layers[i].data;
- char *dest_data = (char*)*dest_block + offset;
+ dest_i = 0;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+ if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
+
+ /* find the first dest layer with type >= the source type
+ * (this should work because layers are ordered by type)
+ */
+ while(dest_i < dest->totlayer
+ && dest->layers[dest_i].type < source->layers[src_i].type)
+ ++dest_i;
- type_info = layerType_getInfo(dest->layers[i].type);
- src_offset = src_index * type_info->size;
+ /* if there are no more dest layers, we're done */
+ if(dest_i >= dest->totlayer) return;
- if(type_info->copy)
- type_info->copy(src_data + src_offset, dest_data, 1,
- type_info->size);
- else
- memcpy(dest_data, src_data + src_offset, type_info->size);
+ /* if we found a matching layer, copy the data */
+ if(dest->layers[dest_i].type == source->layers[src_i].type) {
+ int offset = dest->layers[dest_i].offset;
+ char *src_data = source->layers[src_i].data;
+ char *dest_data = (char*)*dest_block + offset;
+
+ type_info = layerType_getInfo(dest->layers[dest_i].type);
+ src_offset = src_index * type_info->size;
+
+ if(type_info->copy)
+ type_info->copy(src_data + src_offset, dest_data, 1,
+ type_info->size);
+ else
+ memcpy(dest_data, src_data + src_offset, type_info->size);
+
+ /* if there are multiple source & dest layers of the same type,
+ * we don't want to copy all source layers to the same dest, so
+ * increment dest_i
+ */
+ ++dest_i;
+ }
}
}
@@ -887,22 +1051,59 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
void *src_block, int dest_index)
{
const LayerTypeInfo *type_info;
- int i, dest_offset;
+ int dest_i, src_i, dest_offset;
/* copies a layer at a time */
- for(i = 0; i < dest->numLayers; ++i) {
- int offset = source->layers[i].offset;
- char *src_data = (char*)src_block + offset;
- char *dest_data = dest->layers[i].data;
+ dest_i = 0;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+ if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
+
+ /* find the first dest layer with type >= the source type
+ * (this should work because layers are ordered by type)
+ */
+ while(dest_i < dest->totlayer
+ && dest->layers[dest_i].type < source->layers[src_i].type)
+ ++dest_i;
- type_info = layerType_getInfo(dest->layers[i].type);
- dest_offset = dest_index * type_info->size;
+ /* if there are no more dest layers, we're done */
+ if(dest_i >= dest->totlayer) return;
- if(type_info->copy)
- type_info->copy(src_data, dest_data + dest_offset, 1,
- type_info->size);
- else
- memcpy(dest_data + dest_offset, src_data, type_info->size);
+ /* if we found a matching layer, copy the data */
+ if(dest->layers[dest_i].type == source->layers[src_i].type) {
+ int offset = source->layers[src_i].offset;
+ char *src_data = (char*)src_block + offset;
+ char *dest_data = dest->layers[dest_i].data;
+
+ type_info = layerType_getInfo(dest->layers[dest_i].type);
+ dest_offset = dest_index * type_info->size;
+
+ if(type_info->copy)
+ type_info->copy(src_data, dest_data + dest_offset, 1,
+ type_info->size);
+ else
+ memcpy(dest_data + dest_offset, src_data, type_info->size);
+
+ /* if there are multiple source & dest layers of the same type,
+ * we don't want to copy all source layers to the same dest, so
+ * increment dest_i
+ */
+ ++dest_i;
+ }
}
+
}
+void CustomData_file_write_info(int type, char **structname, int *structnum)
+{
+ const LayerTypeInfo *type_info = layerType_getInfo(type);
+
+ *structname = type_info->structname;
+ *structnum = type_info->structnum;
+}
+
+int CustomData_sizeof(int type)
+{
+ const LayerTypeInfo *type_info = layerType_getInfo(type);
+
+ return type_info->size;
+}