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.
This commit is contained in:
2006-11-11 16:38:37 +00:00
parent 9e717b59cb
commit 97f892b86b
14 changed files with 934 additions and 961 deletions

View File

@@ -45,7 +45,7 @@
* conversion to DLM. * conversion to DLM.
*/ */
#include "BKE_customdata.h" #include "DNA_customdata_types.h"
struct MVert; struct MVert;
struct MEdge; struct MEdge;

View File

@@ -27,39 +27,12 @@
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
*/ */
/* CustomData interface. /* CustomData interface, see also DNA_customdata_types.h. */
* 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.).
*/
#ifndef BKE_CUSTOMDATA_H #ifndef BKE_CUSTOMDATA_H
#define BKE_CUSTOMDATA_H #define BKE_CUSTOMDATA_H
typedef struct CustomData { 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
};
#define ORIGINDEX_NONE -1 /* indicates no original index for this element */ #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 /* initialises a CustomData object with space for the given number
* of data layers and the given number of elements per layer * 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); int maxLayers, int maxElems, int subElems);
/* initialises a CustomData object with the same layer setup as source /* 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, void CustomData_from_template(const struct CustomData *source,
int maxElems); struct CustomData *dest, int flag, int maxElems);
/* frees data associated with a CustomData object (doesn't free the object /* frees data associated with a CustomData object (doesn't free the object
* itself, though) * 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 /* adds a data layer of the given type to the CustomData object, optionally
* backed by an external data array * 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 * grows the number of layers in data if data->maxLayers has been reached
* returns 1 on success, 0 on failure * 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 /* returns 1 if the two objects are compatible (same layer types and
* flags in the same order), 0 if not * 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 /* copies data from one CustomData object to another
* objects need not be compatible, each source layer is copied to the * 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) * first dest layer of correct type (if there is none, the layer is skipped)
* return 1 on success, 0 on failure * return 1 on success, 0 on failure
*/ */
int CustomData_copy_data(const CustomData *source, CustomData *dest, int CustomData_copy_data(const struct CustomData *source,
int source_index, int dest_index, int count); 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 /* frees data in a CustomData object
* return 1 on success, 0 on failure * 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 /* interpolates data from one CustomData object to another
* objects need not be compatible, each source layer is interpolated to the * 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 * 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 *src_indices, float *weights, float *sub_weights,
int count, int dest_index); 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 /* gets a pointer to the data element at index from the first layer of type
* returns NULL if there is no 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 /* gets a pointer to the first layer of type
* returns NULL if there is no 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 /* copies the data from source to the data element at index in the first
* layer of type * layer of type
* no effect if there is no 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 /* sets the number of elements in a CustomData object
* if the value given is more than the maximum, the maximum is used * 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 #endif

View File

@@ -59,6 +59,7 @@
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
#include "BKE_cdderivedmesh.h" #include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
#include "BKE_DerivedMesh.h" #include "BKE_DerivedMesh.h"
#include "BKE_displist.h" #include "BKE_displist.h"
#include "BKE_effect.h" #include "BKE_effect.h"
@@ -154,9 +155,9 @@ void DM_init(DerivedMesh *dm,
void DM_from_template(DerivedMesh *dm, DerivedMesh *source, void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
int numVerts, int numEdges, int numFaces) int numVerts, int numEdges, int numFaces)
{ {
CustomData_from_template(&source->vertData, &dm->vertData, numVerts); CustomData_from_template(&source->vertData, &dm->vertData, 0, numVerts);
CustomData_from_template(&source->edgeData, &dm->edgeData, numEdges); CustomData_from_template(&source->edgeData, &dm->edgeData, 0, numEdges);
CustomData_from_template(&source->faceData, &dm->faceData, numFaces); CustomData_from_template(&source->faceData, &dm->faceData, 0, numFaces);
DM_init_funcs(dm); DM_init_funcs(dm);
} }
@@ -335,7 +336,7 @@ void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest,
int count, int dest_index) int count, int dest_index)
{ {
CustomData_interp(&source->edgeData, &dest->edgeData, src_indices, 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, 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) int count, int dest_index)
{ {
CustomData_interp(&source->faceData, &dest->faceData, src_indices, CustomData_interp(&source->faceData, &dest->faceData, src_indices,
weights, (float *)vert_weights, count, dest_index); weights, (float*)vert_weights, count, dest_index);
} }
typedef struct { typedef struct {
@@ -1087,24 +1088,27 @@ static void emDM_drawUVEdges(DerivedMesh *dm)
{ {
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditFace *efa; EditFace *efa;
TFace *tf;
glBegin(GL_LINES); glBegin(GL_LINES);
for(efa= emdm->em->faces.first; efa; efa= efa->next) { for(efa= emdm->em->faces.first; efa; efa= efa->next) {
if(!(efa->tf.flag&TF_HIDE)) { tf = CustomData_em_get(&emdm->em->fdata, efa->data, LAYERTYPE_TFACE);
glVertex2fv(efa->tf.uv[0]);
glVertex2fv(efa->tf.uv[1]);
glVertex2fv(efa->tf.uv[1]); if(tf && !(tf->flag&TF_HIDE)) {
glVertex2fv(efa->tf.uv[2]); glVertex2fv(tf->uv[0]);
glVertex2fv(tf->uv[1]);
glVertex2fv(tf->uv[1]);
glVertex2fv(tf->uv[2]);
if (!efa->v4) { if (!efa->v4) {
glVertex2fv(efa->tf.uv[2]); glVertex2fv(tf->uv[2]);
glVertex2fv(efa->tf.uv[0]); glVertex2fv(tf->uv[0]);
} else { } else {
glVertex2fv(efa->tf.uv[2]); glVertex2fv(tf->uv[2]);
glVertex2fv(efa->tf.uv[3]); glVertex2fv(tf->uv[3]);
glVertex2fv(efa->tf.uv[3]); glVertex2fv(tf->uv[3]);
glVertex2fv(efa->tf.uv[0]); glVertex2fv(tf->uv[0]);
} }
} }
} }

View File

@@ -37,6 +37,7 @@
#include "BIF_gl.h" #include "BIF_gl.h"
#include "BKE_cdderivedmesh.h" #include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
#include "BKE_DerivedMesh.h" #include "BKE_DerivedMesh.h"
#include "BKE_displist.h" #include "BKE_displist.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
@@ -751,13 +752,11 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
MEdge *medge = CDDM_get_edges(dm); MEdge *medge = CDDM_get_edges(dm);
MFace *mface = CDDM_get_faces(dm); MFace *mface = CDDM_get_faces(dm);
int *index; int *index;
TFace *tf;
/* this maps from vert pointer to vert index */ /* set eve->hash to vert index */
GHash *vertHash = BLI_ghash_new(BLI_ghashutil_ptrhash,
BLI_ghashutil_ptrcmp);
for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i) 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) if(me->msticky)
CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL); 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++) { i++, eed = eed->next, index++) {
MEdge *med = &medge[i]; MEdge *med = &medge[i];
med->v1 = (int) BLI_ghash_lookup(vertHash, eed->v1); med->v1 = eed->v1->hash;
med->v2 = (int) BLI_ghash_lookup(vertHash, eed->v2); med->v2 = eed->v2->hash;
med->crease = (unsigned char) (eed->crease * 255.0f); med->crease = (unsigned char) (eed->crease * 255.0f);
med->flag = ME_EDGEDRAW|ME_EDGERENDER; med->flag = ME_EDGEDRAW|ME_EDGERENDER;
@@ -824,22 +823,21 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
i++, efa = efa->next, index++) { i++, efa = efa->next, index++) {
MFace *mf = &mface[i]; MFace *mf = &mface[i];
mf->v1 = (int) BLI_ghash_lookup(vertHash, efa->v1); mf->v1 = efa->v1->hash;
mf->v2 = (int) BLI_ghash_lookup(vertHash, efa->v2); mf->v2 = efa->v2->hash;
mf->v3 = (int) BLI_ghash_lookup(vertHash, efa->v3); mf->v3 = efa->v3->hash;
mf->v4 = efa->v4 ? (int)BLI_ghash_lookup(vertHash, efa->v4) : 0; mf->v4 = efa->v4 ? efa->v4->hash : 0;
mf->mat_nr = efa->mat_nr; mf->mat_nr = efa->mat_nr;
mf->flag = efa->flag; mf->flag = efa->flag;
test_index_face(mf, NULL, NULL, efa->v4?4:3); test_index_face(mf, NULL, NULL, efa->v4?4:3);
*index = i; *index = i;
if(me->tface) tf = CustomData_em_get(&em->fdata, efa->data, LAYERTYPE_TFACE);
DM_set_face_data(dm, i, LAYERTYPE_TFACE, &efa->tf); if(tf)
DM_set_face_data(dm, i, LAYERTYPE_TFACE, tf);
} }
BLI_ghash_free(vertHash, NULL, NULL);
return dm; 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)) if(!CustomData_get_layer(&edgeData, LAYERTYPE_MEDGE))
CustomData_add_layer(&edgeData, LAYERTYPE_MEDGE, CustomData_add_layer(&edgeData, LAYERTYPE_MEDGE,

View File

@@ -36,6 +36,7 @@
#include "BLI_linklist.h" #include "BLI_linklist.h"
#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
@@ -46,13 +47,6 @@
/* number of layers to add when growing a CustomData object */ /* number of layers to add when growing a CustomData object */
#define CUSTOMDATA_GROW 5 #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 **********************/ /********************* Layer type information **********************/
typedef struct LayerTypeInfo { typedef struct LayerTypeInfo {
int size; /* the memory size of one element of this layer's data */ int size; /* the memory size of one element of this layer's data */
@@ -83,45 +77,12 @@ typedef struct LayerTypeInfo {
*/ */
void (*interp)(void **sources, float *weights, float *sub_weights, void (*interp)(void **sources, float *weights, float *sub_weights,
int count, void *dest); int count, void *dest);
/* 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; } 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];
}
static void layerCopy_mdeformvert(const void *source, void *dest, static void layerCopy_mdeformvert(const void *source, void *dest,
int count, int size) int count, int size)
{ {
@@ -210,6 +171,18 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
BLI_linklist_free(dest_dw, linklist_free_simple); 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, static void layerInterp_tface(void **sources, float *weights,
float *sub_weights, int count, void *dest) float *sub_weights, int count, void *dest)
{ {
@@ -217,30 +190,32 @@ static void layerInterp_tface(void **sources, float *weights,
int i, j, k; int i, j, k;
float uv[4][2]; float uv[4][2];
float col[4][4]; float col[4][4];
float *sub_weight;
if(count <= 0) return; if(count <= 0) return;
memset(uv, 0, sizeof(uv)); memset(uv, 0, sizeof(uv));
memset(col, 0, sizeof(col)); memset(col, 0, sizeof(col));
sub_weight = sub_weights;
for(i = 0; i < count; ++i) { for(i = 0; i < count; ++i) {
float weight = weights ? weights[i] : 1; float weight = weights ? weights[i] : 1;
TFace *src = sources[i]; TFace *src = sources[i];
for(j = 0; j < 4; ++j) { for(j = 0; j < 4; ++j) {
if(sub_weights) { if(sub_weights) {
for(k = 0; k < 4; ++k) { for(k = 0; k < 4; ++k, ++sub_weight) {
float sub_weight = sub_weights[j * 4 + k]; float w = (*sub_weight) * weight;
char *tmp_col = (char *)&src->col[k]; char *tmp_col = (char *)&src->col[k];
float *tmp_uv = src->uv[k]; float *tmp_uv = src->uv[k];
uv[j][0] += tmp_uv[0] * sub_weight * weight; uv[j][0] += tmp_uv[0] * w;
uv[j][1] += tmp_uv[1] * sub_weight * weight; uv[j][1] += tmp_uv[1] * w;
col[j][0] += tmp_col[0] * sub_weight * weight; col[j][0] += tmp_col[0] * w;
col[j][1] += tmp_col[1] * sub_weight * weight; col[j][1] += tmp_col[1] * w;
col[j][2] += tmp_col[2] * sub_weight * weight; col[j][2] += tmp_col[2] * w;
col[j][3] += tmp_col[3] * sub_weight * weight; col[j][3] += tmp_col[3] * w;
} }
} else { } else {
char *tmp_col = (char *)&src->col[j]; 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, static void layerInterp_mcol(void **sources, float *weights,
float *sub_weights, int count, void *dest) float *sub_weights, int count, void *dest)
{ {
@@ -280,14 +263,15 @@ static void layerInterp_mcol(void **sources, float *weights,
float g; float g;
float b; float b;
} col[4]; } col[4];
float *sub_weight;
if(count <= 0) return; if(count <= 0) return;
memset(col, 0, sizeof(col)); memset(col, 0, sizeof(col));
sub_weight = sub_weights;
for(i = 0; i < count; ++i) { for(i = 0; i < count; ++i) {
float weight = weights ? weights[i] : 1; float weight = weights ? weights[i] : 1;
float *sub_weight = sub_weights;
for(j = 0; j < 4; ++j) { for(j = 0; j < 4; ++j) {
if(sub_weights) { 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 *********************/ /********************* CustomData functions *********************/
void CustomData_init(CustomData *data, void CustomData_init(CustomData *data,
int maxLayers, int maxElems, int subElems) int maxLayers, int maxElems, int subElems)
@@ -329,19 +348,36 @@ void CustomData_init(CustomData *data,
data->subElems = subElems; data->subElems = subElems;
} }
void CustomData_from_template(const CustomData *source, CustomData *dest, static void CustomData_update_offsets(CustomData *data)
int maxElems)
{ {
int i; 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 flag, int maxElems)
{
int i, layerflag;
CustomData_init(dest, source->maxLayers, maxElems, source->subElems); CustomData_init(dest, source->maxLayers, maxElems, source->subElems);
for(i = 0; i < source->numLayers; ++i) { for(i = 0; i < source->numLayers; ++i) {
if(source->layers[i].flag & LAYERFLAG_NOCOPY) continue; if(source->layers[i].flag & LAYERFLAG_NOCOPY) continue;
CustomData_add_layer(dest, source->layers[i].type, layerflag = (source->layers[i].flag & ~LAYERFLAG_NOFREE) | flag;
source->layers[i].flag & ~LAYERFLAG_NOFREE, NULL); CustomData_add_layer(dest, source->layers[i].type, layerflag, NULL);
} }
CustomData_update_offsets(dest);
} }
void CustomData_free(CustomData *data) void CustomData_free(CustomData *data)
@@ -356,7 +392,8 @@ void CustomData_free(CustomData *data)
typeInfo->free(data->layers[i].data, data->numElems, typeInfo->free(data->layers[i].data, data->numElems,
typeInfo->size); typeInfo->size);
MEM_freeN(data->layers[i].data); if(data->layers[i].data)
MEM_freeN(data->layers[i].data);
} }
} }
@@ -368,73 +405,6 @@ void CustomData_free(CustomData *data)
} }
} }
static int customData_grow(CustomData *data, int amount)
{
LayerDesc *tmp = MEM_callocN(sizeof(*tmp) * (data->maxLayers + amount),
"CustomData->layers");
if(!tmp) return 0;
data->maxLayers += amount;
memcpy(tmp, data->layers, sizeof(*tmp) * data->numLayers);
MEM_freeN(data->layers);
data->layers = tmp;
return 1;
}
static int customData_add_layer__internal(CustomData *data, int type,
int flag, void *layer)
{
int index = data->numLayers;
if(index >= data->maxLayers)
if(!customData_grow(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];
data->layers[index].type = type;
data->layers[index].flag = flag;
data->layers[index].data = layer;
data->numLayers++;
return 1;
}
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(!tmp_layer) return 0;
if(customData_add_layer__internal(data, type, flag, tmp_layer))
return 1;
else {
MEM_freeN(tmp_layer);
return 0;
}
}
int CustomData_compat(const CustomData *data1, const CustomData *data2)
{
int i;
if(data1->numLayers != data2->numLayers) return 0;
for(i = 0; i < data1->numLayers; ++i) {
if(data1->layers[i].type != data2->layers[i].type) return 0;
if(data1->layers[i].flag != data2->layers[i].flag) return 0;
}
return 1;
}
/* gets index of first layer matching type after start_index /* gets index of first layer matching type after start_index
* if start_index < 0, starts searching at 0 * if start_index < 0, starts searching at 0
* returns -1 if there is no layer of type * returns -1 if there is no layer of type
@@ -452,6 +422,99 @@ static int CustomData_find_next(const CustomData *data, int type,
return -1; return -1;
} }
static int customData_resize(CustomData *data, int amount)
{
CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxLayers + amount),
"CustomData->layers");
if(!tmp) return 0;
data->maxLayers += amount;
memcpy(tmp, data->layers, sizeof(*tmp) * data->numLayers);
MEM_freeN(data->layers);
data->layers = tmp;
return 1;
}
static int customData_add_layer__internal(CustomData *data, int type,
int flag, void *layer)
{
int index = data->numLayers;
if(index >= data->maxLayers)
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];
data->layers[index].type = type;
data->layers[index].flag = flag;
data->layers[index].data = layer;
data->numLayers++;
CustomData_update_offsets(data);
return 1;
}
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, "CustomDataLayer.data");
if(!tmp_layer) return 0;
if(customData_add_layer__internal(data, type, flag, tmp_layer))
return 1;
else {
MEM_freeN(tmp_layer);
return 0;
}
}
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;
if(data1->numLayers != data2->numLayers) return 0;
for(i = 0; i < data1->numLayers; ++i) {
if(data1->layers[i].type != data2->layers[i].type) return 0;
if(data1->layers[i].flag != data2->layers[i].flag) return 0;
}
return 1;
}
int CustomData_copy_data(const CustomData *source, CustomData *dest, int CustomData_copy_data(const CustomData *source, CustomData *dest,
int source_index, int dest_index, int count) 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 */ /* interpolates a layer at a time */
for(src_i = 0; src_i < source->numLayers; ++src_i) { 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 = const LayerTypeInfo *type_info =
layerType_getInfo(source_layer->type); 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; if(numElems < data->maxElems) data->numElems = numElems;
else data->numElems = data->maxElems; 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);
}
}

View File

@@ -45,6 +45,7 @@
#include "BKE_bad_level_calls.h" #include "BKE_bad_level_calls.h"
#include "BKE_cdderivedmesh.h" #include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"

View File

@@ -38,6 +38,7 @@
#ifndef BLI_EDITVERT_H #ifndef BLI_EDITVERT_H
#define BLI_EDITVERT_H #define BLI_EDITVERT_H
#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
struct DerivedMesh; struct DerivedMesh;
@@ -125,7 +126,6 @@ typedef struct EditFace
float fp; float fp;
} tmp; } tmp;
float n[3], cent[3]; float n[3], cent[3];
struct TFace tf; /* a copy of original tface. */
unsigned char mat_nr, flag; unsigned char mat_nr, flag;
unsigned char f, f1, h; unsigned char f, f1, h;
unsigned char fast; /* only 0 or 1, for editmesh_fastmalloc */ unsigned char fast; /* only 0 or 1, for editmesh_fastmalloc */
@@ -133,6 +133,7 @@ typedef struct EditFace
/*#ifdef WITH_VERSE*/ /*#ifdef WITH_VERSE*/
void *vface; void *vface;
/*#endif*/ /*#endif*/
void *data; /* custom face data */
} EditFace; } EditFace;
@@ -167,6 +168,8 @@ typedef struct EditMesh
char retopo_mode; /* 0=OFF, 1=ON, 2=PAINT */ char retopo_mode; /* 0=OFF, 1=ON, 2=PAINT */
struct RetopoPaintData *retopo_paint_data; struct RetopoPaintData *retopo_paint_data;
CustomData fdata;
#ifdef WITH_VERSE #ifdef WITH_VERSE
void *vnode; void *vnode;
#endif #endif

View File

@@ -104,6 +104,11 @@ extern int faceselectedAND(struct EditFace *efa, int flag);
extern void recalc_editnormals(void); extern void recalc_editnormals(void);
extern void flip_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 */ /* ******************* editmesh_mods.c */
extern void EM_init_index_arrays(int forVert, int forEdge, int forFace); extern void EM_init_index_arrays(int forVert, int forEdge, int forFace);

View File

@@ -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_unused_geometry(struct VNode *vnode);
void destroy_binding_between_versemesh_and_editmesh(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); void unsubscribe_from_geom_node(struct VNode *vnode);

View File

@@ -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

View File

@@ -43,6 +43,7 @@
#include "PIL_time.h" #include "PIL_time.h"
#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
@@ -64,6 +65,7 @@
#include "BKE_DerivedMesh.h" #include "BKE_DerivedMesh.h"
#include "BKE_depsgraph.h" #include "BKE_depsgraph.h"
#include "BKE_customdata.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_key.h" #include "BKE_key.h"
#include "BKE_library.h" #include "BKE_library.h"
@@ -150,7 +152,6 @@ EditVert *addvertlist(float *vec)
* have a pre-editmode vertex order * have a pre-editmode vertex order
*/ */
eve->keyindex = -1; eve->keyindex = -1;
#ifdef WITH_VERSE #ifdef WITH_VERSE
createVerseVert(eve); createVerseVert(eve);
#endif #endif
@@ -325,9 +326,9 @@ void free_editface(EditFace *efa)
} }
#endif #endif
EM_remove_selection(efa, EDITFACE); EM_remove_selection(efa, EDITFACE);
if(efa->fast==0){ CustomData_em_free_block(&G.editMesh->fdata, &efa->data);
if(efa->fast==0)
free(efa); free(efa);
}
} }
void free_vertlist(ListBase *edve) void free_vertlist(ListBase *edve)
@@ -409,17 +410,14 @@ EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, Ed
if(example) { if(example) {
efa->mat_nr= example->mat_nr; efa->mat_nr= example->mat_nr;
efa->tf= example->tf;
efa->tf.flag &= ~TF_ACTIVE;
efa->flag= example->flag; efa->flag= example->flag;
CustomData_em_copy_data(&em->fdata, example->data, &efa->data);
} }
else { else {
if (G.obedit && G.obedit->actcol) if (G.obedit && G.obedit->actcol)
efa->mat_nr= G.obedit->actcol-1; efa->mat_nr= G.obedit->actcol-1;
default_uv(efa->tf.uv, 1.0);
/* Initialize colors */ CustomData_em_set_default(&em->fdata, &efa->data);
efa->tf.col[0]= efa->tf.col[1]= efa->tf.col[2]= efa->tf.col[3]= vpaint_get_current_col();
} }
BLI_addtail(&em->faces, efa); 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) static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface)
{ {
if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts"); if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts");
else em->allverts= NULL; else em->allverts= NULL;
em->curvert= em->allverts; em->curvert= em->allverts;
@@ -556,6 +553,9 @@ void free_editMesh(EditMesh *em)
if(em->edges.first) free_edgelist(&em->edges); if(em->edges.first) free_edgelist(&em->edges);
if(em->faces.first) free_facelist(&em->faces); if(em->faces.first) free_facelist(&em->faces);
if(em->selected.first) BLI_freelistN(&(em->selected)); if(em->selected.first) BLI_freelistN(&(em->selected));
CustomData_free(&em->fdata);
if(em->derivedFinal) { if(em->derivedFinal) {
if (em->derivedFinal!=em->derivedCage) { if (em->derivedFinal!=em->derivedCage) {
em->derivedFinal->release(em->derivedFinal); em->derivedFinal->release(em->derivedFinal);
@@ -774,6 +774,7 @@ static void edge_drawflags(void)
void make_editMesh() void make_editMesh()
{ {
Mesh *me= G.obedit->data; Mesh *me= G.obedit->data;
EditMesh *em= G.editMesh;
MFace *mface; MFace *mface;
TFace *tface; TFace *tface;
MVert *mvert; MVert *mvert;
@@ -783,6 +784,7 @@ void make_editMesh()
EditFace *efa; EditFace *efa;
EditEdge *eed; EditEdge *eed;
EditSelection *ese; EditSelection *ese;
CustomData mfdata;
int tot, a, eekadoodle= 0; int tot, a, eekadoodle= 0;
#ifdef WITH_VERSE #ifdef WITH_VERSE
@@ -793,7 +795,7 @@ void make_editMesh()
#endif #endif
/* because of reload */ /* because of reload */
free_editMesh(G.editMesh); free_editMesh(em);
G.totvert= tot= me->totvert; G.totvert= tot= me->totvert;
G.totedge= me->totedge; G.totedge= me->totedge;
@@ -804,9 +806,8 @@ void make_editMesh()
return; return;
} }
/* initialize fastmalloc for editmesh */ /* 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); actkey = ob_get_keyblock(G.obedit);
if(actkey) { if(actkey) {
@@ -847,10 +848,9 @@ void make_editMesh()
} }
} }
if(actkey && actkey->totelem!=me->totvert); if(actkey && actkey->totelem!=me->totvert);
else { else {
unsigned int *mcol;
MEdge *medge= me->medge; MEdge *medge= me->medge;
/* make edges */ /* 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 */ /* make faces */
mface= me->mface; mface= me->mface;
tface= me->tface; tface= me->tface;
mcol= (unsigned int *)me->mcol;
for(a=0; a<me->totface; a++, mface++) { for(a=0; a<me->totface; a++, mface++) {
eve1= evlist[mface->v1]; eve1= evlist[mface->v1];
eve2= evlist[mface->v2]; eve2= evlist[mface->v2];
@@ -885,13 +893,8 @@ void make_editMesh()
efa= addfacelist(eve1, eve2, eve3, eve4, NULL, NULL); efa= addfacelist(eve1, eve2, eve3, eve4, NULL, NULL);
if(efa) { if(efa) {
CustomData_to_em_block(&mfdata, &em->fdata, a, &efa->data);
if(mcol) memcpy(efa->tf.col, mcol, 4*sizeof(int));
if(me->tface) {
efa->tf= *tface;
}
efa->mat_nr= mface->mat_nr; efa->mat_nr= mface->mat_nr;
efa->flag= mface->flag & ~ME_HIDE; efa->flag= mface->flag & ~ME_HIDE;
@@ -902,18 +905,18 @@ void make_editMesh()
} }
if(mface->flag & ME_HIDE) efa->h= 1; if(mface->flag & ME_HIDE) efa->h= 1;
} }
else if (tface) { else if((tface = CustomData_get(&mfdata, a, LAYERTYPE_TFACE))) {
if( tface->flag & TF_HIDE) if(tface->flag & TF_HIDE)
efa->h= 1; efa->h= 1;
else if( tface->flag & TF_SELECT) { else if(tface->flag & TF_SELECT)
EM_select_face(efa, 1); EM_select_face(efa, 1);
}
} }
} }
if(me->tface) tface++; if(me->tface) tface++;
if(mcol) mcol+=4;
} }
CustomData_free(&mfdata);
} }
if(eekadoodle) 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 == 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 == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else
if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index); 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(); EM_free_index_arrays();
@@ -962,6 +965,7 @@ void load_editMesh(void)
MFace *mface; MFace *mface;
MSticky *ms; MSticky *ms;
MSelect *mselect; MSelect *mselect;
TFace *tf;
EditVert *eve; EditVert *eve;
EditFace *efa; EditFace *efa;
EditEdge *eed; EditEdge *eed;
@@ -969,7 +973,7 @@ void load_editMesh(void)
float *fp, *newkey, *oldkey, nor[3]; float *fp, *newkey, *oldkey, nor[3];
int i, a, ototvert, totedge=0; int i, a, ototvert, totedge=0;
MDeformVert *dvert; MDeformVert *dvert;
CustomData mfdata;
#ifdef WITH_VERSE #ifdef WITH_VERSE
if(em->vnode) { if(em->vnode) {
@@ -1005,7 +1009,7 @@ void load_editMesh(void)
/* new Face block */ /* new Face block */
if(G.totface==0) mface= NULL; if(G.totface==0) mface= NULL;
else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face"); else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face");
/* are we adding dverts? */ /* are we adding dverts? */
if (G.totvert==0) dvert= NULL; if (G.totvert==0) dvert= NULL;
else if(G.obedit->defbase.first==NULL) dvert= NULL; else if(G.obedit->defbase.first==NULL) dvert= NULL;
@@ -1028,9 +1032,21 @@ void load_editMesh(void)
me->totedge= totedge; me->totedge= totedge;
if(me->mface) MEM_freeN(me->mface); if(me->mface) MEM_freeN(me->mface);
me->mface= mface; me->mface= mface;
me->totface= G.totface; 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 */ /* the vertices, use ->tmp.l as counter */
eve= em->verts.first; eve= em->verts.first;
a= 0; a= 0;
@@ -1145,9 +1161,11 @@ void load_editMesh(void)
efa->e4->f2= 2; efa->e4->f2= 2;
} }
CustomData_from_em_block(&em->fdata, &mfdata, efa->data, i);
/* no index '0' at location 3 or 4 */ /* 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 #ifdef WITH_VERSE
if(efa->vface) { if(efa->vface) {
@@ -1159,55 +1177,27 @@ void load_editMesh(void)
i++; i++;
efa= efa->next; efa= efa->next;
} }
/* tface block */ /* sync hide and select flags with faceselect mode */
if( me->tface && me->totface ) { if(G.f & G_FACESELECT) {
TFace *tfn, *tf; if(me->tface && (me->totface > 0)) {
efa= em->faces.first;
tf=tfn= MEM_callocN(sizeof(TFace)*me->totface, "tface"); for(a=0, efa=em->faces.first; efa; a++, efa++) {
efa= em->faces.first; tf = CustomData_get(&mfdata, a, LAYERTYPE_TFACE);
while(efa) {
if(efa->h) tf->flag |= TF_HIDE;
*tf= efa->tf;
if(G.f & G_FACESELECT) {
if( efa->h) tf->flag |= TF_HIDE;
else 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; else tf->flag &= ~TF_SELECT;
} }
tf++;
efa= efa->next;
} }
}
if(me->tface) MEM_freeN(me->tface); /* from CustomData to tface and mcol in Mesh */
me->tface= tfn; me->tface = CustomData_get(&mfdata, 0, LAYERTYPE_TFACE);
} me->mcol = CustomData_get(&mfdata, 0, LAYERTYPE_MCOL);
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"); CustomData_free(&mfdata);
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;
}
/* patch hook indices */ /* patch hook indices */
{ {
@@ -1576,6 +1566,7 @@ void separate_mesh(void)
emcopy.alledges= NULL; emcopy.alledges= NULL;
emcopy.allfaces= NULL; emcopy.allfaces= NULL;
emcopy.derivedFinal= emcopy.derivedCage= NULL; emcopy.derivedFinal= emcopy.derivedCage= NULL;
memset(&emcopy.fdata, 0, sizeof(emcopy.fdata));
free_editMesh(&emcopy); free_editMesh(&emcopy);
em->verts= edve; em->verts= edve;
@@ -1769,6 +1760,7 @@ void separate_mesh_loose(void)
emcopy.alledges= NULL; emcopy.alledges= NULL;
emcopy.allfaces= NULL; emcopy.allfaces= NULL;
emcopy.derivedFinal= emcopy.derivedCage= NULL; emcopy.derivedFinal= emcopy.derivedCage= NULL;
memset(&emcopy.fdata, 0, sizeof(emcopy.fdata));
free_editMesh(&emcopy); free_editMesh(&emcopy);
em->verts= edve; em->verts= edve;
@@ -1839,14 +1831,13 @@ typedef struct UndoMesh {
EditEdgeC *edges; EditEdgeC *edges;
EditFaceC *faces; EditFaceC *faces;
EditSelectionC *selected; EditSelectionC *selected;
TFace *tfaces; int totvert, totedge, totface, totsel;
int totvert, totedge, totface,totsel;
short selectmode; short selectmode;
RetopoPaintData *retopo_paint_data; RetopoPaintData *retopo_paint_data;
char retopo_mode; char retopo_mode;
CustomData fdata;
} UndoMesh; } UndoMesh;
/* for callbacks */ /* for callbacks */
static void free_undoMesh(void *umv) 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->verts) MEM_freeN(um->verts);
if(um->edges) MEM_freeN(um->edges); if(um->edges) MEM_freeN(um->edges);
if(um->faces) MEM_freeN(um->faces); if(um->faces) MEM_freeN(um->faces);
if(um->tfaces) MEM_freeN(um->tfaces);
if(um->selected) MEM_freeN(um->selected); if(um->selected) MEM_freeN(um->selected);
if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data); if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
CustomData_free(&um->fdata);
MEM_freeN(um); MEM_freeN(um);
} }
@@ -1872,7 +1863,6 @@ static void *editMesh_to_undoMesh(void)
{ {
EditMesh *em= G.editMesh; EditMesh *em= G.editMesh;
UndoMesh *um; UndoMesh *um;
Mesh *me= G.obedit->data;
EditVert *eve; EditVert *eve;
EditEdge *eed; EditEdge *eed;
EditFace *efa; EditFace *efa;
@@ -1881,7 +1871,6 @@ static void *editMesh_to_undoMesh(void)
EditEdgeC *eedc=NULL; EditEdgeC *eedc=NULL;
EditFaceC *efac=NULL; EditFaceC *efac=NULL;
EditSelectionC *esec=NULL; EditSelectionC *esec=NULL;
TFace *tface= NULL;
int a; int a;
um= MEM_callocN(sizeof(UndoMesh), "undomesh"); 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->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->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(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)); if(um->totface) CustomData_from_template(&em->fdata, &um->fdata, 0, um->totface);
//printf("copy undomesh %d\n", um->totvert*sizeof(EditVertC) + um->totedge*sizeof(EditEdgeC) + um->totface*sizeof(EditFaceC));
/* now copy vertices */ /* now copy vertices */
a = 0; a = 0;
@@ -1946,12 +1932,10 @@ static void *editMesh_to_undoMesh(void)
efac->f= efa->f; efac->f= efa->f;
efac->h= efa->h; efac->h= efa->h;
efac->fgonf= efa->fgonf; efac->fgonf= efa->fgonf;
if(tface) {
*tface= efa->tf;
tface++;
}
efa->tmp.l = a; /*store index*/ efa->tmp.l = a; /*store index*/
CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
} }
a = 0; a = 0;
@@ -1980,7 +1964,6 @@ static void undoMesh_to_editMesh(void *umv)
EditEdgeC *eedc; EditEdgeC *eedc;
EditFaceC *efac; EditFaceC *efac;
EditSelectionC *esec; EditSelectionC *esec;
TFace *tface;
int a=0; int a=0;
#ifdef WITH_VERSE #ifdef WITH_VERSE
@@ -2031,7 +2014,9 @@ static void undoMesh_to_editMesh(void *umv)
} }
/* copy faces */ /* 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++) { for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
if(efac->v4 != -1) if(efac->v4 != -1)
efa= addfacelist(evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL); 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->h= efac->h;
efa->fgonf= efac->fgonf; efa->fgonf= efac->fgonf;
if(tface) { CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
efa->tf= *tface;
tface++;
}
} }
end_editmesh_fastmalloc(); end_editmesh_fastmalloc();

View File

@@ -57,6 +57,7 @@ editmesh_lib: generic (no UI, no menus) operations/evaluators for editmesh data
#include "BLI_arithb.h" #include "BLI_arithb.h"
#include "BLI_editVert.h" #include "BLI_editVert.h"
#include "BKE_customdata.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_utildefines.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 ********* */ /* ******** EXTRUDE ********* */
@@ -1442,8 +1481,8 @@ short extrudeflag_vert(short flag, float *nor)
if(eed->tmp.f) { if(eed->tmp.f) {
efa = eed->tmp.f; efa = eed->tmp.f;
efa2->mat_nr= efa->mat_nr; efa2->mat_nr= efa->mat_nr;
efa2->tf= efa->tf;
efa2->flag= efa->flag; efa2->flag= efa->flag;
CustomData_em_copy_data(&em->fdata, &efa->data, &efa2->data);
} }
/* Needs smarter adaption of existing creases. /* Needs smarter adaption of existing creases.
@@ -1761,18 +1800,15 @@ void flipface(EditFace *efa)
SWAP(EditVert *, efa->v2, efa->v4); SWAP(EditVert *, efa->v2, efa->v4);
SWAP(EditEdge *, efa->e1, efa->e4); SWAP(EditEdge *, efa->e1, efa->e4);
SWAP(EditEdge *, efa->e2, efa->e3); SWAP(EditEdge *, efa->e2, efa->e3);
SWAP(unsigned int, efa->tf.col[1], efa->tf.col[3]); EM_interp_from_faces(efa, NULL, efa, 0, 3, 2, 1);
SWAP(float, efa->tf.uv[1][0], efa->tf.uv[3][0]);
SWAP(float, efa->tf.uv[1][1], efa->tf.uv[3][1]);
} }
else { else {
SWAP(EditVert *, efa->v2, efa->v3); SWAP(EditVert *, efa->v2, efa->v3);
SWAP(EditEdge *, efa->e1, efa->e3); SWAP(EditEdge *, efa->e1, efa->e3);
SWAP(unsigned int, efa->tf.col[1], efa->tf.col[2]);
efa->e2->dir= 1-efa->e2->dir; efa->e2->dir= 1-efa->e2->dir;
SWAP(float, efa->tf.uv[1][0], efa->tf.uv[2][0]); EM_interp_from_faces(efa, NULL, efa, 0, 2, 1, 3);
SWAP(float, efa->tf.uv[1][1], efa->tf.uv[2][1]);
} }
if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n); 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); else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
} }

View File

@@ -62,6 +62,7 @@ editmesh_mods.c, UI level access, no geometry changes
#include "BKE_displist.h" #include "BKE_displist.h"
#include "BKE_depsgraph.h" #include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h" #include "BKE_DerivedMesh.h"
#include "BKE_customdata.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_material.h" #include "BKE_material.h"
@@ -824,13 +825,26 @@ int facegroup_select(short mode)
} }
} }
} else if (mode==2) { /* same image */ } 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) { for(efa= em->faces.first; efa; efa= efa->next) {
if (!(efa->f & SELECT) && !efa->h && base_efa->tf.tpage == efa->tf.tpage) { if (!(efa->f & SELECT) && !efa->h) {
EM_select_face(efa, 1); tf = (TFace*)CustomData_em_get(&em->fdata, efa->data,
selcount++; LAYERTYPE_TFACE);
deselcount--;
if (!deselcount) /*have we selected all posible faces?, if so return*/ if(base_tf->tpage == tf->tpage) {
return selcount; 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 */ } 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)); 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, /* XXX, code for both these functions should be abstract,
* then unified, then written for other things (like objects, * then unified, then written for other things (like objects,
* which would use same as vertices method), then added * 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) void faceselect_align_view_to_selected(View3D *v3d, Mesh *me, int axis)
{ {
if (!faceselect_nfaces_selected(me)) { float norm[3];
error("No faces selected."); int i, totselected = 0;
} else {
float norm[3];
int i;
norm[0]= norm[1]= norm[2]= 0.0; norm[0]= norm[1]= norm[2]= 0.0;
for (i=0; i<me->totface; i++) { for (i=0; i<me->totface; i++) {
MFace *mf= ((MFace*) me->mface) + i; MFace *mf= ((MFace*) me->mface) + i;
TFace *tf= ((TFace*) me->tface) + i; TFace *tf= ((TFace*) me->tface) + i;
if (tface_is_selected(tf)) {
float *v1, *v2, *v3, fno[3];
v1= me->mvert[mf->v1].co; if (tface_is_selected(tf)) {
v2= me->mvert[mf->v2].co; float *v1, *v2, *v3, fno[3];
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]; v1= me->mvert[mf->v1].co;
norm[1]+= fno[1]; v2= me->mvert[mf->v2].co;
norm[2]+= fno[2]; 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);
} }
}
view3d_align_axis_to_vector(v3d, axis, norm); 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) void editmesh_align_view_to_selected(View3D *v3d, int axis)

File diff suppressed because it is too large Load Diff