[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23123] branches/bmesh/blender/source/ blender: rewrote edge split modifier to be simpler and hopefully faster.

Joseph Eagar joeedh at gmail.com
Fri Sep 11 12:21:54 CEST 2009


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




More information about the Bf-blender-cvs mailing list