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:
@@ -45,7 +45,7 @@
|
||||
* conversion to DLM.
|
||||
*/
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
|
||||
struct MVert;
|
||||
struct MEdge;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,45 +77,12 @@ typedef struct LayerTypeInfo {
|
||||
*/
|
||||
void (*interp)(void **sources, float *weights, float *sub_weights,
|
||||
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;
|
||||
|
||||
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,
|
||||
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;
|
||||
}
|
||||
|
||||
void CustomData_from_template(const CustomData *source, CustomData *dest,
|
||||
int maxElems)
|
||||
static void CustomData_update_offsets(CustomData *data)
|
||||
{
|
||||
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);
|
||||
|
||||
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,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
|
||||
* if start_index < 0, starts searching at 0
|
||||
* 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;
|
||||
}
|
||||
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
69
source/blender/makesdna/DNA_customdata_types.h
Normal file
69
source/blender/makesdna/DNA_customdata_types.h
Normal 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
|
||||
@@ -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;
|
||||
/* from CustomData to tface and mcol in Mesh */
|
||||
me->tface = CustomData_get(&mfdata, 0, LAYERTYPE_TFACE);
|
||||
me->mcol = CustomData_get(&mfdata, 0, LAYERTYPE_MCOL);
|
||||
|
||||
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;
|
||||
}
|
||||
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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
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];
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
if (tface_is_selected(tf)) {
|
||||
float *v1, *v2, *v3, fno[3];
|
||||
|
||||
norm[0]+= fno[0];
|
||||
norm[1]+= fno[1];
|
||||
norm[2]+= fno[2];
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user