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-11 19:38:37 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2006-11-11 19:38:37 +0300
commit97f892b86b9b31e8165c27c698da7996dfd2d0a2 (patch)
tree41a2de3709265c3e871c29aa02d1aacf36e21dac /source/blender/blenkernel
parent9e717b59cb4feb16314f0b2c026ebfd9278862a5 (diff)
Added custom face data support in edit mode. The code used to do this is
the CustomData module from the modifier stack rewrite, but with additions to make it also usable in edit mode. Some of the datatypes from that module were move to a DNA header file, they are not saved to file now, but will be soon. The only code that wasn't abstracted is the uv collapse / merging code. It is rather complicated, will look into that in the future. There should be no user level changes.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_customdata.h93
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c36
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c30
-rw-r--r--source/blender/blenkernel/intern/customdata.c403
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c1
6 files changed, 405 insertions, 160 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index d09cb458ba4..4506f5740fb 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -45,7 +45,7 @@
* conversion to DLM.
*/
-#include "BKE_customdata.h"
+#include "DNA_customdata_types.h"
struct MVert;
struct MEdge;
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 6f8d9911d89..9733c26ade2 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -27,39 +27,12 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/* CustomData interface.
- * CustomData is a structure which stores custom element data associated
- * with mesh elements (vertices, edges or faces). The custom data is
- * organised into a series of layers, each with a data type (e.g. TFace,
- * MDeformVert, etc.).
- */
+/* CustomData interface, see also DNA_customdata_types.h. */
#ifndef BKE_CUSTOMDATA_H
#define BKE_CUSTOMDATA_H
-typedef struct CustomData {
- struct LayerDesc *layers; /* data layer descriptors, ordered by type */
- int numLayers; /* current number of layers */
- int maxLayers; /* maximum number of layers */
- int numElems; /* current number of elements */
- int maxElems; /* maximum number of elements */
- int subElems; /* number of sub-elements layers can have */
-} CustomData;
-
-/* custom data types */
-enum {
- LAYERTYPE_MVERT = 0,
- LAYERTYPE_MSTICKY,
- LAYERTYPE_MDEFORMVERT,
- LAYERTYPE_MEDGE,
- LAYERTYPE_MFACE,
- LAYERTYPE_TFACE,
- LAYERTYPE_MCOL,
- LAYERTYPE_ORIGINDEX,
- LAYERTYPE_NORMAL,
- LAYERTYPE_FLAGS,
- LAYERTYPE_NUMTYPES
-};
+struct CustomData;
#define ORIGINDEX_NONE -1 /* indicates no original index for this element */
@@ -77,19 +50,19 @@ enum {
/* initialises a CustomData object with space for the given number
* of data layers and the given number of elements per layer
*/
-void CustomData_init(CustomData *data,
+void CustomData_init(struct CustomData *data,
int maxLayers, int maxElems, int subElems);
/* initialises a CustomData object with the same layer setup as source
- * and memory space for maxElems elements
+ * and memory space for maxElems elements. flag is added to all layer flags
*/
-void CustomData_from_template(const CustomData *source, CustomData *dest,
- int maxElems);
+void CustomData_from_template(const struct CustomData *source,
+ struct CustomData *dest, int flag, int maxElems);
/* frees data associated with a CustomData object (doesn't free the object
* itself, though)
*/
-void CustomData_free(CustomData *data);
+void CustomData_free(struct CustomData *data);
/* adds a data layer of the given type to the CustomData object, optionally
* backed by an external data array
@@ -100,25 +73,38 @@ void CustomData_free(CustomData *data);
* grows the number of layers in data if data->maxLayers has been reached
* returns 1 on success, 0 on failure
*/
-int CustomData_add_layer(CustomData *data, int type, int flag, void *layer);
+int CustomData_add_layer(struct CustomData *data, int type, int flag,
+ void *layer);
+
+/* frees the first data layer with the give type.
+ * returns 1 on succes, 0 if no layer with the given type is found
+ */
+int CustomData_free_layer(struct CustomData *data, int type);
/* returns 1 if the two objects are compatible (same layer types and
* flags in the same order), 0 if not
*/
-int CustomData_compat(const CustomData *data1, const CustomData *data2);
+int CustomData_compat(const struct CustomData *data1,
+ const struct CustomData *data2);
+
+/* returns 1 if a layer with the specified type exists */
+int CustomData_has_layer(const struct CustomData *data, int type);
/* copies data from one CustomData object to another
* objects need not be compatible, each source layer is copied to the
* first dest layer of correct type (if there is none, the layer is skipped)
* return 1 on success, 0 on failure
*/
-int CustomData_copy_data(const CustomData *source, CustomData *dest,
- int source_index, int dest_index, int count);
+int CustomData_copy_data(const struct CustomData *source,
+ struct CustomData *dest, int source_index,
+ int dest_index, int count);
+int CustomData_em_copy_data(struct CustomData *data, void *src_block,
+ void **dest_block);
/* frees data in a CustomData object
* return 1 on success, 0 on failure
*/
-int CustomData_free_elem(CustomData *data, int index, int count);
+int CustomData_free_elem(struct CustomData *data, int index, int count);
/* interpolates data from one CustomData object to another
* objects need not be compatible, each source layer is interpolated to the
@@ -134,28 +120,47 @@ int CustomData_free_elem(CustomData *data, int index, int count);
*
* returns 1 on success, 0 on failure
*/
-int CustomData_interp(const CustomData *source, CustomData *dest,
+int CustomData_interp(const struct CustomData *source, struct CustomData *dest,
int *src_indices, float *weights, float *sub_weights,
int count, int dest_index);
+int CustomData_em_interp(struct CustomData *data, void **src_blocks,
+ float *weights, float *sub_weights, int count,
+ void *dest_block);
/* gets a pointer to the data element at index from the first layer of type
* returns NULL if there is no layer of type
*/
-void *CustomData_get(const CustomData *data, int index, int type);
+void *CustomData_get(const struct CustomData *data, int index, int type);
+void *CustomData_em_get(const struct CustomData *data, void *block, int type);
/* gets a pointer to the first layer of type
* returns NULL if there is no layer of type
*/
-void *CustomData_get_layer(const CustomData *data, int type);
+void *CustomData_get_layer(const struct CustomData *data, int type);
/* copies the data from source to the data element at index in the first
* layer of type
* no effect if there is no layer of type
*/
-void CustomData_set(const CustomData *data, int index, int type, void *source);
+void CustomData_set(const struct CustomData *data, int index, int type,
+ void *source);
+void CustomData_em_set(struct CustomData *data, void *block, int type,
+ void *source);
/* sets the number of elements in a CustomData object
* if the value given is more than the maximum, the maximum is used
*/
-void CustomData_set_num_elems(CustomData *data, int numElems);
+void CustomData_set_num_elems(struct CustomData *data, int numElems);
+
+/* alloc/free a block of custom data attached to one element in editmode */
+void CustomData_em_set_default(struct CustomData *data, void **block);
+void CustomData_em_free_block(struct CustomData *data, void **block);
+
+/* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
+ blocks of data. the CustomData's must be compatible */
+void CustomData_to_em_block(const struct CustomData *source,
+ struct CustomData *dest, int index, void **block);
+void CustomData_from_em_block(const struct CustomData *source,
+ struct CustomData *dest, void *block, int index);
+
#endif
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 308a32439d4..04cb371226b 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -59,6 +59,7 @@
#include "BKE_utildefines.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_customdata.h"
#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
@@ -154,9 +155,9 @@ void DM_init(DerivedMesh *dm,
void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
int numVerts, int numEdges, int numFaces)
{
- CustomData_from_template(&source->vertData, &dm->vertData, numVerts);
- CustomData_from_template(&source->edgeData, &dm->edgeData, numEdges);
- CustomData_from_template(&source->faceData, &dm->faceData, numFaces);
+ CustomData_from_template(&source->vertData, &dm->vertData, 0, numVerts);
+ CustomData_from_template(&source->edgeData, &dm->edgeData, 0, numEdges);
+ CustomData_from_template(&source->faceData, &dm->faceData, 0, numFaces);
DM_init_funcs(dm);
}
@@ -335,7 +336,7 @@ void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest,
int count, int dest_index)
{
CustomData_interp(&source->edgeData, &dest->edgeData, src_indices,
- weights, (float *)vert_weights, count, dest_index);
+ weights, (float*)vert_weights, count, dest_index);
}
void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
@@ -344,7 +345,7 @@ void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
int count, int dest_index)
{
CustomData_interp(&source->faceData, &dest->faceData, src_indices,
- weights, (float *)vert_weights, count, dest_index);
+ weights, (float*)vert_weights, count, dest_index);
}
typedef struct {
@@ -1087,24 +1088,27 @@ static void emDM_drawUVEdges(DerivedMesh *dm)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditFace *efa;
+ TFace *tf;
glBegin(GL_LINES);
for(efa= emdm->em->faces.first; efa; efa= efa->next) {
- if(!(efa->tf.flag&TF_HIDE)) {
- glVertex2fv(efa->tf.uv[0]);
- glVertex2fv(efa->tf.uv[1]);
+ tf = CustomData_em_get(&emdm->em->fdata, efa->data, LAYERTYPE_TFACE);
- glVertex2fv(efa->tf.uv[1]);
- glVertex2fv(efa->tf.uv[2]);
+ if(tf && !(tf->flag&TF_HIDE)) {
+ glVertex2fv(tf->uv[0]);
+ glVertex2fv(tf->uv[1]);
+
+ glVertex2fv(tf->uv[1]);
+ glVertex2fv(tf->uv[2]);
if (!efa->v4) {
- glVertex2fv(efa->tf.uv[2]);
- glVertex2fv(efa->tf.uv[0]);
+ glVertex2fv(tf->uv[2]);
+ glVertex2fv(tf->uv[0]);
} else {
- glVertex2fv(efa->tf.uv[2]);
- glVertex2fv(efa->tf.uv[3]);
- glVertex2fv(efa->tf.uv[3]);
- glVertex2fv(efa->tf.uv[0]);
+ glVertex2fv(tf->uv[2]);
+ glVertex2fv(tf->uv[3]);
+ glVertex2fv(tf->uv[3]);
+ glVertex2fv(tf->uv[0]);
}
}
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 1ec318ae455..21ad73aa240 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -37,6 +37,7 @@
#include "BIF_gl.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_customdata.h"
#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
#include "BKE_mesh.h"
@@ -751,13 +752,11 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
MEdge *medge = CDDM_get_edges(dm);
MFace *mface = CDDM_get_faces(dm);
int *index;
+ TFace *tf;
- /* this maps from vert pointer to vert index */
- GHash *vertHash = BLI_ghash_new(BLI_ghashutil_ptrhash,
- BLI_ghashutil_ptrcmp);
-
+ /* set eve->hash to vert index */
for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
- BLI_ghash_insert(vertHash, eve, (void *)i);
+ eve->hash = i;
if(me->msticky)
CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL);
@@ -807,8 +806,8 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
i++, eed = eed->next, index++) {
MEdge *med = &medge[i];
- med->v1 = (int) BLI_ghash_lookup(vertHash, eed->v1);
- med->v2 = (int) BLI_ghash_lookup(vertHash, eed->v2);
+ med->v1 = eed->v1->hash;
+ med->v2 = eed->v2->hash;
med->crease = (unsigned char) (eed->crease * 255.0f);
med->flag = ME_EDGEDRAW|ME_EDGERENDER;
@@ -824,22 +823,21 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
i++, efa = efa->next, index++) {
MFace *mf = &mface[i];
- mf->v1 = (int) BLI_ghash_lookup(vertHash, efa->v1);
- mf->v2 = (int) BLI_ghash_lookup(vertHash, efa->v2);
- mf->v3 = (int) BLI_ghash_lookup(vertHash, efa->v3);
- mf->v4 = efa->v4 ? (int)BLI_ghash_lookup(vertHash, efa->v4) : 0;
+ mf->v1 = efa->v1->hash;
+ mf->v2 = efa->v2->hash;
+ mf->v3 = efa->v3->hash;
+ mf->v4 = efa->v4 ? efa->v4->hash : 0;
mf->mat_nr = efa->mat_nr;
mf->flag = efa->flag;
test_index_face(mf, NULL, NULL, efa->v4?4:3);
*index = i;
- if(me->tface)
- DM_set_face_data(dm, i, LAYERTYPE_TFACE, &efa->tf);
+ tf = CustomData_em_get(&em->fdata, efa->data, LAYERTYPE_TFACE);
+ if(tf)
+ DM_set_face_data(dm, i, LAYERTYPE_TFACE, tf);
}
- BLI_ghash_free(vertHash, NULL, NULL);
-
return dm;
}
@@ -976,7 +974,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
}
}
- CustomData_from_template(&dm->edgeData, &edgeData, BLI_edgehash_size(eh));
+ CustomData_from_template(&dm->edgeData, &edgeData, 0, BLI_edgehash_size(eh));
if(!CustomData_get_layer(&edgeData, LAYERTYPE_MEDGE))
CustomData_add_layer(&edgeData, LAYERTYPE_MEDGE,
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index d774324f1c1..b7b034be216 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -36,6 +36,7 @@
#include "BLI_linklist.h"
+#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -46,13 +47,6 @@
/* number of layers to add when growing a CustomData object */
#define CUSTOMDATA_GROW 5
-/* descriptor and storage for a custom data layer */
-typedef struct LayerDesc {
- int type; /* type of data in layer */
- int flag; /* general purpose flag */
- void *data; /* layer data */
-} LayerDesc;
-
/********************* Layer type information **********************/
typedef struct LayerTypeInfo {
int size; /* the memory size of one element of this layer's data */
@@ -83,44 +77,11 @@ typedef struct LayerTypeInfo {
*/
void (*interp)(void **sources, float *weights, float *sub_weights,
int count, void *dest);
-} LayerTypeInfo;
-
-static void layerCopy_mdeformvert(const void *source, void *dest,
- int count, int size);
-
-static void layerFree_mdeformvert(void *data, int count, int size);
-
-static void layerInterp_mdeformvert(void **sources, float *weights,
- float *sub_weights, int count, void *dest);
-static void layerInterp_tface(void **sources, float *weights,
- float *sub_weights, int count, void *dest);
-
-static void layerInterp_mcol(void **sources, float *weights,
- float *sub_weights, int count, void *dest);
-
-const LayerTypeInfo LAYERTYPEINFO[LAYERTYPE_NUMTYPES] = {
- {sizeof(MVert), NULL, NULL, NULL},
- {sizeof(MSticky), NULL, NULL, NULL},
- {sizeof(MDeformVert),
- layerCopy_mdeformvert, layerFree_mdeformvert, layerInterp_mdeformvert},
- {sizeof(MEdge), NULL, NULL, NULL},
- {sizeof(MFace), NULL, NULL, NULL},
- {sizeof(TFace), NULL, NULL, layerInterp_tface},
- /* 4 MCol structs per face */
- {sizeof(MCol) * 4, NULL, NULL, layerInterp_mcol},
- {sizeof(int), NULL, NULL, NULL},
- /* 3 floats per normal vector */
- {sizeof(float) * 3, NULL, NULL, NULL},
- {sizeof(int), NULL, NULL, NULL},
-};
-
-const LayerTypeInfo *layerType_getInfo(int type)
-{
- if(type < 0 || type >= LAYERTYPE_NUMTYPES) return NULL;
-
- return &LAYERTYPEINFO[type];
-}
+ /* 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);
+} LayerTypeInfo;
static void layerCopy_mdeformvert(const void *source, void *dest,
int count, int size)
@@ -210,6 +171,18 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
BLI_linklist_free(dest_dw, linklist_free_simple);
}
+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;
+ int i;
+
+ for(i = 0; i < count; ++i) {
+ dest_tf[i] = source_tf[i];
+ dest_tf[i].flag &= ~TF_ACTIVE;
+ }
+}
+
static void layerInterp_tface(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
@@ -217,30 +190,32 @@ static void layerInterp_tface(void **sources, float *weights,
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];
for(j = 0; j < 4; ++j) {
if(sub_weights) {
- for(k = 0; k < 4; ++k) {
- float sub_weight = sub_weights[j * 4 + k];
+ 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] * sub_weight * weight;
- uv[j][1] += tmp_uv[1] * sub_weight * weight;
+ uv[j][0] += tmp_uv[0] * w;
+ uv[j][1] += tmp_uv[1] * w;
- col[j][0] += tmp_col[0] * sub_weight * weight;
- col[j][1] += tmp_col[1] * sub_weight * weight;
- col[j][2] += tmp_col[2] * sub_weight * weight;
- col[j][3] += tmp_col[3] * sub_weight * weight;
+ 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];
@@ -269,6 +244,14 @@ static void layerInterp_tface(void **sources, float *weights,
}
}
+static void layerDefault_tface(void *data)
+{
+ static TFace default_tf = {NULL, {{0, 1}, {0, 0}, {1, 0}, {1, 1}},
+ {~0, ~0, ~0, ~0}, TF_SELECT, 0, TF_DYNAMIC, 0, 0};
+
+ *((TFace*)data) = default_tf;
+}
+
static void layerInterp_mcol(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
@@ -280,14 +263,15 @@ static void layerInterp_mcol(void **sources, float *weights,
float g;
float b;
} col[4];
+ float *sub_weight;
if(count <= 0) return;
memset(col, 0, sizeof(col));
-
+
+ sub_weight = sub_weights;
for(i = 0; i < count; ++i) {
float weight = weights ? weights[i] : 1;
- float *sub_weight = sub_weights;
for(j = 0; j < 4; ++j) {
if(sub_weights) {
@@ -316,6 +300,41 @@ static void layerInterp_mcol(void **sources, float *weights,
}
}
+static void layerDefault_mcol(void *data)
+{
+ static MCol default_mcol = {255, 255, 255, 255};
+ MCol *mcol = (MCol*)data;
+
+ 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},
+ /* 4 MCol structs per face */
+ {sizeof(MCol) * 4, NULL, NULL, layerInterp_mcol, layerDefault_mcol},
+ {sizeof(int), NULL, NULL, NULL, NULL},
+ /* 3 floats per normal vector */
+ {sizeof(float) * 3, NULL, NULL, NULL, NULL},
+ {sizeof(int), NULL, NULL, NULL, NULL},
+};
+
+static const LayerTypeInfo *layerType_getInfo(int type)
+{
+ if(type < 0 || type >= LAYERTYPE_NUMTYPES) return NULL;
+
+ return &LAYERTYPEINFO[type];
+}
+
/********************* CustomData functions *********************/
void CustomData_init(CustomData *data,
int maxLayers, int maxElems, int subElems)
@@ -329,19 +348,36 @@ void CustomData_init(CustomData *data,
data->subElems = subElems;
}
+static void CustomData_update_offsets(CustomData *data)
+{
+ const LayerTypeInfo *typeInfo;
+ int i, offset = 0;
+
+ for(i = 0; i < data->numLayers; ++i) {
+ typeInfo = layerType_getInfo(data->layers[i].type);
+
+ data->layers[i].offset = offset;
+ offset += typeInfo->size;
+ }
+
+ data->totSize = offset;
+}
+
void CustomData_from_template(const CustomData *source, CustomData *dest,
- int maxElems)
+ int flag, int maxElems)
{
- int i;
+ int i, layerflag;
CustomData_init(dest, source->maxLayers, maxElems, source->subElems);
for(i = 0; i < source->numLayers; ++i) {
if(source->layers[i].flag & LAYERFLAG_NOCOPY) continue;
- CustomData_add_layer(dest, source->layers[i].type,
- source->layers[i].flag & ~LAYERFLAG_NOFREE, NULL);
+ layerflag = (source->layers[i].flag & ~LAYERFLAG_NOFREE) | flag;
+ CustomData_add_layer(dest, source->layers[i].type, layerflag, NULL);
}
+
+ CustomData_update_offsets(dest);
}
void CustomData_free(CustomData *data)
@@ -356,7 +392,8 @@ void CustomData_free(CustomData *data)
typeInfo->free(data->layers[i].data, data->numElems,
typeInfo->size);
- MEM_freeN(data->layers[i].data);
+ if(data->layers[i].data)
+ MEM_freeN(data->layers[i].data);
}
}
@@ -368,10 +405,27 @@ void CustomData_free(CustomData *data)
}
}
-static int customData_grow(CustomData *data, int amount)
+/* 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
+ */
+static int CustomData_find_next(const CustomData *data, int type,
+ int start_index)
+{
+ int i = start_index + 1;
+
+ if(i < 0) i = 0;
+
+ for(; i < data->numLayers; ++i)
+ if(data->layers[i].type == type) return i;
+
+ return -1;
+}
+
+static int customData_resize(CustomData *data, int amount)
{
- LayerDesc *tmp = MEM_callocN(sizeof(*tmp) * (data->maxLayers + amount),
- "CustomData->layers");
+ CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxLayers + amount),
+ "CustomData->layers");
if(!tmp) return 0;
data->maxLayers += amount;
@@ -389,8 +443,8 @@ static int customData_add_layer__internal(CustomData *data, int type,
int index = data->numLayers;
if(index >= data->maxLayers)
- if(!customData_grow(data, CUSTOMDATA_GROW)) return 0;
-
+ if(!customData_resize(data, CUSTOMDATA_GROW)) return 0;
+
/* keep layers ordered by type */
for( ; index > 0 && data->layers[index - 1].type > type; --index)
data->layers[index] = data->layers[index - 1];
@@ -401,6 +455,8 @@ static int customData_add_layer__internal(CustomData *data, int type,
data->numLayers++;
+ CustomData_update_offsets(data);
+
return 1;
}
@@ -409,7 +465,7 @@ int CustomData_add_layer(CustomData *data, int type, int flag, void *layer)
int size = layerType_getInfo(type)->size * data->numElems;
void *tmp_layer = layer;
- if(!layer) tmp_layer = MEM_callocN(size, "LayerDesc.data");
+ if(!layer) tmp_layer = MEM_callocN(size, "CustomDataLayer.data");
if(!tmp_layer) return 0;
@@ -421,6 +477,30 @@ int CustomData_add_layer(CustomData *data, int type, int flag, void *layer)
}
}
+int CustomData_free_layer(CustomData *data, int type)
+{
+ int index = CustomData_find_next(data, type, -1);
+
+ if (index < 0) return 0;
+
+ for(++index; index < data->numLayers; ++index)
+ data->layers[index - 1] = data->layers[index];
+
+ data->numLayers--;
+
+ if(data->numLayers <= data->maxLayers-CUSTOMDATA_GROW)
+ customData_resize(data, -CUSTOMDATA_GROW);
+
+ CustomData_update_offsets(data);
+
+ return 1;
+}
+
+int CustomData_has_layer(const struct CustomData *data, int type)
+{
+ return (CustomData_find_next(data, type, -1) != -1);
+}
+
int CustomData_compat(const CustomData *data1, const CustomData *data2)
{
int i;
@@ -435,23 +515,6 @@ int CustomData_compat(const CustomData *data1, const CustomData *data2)
return 1;
}
-/* 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
- */
-static int CustomData_find_next(const CustomData *data, int type,
- int start_index)
-{
- int i = start_index + 1;
-
- if(i < 0) i = 0;
-
- for(; i < data->numLayers; ++i)
- if(data->layers[i].type == type) return i;
-
- return -1;
-}
-
int CustomData_copy_data(const CustomData *source, CustomData *dest,
int source_index, int dest_index, int count)
{
@@ -558,7 +621,7 @@ int CustomData_interp(const CustomData *source, CustomData *dest,
/* interpolates a layer at a time */
for(src_i = 0; src_i < source->numLayers; ++src_i) {
- LayerDesc *source_layer = &source->layers[src_i];
+ CustomDataLayer *source_layer = &source->layers[src_i];
const LayerTypeInfo *type_info =
layerType_getInfo(source_layer->type);
@@ -628,3 +691,177 @@ void CustomData_set_num_elems(CustomData *data, int numElems)
if(numElems < data->maxElems) data->numElems = numElems;
else data->numElems = data->maxElems;
}
+
+/* EditMesh functions */
+
+static void CustomData_em_alloc_block(CustomData *data, void **block)
+{
+ /* TODO: optimize free/alloc */
+
+ if (*block)
+ MEM_freeN(*block);
+
+ if (data->totSize > 0)
+ *block = MEM_callocN(data->totSize, "CustomData EM block");
+ else
+ *block = NULL;
+}
+
+void CustomData_em_free_block(CustomData *data, void **block)
+{
+ if (*block) {
+ MEM_freeN(*block);
+ *block = NULL;
+ }
+}
+
+int CustomData_em_copy_data(CustomData *data, void *src_block, void **dest_block)
+{
+ const LayerTypeInfo *type_info;
+ int i;
+
+ if (!*dest_block)
+ CustomData_em_alloc_block(data, dest_block);
+
+ /* copies a layer at a time */
+ for(i = 0; i < data->numLayers; ++i) {
+ int offset = data->layers[i].offset;
+ char *src_data = (char*)src_block + offset;
+ char *dest_data = (char*)*dest_block + offset;
+
+ type_info = layerType_getInfo(data->layers[i].type);
+
+ if(type_info->copy)
+ type_info->copy(src_data, dest_data, 1, type_info->size);
+ else
+ memcpy(dest_data, src_data, type_info->size);
+ }
+
+ return 1;
+}
+
+void *CustomData_em_get(const CustomData *data, void *block, int type)
+{
+ 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;
+
+ return (char *)block + data->layers[layer_index].offset;
+}
+
+void CustomData_em_set(CustomData *data, void *block, int type, void *source)
+{
+ void *dest = CustomData_em_get(data, index, type);
+ const LayerTypeInfo *type_info = layerType_getInfo(type);
+
+ if(!dest) return;
+
+ if(type_info->copy)
+ type_info->copy(source, dest, 1, type_info->size);
+ else
+ 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)
+{
+ 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
+ */
+ if(count > SOURCE_BUF_SIZE)
+ sources = MEM_callocN(sizeof(*sources) * count,
+ "CustomData_interp sources");
+
+ /* interpolates a layer at a time */
+ for(i = 0; i < data->numLayers; ++i) {
+ CustomDataLayer *layer = &data->layers[i];
+ const LayerTypeInfo *type_info = layerType_getInfo(layer->type);
+
+ if(type_info->interp) {
+ for(j = 0; j < count; ++j)
+ sources[j] = (char *)src_blocks[j] + layer->offset;
+
+ type_info->interp(sources, weights, sub_weights, count,
+ (char *)dest_block + layer->offset);
+ }
+ }
+
+ if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
+ return 1;
+}
+
+void CustomData_em_set_default(CustomData *data, void **block)
+{
+ const LayerTypeInfo *type_info;
+ int i;
+
+ if (!*block)
+ CustomData_em_alloc_block(data, block);
+
+ for(i = 0; i < data->numLayers; ++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);
+ }
+}
+
+void CustomData_to_em_block(const CustomData *source, CustomData *dest,
+ int src_index, void **dest_block)
+{
+ const LayerTypeInfo *type_info;
+ int 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;
+
+ type_info = layerType_getInfo(dest->layers[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);
+ }
+}
+
+void CustomData_from_em_block(const CustomData *source, CustomData *dest,
+ void *src_block, int dest_index)
+{
+ const LayerTypeInfo *type_info;
+ int 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;
+
+ type_info = layerType_getInfo(dest->layers[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);
+ }
+}
+
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index f8798de2650..3b6a7dba40b 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -45,6 +45,7 @@
#include "BKE_bad_level_calls.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_customdata.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_mesh.h"