Revision: 23123 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23123 Author: joeedh Date: 2009-09-11 12:21:54 +0200 (Fri, 11 Sep 2009)
Log Message: ----------- rewrote edge split modifier to be simpler and hopefully faster. and of course it handles ngons properly now. Modified Paths: -------------- branches/bmesh/blender/source/blender/blenkernel/BKE_cdderivedmesh.h branches/bmesh/blender/source/blender/blenkernel/BKE_utildefines.h branches/bmesh/blender/source/blender/blenkernel/intern/cdderivedmesh.c branches/bmesh/blender/source/blender/blenkernel/intern/modifier.c branches/bmesh/blender/source/blender/bmesh/operators/mesh_conv.c Modified: branches/bmesh/blender/source/blender/blenkernel/BKE_cdderivedmesh.h =================================================================== --- branches/bmesh/blender/source/blender/blenkernel/BKE_cdderivedmesh.h 2009-09-11 09:13:25 UTC (rev 23122) +++ branches/bmesh/blender/source/blender/blenkernel/BKE_cdderivedmesh.h 2009-09-11 10:21:54 UTC (rev 23123) @@ -93,9 +93,14 @@ /* calculates edges for a CDDerivedMesh (from face data) * this completely replaces the current edge data in the DerivedMesh + * builds edges from the tesselated face data. */ void CDDM_calc_edges(struct DerivedMesh *dm); +/* same as CDDM_calc_edges only makes edges from ngon faces instead of tesselation + faces*/ +void CDDM_calc_edges_poly(struct DerivedMesh *dm); + /* lowers the number of vertices/edges/faces in a CDDerivedMesh * the layer data stays the same size */ @@ -124,5 +129,14 @@ struct MLoop *CDDM_get_loops(struct DerivedMesh *dm); struct MPoly *CDDM_get_faces(struct DerivedMesh *dm); +/*Assigns news m*** layers to the cddm. Note that you must handle + freeing the old ones yourself. Also you must ensure dm->num****Data + is correct.*/ +void CDDM_set_mvert(struct DerivedMesh *dm, struct MVert *mvert); +void CDDM_set_medge(struct DerivedMesh *dm, struct MEdge *medge); +void CDDM_set_mface(struct DerivedMesh *dm, struct MFace *mface); +void CDDM_set_mloop(struct DerivedMesh *dm, struct MLoop *mloop); +void CDDM_set_mpoly(struct DerivedMesh *dm, struct MPoly *mpoly); + #endif Modified: branches/bmesh/blender/source/blender/blenkernel/BKE_utildefines.h =================================================================== --- branches/bmesh/blender/source/blender/blenkernel/BKE_utildefines.h 2009-09-11 09:13:25 UTC (rev 23122) +++ branches/bmesh/blender/source/blender/blenkernel/BKE_utildefines.h 2009-09-11 10:21:54 UTC (rev 23123) @@ -235,10 +235,14 @@ _##vec##_count++) #define V_FREE(vec) if (vec) MEM_freeN(vec); + /*resets the logical size of an array to zero, but doesn't free the memory.*/ #define V_RESET(vec) _##vec##_count=0 +/*set the count of the array*/ +#define V_SETCOUNT(vec, count) _##vec##_count = (count) + /*little macro so inline keyword works*/ #if defined(_MSC_VER) #define BM_INLINE static __forceinline Modified: branches/bmesh/blender/source/blender/blenkernel/intern/cdderivedmesh.c =================================================================== --- branches/bmesh/blender/source/blender/blenkernel/intern/cdderivedmesh.c 2009-09-11 09:13:25 UTC (rev 23122) +++ branches/bmesh/blender/source/blender/blenkernel/intern/cdderivedmesh.c 2009-09-11 10:21:54 UTC (rev 23123) @@ -1620,6 +1620,83 @@ BLI_edgehash_free(eh, NULL); } + +void CDDM_calc_edges_poly(DerivedMesh *dm) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + CustomData edgeData; + EdgeHashIterator *ehi; + MPoly *mp = cddm->mpoly; + MLoop *ml; + MEdge *med; + EdgeHash *eh = BLI_edgehash_new(); + int v1, v2; + int *eindex; + int i, j, k, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData; + + eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX); + + med = cddm->medge; + if (med) { + for (i=0; i < numEdges; i++, med++) { + BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i+1)); + } + } + + for (i=0; i < maxFaces; i++, mp++) { + ml = cddm->mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + v1 = ml->v; + v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v; + if (!BLI_edgehash_haskey(eh, v1, v2)) { + BLI_edgehash_insert(eh, v1, v2, NULL); + } + } + } + + k = numEdges; + numEdges = BLI_edgehash_size(eh); + + /* write new edges into a temporary CustomData */ + memset(&edgeData, 0, sizeof(edgeData)); + CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); + CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); + + ehi = BLI_edgehashIterator_new(eh); + med = CustomData_get_layer(&edgeData, CD_MEDGE); + index = CustomData_get_layer(&edgeData, CD_ORIGINDEX); + for(i = 0; !BLI_edgehashIterator_isDone(ehi); + BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) { + BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2); + j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); + + med->flag = ME_EDGEDRAW|ME_EDGERENDER; + *index = j==0 ? ORIGINDEX_NONE : eindex[j-1]; + + BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i)); + } + BLI_edgehashIterator_free(ehi); + + /* free old CustomData and assign new one */ + CustomData_free(&dm->edgeData, dm->numEdgeData); + dm->edgeData = edgeData; + dm->numEdgeData = numEdges; + + cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); + + mp = cddm->mpoly; + for (i=0; i < maxFaces; i++, mp++) { + ml = cddm->mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + v1 = ml->v; + v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v; + ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2)); + } + } + + BLI_edgehash_free(eh, NULL); +} + void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts) { if (numVerts < dm->numVertData) @@ -1752,6 +1829,42 @@ BLI_edgehash_free(eh, NULL); } +void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + CustomData_add_layer(&cddm->dm.vertData, CD_MVERT, CD_ASSIGN, mvert, cddm->dm.numVertData); + cddm->mvert = mvert; +} + +void CDDM_set_medge(DerivedMesh *dm, MEdge *medge) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + CustomData_add_layer(&cddm->dm.edgeData, CD_MEDGE, CD_ASSIGN, medge, cddm->dm.numEdgeData); + cddm->medge = medge; +} + +void CDDM_set_mface(DerivedMesh *dm, MFace *mface) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + CustomData_add_layer(&cddm->dm.faceData, CD_MFACE, CD_ASSIGN, mface, cddm->dm.numFaceData); + cddm->mface = mface; +} + +void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, mloop, cddm->dm.numLoopData); + cddm->mloop = mloop; +} + +void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, mpoly, cddm->dm.numPolyData); + cddm->mpoly = mpoly; +} + + /* Multires DerivedMesh, extends CDDM */ typedef struct MultiresDM { CDDerivedMesh cddm; Modified: branches/bmesh/blender/source/blender/blenkernel/intern/modifier.c =================================================================== --- branches/bmesh/blender/source/blender/blenkernel/intern/modifier.c 2009-09-11 09:13:25 UTC (rev 23122) +++ branches/bmesh/blender/source/blender/blenkernel/intern/modifier.c 2009-09-11 10:21:54 UTC (rev 23123) @@ -51,6 +51,7 @@ #include "BLI_ghash.h" #include "BLI_memarena.h" #include "BLI_cellalloc.h" +#include "BLI_mempool.h" #include "MEM_guardedalloc.h" @@ -2122,6 +2123,11 @@ } #endif +DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, + Object *ob, + DerivedMesh *dm, + int initFlags, + int axis); static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, Object *ob, DerivedMesh *dm, int initFlags) @@ -2174,7 +2180,7 @@ */ /*new cddm-based edge split code*/ -#if 0 +#if 1 typedef struct VertUser { int ov, v, done; ListBase users; @@ -2186,36 +2192,303 @@ } EdgeNode; typedef struct EdgeData { - EdgeNode v1list, v2list; + EdgeNode v1node, v2node; VertUser *v1user, *v2user; int tag; int v1, v2; + int used; } EdgeData; +typedef struct MemBase { + BLI_mempool *vertuserpool; +} MemBase; + +static EdgeData *edge_get_next(EdgeData *e, int ov) { + if (ov == e->v1) + return e->v1node.next ? e->v1node.next->edge : NULL; + else return e->v2node.next ? e->v2node.next->edge : NULL; +} + +static EdgeNode *edge_get_node(EdgeData *e, int ov) +{ + if (ov == e->v1) + return &e->v1node; + else return &e->v2node; +} + +static VertUser *edge_get_vuser(MemBase *b, EdgeData *edge, int ov) +{ + if (ov == edge->v1) + return edge->v1user; + else if (ov == edge->v2) + return edge->v2user; + else { + printf("yeek!!\n"); + return NULL; + } +} + +static void edge_set_vuser(MemBase *b, EdgeData *e, int ov, VertUser *vu) + +{ + VertUser *olduser = edge_get_vuser(b, e, ov); + + if (vu == olduser) + return; + + if (olduser) + BLI_remlink(&olduser->users, ov==e->v1 ? &e->v1node : &e->v2node); + BLI_addtail(&vu->users, ov==e->v1 ? &e->v1node : &e->v2node); + + if (ov == e->v1) + e->v1user = vu; + else e->v2user = vu; +} + +static VertUser *new_vuser(MemBase *base) +{ + VertUser *vusr = BLI_mempool_calloc(base->vertuserpool); + + return vusr; +} + +static MemBase *new_membase(void) +{ + MemBase *b = MEM_callocN(sizeof(MemBase), "MemBase for edgesplit in modifier.c"); + b->vertuserpool = BLI_mempool_create(sizeof(VertUser), 1, 2048); + + return b; +} + +static void free_membase(MemBase *b) +{ + BLI_mempool_destroy(b->vertuserpool); + MEM_freeN(b); +} + +static EdgeData *edge_get_first(VertUser *vu) +{ + return vu->users.first ? ((EdgeNode*)vu->users.first)->edge : NULL; +} + DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) { DerivedMesh *cddm = CDDM_copy(dm); - EdgeData *etags; - VertUser *vusers; + MEdge *medge; + V_DECLARE(medge); + MLoop *mloop, *ml, *prevl; + MPoly *mpoly, *mp; + MVert *mvert; + V_DECLARE(mvert); + EdgeData *etags, *e, *enext; + V_DECLARE(etags); + VertUser *vu, *vu2; + MemBase *membase; + CustomData edata, vdata; + int i, j, curv, cure; if (!cddm->numVertData || !cddm->numEdgeData) return cddm; + membase = new_membase(); + etags = MEM_callocN(sizeof(EdgeData)*cddm->numEdgeData, "edgedata tag thingies"); + V_SETCOUNT(etags, cddm->numEdgeData); + mvert = cddm->getVertArray(cddm); + V_SETCOUNT(mvert, cddm->numVertData); + medge = cddm->getEdgeArray(cddm); + V_SETCOUNT(medge, cddm->numEdgeData); + mloop = CustomData_get_layer(&cddm->loopData, CD_MLOOP); + mpoly = CustomData_get_layer(&cddm->polyData, CD_MPOLY); + + for (i=0; i<cddm->numEdgeData; i++) { + etags[i].v1 = medge[i].v1; + etags[i].v2 = medge[i].v2; + + etags[i].tag = (medge[i].flag & ME_SHARP) != 0; + + etags[i].v1node.edge = etags+i; + etags[i].v2node.edge = etags+i; + } + + mp = mpoly; + for (i=0; i<cddm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + if (etags[ml->e].tag) + continue; + + prevl = mloop + mp->loopstart + ((j-1)+mp->totloop) % mp->totloop; + + if (!edge_get_vuser(membase, etags+prevl->e, ml->v)) { + vu = new_vuser(membase); + vu->ov = vu->v = ml->v; @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs