diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2006-11-11 19:38:37 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2006-11-11 19:38:37 +0300 |
commit | 97f892b86b9b31e8165c27c698da7996dfd2d0a2 (patch) | |
tree | 41a2de3709265c3e871c29aa02d1aacf36e21dac | |
parent | 9e717b59cb4feb16314f0b2c026ebfd9278862a5 (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.
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 93 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 36 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 403 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 1 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_editVert.h | 5 | ||||
-rw-r--r-- | source/blender/include/BIF_editmesh.h | 5 | ||||
-rw-r--r-- | source/blender/include/BIF_verse.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_customdata_types.h | 69 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 174 | ||||
-rw-r--r-- | source/blender/src/editmesh_lib.c | 50 | ||||
-rw-r--r-- | source/blender/src/editmesh_mods.c | 94 | ||||
-rw-r--r-- | source/blender/src/editmesh_tools.c | 851 |
14 files changed, 894 insertions, 921 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" diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index 0592f04f05d..25559043bc8 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -38,6 +38,7 @@ #ifndef BLI_EDITVERT_H #define BLI_EDITVERT_H +#include "DNA_customdata_types.h" #include "DNA_mesh_types.h" struct DerivedMesh; @@ -125,7 +126,6 @@ typedef struct EditFace float fp; } tmp; float n[3], cent[3]; - struct TFace tf; /* a copy of original tface. */ unsigned char mat_nr, flag; unsigned char f, f1, h; unsigned char fast; /* only 0 or 1, for editmesh_fastmalloc */ @@ -133,6 +133,7 @@ typedef struct EditFace /*#ifdef WITH_VERSE*/ void *vface; /*#endif*/ + void *data; /* custom face data */ } EditFace; @@ -167,6 +168,8 @@ typedef struct EditMesh char retopo_mode; /* 0=OFF, 1=ON, 2=PAINT */ struct RetopoPaintData *retopo_paint_data; + CustomData fdata; + #ifdef WITH_VERSE void *vnode; #endif diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index 0df24d17917..ef568b9d84f 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -104,6 +104,11 @@ extern int faceselectedAND(struct EditFace *efa, int flag); extern void recalc_editnormals(void); extern void flip_editnormals(void); +extern struct EditFace *EM_face_from_faces(struct EditFace *efa1, + struct EditFace *efa2, int i1, int i2, int i3, int i4); +extern void EM_interp_from_faces(struct EditFace *efa1, struct EditFace *efa2, + struct EditFace *efan, int i1, int i2, int i3, int i4); + /* ******************* editmesh_mods.c */ extern void EM_init_index_arrays(int forVert, int forEdge, int forFace); diff --git a/source/blender/include/BIF_verse.h b/source/blender/include/BIF_verse.h index 01b6123c966..2145b8209d0 100644 --- a/source/blender/include/BIF_verse.h +++ b/source/blender/include/BIF_verse.h @@ -83,7 +83,7 @@ struct VNode *create_geom_vnode_data_from_mesh(struct VerseSession *session, str void destroy_unused_geometry(struct VNode *vnode); void destroy_binding_between_versemesh_and_editmesh(struct VNode *vnode); -void destroy_verse_mesh(struct VNode *vnode); +void destroy_versemesh(struct VNode *vnode); void unsubscribe_from_geom_node(struct VNode *vnode); diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h new file mode 100644 index 00000000000..2886f012c8e --- /dev/null +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -0,0 +1,69 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef DNA_CUSTOMDATA_TYPES_H +#define DNA_CUSTOMDATA_TYPES_H + +/* descriptor and storage for a custom data layer */ +typedef struct CustomDataLayer { + int type; /* type of data in layer */ + int offset; /* in editmode, offset of layer in block */ + int flag, pad; /* general purpose flag */ + void *data; /* layer data */ +} CustomDataLayer; + +/* 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.). */ +typedef struct CustomData { + CustomDataLayer *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 */ + int totSize; /* in editmode, total size of all data layers */ +} CustomData; + +/* custom data types */ +#define LAYERTYPE_MVERT 0 +#define LAYERTYPE_MSTICKY 1 +#define LAYERTYPE_MDEFORMVERT 2 +#define LAYERTYPE_MEDGE 3 +#define LAYERTYPE_MFACE 4 +#define LAYERTYPE_TFACE 5 +#define LAYERTYPE_MCOL 6 +#define LAYERTYPE_ORIGINDEX 7 +#define LAYERTYPE_NORMAL 8 +#define LAYERTYPE_FLAGS 9 +#define LAYERTYPE_NUMTYPES 10 + +#endif diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index e138631e548..a891fe1adab 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -43,6 +43,7 @@ #include "PIL_time.h" +#include "DNA_customdata_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -64,6 +65,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_depsgraph.h" +#include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_key.h" #include "BKE_library.h" @@ -150,7 +152,6 @@ EditVert *addvertlist(float *vec) * have a pre-editmode vertex order */ eve->keyindex = -1; - #ifdef WITH_VERSE createVerseVert(eve); #endif @@ -325,9 +326,9 @@ void free_editface(EditFace *efa) } #endif EM_remove_selection(efa, EDITFACE); - if(efa->fast==0){ + CustomData_em_free_block(&G.editMesh->fdata, &efa->data); + if(efa->fast==0) free(efa); - } } void free_vertlist(ListBase *edve) @@ -409,17 +410,14 @@ EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, Ed if(example) { efa->mat_nr= example->mat_nr; - efa->tf= example->tf; - efa->tf.flag &= ~TF_ACTIVE; efa->flag= example->flag; + CustomData_em_copy_data(&em->fdata, example->data, &efa->data); } else { if (G.obedit && G.obedit->actcol) efa->mat_nr= G.obedit->actcol-1; - default_uv(efa->tf.uv, 1.0); - /* Initialize colors */ - efa->tf.col[0]= efa->tf.col[1]= efa->tf.col[2]= efa->tf.col[3]= vpaint_get_current_col(); + CustomData_em_set_default(&em->fdata, &efa->data); } BLI_addtail(&em->faces, efa); @@ -511,7 +509,6 @@ static void *calloc_fastface(size_t size, size_t nr) */ static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface) { - if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts"); else em->allverts= NULL; em->curvert= em->allverts; @@ -556,6 +553,9 @@ void free_editMesh(EditMesh *em) if(em->edges.first) free_edgelist(&em->edges); if(em->faces.first) free_facelist(&em->faces); if(em->selected.first) BLI_freelistN(&(em->selected)); + + CustomData_free(&em->fdata); + if(em->derivedFinal) { if (em->derivedFinal!=em->derivedCage) { em->derivedFinal->release(em->derivedFinal); @@ -774,6 +774,7 @@ static void edge_drawflags(void) void make_editMesh() { Mesh *me= G.obedit->data; + EditMesh *em= G.editMesh; MFace *mface; TFace *tface; MVert *mvert; @@ -783,6 +784,7 @@ void make_editMesh() EditFace *efa; EditEdge *eed; EditSelection *ese; + CustomData mfdata; int tot, a, eekadoodle= 0; #ifdef WITH_VERSE @@ -793,7 +795,7 @@ void make_editMesh() #endif /* because of reload */ - free_editMesh(G.editMesh); + free_editMesh(em); G.totvert= tot= me->totvert; G.totedge= me->totedge; @@ -804,9 +806,8 @@ void make_editMesh() return; } - /* initialize fastmalloc for editmesh */ - init_editmesh_fastmalloc(G.editMesh, me->totvert, me->totedge, me->totface); + init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface); actkey = ob_get_keyblock(G.obedit); if(actkey) { @@ -847,10 +848,9 @@ void make_editMesh() } } - + if(actkey && actkey->totelem!=me->totvert); else { - unsigned int *mcol; MEdge *medge= me->medge; /* make edges */ @@ -870,11 +870,19 @@ void make_editMesh() } } + /* fill a CustomData, this is only temporary until Mesh get its own */ + CustomData_init(&mfdata, 0, me->totface, SUB_ELEMS_FACE); + if(me->mcol) + CustomData_add_layer(&mfdata, LAYERTYPE_MCOL, LAYERFLAG_NOFREE, me->mcol); + if(me->tface) + CustomData_add_layer(&mfdata, LAYERTYPE_TFACE, LAYERFLAG_NOFREE, me->tface); + + CustomData_from_template(&mfdata, &em->fdata, 0, 0); + /* make faces */ mface= me->mface; tface= me->tface; - mcol= (unsigned int *)me->mcol; - + for(a=0; a<me->totface; a++, mface++) { eve1= evlist[mface->v1]; eve2= evlist[mface->v2]; @@ -885,13 +893,8 @@ void make_editMesh() efa= addfacelist(eve1, eve2, eve3, eve4, NULL, NULL); if(efa) { - - if(mcol) memcpy(efa->tf.col, mcol, 4*sizeof(int)); + CustomData_to_em_block(&mfdata, &em->fdata, a, &efa->data); - if(me->tface) { - efa->tf= *tface; - } - efa->mat_nr= mface->mat_nr; efa->flag= mface->flag & ~ME_HIDE; @@ -902,18 +905,18 @@ void make_editMesh() } if(mface->flag & ME_HIDE) efa->h= 1; } - else if (tface) { - if( tface->flag & TF_HIDE) + else if((tface = CustomData_get(&mfdata, a, LAYERTYPE_TFACE))) { + if(tface->flag & TF_HIDE) efa->h= 1; - else if( tface->flag & TF_SELECT) { + else if(tface->flag & TF_SELECT) EM_select_face(efa, 1); - } } } if(me->tface) tface++; - if(mcol) mcol+=4; } + + CustomData_free(&mfdata); } if(eekadoodle) @@ -936,7 +939,7 @@ void make_editMesh() if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index); - BLI_addtail(&(G.editMesh->selected),ese); + BLI_addtail(&(em->selected),ese); } } EM_free_index_arrays(); @@ -962,6 +965,7 @@ void load_editMesh(void) MFace *mface; MSticky *ms; MSelect *mselect; + TFace *tf; EditVert *eve; EditFace *efa; EditEdge *eed; @@ -969,7 +973,7 @@ void load_editMesh(void) float *fp, *newkey, *oldkey, nor[3]; int i, a, ototvert, totedge=0; MDeformVert *dvert; - + CustomData mfdata; #ifdef WITH_VERSE if(em->vnode) { @@ -1005,7 +1009,7 @@ void load_editMesh(void) /* new Face block */ if(G.totface==0) mface= NULL; else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face"); - + /* are we adding dverts? */ if (G.totvert==0) dvert= NULL; else if(G.obedit->defbase.first==NULL) dvert= NULL; @@ -1028,9 +1032,21 @@ void load_editMesh(void) me->totedge= totedge; if(me->mface) MEM_freeN(me->mface); + me->mface= mface; me->totface= G.totface; - + + /* face data */ + if(me->tface) { + MEM_freeN(me->tface); + me->tface = NULL; + } + if(me->mcol) { + MEM_freeN(me->mcol); + me->mcol = NULL; + } + CustomData_from_template(&em->fdata, &mfdata, LAYERFLAG_NOFREE, me->totface); + /* the vertices, use ->tmp.l as counter */ eve= em->verts.first; a= 0; @@ -1145,9 +1161,11 @@ void load_editMesh(void) efa->e4->f2= 2; } + CustomData_from_em_block(&em->fdata, &mfdata, efa->data, i); /* no index '0' at location 3 or 4 */ - test_index_face(mface, NULL, &efa->tf, efa->v4?4:3); + test_index_face(mface, CustomData_get(&mfdata, i, LAYERTYPE_MCOL), + CustomData_get(&mfdata, i, LAYERTYPE_TFACE), efa->v4?4:3); #ifdef WITH_VERSE if(efa->vface) { @@ -1159,55 +1177,27 @@ void load_editMesh(void) i++; efa= efa->next; } - - /* tface block */ - if( me->tface && me->totface ) { - TFace *tfn, *tf; - - tf=tfn= MEM_callocN(sizeof(TFace)*me->totface, "tface"); - efa= em->faces.first; - while(efa) { - - *tf= efa->tf; - - if(G.f & G_FACESELECT) { - if( efa->h) tf->flag |= TF_HIDE; + + /* sync hide and select flags with faceselect mode */ + if(G.f & G_FACESELECT) { + if(me->tface && (me->totface > 0)) { + efa= em->faces.first; + for(a=0, efa=em->faces.first; efa; a++, efa++) { + tf = CustomData_get(&mfdata, a, LAYERTYPE_TFACE); + + if(efa->h) tf->flag |= TF_HIDE; else tf->flag &= ~TF_HIDE; - if( efa->f & SELECT) tf->flag |= TF_SELECT; + if(efa->f & SELECT) tf->flag |= TF_SELECT; else tf->flag &= ~TF_SELECT; } - - tf++; - efa= efa->next; } - - if(me->tface) MEM_freeN(me->tface); - me->tface= tfn; - } - else if(me->tface) { - MEM_freeN(me->tface); - me->tface= NULL; } - - /* mcol: same as tface... */ - if(me->mcol && me->totface) { - unsigned int *mcn, *mc; - mc=mcn= MEM_mallocN(4*sizeof(int)*me->totface, "mcol"); - efa= em->faces.first; - while(efa) { - memcpy(mc, efa->tf.col, 4*sizeof(int)); - - mc+=4; - efa= efa->next; - } - if(me->mcol) MEM_freeN(me->mcol); - me->mcol= (MCol *)mcn; - } - else if(me->mcol) { - MEM_freeN(me->mcol); - me->mcol= 0; - } + /* from CustomData to tface and mcol in Mesh */ + me->tface = CustomData_get(&mfdata, 0, LAYERTYPE_TFACE); + me->mcol = CustomData_get(&mfdata, 0, LAYERTYPE_MCOL); + + CustomData_free(&mfdata); /* patch hook indices */ { @@ -1576,6 +1566,7 @@ void separate_mesh(void) emcopy.alledges= NULL; emcopy.allfaces= NULL; emcopy.derivedFinal= emcopy.derivedCage= NULL; + memset(&emcopy.fdata, 0, sizeof(emcopy.fdata)); free_editMesh(&emcopy); em->verts= edve; @@ -1769,6 +1760,7 @@ void separate_mesh_loose(void) emcopy.alledges= NULL; emcopy.allfaces= NULL; emcopy.derivedFinal= emcopy.derivedCage= NULL; + memset(&emcopy.fdata, 0, sizeof(emcopy.fdata)); free_editMesh(&emcopy); em->verts= edve; @@ -1839,14 +1831,13 @@ typedef struct UndoMesh { EditEdgeC *edges; EditFaceC *faces; EditSelectionC *selected; - TFace *tfaces; - int totvert, totedge, totface,totsel; + int totvert, totedge, totface, totsel; short selectmode; RetopoPaintData *retopo_paint_data; char retopo_mode; + CustomData fdata; } UndoMesh; - /* for callbacks */ static void free_undoMesh(void *umv) @@ -1862,9 +1853,9 @@ static void free_undoMesh(void *umv) if(um->verts) MEM_freeN(um->verts); if(um->edges) MEM_freeN(um->edges); if(um->faces) MEM_freeN(um->faces); - if(um->tfaces) MEM_freeN(um->tfaces); if(um->selected) MEM_freeN(um->selected); if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data); + CustomData_free(&um->fdata); MEM_freeN(um); } @@ -1872,7 +1863,6 @@ static void *editMesh_to_undoMesh(void) { EditMesh *em= G.editMesh; UndoMesh *um; - Mesh *me= G.obedit->data; EditVert *eve; EditEdge *eed; EditFace *efa; @@ -1881,7 +1871,6 @@ static void *editMesh_to_undoMesh(void) EditEdgeC *eedc=NULL; EditFaceC *efac=NULL; EditSelectionC *esec=NULL; - TFace *tface= NULL; int a; um= MEM_callocN(sizeof(UndoMesh), "undomesh"); @@ -1898,11 +1887,8 @@ static void *editMesh_to_undoMesh(void) if(um->totedge) eedc= um->edges= MEM_callocN(um->totedge*sizeof(EditEdgeC), "alledgesC"); if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC"); if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections"); - - if(me->tface || me->mcol) tface= um->tfaces= MEM_mallocN(um->totface*sizeof(TFace), "all tfacesC"); - //printf("copy editmesh %d\n", um->totvert*sizeof(EditVert) + um->totedge*sizeof(EditEdge) + um->totface*sizeof(EditFace)); - //printf("copy undomesh %d\n", um->totvert*sizeof(EditVertC) + um->totedge*sizeof(EditEdgeC) + um->totface*sizeof(EditFaceC)); + if(um->totface) CustomData_from_template(&em->fdata, &um->fdata, 0, um->totface); /* now copy vertices */ a = 0; @@ -1946,12 +1932,10 @@ static void *editMesh_to_undoMesh(void) efac->f= efa->f; efac->h= efa->h; efac->fgonf= efa->fgonf; - - if(tface) { - *tface= efa->tf; - tface++; - } + efa->tmp.l = a; /*store index*/ + + CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a); } a = 0; @@ -1980,7 +1964,6 @@ static void undoMesh_to_editMesh(void *umv) EditEdgeC *eedc; EditFaceC *efac; EditSelectionC *esec; - TFace *tface; int a=0; #ifdef WITH_VERSE @@ -2031,7 +2014,9 @@ static void undoMesh_to_editMesh(void *umv) } /* copy faces */ - tface= um->tfaces; + CustomData_free(&em->fdata); + CustomData_from_template(&um->fdata, &em->fdata, 0, 0); + for(a=0, efac= um->faces; a<um->totface; a++, efac++) { if(efac->v4 != -1) efa= addfacelist(evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL); @@ -2044,10 +2029,7 @@ static void undoMesh_to_editMesh(void *umv) efa->h= efac->h; efa->fgonf= efac->fgonf; - if(tface) { - efa->tf= *tface; - tface++; - } + CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data); } end_editmesh_fastmalloc(); diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c index 2f742d8e985..ca03dcef555 100644 --- a/source/blender/src/editmesh_lib.c +++ b/source/blender/src/editmesh_lib.c @@ -57,6 +57,7 @@ editmesh_lib: generic (no UI, no menus) operations/evaluators for editmesh data #include "BLI_arithb.h" #include "BLI_editVert.h" +#include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_utildefines.h" @@ -708,6 +709,44 @@ void EM_hide_reset(void) } +void EM_interp_from_faces(EditFace *efa1, EditFace *efa2, EditFace *efan, int i1, int i2, int i3, int i4) +{ + EditMesh *em= G.editMesh; + float w[2][4][4]; + void *src[2]; + int count = (efa2)? 2: 1; + + /* set weights for copying from corners directly to other corners */ + memset(w, 0, sizeof(w)); + + w[i1/4][0][i1%4]= 1.0f; + w[i2/4][1][i2%4]= 1.0f; + w[i3/4][2][i3%4]= 1.0f; + if (i4 != -1) + w[i4/4][3][i4%4]= 1.0f; + + src[0]= efa1->data; + src[1]= (efa2)? efa2->data: NULL; + + CustomData_em_interp(&em->fdata, src, NULL, (float*)w, count, efan->data); +} + +EditFace *EM_face_from_faces(EditFace *efa1, EditFace *efa2, int i1, int i2, int i3, int i4) +{ + EditFace *efan; + EditVert **v[2]; + + v[0]= &efa1->v1; + v[1]= (efa2)? &efa2->v1: NULL; + + efan= addfacelist(v[i1/4][i1%4], v[i2/4][i2%4], v[i3/4][i3%4], + (i4 == -1)? 0: v[i4/4][i4%4], efa1, NULL); + + if (efa1->data) + EM_interp_from_faces(efa1, efa2, efan, i1, i2, i3, i4); + + return efan; +} /* ******** EXTRUDE ********* */ @@ -1442,8 +1481,8 @@ short extrudeflag_vert(short flag, float *nor) if(eed->tmp.f) { efa = eed->tmp.f; efa2->mat_nr= efa->mat_nr; - efa2->tf= efa->tf; efa2->flag= efa->flag; + CustomData_em_copy_data(&em->fdata, &efa->data, &efa2->data); } /* Needs smarter adaption of existing creases. @@ -1761,18 +1800,15 @@ void flipface(EditFace *efa) SWAP(EditVert *, efa->v2, efa->v4); SWAP(EditEdge *, efa->e1, efa->e4); SWAP(EditEdge *, efa->e2, efa->e3); - SWAP(unsigned int, efa->tf.col[1], efa->tf.col[3]); - SWAP(float, efa->tf.uv[1][0], efa->tf.uv[3][0]); - SWAP(float, efa->tf.uv[1][1], efa->tf.uv[3][1]); + EM_interp_from_faces(efa, NULL, efa, 0, 3, 2, 1); } else { SWAP(EditVert *, efa->v2, efa->v3); SWAP(EditEdge *, efa->e1, efa->e3); - SWAP(unsigned int, efa->tf.col[1], efa->tf.col[2]); efa->e2->dir= 1-efa->e2->dir; - SWAP(float, efa->tf.uv[1][0], efa->tf.uv[2][0]); - SWAP(float, efa->tf.uv[1][1], efa->tf.uv[2][1]); + EM_interp_from_faces(efa, NULL, efa, 0, 2, 1, 3); } + if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n); else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n); } diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index d0e9302f82b..c5958be912b 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -62,6 +62,7 @@ editmesh_mods.c, UI level access, no geometry changes #include "BKE_displist.h" #include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" +#include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_material.h" @@ -824,13 +825,26 @@ int facegroup_select(short mode) } } } else if (mode==2) { /* same image */ + TFace *tf, *base_tf; + + base_tf = (TFace*)CustomData_em_get(&em->fdata, base_efa->data, + LAYERTYPE_TFACE); + + if(!base_tf) + return selcount; + for(efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->f & SELECT) && !efa->h && base_efa->tf.tpage == efa->tf.tpage) { - EM_select_face(efa, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; + if (!(efa->f & SELECT) && !efa->h) { + tf = (TFace*)CustomData_em_get(&em->fdata, efa->data, + LAYERTYPE_TFACE); + + if(base_tf->tpage == tf->tpage) { + EM_select_face(efa, 1); + selcount++; + deselcount--; + if (!deselcount) /*have we selected all posible faces?, if so return*/ + return selcount; + } } } } else if (mode==3 || mode==4) { /* same area OR same perimeter, both use the same temp var */ @@ -2888,17 +2902,6 @@ static int tface_is_selected(TFace *tf) return (!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT)); } -static int faceselect_nfaces_selected(Mesh *me) -{ - int i, count= 0; - - for (i=0; i<me->totface; i++) - if (tface_is_selected(&me->tface[i])) - count++; - - return count; -} - /* XXX, code for both these functions should be abstract, * then unified, then written for other things (like objects, * which would use same as vertices method), then added @@ -2906,38 +2909,39 @@ static int faceselect_nfaces_selected(Mesh *me) */ void faceselect_align_view_to_selected(View3D *v3d, Mesh *me, int axis) { - if (!faceselect_nfaces_selected(me)) { - error("No faces selected."); - } else { - float norm[3]; - int i; - - norm[0]= norm[1]= norm[2]= 0.0; - for (i=0; i<me->totface; i++) { - MFace *mf= ((MFace*) me->mface) + i; - TFace *tf= ((TFace*) me->tface) + i; - - if (tface_is_selected(tf)) { - float *v1, *v2, *v3, fno[3]; - - v1= me->mvert[mf->v1].co; - v2= me->mvert[mf->v2].co; - v3= me->mvert[mf->v3].co; - if (mf->v4) { - float *v4= me->mvert[mf->v4].co; - CalcNormFloat4(v1, v2, v3, v4, fno); - } else { - CalcNormFloat(v1, v2, v3, fno); - } - - norm[0]+= fno[0]; - norm[1]+= fno[1]; - norm[2]+= fno[2]; + float norm[3]; + int i, totselected = 0; + + norm[0]= norm[1]= norm[2]= 0.0; + for (i=0; i<me->totface; i++) { + MFace *mf= ((MFace*) me->mface) + i; + TFace *tf= ((TFace*) me->tface) + i; + + if (tface_is_selected(tf)) { + float *v1, *v2, *v3, fno[3]; + + v1= me->mvert[mf->v1].co; + v2= me->mvert[mf->v2].co; + v3= me->mvert[mf->v3].co; + if (mf->v4) { + float *v4= me->mvert[mf->v4].co; + CalcNormFloat4(v1, v2, v3, v4, fno); + } else { + CalcNormFloat(v1, v2, v3, fno); } + + norm[0]+= fno[0]; + norm[1]+= fno[1]; + norm[2]+= fno[2]; + + totselected++; } + } + if (totselected == 0) + error("No faces selected."); + else view3d_align_axis_to_vector(v3d, axis, norm); - } } void editmesh_align_view_to_selected(View3D *v3d, int axis) diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index 33f47fe76dd..2d10f93ef1c 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -66,6 +66,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include "BLI_heap.h" #include "BKE_depsgraph.h" +#include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_mesh.h" @@ -163,41 +164,16 @@ void convert_to_triface(int direction) fac= VecLenf(efa->v1->co, efa->v3->co) - VecLenf(efa->v2->co, efa->v4->co); /* this makes sure exact squares get split different in both cases */ if( (direction==0 && fac<FLT_EPSILON) || (direction && fac>0.0f) ) { - - efan= addfacelist(efa->v1, efa->v2, efa->v3, 0, efa, NULL); + efan= EM_face_from_faces(efa, NULL, 0, 1, 2, -1); if(efa->f & SELECT) EM_select_face(efan, 1); - efan= addfacelist(efa->v1, efa->v3, efa->v4, 0, efa, NULL); + efan= EM_face_from_faces(efa, NULL, 0, 2, 3, -1); if(efa->f & SELECT) EM_select_face(efan, 1); - - efan->tf.uv[1][0]= efan->tf.uv[2][0]; - efan->tf.uv[1][1]= efan->tf.uv[2][1]; - efan->tf.uv[2][0]= efan->tf.uv[3][0]; - efan->tf.uv[2][1]= efan->tf.uv[3][1]; - - efan->tf.col[1]= efan->tf.col[2]; - efan->tf.col[2]= efan->tf.col[3]; } else { - efan= addfacelist(efa->v1, efa->v2, efa->v4, 0, efa, NULL); + efan= EM_face_from_faces(efa, NULL, 0, 1, 3, -1); if(efa->f & SELECT) EM_select_face(efan, 1); - - efan->tf.uv[2][0]= efan->tf.uv[3][0]; - efan->tf.uv[2][1]= efan->tf.uv[3][1]; - efan->tf.col[2]= efan->tf.col[3]; - - efan= addfacelist(efa->v2, efa->v3, efa->v4, 0, efa, NULL); + efan= EM_face_from_faces(efa, NULL, 1, 2, 3, -1); if(efa->f & SELECT) EM_select_face(efan, 1); - - efan->tf.uv[0][0]= efan->tf.uv[1][0]; - efan->tf.uv[0][1]= efan->tf.uv[1][1]; - efan->tf.uv[1][0]= efan->tf.uv[2][0]; - efan->tf.uv[1][1]= efan->tf.uv[2][1]; - efan->tf.uv[2][0]= efan->tf.uv[3][0]; - efan->tf.uv[2][1]= efan->tf.uv[3][1]; - - efan->tf.col[0]= efan->tf.col[1]; - efan->tf.col[1]= efan->tf.col[2]; - efan->tf.col[2]= efan->tf.col[3]; } BLI_remlink(&em->faces, efa); @@ -217,7 +193,6 @@ void convert_to_triface(int direction) } - int removedoublesflag(short flag, float limit) /* return amount */ { EditMesh *em = G.editMesh; @@ -395,15 +370,11 @@ int removedoublesflag(short flag, float limit) /* return amount */ if(efa->v4) { if(test==1 || test==2) { efa->v2= efa->v3; - efa->tf.uv[1][0] = efa->tf.uv[2][0]; - efa->tf.uv[1][1] = efa->tf.uv[2][1]; - efa->tf.col[1] = efa->tf.col[2]; - efa->v3= efa->v4; - efa->tf.uv[2][0] = efa->tf.uv[3][0]; - efa->tf.uv[2][1] = efa->tf.uv[3][1]; - efa->tf.col[2] = efa->tf.col[3]; efa->v4= 0; + + EM_interp_from_faces(efa, NULL, efa, 0, 2, 3, 3); + test= 0; } else if(test==8 || test==16) { @@ -1424,21 +1395,21 @@ static void facecopy(EditFace *source, EditFace *target) { float *v1 = source->v1->co, *v2 = source->v2->co, *v3 = source->v3->co; float *v4 = source->v4? source->v4->co: NULL; + float w[4][4]; + + CustomData_em_copy_data(&G.editMesh->fdata, source->data, &target->data); + + target->mat_nr = source->mat_nr; + target->flag = source->flag; - interp_uv_vcol(v1, v2, v3, v4, target->v1->co, &source->tf, &target->tf, 0); - interp_uv_vcol(v1, v2, v3, v4, target->v2->co, &source->tf, &target->tf, 1); - interp_uv_vcol(v1, v2, v3, v4, target->v3->co, &source->tf, &target->tf, 2); + InterpWeightsQ3Dfl(v1, v2, v3, v4, target->v1->co, w[0]); + InterpWeightsQ3Dfl(v1, v2, v3, v4, target->v2->co, w[1]); + InterpWeightsQ3Dfl(v1, v2, v3, v4, target->v3->co, w[2]); if (target->v4) - interp_uv_vcol(v1, v2, v3, v4, target->v4->co, &source->tf, &target->tf, 3); - - target->mat_nr = source->mat_nr; - target->tf.flag = source->tf.flag&~TF_ACTIVE; - target->tf.transp = source->tf.transp; - target->tf.mode = source->tf.mode; - target->tf.tile = source->tf.tile; - target->tf.unwrap = source->tf.unwrap; - target->tf.tpage = source->tf.tpage; - target->flag = source->flag; + InterpWeightsQ3Dfl(v1, v2, v3, v4, target->v4->co, w[3]); + + CustomData_em_interp(&G.editMesh->fdata, &source->data, NULL, + (float*)w, 1, target->data); } static void fill_quad_single(EditFace *efa, struct GHash *gh, int numcuts, int seltype) @@ -1972,7 +1943,7 @@ static void fill_tri_double(EditFace *efa, struct GHash *gh, int numcuts) static void fill_quad_triple(EditFace *efa, struct GHash *gh, int numcuts) { - EditEdge *cedge[3]; + EditEdge *cedge[3]={0}; EditVert *v[4], **verts[3]; EditFace *hold; short start=0, start2=0, start3=0, vertsize, i, repeats; @@ -2924,99 +2895,47 @@ static int collect_quadedges(EVPTuple *efaa, EditEdge *eed, EditFace *efa) #define VTEST(face, num, other) \ (face->v##num != other->v1 && face->v##num != other->v2 && face->v##num != other->v3) -static void givequadverts(EditFace *efa, EditFace *efa1, EditVert **v1, EditVert **v2, EditVert **v3, EditVert **v4, float **uv, unsigned int *col) +static void givequadverts(EditFace *efa, EditFace *efa1, EditVert **v1, EditVert **v2, EditVert **v3, EditVert **v4, int *vindex) { if VTEST(efa, 1, efa1) { - //if(efa->v1!=efa1->v1 && efa->v1!=efa1->v2 && efa->v1!=efa1->v3) { *v1= efa->v1; *v2= efa->v2; - uv[0] = efa->tf.uv[0]; - uv[1] = efa->tf.uv[1]; - col[0] = efa->tf.col[0]; - col[1] = efa->tf.col[1]; + vindex[0]= 0; + vindex[1]= 1; } else if VTEST(efa, 2, efa1) { - //else if(efa->v2!=efa1->v1 && efa->v2!=efa1->v2 && efa->v2!=efa1->v3) { *v1= efa->v2; *v2= efa->v3; - uv[0] = efa->tf.uv[1]; - uv[1] = efa->tf.uv[2]; - col[0] = efa->tf.col[1]; - col[1] = efa->tf.col[2]; + vindex[0]= 1; + vindex[1]= 2; } else if VTEST(efa, 3, efa1) { - // else if(efa->v3!=efa1->v1 && efa->v3!=efa1->v2 && efa->v3!=efa1->v3) { *v1= efa->v3; *v2= efa->v1; - uv[0] = efa->tf.uv[2]; - uv[1] = efa->tf.uv[0]; - col[0] = efa->tf.col[2]; - col[1] = efa->tf.col[0]; + vindex[0]= 2; + vindex[1]= 0; } if VTEST(efa1, 1, efa) { - // if(efa1->v1!=efa->v1 && efa1->v1!=efa->v2 && efa1->v1!=efa->v3) { *v3= efa1->v1; - uv[2] = efa1->tf.uv[0]; - col[2] = efa1->tf.col[0]; - *v4= efa1->v2; - uv[3] = efa1->tf.uv[1]; - col[3] = efa1->tf.col[1]; -/* -if(efa1->v2== *v2) { - *v4= efa1->v3; - uv[3] = efa1->tf.uv[2]; - } else { - *v4= efa1->v2; - uv[3] = efa1->tf.uv[1]; - } - */ + vindex[2]= 0; + vindex[3]= 1; } else if VTEST(efa1, 2, efa) { - // else if(efa1->v2!=efa->v1 && efa1->v2!=efa->v2 && efa1->v2!=efa->v3) { *v3= efa1->v2; - uv[2] = efa1->tf.uv[1]; - col[2] = efa1->tf.col[1]; - *v4= efa1->v3; - uv[3] = efa1->tf.uv[2]; - col[3] = efa1->tf.col[2]; -/* -if(efa1->v3== *v2) { - *v4= efa1->v1; - uv[3] = efa1->tf.uv[0]; - } else { - *v4= efa1->v3; - uv[3] = efa1->tf.uv[2]; - } - */ + vindex[2]= 1; + vindex[3]= 2; } else if VTEST(efa1, 3, efa) { - // else if(efa1->v3!=efa->v1 && efa1->v3!=efa->v2 && efa1->v3!=efa->v3) { *v3= efa1->v3; - uv[2] = efa1->tf.uv[2]; - col[2] = efa1->tf.col[2]; - *v4= efa1->v1; - uv[3] = efa1->tf.uv[0]; - col[3] = efa1->tf.col[0]; -/* -if(efa1->v1== *v2) { - *v4= efa1->v2; - uv[3] = efa1->tf.uv[3]; - } else { - *v4= efa1->v1; - uv[3] = efa1->tf.uv[0]; - } - */ + vindex[2]= 2; + vindex[3]= 0; } - else { + else *v3= *v4= NULL; - - return; - } - } /* Helper functions for edge/quad edit features*/ @@ -3071,10 +2990,8 @@ void beauty_fill(void) // void **efaar, **efaa; EVPTuple *efaar; EVPtr *efaa; - float *uv[4]; - unsigned int col[4]; float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2; - int totedge, ok, notbeauty=8, onedone; + int totedge, ok, notbeauty=8, onedone, vindex[4]; /* - all selected edges with two faces * - find the faces: store them in edges (using datablock) @@ -3121,7 +3038,7 @@ void beauty_fill(void) if(ok) { /* test convex */ - givequadverts(efaa[0], efaa[1], &v1, &v2, &v3, &v4, uv, col); + givequadverts(efaa[0], efaa[1], &v1, &v2, &v3, &v4, vindex); if(v1 && v2 && v3 && v4) { if( convex(v1->co, v2->co, v3->co, v4->co) ) { @@ -3174,22 +3091,14 @@ void beauty_fill(void) efa= efaa[1]; efa->f1= 1; - w= addfacelist(v1, v2, v3, 0, efa, NULL); + w= EM_face_from_faces(efaa[0], efaa[1], + vindex[0], vindex[1], 4+vindex[2], -1); w->f |= SELECT; - - UVCOPY(w->tf.uv[0], uv[0]); - UVCOPY(w->tf.uv[1], uv[1]); - UVCOPY(w->tf.uv[2], uv[2]); - w->tf.col[0] = col[0]; w->tf.col[1] = col[1]; w->tf.col[2] = col[2]; - w= addfacelist(v1, v3, v4, 0, efa, NULL); - w->f |= SELECT; - - UVCOPY(w->tf.uv[0], uv[0]); - UVCOPY(w->tf.uv[1], uv[2]); - UVCOPY(w->tf.uv[2], uv[3]); - w->tf.col[0] = col[0]; w->tf.col[1] = col[2]; w->tf.col[2] = col[3]; + w= EM_face_from_faces(efaa[0], efaa[1], + vindex[0], 4+vindex[2], 4+vindex[3], -1); + w->f |= SELECT; onedone= 1; } @@ -3202,20 +3111,16 @@ void beauty_fill(void) efa= efaa[1]; efa->f1= 1; - w= addfacelist(v2, v3, v4, 0, efa, NULL); + + w= EM_face_from_faces(efaa[0], efaa[1], + vindex[1], 4+vindex[2], 4+vindex[3], -1); w->f |= SELECT; - UVCOPY(w->tf.uv[0], uv[1]); - UVCOPY(w->tf.uv[1], uv[3]); - UVCOPY(w->tf.uv[2], uv[4]); - w= addfacelist(v1, v2, v4, 0, efa, NULL); + w= EM_face_from_faces(efaa[0], efaa[1], + vindex[0], 4+vindex[1], 4+vindex[3], -1); w->f |= SELECT; - UVCOPY(w->tf.uv[0], uv[0]); - UVCOPY(w->tf.uv[1], uv[1]); - UVCOPY(w->tf.uv[2], uv[3]); - onedone= 1; } } @@ -3414,10 +3319,15 @@ static int compareFaceUV(EditFace *f1, EditFace *f2) { EditVert **faceVert1, **faceVert2, *faceVerts1[5], *faceVerts2[5]; int i1, i2; + TFace *tf1, *tf2; + + tf1 = CustomData_em_get(&G.editMesh->fdata, f1->data, LAYERTYPE_TFACE); + tf2 = CustomData_em_get(&G.editMesh->fdata, f2->data, LAYERTYPE_TFACE); - if(f1->tf.tpage == NULL && f2->tf.tpage == NULL) + if(tf1 == NULL || tf2 == NULL) return 1; + else if(tf1->tpage == NULL && tf2->tpage == NULL) return 1; - else if(f1->tf.tpage != f2->tf.tpage) + else if(tf1->tpage != tf2->tpage) return 0; FILL_FACEVERTS(f1, faceVerts1); @@ -3430,7 +3340,7 @@ static int compareFaceUV(EditFace *f1, EditFace *f2) i2 = 0; while(*faceVert2){ if( *faceVert1 == *faceVert2){ - if(!compare2(f1->tf.uv[i1], f2->tf.uv[i2], UV_LIMIT)) + if(!compare2(tf1->uv[i1], tf2->uv[i2], UV_LIMIT)) return 0; } i2++; @@ -3447,6 +3357,18 @@ static int compareFaceCol(EditFace *f1, EditFace *f2) { EditVert **faceVert1, **faceVert2, *faceVerts1[5], *faceVerts2[5]; int i1, i2; + TFace *tf1, *tf2; + unsigned int *col1, *col2; + + tf1 = CustomData_em_get(&G.editMesh->fdata, f1->data, LAYERTYPE_TFACE); + tf2 = CustomData_em_get(&G.editMesh->fdata, f2->data, LAYERTYPE_TFACE); + + if(tf1) col1 = tf1->col; + else col1 = CustomData_em_get(&G.editMesh->fdata, f1->data, LAYERTYPE_MCOL); + if(tf2) col2 = tf2->col; + else col2 = CustomData_em_get(&G.editMesh->fdata, f2->data, LAYERTYPE_MCOL); + + if(!col1 || !col2) return 1; FILL_FACEVERTS(f1, faceVerts1); FILL_FACEVERTS(f2, faceVerts2); @@ -3458,7 +3380,7 @@ static int compareFaceCol(EditFace *f1, EditFace *f2) i2 = 0; while(*faceVert2){ if( *faceVert1 == *faceVert2){ - if(!compare3(f1->tf.col[i1], f2->tf.col[i2], COL_LIMIT)) + if(!compare3(col1[i1], col2[i2], COL_LIMIT)) return 0; } i2++; @@ -3475,7 +3397,6 @@ static void meshJoinFaces(EditEdge *joined) FacePairL *fpl = joined->tmp.p; EditFace *face1, *face2, *efa; EditVert *v1free, *v2free; - int i; face1 = fpl->face1; face2 = fpl->face2; @@ -3490,75 +3411,12 @@ static void meshJoinFaces(EditEdge *joined) face2->v2->f1 = 1; face2->v3->f1 = 2; -switch(v1free->f1){ - case 0: - i = 2; - break; - case 1: - i = 3; - break; - case 2: - i = 1; - break; - } - - switch(i){ - case 2: - /*this is really lazy...*/ - efa = addfacelist(face1->v1, face1->v2, v2free, face1->v3, face1, NULL); - efa->tf.uv[0][0] = face1->tf.uv[0][0]; - efa->tf.uv[0][1] = face1->tf.uv[0][1]; - efa->tf.col[0] = face1->tf.col[0]; - - efa->tf.uv[1][0] = face1->tf.uv[1][0]; - efa->tf.uv[1][1] = face1->tf.uv[1][1]; - efa->tf.col[1] = face1->tf.col[1]; - - efa->tf.uv[2][0] = face2->tf.uv[v2free->f1][0]; - efa->tf.uv[2][1] = face2->tf.uv[v2free->f1][1]; - efa->tf.col[2] = face2->tf.col[v2free->f1]; - - efa->tf.uv[3][0] = face1->tf.uv[2][0]; - efa->tf.uv[3][1] = face1->tf.uv[2][1]; - efa->tf.col[3] = face1->tf.col[2]; - break; - case 3: - efa = addfacelist(face1->v1, face1->v2, face1->v3, v2free, face1, NULL); - efa->tf.uv[0][0] = face1->tf.uv[0][0]; - efa->tf.uv[0][1] = face1->tf.uv[0][1]; - efa->tf.col[0] = face1->tf.col[0]; - - efa->tf.uv[1][0] = face1->tf.uv[1][0]; - efa->tf.uv[1][1] = face1->tf.uv[1][1]; - efa->tf.col[1] = face1->tf.col[1]; - - efa->tf.uv[2][0] = face1->tf.uv[2][0]; - efa->tf.uv[2][1] = face1->tf.uv[2][1]; - efa->tf.col[2] = face1->tf.col[2]; - - efa->tf.uv[3][0] = face2->tf.uv[v2free->f1][0]; - efa->tf.uv[3][1] = face2->tf.uv[v2free->f1][1]; - efa->tf.col[3] = face1->tf.col[v2free->f1]; - break; - case 1: - efa = addfacelist(face1->v1, v2free, face1->v2, face1->v3, face1, NULL); - efa->tf.uv[0][0] = face1->tf.uv[0][0]; - efa->tf.uv[0][1] = face1->tf.uv[0][1]; - efa->tf.col[0] = face1->tf.col[0]; - - efa->tf.uv[1][0] = face2->tf.uv[v2free->f1][0]; - efa->tf.uv[1][1] = face2->tf.uv[v2free->f1][1]; - efa->tf.col[1] = face2->tf.col[v2free->f1]; - - efa->tf.uv[2][0] = face1->tf.uv[1][0]; - efa->tf.uv[2][1] = face1->tf.uv[1][1]; - efa->tf.col[2] = face1->tf.col[1]; - - efa->tf.uv[3][0] = face1->tf.uv[2][0]; - efa->tf.uv[3][1] = face1->tf.uv[2][1]; - efa->tf.col[3] = face1->tf.col[2]; - break; - } + if(v1free->f1 == 0) + efa= EM_face_from_faces(face1, face2, 0, 1, 4+v2free->f1, 2); + else if(v1free->f1 == 1) + efa= EM_face_from_faces(face1, face2, 0, 1, 2, 4+v2free->f1); + else /* if(v1free->f1 == 2) */ + efa= EM_face_from_faces(face1, face2, 0, 4+v2free->f1, 1, 2); EM_select_face(efa,1); /*flag for removal*/ @@ -3771,11 +3629,7 @@ void edge_flip(void) //void **efaar, **efaa; EVPTuple *efaar; EVPtr *efaa; - - float *uv[4]; - unsigned int col[4]; - - int totedge, ok; + int totedge, ok, vindex[4]; /* - all selected edges with two faces * - find the faces: store them in edges (using datablock) @@ -3812,7 +3666,7 @@ void edge_flip(void) if(ok) { /* test convex */ - givequadverts(efaa[0], efaa[1], &v1, &v2, &v3, &v4, uv, col); + givequadverts(efaa[0], efaa[1], &v1, &v2, &v3, &v4, vindex); /* 4-----3 4-----3 @@ -3827,27 +3681,19 @@ void edge_flip(void) if (v1 && v2 && v3) { if( convex(v1->co, v2->co, v3->co, v4->co) ) { if(exist_face(v1, v2, v3, v4)==0) { - w = addfacelist(v1, v2, v3, 0, efaa[1], NULL); /* outch this may break seams */ + /* outch this may break seams */ + w= EM_face_from_faces(efaa[0], efaa[1], vindex[0], + vindex[1], 4+vindex[2], -1); + EM_select_face(w, 1); untag_edges(w); - UVCOPY(w->tf.uv[0], uv[0]); - UVCOPY(w->tf.uv[1], uv[1]); - UVCOPY(w->tf.uv[2], uv[2]); + /* outch this may break seams */ + w= EM_face_from_faces(efaa[0], efaa[1], vindex[0], + 4+vindex[2], 4+vindex[3], -1); - w->tf.col[0] = col[0]; w->tf.col[1] = col[1]; w->tf.col[2] = col[2]; - - w = addfacelist(v1, v3, v4, 0, efaa[1], NULL); /* outch this may break seams */ EM_select_face(w, 1); untag_edges(w); - - UVCOPY(w->tf.uv[0], uv[0]); - UVCOPY(w->tf.uv[1], uv[2]); - UVCOPY(w->tf.uv[2], uv[3]); - - w->tf.col[0] = col[0]; w->tf.col[1] = col[2]; w->tf.col[2] = col[3]; - - /* erase old faces and edge */ } /* tag as to-be-removed */ FACE_MARKCLEAR(efaa[1]); @@ -3880,326 +3726,153 @@ void edge_flip(void) static void edge_rotate(EditEdge *eed,int dir) { EditMesh *em = G.editMesh; + EditVert **verts[2]; EditFace *face[2], *efa, *newFace[2]; - EditVert *faces[2][4],*v1,*v2,*v3,*v4,*vtemp; - EditEdge *srchedge = NULL; - short facecount=0, p1=0,p2=0,p3=0,p4=0,fac1=4,fac2=4,i,j,numhidden; - EditEdge **hiddenedges; + EditEdge **edges[2], **hiddenedges, *srchedge; + int facecount, p1, p2, p3, p4, fac1, fac2, i, j; + int numhidden, numshared, p[2][4]; /* check to make sure that the edge is only part of 2 faces */ + facecount = 0; for(efa = em->faces.first;efa;efa = efa->next) { if((efa->e1 == eed || efa->e2 == eed) || (efa->e3 == eed || efa->e4 == eed)) { - if(facecount == 2) { + if(facecount >= 2) { + /* more than two faces with this edge */ return; } - if(facecount < 2) + else { face[facecount] = efa; - facecount++; + facecount++; + } } } - if(facecount < 2) { + if(facecount < 2) return; - } /* how many edges does each face have */ - if(face[0]->e4 == NULL) - fac1=3; - else - fac1=4; - if(face[1]->e4 == NULL) - fac2=3; - else - fac2=4; - - /*store the face info in a handy array */ - faces[0][0] = face[0]->v1; - faces[0][1] = face[0]->v2; - faces[0][2] = face[0]->v3; - if(face[0]->e4 != NULL) - faces[0][3] = face[0]->v4; - else - faces[0][3] = NULL; - - faces[1][0] = face[1]->v1; - faces[1][1] = face[1]->v2; - faces[1][2] = face[1]->v3; - if(face[1]->e4 != NULL) - faces[1][3] = face[1]->v4; - else - faces[1][3] = NULL; + if(face[0]->e4) fac1= 4; + else fac1= 3; + + if(face[1]->e4) fac2= 4; + else fac2= 3; + /* make a handy array for verts and edges */ + verts[0]= &face[0]->v1; + edges[0]= &face[0]->e1; + verts[1]= &face[1]->v1; + edges[1]= &face[1]->e1; /* we don't want to rotate edges between faces that share more than one edge */ - - j=0; - if(face[0]->e1 == face[1]->e1 || - face[0]->e1 == face[1]->e2 || - face[0]->e1 == face[1]->e3 || - ((face[1]->e4) && face[0]->e1 == face[1]->e4) ) - j++; - - if(face[0]->e2 == face[1]->e1 || - face[0]->e2 == face[1]->e2 || - face[0]->e2 == face[1]->e3 || - ((face[1]->e4) && face[0]->e2 == face[1]->e4) ) - j++; - - if(face[0]->e3 == face[1]->e1 || - face[0]->e3 == face[1]->e2 || - face[0]->e3 == face[1]->e3 || - ((face[1]->e4) && face[0]->e3 == face[1]->e4) ) - j++; - - if(face[0]->e4) { - if(face[0]->e4 == face[1]->e1 || - face[0]->e4 == face[1]->e2 || - face[0]->e4 == face[1]->e3 || - ((face[1]->e4) && face[0]->e4 == face[1]->e4) ) - j++; - } - if(j > 1) { + numshared= 0; + for(i=0; i<fac1; i++) + for(j=0; j<fac2; j++) + if (edges[0][i] == edges[1][j]) + numshared++; + + if(numshared > 1) return; - } - /* Coplaner Faces Only Please */ - if(Inpf(face[0]->n,face[1]->n) <= 0.000001) { + /* coplaner faces only please */ + if(Inpf(face[0]->n,face[1]->n) <= 0.000001) return; - } - /*get the edges verts */ - v1 = eed->v1; - v2 = eed->v2; - v3 = eed->v1; - v4 = eed->v2; - - /*figure out where the edges verts lie one the 2 faces */ - for(i=0;i<4;i++) { - if(v1 == faces[0][i]) - p1 = i; - if(v2 == faces[0][i]) - p2 = i; - if(v1 == faces[1][i]) - p3 = i; - if(v2 == faces[1][i]) - p4 = i; - } - - /*make sure the verts are in the correct order */ - if((p1+1)%fac1 == p2) { - vtemp = v2; - v2 = v1; - v1 = vtemp; - - i = p1; - p1 = p2; - p2 = i; - } - if((p3+1)%fac2 == p4) { - vtemp = v4; - v4 = v3; - v3 = vtemp; - - i = p3; - p3 = p4; - p4 = i; - } + /* we want to construct an array of vertex indicis in both faces, starting at + the last vertex of the edge being rotated. + - first we find the two vertices that lie on the rotating edge + - then we make sure they are ordered according to the face vertex order + - and then we construct the array */ + p1= p2= p3= p4= 0; + for(i=0; i<4; i++) { + if(eed->v1 == verts[0][i]) p1 = i; + if(eed->v2 == verts[0][i]) p2 = i; + if(eed->v1 == verts[1][i]) p3 = i; + if(eed->v2 == verts[1][i]) p4 = i; + } + + if((p1+1)%fac1 == p2) + SWAP(int, p1, p2); + if((p3+1)%fac2 == p4) + SWAP(int, p3, p4); + + for (i = 0; i < 4; i++) { + p[0][i]= (p1 + i)%fac1; + p[1][i]= (p3 + i)%fac2; + } - /* Create an Array of the Edges who have h set prior to rotate */ + /* create an Array of the Edges who have h set prior to rotate */ numhidden = 0; - for(srchedge = em->edges.first;srchedge;srchedge = srchedge->next) { - if(srchedge->h && (srchedge->v1->f & SELECT || srchedge->v2->f & SELECT)) { + for(srchedge = em->edges.first;srchedge;srchedge = srchedge->next) + if(srchedge->h && ((srchedge->v1->f & SELECT) || (srchedge->v2->f & SELECT))) numhidden++; - } - } - hiddenedges = MEM_mallocN(sizeof(EditVert*)*numhidden+1,"Hidden Vert Scratch Array for Rotate Edges"); + + hiddenedges = MEM_mallocN(sizeof(EditVert*)*numhidden+1, "RotateEdgeHiddenVerts"); if(!hiddenedges) { error("Malloc Was not happy!"); return; } + numhidden = 0; - for(srchedge = em->edges.first;srchedge;srchedge = srchedge->next) { - if(srchedge->h && (srchedge->v1->f & SELECT || srchedge->v2->f & SELECT)) { - hiddenedges[numhidden] = srchedge; - numhidden++; - } - } - - /* create the 2 new faces */ + for(srchedge=em->edges.first; srchedge; srchedge=srchedge->next) + if(srchedge->h && (srchedge->v1->f & SELECT || srchedge->v2->f & SELECT)) + hiddenedges[numhidden++] = srchedge; + + /* create the 2 new faces */ if(fac1 == 3 && fac2 == 3) { - /*No need of reverse setup*/ - newFace[0] = addfacelist(faces[0][(p1+1 )%3],faces[0][(p1+2 )%3],faces[1][(p3+1 )%3],NULL,NULL,NULL); - newFace[1] = addfacelist(faces[1][(p3+1 )%3],faces[1][(p3+2 )%3],faces[0][(p1+1 )%3],NULL,NULL,NULL); - - newFace[0]->tf.col[0] = face[0]->tf.col[(p1+1 )%3]; - newFace[0]->tf.col[1] = face[0]->tf.col[(p1+2 )%3]; - newFace[0]->tf.col[2] = face[1]->tf.col[(p3+1 )%3]; - newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1 )%3]; - newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2 )%3]; - newFace[1]->tf.col[2] = face[0]->tf.col[(p1+1 )%3]; - - UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+1 )%3]); - UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+2 )%3]); - UVCOPY(newFace[0]->tf.uv[2],face[1]->tf.uv[(p3+1 )%3]); - UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1 )%3]); - UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2 )%3]); - UVCOPY(newFace[1]->tf.uv[2],face[0]->tf.uv[(p1+1 )%3]); + /* no need of reverse setup */ + + newFace[0]= EM_face_from_faces(face[0], face[1], p[0][1], p[0][2], 4+p[1][1], -1); + newFace[1]= EM_face_from_faces(face[1], face[0], p[1][1], p[1][2], 4+p[0][1], -1); } else if(fac1 == 4 && fac2 == 3) { if(dir == 1) { - newFace[0] = addfacelist(faces[0][(p1+1 )%4],faces[0][(p1+2 )%4],faces[0][(p1+3 )%4],faces[1][(p3+1 )%3],NULL,NULL); - newFace[1] = addfacelist(faces[1][(p3+1 )%3],faces[1][(p3+2 )%3],faces[0][(p1+1 )%4],NULL,NULL,NULL); - - newFace[0]->tf.col[0] = face[0]->tf.col[(p1+1 )%4]; - newFace[0]->tf.col[1] = face[0]->tf.col[(p1+2 )%4]; - newFace[0]->tf.col[2] = face[0]->tf.col[(p1+3 )%4]; - newFace[0]->tf.col[3] = face[1]->tf.col[(p3+1 )%3]; - newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1 )%3]; - newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2 )%3]; - newFace[1]->tf.col[2] = face[0]->tf.col[(p1+1 )%4]; - - UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+1 )%4]); - UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+2 )%4]); - UVCOPY(newFace[0]->tf.uv[2],face[0]->tf.uv[(p1+3 )%4]); - UVCOPY(newFace[0]->tf.uv[3],face[1]->tf.uv[(p3+1 )%3]); - UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1 )%3]); - UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2 )%3]); - UVCOPY(newFace[1]->tf.uv[2],face[0]->tf.uv[(p1+1 )%4]); + newFace[0]= EM_face_from_faces(face[0], face[1], p[0][1], p[0][2], p[0][3], 4+p[1][1]); + newFace[1]= EM_face_from_faces(face[1], face[0], p[1][1], p[1][2], 4+p[0][1], -1); } else if (dir == 2) { - newFace[0] = addfacelist(faces[0][(p1+2 )%4],faces[1][(p3+1)%3],faces[0][(p1)%4],faces[0][(p1+1 )%4],NULL,NULL); - newFace[1] = addfacelist(faces[0][(p1+2 )%4],faces[1][(p3)%3],faces[1][(p3+1 )%3],NULL,NULL,NULL); - - newFace[0]->tf.col[0] = face[0]->tf.col[(p1+2)%4]; - newFace[0]->tf.col[1] = face[1]->tf.col[(p3+1)%3]; - newFace[0]->tf.col[2] = face[0]->tf.col[(p1 )%4]; - newFace[0]->tf.col[3] = face[0]->tf.col[(p1+1)%4]; - newFace[1]->tf.col[0] = face[0]->tf.col[(p1+2)%4]; - newFace[1]->tf.col[1] = face[1]->tf.col[(p3 )%3]; - newFace[1]->tf.col[2] = face[1]->tf.col[(p3+1)%3]; - - UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+2)%4]); - UVCOPY(newFace[0]->tf.uv[1],face[1]->tf.uv[(p3+1)%3]); - UVCOPY(newFace[0]->tf.uv[2],face[0]->tf.uv[(p1 )%4]); - UVCOPY(newFace[0]->tf.uv[3],face[0]->tf.uv[(p1+1)%4]); - UVCOPY(newFace[1]->tf.uv[0],face[0]->tf.uv[(p1+2)%4]); - UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3 )%3]); - UVCOPY(newFace[1]->tf.uv[2],face[1]->tf.uv[(p3+1)%3]); + newFace[0]= EM_face_from_faces(face[0], face[1], p[0][2], 4+p[1][1], p[0][0], p[0][1]); + newFace[1]= EM_face_from_faces(face[1], face[0], 4+p[0][2], p[1][0], p[1][1], -1); - faces[0][(p1+2)%fac1]->f |= SELECT; - faces[1][(p3+1)%fac2]->f |= SELECT; + verts[0][p[0][2]]->f |= SELECT; + verts[1][p[1][1]]->f |= SELECT; } } - else if(fac1 == 3 && fac2 == 4) { if(dir == 1) { - newFace[0] = addfacelist(faces[0][(p1+1 )%3],faces[0][(p1+2 )%3],faces[1][(p3+1 )%4],NULL,NULL,NULL); - newFace[1] = addfacelist(faces[1][(p3+1 )%4],faces[1][(p3+2 )%4],faces[1][(p3+3 )%4],faces[0][(p1+1 )%3],NULL,NULL); - - newFace[0]->tf.col[0] = face[0]->tf.col[(p1+1 )%3]; - newFace[0]->tf.col[1] = face[0]->tf.col[(p1+2 )%3]; - newFace[0]->tf.col[2] = face[1]->tf.col[(p3+1 )%4]; - newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1 )%4]; - newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2 )%4]; - newFace[1]->tf.col[2] = face[1]->tf.col[(p3+3 )%4]; - newFace[1]->tf.col[3] = face[0]->tf.col[(p1+1 )%3]; - - UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+1 )%3]); - UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+2 )%3]); - UVCOPY(newFace[0]->tf.uv[2],face[1]->tf.uv[(p3+1 )%4]); - UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1 )%4]); - UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2 )%4]); - UVCOPY(newFace[1]->tf.uv[2],face[1]->tf.uv[(p3+3 )%4]); - UVCOPY(newFace[1]->tf.uv[3],face[0]->tf.uv[(p1+1 )%3]); + newFace[0]= EM_face_from_faces(face[0], face[1], p[0][1], p[0][2], 4+p[1][1], -1); + newFace[1]= EM_face_from_faces(face[1], face[0], p[1][1], p[1][2], p[1][3], 4+p[0][1]); } else if (dir == 2) { - newFace[0] = addfacelist(faces[0][(p1)%3],faces[0][(p1+1 )%3],faces[1][(p3+2 )%4],NULL,NULL,NULL); - newFace[1] = addfacelist(faces[1][(p3+1 )%4],faces[1][(p3+2 )%4],faces[0][(p1+1 )%3],faces[0][(p1+2 )%3],NULL,NULL); - - newFace[0]->tf.col[0] = face[0]->tf.col[(p1 )%3]; - newFace[0]->tf.col[1] = face[0]->tf.col[(p1+1 )%3]; - newFace[0]->tf.col[2] = face[1]->tf.col[(p3+2 )%4]; - newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1 )%4]; - newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2 )%4]; - newFace[1]->tf.col[2] = face[0]->tf.col[(p1+1 )%3]; - newFace[1]->tf.col[3] = face[0]->tf.col[(p1+2 )%3]; - - UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1 )%3]); - UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+1 )%3]); - UVCOPY(newFace[0]->tf.uv[2],face[1]->tf.uv[(p3+2 )%4]); - UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1 )%4]); - UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2 )%4]); - UVCOPY(newFace[1]->tf.uv[2],face[0]->tf.uv[(p1+1 )%3]); - UVCOPY(newFace[1]->tf.uv[3],face[0]->tf.uv[(p1+2 )%3]); + newFace[0]= EM_face_from_faces(face[0], face[1], p[0][0], p[0][1], 4+p[1][2], -1); + newFace[1]= EM_face_from_faces(face[1], face[0], p[1][1], p[1][2], 4+p[0][1], 4+p[0][2]); - faces[0][(p1+1)%fac1]->f |= SELECT; - faces[1][(p3+2)%fac2]->f |= SELECT; + verts[0][p[0][1]]->f |= SELECT; + verts[1][p[1][2]]->f |= SELECT; } } - else if(fac1 == 4 && fac2 == 4) { if(dir == 1) { - newFace[0] = addfacelist(faces[0][(p1+1 )%4],faces[0][(p1+2 )%4],faces[0][(p1+3 )%4],faces[1][(p3+1 )%4],NULL,NULL); - newFace[1] = addfacelist(faces[1][(p3+1 )%4],faces[1][(p3+2 )%4],faces[1][(p3+3 )%4],faces[0][(p1+1 )%4],NULL,NULL); - - newFace[0]->tf.col[0] = face[0]->tf.col[(p1+1 )%4]; - newFace[0]->tf.col[1] = face[0]->tf.col[(p1+2 )%4]; - newFace[0]->tf.col[2] = face[0]->tf.col[(p1+3 )%4]; - newFace[0]->tf.col[3] = face[1]->tf.col[(p3+1 )%4]; - newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1 )%4]; - newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2 )%4]; - newFace[1]->tf.col[2] = face[1]->tf.col[(p3+3 )%4]; - newFace[1]->tf.col[3] = face[0]->tf.col[(p1+1 )%4]; - - UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+1 )%4]); - UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+2 )%4]); - UVCOPY(newFace[0]->tf.uv[2],face[0]->tf.uv[(p1+3 )%4]); - UVCOPY(newFace[0]->tf.uv[3],face[1]->tf.uv[(p3+1 )%4]); - UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1 )%4]); - UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2 )%4]); - UVCOPY(newFace[1]->tf.uv[2],face[1]->tf.uv[(p3+3 )%4]); - UVCOPY(newFace[1]->tf.uv[3],face[0]->tf.uv[(p1+1 )%4]); + newFace[0]= EM_face_from_faces(face[0], face[1], p[0][1], p[0][2], p[0][3], 4+p[1][1]); + newFace[1]= EM_face_from_faces(face[1], face[0], p[1][1], p[1][2], p[1][3], 4+p[0][1]); } else if (dir == 2) { - newFace[0] = addfacelist(faces[0][(p1+2 )%4],faces[0][(p1+3 )%4],faces[1][(p3+1 )%4],faces[1][(p3+2 )%4],NULL,NULL); - newFace[1] = addfacelist(faces[1][(p3+2 )%4],faces[1][(p3+3 )%4],faces[0][(p1+1 )%4],faces[0][(p1+2 )%4],NULL,NULL); - - newFace[0]->tf.col[0] = face[0]->tf.col[(p1+2 )%4]; - newFace[0]->tf.col[1] = face[0]->tf.col[(p1+3 )%4]; - newFace[0]->tf.col[2] = face[1]->tf.col[(p3+1 )%4]; - newFace[0]->tf.col[3] = face[1]->tf.col[(p3+2 )%4]; - newFace[1]->tf.col[0] = face[1]->tf.col[(p3+2 )%4]; - newFace[1]->tf.col[1] = face[1]->tf.col[(p3+3 )%4]; - newFace[1]->tf.col[2] = face[0]->tf.col[(p1+1 )%4]; - newFace[1]->tf.col[3] = face[0]->tf.col[(p1+2 )%4]; - - UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+2 )%4]); - UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+3 )%4]); - UVCOPY(newFace[0]->tf.uv[2],face[1]->tf.uv[(p3+1 )%4]); - UVCOPY(newFace[0]->tf.uv[3],face[1]->tf.uv[(p3+2 )%4]); - UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+2 )%4]); - UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+3 )%4]); - UVCOPY(newFace[1]->tf.uv[2],face[0]->tf.uv[(p1+1 )%4]); - UVCOPY(newFace[1]->tf.uv[3],face[0]->tf.uv[(p1+2 )%4]); + newFace[0]= EM_face_from_faces(face[0], face[1], p[0][2], p[0][3], 4+p[1][1], 4+p[1][2]); + newFace[1]= EM_face_from_faces(face[1], face[0], p[1][2], p[1][3], 4+p[0][1], 4+p[0][2]); - faces[0][(p1+2)%fac1]->f |= SELECT; - faces[1][(p3+2)%fac2]->f |= SELECT; + verts[0][p[0][2]]->f |= SELECT; + verts[1][p[1][2]]->f |= SELECT; } - - } - else{ - /*This should never happen*/ - return; - } + else + return; /* This should never happen */ - if(dir == 1) { - faces[0][(p1+1)%fac1]->f |= SELECT; - faces[1][(p3+1)%fac2]->f |= SELECT; + if(dir == 1 || (fac1 == 3 && fac2 == 3)) { + verts[0][p[0][1]]->f |= SELECT; + verts[1][p[1][1]]->f |= SELECT; } - /*Copy old edge's flags to new center edge*/ + /* copy old edge's flags to new center edge*/ for(srchedge=em->edges.first;srchedge;srchedge=srchedge->next) { - if(srchedge->v1->f & SELECT &&srchedge->v2->f & SELECT ) { + if((srchedge->v1->f & SELECT) && (srchedge->v2->f & SELECT)) { srchedge->f = eed->f; srchedge->h = eed->h; srchedge->dir = eed->dir; @@ -4208,63 +3881,15 @@ static void edge_rotate(EditEdge *eed,int dir) } } - - /* copy flags and material */ - - newFace[0]->mat_nr = face[0]->mat_nr; - newFace[0]->tf.flag = face[0]->tf.flag; - newFace[0]->tf.transp = face[0]->tf.transp; - newFace[0]->tf.mode = face[0]->tf.mode; - newFace[0]->tf.tile = face[0]->tf.tile; - newFace[0]->tf.unwrap = face[0]->tf.unwrap; - newFace[0]->tf.tpage = face[0]->tf.tpage; - newFace[0]->flag = face[0]->flag; - - newFace[1]->mat_nr = face[1]->mat_nr; - newFace[1]->tf.flag = face[1]->tf.flag; - newFace[1]->tf.transp = face[1]->tf.transp; - newFace[1]->tf.mode = face[1]->tf.mode; - newFace[1]->tf.tile = face[1]->tf.tile; - newFace[1]->tf.unwrap = face[1]->tf.unwrap; - newFace[1]->tf.tpage = face[1]->tf.tpage; - newFace[1]->flag = face[1]->flag; - - /* Resetting Hidden Flag */ - for(numhidden--;numhidden>=0;numhidden--) { - hiddenedges[numhidden]->h = 1; - - } + /* resetting hidden flag */ + for(numhidden--; numhidden>=0; numhidden--) + hiddenedges[numhidden]->h= 1; /* check for orhphan edges */ - for(srchedge=em->edges.first;srchedge;srchedge = srchedge->next) { - srchedge->f1 = -1; - } + for(srchedge=em->edges.first; srchedge; srchedge=srchedge->next) + srchedge->f1= -1; - /*for(efa = em->faces.first;efa;efa = efa->next) { - if(efa->h == 0) { - efa->e1->f1 = 1; - efa->e2->f1 = 1; - efa->e3->f1 = 1; - if(efa->e4) { - efa->e4->f1 = 1; - } - } - if(efa->h == 1) { - if(efa->e1->f1 == -1) { - efa->e1->f1 = 0; - } - if(efa->e2->f1 == -1) { - efa->e2->f1 = 0; - } - if(efa->e1->f1 == -1) { - efa->e1->f1 = 0; - } - if(efa->e4) { - efa->e4->f1 = 1; - } - } - } - A Little Cleanup */ + /* cleanup */ MEM_freeN(hiddenedges); /* get rid of the old edge and faces*/ @@ -4274,8 +3899,7 @@ static void edge_rotate(EditEdge *eed,int dir) free_editface(face[0]); BLI_remlink(&em->faces, face[1]); free_editface(face[1]); - return; -} +} /* only accepts 1 selected edge, or 2 selected faces */ void edge_rotate_selected(int dir) @@ -6355,14 +5979,15 @@ static void append_weldedUV(EditFace *efa, EditVert *eve, int tfindex, ListBase wUV *curwvert, *newwvert; wUVNode *newnode; int found; + TFace *tf = CustomData_em_get(&G.editMesh->fdata, efa->data, LAYERTYPE_TFACE); found = 0; for(curwvert=uvverts->first; curwvert; curwvert=curwvert->next){ - if(curwvert->eve == eve && curwvert->u == efa->tf.uv[tfindex][0] && curwvert->v == efa->tf.uv[tfindex][1]){ + if(curwvert->eve == eve && curwvert->u == tf->uv[tfindex][0] && curwvert->v == tf->uv[tfindex][1]){ newnode = MEM_callocN(sizeof(wUVNode), "Welded UV Vert Node"); - newnode->u = &(efa->tf.uv[tfindex][0]); - newnode->v = &(efa->tf.uv[tfindex][1]); + newnode->u = &(tf->uv[tfindex][0]); + newnode->v = &(tf->uv[tfindex][1]); BLI_addtail(&(curwvert->nodes), newnode); found = 1; break; @@ -6371,8 +5996,8 @@ static void append_weldedUV(EditFace *efa, EditVert *eve, int tfindex, ListBase if(!found){ newnode = MEM_callocN(sizeof(wUVNode), "Welded UV Vert Node"); - newnode->u = &(efa->tf.uv[tfindex][0]); - newnode->v = &(efa->tf.uv[tfindex][1]); + newnode->u = &(tf->uv[tfindex][0]); + newnode->v = &(tf->uv[tfindex][1]); newwvert = MEM_callocN(sizeof(wUV), "Welded UV Vert"); newwvert->u = *(newnode->u); @@ -6400,21 +6025,22 @@ static void append_weldedUVEdge(EditFace *efa, EditEdge *eed, ListBase *uvedges) { wUVEdge *curwedge, *newwedge; int v1tfindex, v2tfindex, found; + TFace *tf = CustomData_em_get(&G.editMesh->fdata, efa->data, LAYERTYPE_TFACE); found = 0; if(eed->v1 == efa->v1) v1tfindex = 0; else if(eed->v1 == efa->v2) v1tfindex = 1; else if(eed->v1 == efa->v3) v1tfindex = 2; - else if(eed->v1 == efa->v4) v1tfindex = 3; + else /* if(eed->v1 == efa->v4) */ v1tfindex = 3; if(eed->v2 == efa->v1) v2tfindex = 0; else if(eed->v2 == efa->v2) v2tfindex = 1; else if(eed->v2 == efa->v3) v2tfindex = 2; - else if(eed->v2 == efa->v4) v2tfindex = 3; + else /* if(eed->v2 == efa->v4) */ v2tfindex = 3; for(curwedge=uvedges->first; curwedge; curwedge=curwedge->next){ - if(curwedge->eed == eed && curwedge->v1uv[0] == efa->tf.uv[v1tfindex][0] && curwedge->v1uv[1] == efa->tf.uv[v1tfindex][1] && curwedge->v2uv[0] == efa->tf.uv[v2tfindex][0] && curwedge->v2uv[1] == efa->tf.uv[v2tfindex][1]){ + if(curwedge->eed == eed && curwedge->v1uv[0] == tf->uv[v1tfindex][0] && curwedge->v1uv[1] == tf->uv[v1tfindex][1] && curwedge->v2uv[0] == tf->uv[v2tfindex][0] && curwedge->v2uv[1] == tf->uv[v2tfindex][1]){ found = 1; break; //do nothing, we don't need another welded uv edge } @@ -6422,10 +6048,10 @@ static void append_weldedUVEdge(EditFace *efa, EditEdge *eed, ListBase *uvedges) if(!found){ newwedge = MEM_callocN(sizeof(wUVEdge), "Welded UV Edge"); - newwedge->v1uv[0] = efa->tf.uv[v1tfindex][0]; - newwedge->v1uv[1] = efa->tf.uv[v1tfindex][1]; - newwedge->v2uv[0] = efa->tf.uv[v2tfindex][0]; - newwedge->v2uv[1] = efa->tf.uv[v2tfindex][1]; + newwedge->v1uv[0] = tf->uv[v1tfindex][0]; + newwedge->v1uv[1] = tf->uv[v1tfindex][1]; + newwedge->v2uv[0] = tf->uv[v2tfindex][0]; + newwedge->v2uv[1] = tf->uv[v2tfindex][1]; newwedge->eed = eed; BLI_addtail(uvedges, newwedge); @@ -6434,7 +6060,6 @@ static void append_weldedUVEdge(EditFace *efa, EditEdge *eed, ListBase *uvedges) static void build_weldedUVEdges(ListBase *uvedges, ListBase *uvverts) { - wUV *curwvert; wUVEdge *curwedge; EditFace *efa; @@ -6480,6 +6105,9 @@ static void collapse_edgeuvs(void) Collection *wuvecollection, *newcollection; int curtag, balanced, collectionfound, vcount; float avg[2]; + + if (!CustomData_has_layer(&G.editMesh->fdata, LAYERTYPE_TFACE)) + return; uvverts.first = uvverts.last = uvedges.first = uvedges.last = allcollections.first = allcollections.last = NULL; @@ -6576,62 +6204,64 @@ static void collapse_edgeuvs(void) static void collapseuvs(void) { EditFace *efa; + TFace *tf; int uvcount; float uvav[2]; + + if (!CustomData_has_layer(&G.editMesh->fdata, LAYERTYPE_TFACE)) + return; uvcount = 0; uvav[0] = 0; uvav[1] = 0; for(efa = G.editMesh->faces.first; efa; efa=efa->next){ + tf = CustomData_em_get(&G.editMesh->fdata, efa->data, LAYERTYPE_TFACE); + if(efa->v1->f1){ - uvav[0] += efa->tf.uv[0][0]; - uvav[1] += efa->tf.uv[0][1]; + uvav[0] += tf->uv[0][0]; + uvav[1] += tf->uv[0][1]; uvcount += 1; } if(efa->v2->f1){ - uvav[0] += efa->tf.uv[1][0]; - uvav[1] += efa->tf.uv[1][1]; + uvav[0] += tf->uv[1][0]; + uvav[1] += tf->uv[1][1]; uvcount += 1; } if(efa->v3->f1){ - uvav[0] += efa->tf.uv[2][0]; - uvav[1] += efa->tf.uv[2][1]; + uvav[0] += tf->uv[2][0]; + uvav[1] += tf->uv[2][1]; uvcount += 1; } - if(efa->v4){ - if(efa->v4->f1){ - uvav[0] += efa->tf.uv[3][0]; - uvav[1] += efa->tf.uv[3][1]; - uvcount += 1; - } + if(efa->v4 && efa->v4->f1){ + uvav[0] += tf->uv[3][0]; + uvav[1] += tf->uv[3][1]; + uvcount += 1; } } - - - if(uvav[0] && uvav[1]){ + if(uvcount > 0) { uvav[0] /= uvcount; uvav[1] /= uvcount; for(efa = G.editMesh->faces.first; efa; efa=efa->next){ + tf = CustomData_em_get(&G.editMesh->fdata, efa->data, LAYERTYPE_TFACE); + if(efa->v1->f1){ - efa->tf.uv[0][0] = uvav[0]; - efa->tf.uv[0][1] = uvav[1]; + tf->uv[0][0] = uvav[0]; + tf->uv[0][1] = uvav[1]; } if(efa->v2->f1){ - efa->tf.uv[1][0] = uvav[0]; - efa->tf.uv[1][1] = uvav[1]; + tf->uv[1][0] = uvav[0]; + tf->uv[1][1] = uvav[1]; } if(efa->v3->f1){ - efa->tf.uv[2][0] = uvav[0]; - efa->tf.uv[2][1] = uvav[1]; + tf->uv[2][0] = uvav[0]; + tf->uv[2][1] = uvav[1]; } - if(efa->v4){ - if(efa->v4->f1){ - efa->tf.uv[3][0] = uvav[0]; - efa->tf.uv[3][1] = uvav[1]; - } + if(efa->v4 && efa->v4->f1){ + tf->uv[3][0] = uvav[0]; + tf->uv[3][1] = uvav[1]; } } } @@ -6646,11 +6276,9 @@ int collapseEdges(void) CollectedEdge *curredge; Collection *edgecollection; - int totedges, groupcount, mergecount,vcount; float avgcount[3]; - allcollections.first = 0; allcollections.last = 0; @@ -6686,15 +6314,17 @@ int collapseEdges(void) VECCOPY(((EditEdge*)curredge->eed)->v2->co,avgcount); } - /*uv collapse*/ - for(eve=G.editMesh->verts.first; eve; eve=eve->next) eve->f1 = 0; - for(eed=G.editMesh->edges.first; eed; eed=eed->next) eed->f1 = 0; - for(curredge = edgecollection->collectionbase.first; curredge; curredge = curredge->next){ - curredge->eed->v1->f1 = 1; - curredge->eed->v2->f1 = 1; - curredge->eed->f1 = 1; + if (CustomData_has_layer(&G.editMesh->fdata, LAYERTYPE_TFACE)) { + /*uv collapse*/ + for(eve=G.editMesh->verts.first; eve; eve=eve->next) eve->f1 = 0; + for(eed=G.editMesh->edges.first; eed; eed=eed->next) eed->f1 = 0; + for(curredge = edgecollection->collectionbase.first; curredge; curredge = curredge->next){ + curredge->eed->v1->f1 = 1; + curredge->eed->v2->f1 = 1; + curredge->eed->f1 = 1; + } + collapse_edgeuvs(); } - collapse_edgeuvs(); } freecollections(&allcollections); @@ -6727,7 +6357,7 @@ int merge_firstlast(int first, int uvmerge) } } - if(uvmerge){ + if(uvmerge && CustomData_has_layer(&G.editMesh->fdata, LAYERTYPE_TFACE)){ for(eve=G.editMesh->verts.first; eve; eve=eve->next) eve->f1 = 0; for(eve=G.editMesh->verts.first; eve; eve=eve->next){ @@ -6748,7 +6378,7 @@ int merge_target(int target, int uvmerge) if(target) snap_sel_to_curs(); else snap_to_center(); - if(uvmerge){ + if(uvmerge && CustomData_has_layer(&G.editMesh->fdata, LAYERTYPE_TFACE)){ for(eve=G.editMesh->verts.first; eve; eve=eve->next) eve->f1 = 0; for(eve=G.editMesh->verts.first; eve; eve=eve->next){ if(eve->f&SELECT) eve->f1 = 1; @@ -7109,7 +6739,6 @@ void loop_to_region(void) if(efa->f1 == testflag){ if(efa->f&SELECT) EM_select_face(efa, 0); else EM_select_face(efa,1); - } } } |