further fixes for modifiers, and edge loop select works now.

This commit is contained in:
Joseph Eagar
2009-06-16 20:08:40 +00:00
parent 80effa20b1
commit a457b7129c
9 changed files with 198 additions and 53 deletions

View File

@@ -65,7 +65,7 @@ struct BMEditMesh;
/* number of sub-elements each mesh element has (for interpolation) */
#define SUB_ELEMS_VERT 0
#define SUB_ELEMS_EDGE 2
#define SUB_ELEMS_FACE 4
#define SUB_ELEMS_FACE 50
/*
note: all mface interfaces now officially operate on tesselated data.

View File

@@ -240,8 +240,8 @@ int DM_release(DerivedMesh *dm)
CustomData_free_temporary(&dm->vertData, dm->numVertData);
CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
CustomData_free_temporary(&dm->faceData, dm->numFaceData);
CustomData_free(&dm->loopData, dm->numLoopData);
CustomData_free(&dm->polyData, dm->numPolyData);
CustomData_free_temporary(&dm->loopData, dm->numLoopData);
CustomData_free_temporary(&dm->polyData, dm->numPolyData);
return 0;
}
@@ -357,6 +357,8 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me)
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
CustomData_free(&me->fdata, me->totface);
CustomData_free(&me->ldata, me->totloop);
CustomData_free(&me->pdata, me->totpoly);
/* if the number of verts has changed, remove invalid data */
if(tmp.totvert != me->totvert) {

View File

@@ -781,8 +781,14 @@ static void cdDM_foreachMappedFaceCenter(
MVert *mv = cddm->mvert;
MPoly *mf = cddm->mpoly;
MLoop *ml = cddm->mloop;
int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
float (*cents)[3];
float (*nors)[3];
int *flens;
int i, j, orig, *index;
int maxf=0;
index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
mf = cddm->mpoly;
for(i = 0; i < dm->numPolyData; i++, mf++) {
float cent[3];
float no[3];
@@ -790,8 +796,7 @@ static void cdDM_foreachMappedFaceCenter(
if (index) {
orig = *index++;
if(orig == ORIGINDEX_NONE) continue;
}
else
} else
orig = i;
ml = &cddm->mloop[mf->loopstart];
@@ -804,14 +809,15 @@ static void cdDM_foreachMappedFaceCenter(
ml = &cddm->mloop[mf->loopstart];
if (j > 3) {
CalcNormFloat4(mv[ml->v].co, mv[(ml+1)->v].co,
mv[(ml+2)->v].co, mv[(ml+3)->v].co, no);
mv[(ml+2)->v].co, mv[(ml+3)->v].co, no);
} else {
CalcNormFloat(mv[ml->v].co, mv[(ml+1)->v].co,
mv[(ml+2)->v].co, no);
mv[(ml+2)->v].co, no);
}
func(userData, orig, cent, no);
}
}
static void cdDM_release(DerivedMesh *dm)
@@ -1651,7 +1657,7 @@ void CDDM_tessfaces_to_faces(DerivedMesh *dm)
MLoop *ml;
MPoly *mp;
EdgeHash *eh = BLI_edgehash_new();
int i, l, totloop;
int i, l, totloop, *index1, *index2;
me = cddm->medge;
for (i=0; i<cddm->dm.numEdgeData; i++, me++) {
@@ -1664,14 +1670,25 @@ void CDDM_tessfaces_to_faces(DerivedMesh *dm)
totloop += mf->v4 ? 4 : 3;
}
cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
cddm->dm.numLoopData = totloop;
cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
cddm->dm.numPolyData = cddm->dm.numFaceData;
if (!totloop) return;
cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData,
CD_MASK_DERIVEDMESH, CD_DUPLICATE, cddm->dm.numFaceData);
index1 = CustomData_get_layer(&cddm->dm.faceData, CD_ORIGINDEX);
index2 = CustomData_get_layer(&cddm->dm.polyData, CD_ORIGINDEX);
mf = cddm->mface;
mp = cddm->mpoly;
ml = cddm->mloop;

View File

@@ -806,7 +806,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
if(layer->flag & CD_FLAG_NOCOPY) continue;
else if(!((int)mask & (int)(1 << (int)type))) continue;
else if(number < CustomData_number_of_layers(dest, type)) continue;
else if(number+1 < CustomData_number_of_layers(dest, type)) continue;
if((alloctype == CD_ASSIGN) && (layer->flag & CD_FLAG_NOFREE))
newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE,

View File

@@ -428,7 +428,7 @@ static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditme
}
#endif
/* face weighting */
static void calc_ss_weights(int gridFaces,
FaceVertWeight **qweight, FaceVertWeight **tweight)
{
@@ -472,6 +472,61 @@ static void calc_ss_weights(int gridFaces,
}
}
/* face weighting */
typedef struct FaceVertWeightEntry {
FaceVertWeight *weight;
int valid;
} FaceVertWeightEntry;
typedef struct WeightTable {
FaceVertWeightEntry *weight_table;
int len;
} WeightTable;
static FaceVertWeight *get_ss_weights(WeightTable *wtable, int gridFaces, int faceLen)
{
int i;
/*ensure we have at least the triangle and quad weights*/
if (wtable->len < 4) {
wtable->weight_table = MEM_callocN(sizeof(FaceVertWeightEntry)*5, "weight table alloc");
wtable->len = 5;
calc_ss_weights(gridFaces, &wtable->weight_table[4].weight, &wtable->weight_table[3].weight);
wtable->weight_table[4].valid = wtable->weight_table[3].valid = 1;
}
if (wtable->len <= faceLen) {
void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry)*(faceLen+1), "weight table alloc 2");
memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry)*wtable->len);
MEM_freeN(wtable->weight_table);
wtable->weight_table = tmp;
wtable->len = faceLen+1;
}
if (!wtable->weight_table[faceLen].valid) {
/*ok, need to calculate weights here*/
wtable->weight_table[faceLen].weight =
MEM_callocN(sizeof(FaceVertWeight)*gridFaces*gridFaces,
"vert face weight");
wtable->weight_table[faceLen].valid = 1;
}
return wtable->weight_table[faceLen].weight;
}
void free_ss_weights(WeightTable *wtable)
{
int i;
for (i=0; i<wtable->len; i++) {
if (wtable->weight_table[i].valid)
MEM_freeN(wtable->weight_table[i].weight);
}
}
static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
int drawInteriorEdges, int useSubsurfUv,
DerivedMesh *dm, MultiresSubsurf *ms)
@@ -493,11 +548,13 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
int totvert, totedge, totface;
MVert *mvert;
MEdge *med;
float *w = NULL;
WeightTable wtable;
V_DECLARE(w);
MFace *mf;
int *origIndex;
FaceVertWeight *qweight, *tweight;
calc_ss_weights(gridFaces, &qweight, &tweight);
memset(&wtable, 0, sizeof(wtable));
/* vert map */
totvert = ccgSubSurf_getNumVerts(ss);
@@ -554,7 +611,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
for(index = 0; index < totface; index++) {
CCGFace *f = faceMap2[index];
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
FaceVertWeight *weight = get_ss_weights(&wtable, gridFaces, numVerts);
V_RESET(vertIdx);
@@ -572,19 +629,22 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
++origIndex;
i++;
V_RESET(w);
for (x=0; x<numVerts; x++) {
V_GROW(w);
}
#if 0 //BMESH_TODO
for(S = 0; S < numVerts; S++) {
int prevS = (S - 1 + numVerts) % numVerts;
int nextS = (S + 1) % numVerts;
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
int otherS = (numVerts >= 4) ? (S + 2) % numVerts : 3;
for(x = 1; x < gridFaces; x++) {
float w[4];
w[prevS] = weight[x][0][0];
w[S] = weight[x][0][1];
w[nextS] = weight[x][0][2];
w[otherS] = weight[x][0][3];
DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
VecCopyf(mvert->co,
ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
@@ -595,20 +655,25 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
i++;
}
}
V_RESET(w);
for (x=0; x<numVerts; x++) {
V_GROW(w);
}
for(S = 0; S < numVerts; S++) {
int prevS = (S - 1 + numVerts) % numVerts;
int nextS = (S + 1) % numVerts;
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
for(y = 1; y < gridFaces; y++) {
for(x = 1; x < gridFaces; x++) {
float w[4];
w[prevS] = weight[y * gridFaces + x][0][0];
w[S] = weight[y * gridFaces + x][0][1];
w[nextS] = weight[y * gridFaces + x][0][2];
w[otherS] = weight[y * gridFaces + x][0][3];
DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
VecCopyf(mvert->co,
ccgSubSurf_getFaceGridData(ss, f, S, x, y));
*origIndex = ORIGINDEX_NONE;
@@ -618,7 +683,6 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
}
}
}
#endif
*((int*)ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
faceBase += 1 + numVerts * ((gridSize-2) + (gridSize-2) * (gridSize-2));
}
@@ -634,12 +698,14 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
v = ccgSubSurf_getEdgeVert1(e);
vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
for(x = 1; x < edgeSize - 1; x++) {
float w[2];
w[1] = (float) x / (edgeSize - 1);
w[0] = 1 - w[1];
DM_interp_vert_data(dm, result, vertIdx, w, 2, i);
float w2[2];
w2[1] = (float) x / (edgeSize - 1);
w2[0] = 1 - w2[1];
DM_interp_vert_data(dm, result, vertIdx, w2, 2, i);
VecCopyf(mvert->co, ccgSubSurf_getEdgeData(ss, e, x));
*origIndex = ORIGINDEX_NONE;
++mvert;
@@ -768,8 +834,8 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
}
for(S = 0; S < numVerts; S++) {
FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
FaceVertWeight *weight = get_ss_weights(&wtable, gridFaces, numVerts);
for(y = 0; y < gridFaces; y++) {
for(x = 0; x < gridFaces; x++) {
mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
@@ -815,9 +881,8 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
MEM_freeN(edgeMap2);
MEM_freeN(vertMap2);
MEM_freeN(tweight);
MEM_freeN(qweight);
free_ss_weights(&wtable);
V_FREE(vertIdx);
if(useSubsurfUv) {
@@ -831,7 +896,9 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
}
CDDM_calc_normals(result);
CDDM_tessfaces_to_faces(result);
V_FREE(w);
return result;
}
@@ -1365,7 +1432,7 @@ void ccgDM_faceIterStep(void *self)
fiter->head.len = fiter->mface.v4 ? 4 : 3;
}
void ccgDM_faceIterCData(void *self, int type, int layer)
void *ccgDM_faceIterCData(void *self, int type, int layer)
{
ccgDM_faceIter *fiter = self;

View File

@@ -71,8 +71,9 @@ struct BMVert;
struct BMEdge;
struct BMFace;
struct BMLoop;
struct EditMesh;
struct BMOperator;
struct Mesh;
struct EditMesh;
/*
* BMHeader
@@ -234,7 +235,7 @@ struct BMFace *BM_Make_Ngon(struct BMesh *bm, struct BMVert *v1, struct BMVert *
#define BM_SetHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag | (f))
#define BM_ClearHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag & ~(f))
/*stuff for setting indices*/
/*stuff for setting indices in elements.*/
#define BMINDEX_SET(ele, i) (((BMHeader*)ele)->index = i)
#define BMINDEX_GET(ele) ((BMHeader*)ele)->index
@@ -332,6 +333,11 @@ int BMFlags_To_MEFlags(void *element);
MVert, MEdge, and MPoly, respectively).*/
int MEFlags_To_BMFlags(void *element, int type);
/*convert MLoop*** in a bmface to mtface and mcol in
an MFace*/
void BM_loops_to_corners(BMesh *bm, struct Mesh *me, int findex,
BMFace *f, int numTex, int numCol);
/*include the rest of the API*/
#include "bmesh_filters.h"
#include "bmesh_iterators.h"

View File

@@ -31,7 +31,12 @@
*/
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_customdata.h"
#include "BKE_utildefines.h"
#include "bmesh.h"
#include "bmesh_private.h"
@@ -104,6 +109,56 @@ void BM_Data_Facevert_Edgeinterp(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, B
}while(l!=e1->loop);
}
void BM_loops_to_corners(BMesh *bm, Mesh *me, int findex,
BMFace *f, int numTex, int numCol)
{
int i, j;
BMLoop *l;
BMIter iter;
MTFace *texface;
MTexPoly *texpoly;
MCol *mcol;
MLoopCol *mloopcol;
MLoopUV *mloopuv;
for(i=0; i < numTex; i++){
texface = CustomData_get_n(&me->fdata, CD_MTFACE, findex, i);
texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
texface->tpage = texpoly->tpage;
texface->flag = texpoly->flag;
texface->transp = texpoly->transp;
texface->mode = texpoly->mode;
texface->tile = texpoly->tile;
texface->unwrap = texpoly->unwrap;
j = 0;
BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
texface->uv[j][0] = mloopuv->uv[0];
texface->uv[j][1] = mloopuv->uv[1];
j++;
}
}
for(i=0; i < numCol; i++){
mcol = CustomData_get_n(&me->fdata, CD_MCOL, findex, i);
j = 0;
BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
mcol[j].r = mloopcol->r;
mcol[j].g = mloopcol->g;
mcol[j].b = mloopcol->b;
mcol[j].a = mloopcol->a;
j++;
}
}
}
//static void bmesh_data_interp_from_face(BME_Mesh *bm, BMFace *source, BMFace *target)
//{
//

View File

@@ -140,11 +140,11 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
BMLoop *l;
BMFace *f;
BMIter iter, liter;
int i, j, ototvert, totloop;
/*we'll going to have the bmesh-to-editmesh operator
do most the work, then layer in ngon data, hehehe*/
int i, j, ototvert, totloop, numTex, numCol;
numTex = CustomData_number_of_layers(&me->pdata, CD_MLOOPUV);
numCol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
bmtess = BM_Copy_Mesh(bm);
BMO_CallOpf(bmtess, "makefgon trifan=%i", 0);
@@ -205,8 +205,11 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
mesh_update_customdata_pointers(me);
CustomData_from_bmeshpoly(&me->fdata, &bmtess->pdata, &bmtess->ldata, bmtess->totface);
mesh_update_customdata_pointers(me);
/*set indices*/
i = 0;
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
@@ -265,6 +268,8 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
mface->v4 = BMINDEX_GET(((BMLoop*)f->loopbase->head.next->next->next)->v);
test_index_face(mface, &me->fdata, i, 1);
BM_loops_to_corners(bmtess, me, i, f, numTex, numCol);
mface++;
i++;
}

View File

@@ -894,21 +894,14 @@ static void edgeloop_select(BMEditMesh *em, BMEdge *starteed, int select)
{
BMesh *bm = em->bm;
BMEdge *e;
BMOperator op;
BMWalker walker;
BMO_Exec_Op(bm, &op);
e = BMO_Get_MapPointer(bm, &op, "map", starteed);
BMW_Init(&walker, bm, BMW_LOOP, 0);
e = BMW_Begin(&walker, e);
e = BMW_Begin(&walker, starteed);
for (; e; e=BMW_Step(&walker)) {
BM_Select(bm, e, 1);
}
BMW_End(&walker);
BMO_Finish_Op(bm, &op);
}
/*
@@ -1034,7 +1027,7 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Multi Select Loops";
ot->idname= "MESH_OT_select_loop_multi";
ot->idname= "MESH_OT_loop_multi_select";
/* api callbacks */
ot->exec= loop_multiselect;
@@ -1112,7 +1105,7 @@ void MESH_OT_loop_select(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Loop Select";
ot->idname= "MESH_OT_select_loop";
ot->idname= "MESH_OT_loop_select";
/* api callbacks */
ot->invoke= mesh_select_loop_invoke;
@@ -1213,7 +1206,7 @@ void MESH_OT_select_shortest_path(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Shortest Path Select";
ot->idname= "MESH_OT_select_path_shortest";
ot->idname= "MESH_OT_select_shortest_path";
/* api callbacks */
ot->invoke= mesh_shortest_path_select_invoke;