[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12562] branches/bmesh/source/blender: -> Tesselation code and normals support in editmode

Geoffrey Bantle hairbat at yahoo.com
Mon Nov 12 08:50:47 CET 2007


Revision: 12562
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12562
Author:   briggs
Date:     2007-11-12 08:50:47 +0100 (Mon, 12 Nov 2007)

Log Message:
-----------
-> Tesselation code and normals support in editmode

Added a new tesselator (it actually relies on blenders old scanfill but with a new
interface and better convention for plane projection.) This is for editmode only right
now but can be adapted to object mode rather easily. 

Also brought back normals to editmode. Shrink/Fatten works again.

Modified Paths:
--------------
    branches/bmesh/source/blender/blenkernel/BKE_bmesh.h
    branches/bmesh/source/blender/blenkernel/intern/BME_mesh.c
    branches/bmesh/source/blender/blenkernel/intern/BME_structure.c
    branches/bmesh/source/blender/blenkernel/intern/DerivedMesh.c
    branches/bmesh/source/blender/blenlib/BLI_blenlib.h
    branches/bmesh/source/blender/blenlib/intern/scanfill.c
    branches/bmesh/source/blender/makesdna/DNA_mesh_types.h
    branches/bmesh/source/blender/src/editbmesh_interface.c
    branches/bmesh/source/blender/src/editbmesh_tools.c

Modified: branches/bmesh/source/blender/blenkernel/BKE_bmesh.h
===================================================================
--- branches/bmesh/source/blender/blenkernel/BKE_bmesh.h	2007-11-12 04:17:03 UTC (rev 12561)
+++ branches/bmesh/source/blender/blenkernel/BKE_bmesh.h	2007-11-12 07:50:47 UTC (rev 12562)
@@ -59,7 +59,7 @@
 #define BME_LOOP 4
 #define SELECT 1
 /*defines for element->flag*/
-#define BME_VISITED 2											/*for traversal/selection functions*/
+#define BME_VISITED 16											/*for traversal/selection functions*/
 #define BME_NEW 4											/*for tools*/
 #define BME_DELETE 8
 
@@ -68,10 +68,12 @@
 	void 				*data;
 } BME_CycleNode;
 
+struct BME_Tria;
+
 typedef struct BME_Mesh
 {
 	ListBase 			verts, edges, polys, loops;
-	int 				lock;									/*if set, all calls to eulers will fail.*/
+	int 				lock, dirty;									/*if set, all calls to eulers will fail.*/
 	short			selectmode;							/*selection mode. Technically a copy of G.scene->selectmode*/
 	struct BME_Mesh 	*backup;								/*full copy of the mesh*/
 	int 				totvert, totedge, totpoly, totloop;				/*record keeping*/
@@ -83,6 +85,10 @@
 	int options;										//bevel
 	int res;											//bevel
 	short imval[2];
+	/*tesselated data*/
+	int tottrias;
+	struct BME_Tria			*trias;
+
 } BME_Mesh;
 
 /*Beginning of all mesh elements should share this layout!*/
@@ -135,24 +141,28 @@
 	struct BME_CycleNode 	radial;								/*circularly linked list used to find faces around an edge*/
 	struct BME_CycleNode 	*gref;								/*pointer to loop ref. Nasty.*/
 	struct BME_Vert 		*v;									/*vertex that this loop starts at.*/
-	struct BME_Edge 	*e;									/*edge this loop belongs to*/
+	struct BME_Edge 		*e;									/*edge this loop belongs to*/
 	struct BME_Poly 		*f;									/*face this loop belongs to*/	
-	void 				*data;								/*custom per face vertex data*/
+	void 				*data;									/*custom per face vertex data*/
 } BME_Loop;
 
+typedef struct BME_Tria{
+	BME_Loop *l1, *l2, *l3;
+} BME_Tria;
+
 typedef struct BME_Poly
 {
 	struct BME_Poly 		*next, *prev;
-	int 				EID;
+	int 					EID;
 	unsigned short 		flag, h; 
 	int 				eflag1, eflag2;							/*reserved for use by eulers*/
 	int 				tflag1, tflag2;							/*reserved for use by tools*/
 	unsigned short 		mat_nr;
 	struct BME_Loop 	*loopbase;								/*First editloop around Polygon.*/
-	struct ListBase 		holes;								/*list of inner loops in the face*/
+	struct ListBase 	holes;									/*list of inner loops in the face*/
 	unsigned int 		len;									/*total length of the face. Eulers should preserve this data*/
-	void 				*data;								/*custom face data*/
-
+	void 				*data;									/*custom face data*/
+	float no[3], cent[3];
 } BME_Poly;
 
 //*EDGE UTILITIES*/
@@ -180,11 +190,13 @@
 struct BME_Mesh *BME_make_mesh(void);
 void BME_free_mesh(struct BME_Mesh *bm);
 struct BME_Mesh *BME_copy_mesh(struct BME_Mesh *bm);
+void BME_tesselate_polys(struct BME_Mesh *bm);
 /*FULL MESH VALIDATION*/
 int BME_validate_mesh(struct BME_Mesh *bm, int halt);
 /*ENTER/EXIT MODELLING LOOP*/
 int BME_model_begin(struct BME_Mesh *bm);
 void BME_model_end(struct BME_Mesh *bm);
+void BME_calc_normals(struct BME_Mesh *bm);
 
 /*MESH CONSTRUCTION API.*/
 /*MAKE*/

Modified: branches/bmesh/source/blender/blenkernel/intern/BME_mesh.c
===================================================================
--- branches/bmesh/source/blender/blenkernel/intern/BME_mesh.c	2007-11-12 04:17:03 UTC (rev 12561)
+++ branches/bmesh/source/blender/blenkernel/intern/BME_mesh.c	2007-11-12 07:50:47 UTC (rev 12562)
@@ -327,6 +327,7 @@
 	
 	for(loopref=bm->loops.first;loopref;loopref=loopref->next) BME_delete_loop(bm,loopref->data);
 	BLI_freelistN(&(bm->loops));
+	if(bm->tottrias) MEM_freeN(bm->trias);
 	MEM_freeN(bm);	
 }
 

Modified: branches/bmesh/source/blender/blenkernel/intern/BME_structure.c
===================================================================
--- branches/bmesh/source/blender/blenkernel/intern/BME_structure.c	2007-11-12 04:17:03 UTC (rev 12561)
+++ branches/bmesh/source/blender/blenkernel/intern/BME_structure.c	2007-11-12 07:50:47 UTC (rev 12562)
@@ -38,6 +38,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_listBase.h"
+#include "DNA_meshdata_types.h"
 #include "BKE_utildefines.h"
 #include "BKE_bmesh.h"
 #include "BLI_blenlib.h"
@@ -194,6 +195,7 @@
 	f->EID = bm->nextp;
 	f->flag |= BME_NEW;
 	if(example && (example->flag & SELECT))f->flag|=SELECT;
+	if(example && (example->flag & ME_NSMOOTH))f->flag|=ME_NSMOOTH;
 	bm->nextp++;
 	bm->totpoly++;
 

Modified: branches/bmesh/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- branches/bmesh/source/blender/blenkernel/intern/DerivedMesh.c	2007-11-12 04:17:03 UTC (rev 12561)
+++ branches/bmesh/source/blender/blenkernel/intern/DerivedMesh.c	2007-11-12 07:50:47 UTC (rev 12562)
@@ -123,6 +123,7 @@
 	return medge;
 }
 
+
 MFace *dm_getFaceArray(DerivedMesh *dm)
 {
 	MFace *mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
@@ -671,12 +672,129 @@
 	emdm->cdraw->drawFacePoints(emdm->cdraw, alpha, fsize);
 }
 
+
+static void BME_tesselate_polys(BME_Mesh *bm){
+
+	BME_Vert *v;
+	BME_Poly *f;
+	BME_Tria *tria;
+	BME_Loop *l;
+	EditFace *efa;
+	unsigned int *handles = NULL, maxloop=0,i;
+	float **cos = NULL, norm[3], cent[3];
+	ListBase tessface = {NULL,NULL}, tempverts = {NULL, NULL}, tempedges = {NULL, NULL};
+	
+	if(bm->tottrias) MEM_freeN(bm->trias);
+	bm->tottrias = 0;
+
+	/*find maxloop*/
+	for(f=BME_first(bm,BME_POLY); f; f=BME_next(bm,BME_POLY,f)){
+		if(f->len > maxloop) maxloop = f->len;
+	}
+	
+	if(maxloop < 3) return;
+
+	/*allocate arrays*/
+	handles = MEM_mallocN(sizeof(unsigned int)*maxloop, "BMesh tesselation mesh handles");
+	cos = MEM_mallocN(sizeof(float *)*maxloop, "BMesh tesselation coordinate pointers");
+	
+	/*do faces greater than 4*/
+	for(f=BME_first(bm,BME_POLY); f; f=BME_next(bm,BME_POLY,f)){
+		/*populate handles and coordinates array*/
+		i=0;
+		l = f->loopbase;
+		do{
+			cos[i] = l->v->co;
+			handles[i] = l;
+			i++;
+			l = l->next;
+			l->eflag1 = i; //mark order
+		}while(l!=f->loopbase);
+
+		/*tesselate*/
+		BLI_tesselate_poly(handles, cos, f->len);
+
+		/*calculate normal*/
+		f->no[0] = f->no[1] = f->no[2] = 0.0;
+		//for(efa = fillfacebase.first; efa; efa = efa->next){
+		//	CalcNormFloat(((BME_Loop*)(efa->v1->tmp.v))->v->co, ((BME_Loop*)(efa->v2->tmp.v))->v->co, ((BME_Loop*)(efa->v3->tmp.v))->v->co, norm);
+				//CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, norm);
+		//	VecAddf(f->no, f->no, norm);
+		//}			
+		//Normalize(f->no);
+		
+
+		/*split list and set pointers to zero*/	
+		addlisttolist(&tessface,&fillfacebase);
+		addlisttolist(&tempverts, &fillvertbase);
+		addlisttolist(&tempedges, &filledgebase);
+	}
+	
+	/*populate tesselation*/
+	bm->tottrias = BLI_countlist(&tessface);
+	tria = bm->trias = MEM_mallocN(sizeof(BME_Tria)*bm->tottrias,"Bmesh tesselation data");
+	for(efa=tessface.first;efa;efa=efa->next){
+		/*make sure winding is correct*/
+		BME_Loop *la[3], *t;
+
+		la[0] = efa->v1->tmp.v;
+		la[1] = efa->v2->tmp.v;
+		la[2] = efa->v3->tmp.v;
+
+		if(la[0]->eflag1 > la[1]->eflag1) { t = la[0]; la[0] = la[1]; la[1] = t;}
+		if(la[1]->eflag1 > la[2]->eflag1) { t = la[1]; la[1] = la[2]; la[2] = t;}
+		if(la[0]->eflag1 > la[1]->eflag1) { t = la[0]; la[0] = la[1]; la[1] = t;}
+
+		tria->l1 = la[0];
+		tria->l2 = la[1];
+		tria->l3 = la[2];
+
+		tria++;
+	}
+
+	/*now calculate face normals*/
+	for(i=0; i < bm->tottrias; i++){
+		CalcNormFloat(bm->trias[i].l1->v->co, bm->trias[i].l2->v->co, bm->trias[i].l3->v->co, norm);
+		VecAddf(bm->trias[i].l1->f->no, bm->trias[i].l1->f->no, norm);
+	}
+	
+	for(f=BME_first(bm,BME_POLY); f; f=BME_next(bm,BME_POLY,f)) Normalize(f->no);
+
+	/*calculate vertex normals*/
+	for(v=BME_first(bm,BME_VERT); v; v=BME_next(bm,BME_VERT,v)){
+		v->no[0] = v->no[1] = v->no[2] = 0.0;
+	}
+
+	for(f=BME_first(bm,BME_POLY); f; f=BME_next(bm,BME_POLY,f)){
+		l=f->loopbase;
+		do{
+			VecAddf(l->v->no, l->v->no, f->no);
+			l=l->next;
+		}while(l!=f->loopbase);
+	}
+
+	for(v=BME_first(bm,BME_VERT); v; v=BME_next(bm,BME_VERT,v)){
+		if(Normalize(v->no)==0.0){
+			VECCOPY(v->no,v->co);
+			Normalize(v->no);
+		}
+	}
+
+	/*clean up mem*/
+	BLI_end_edgefill();
+	MEM_freeN(handles);
+	MEM_freeN(cos);
+}
+
+
+
 static void emDM_recalcDrawCache(EditBMeshDerivedMesh *emdm)
 {
 	BME_Poly *efa;
 	BME_Loop *loop;
 	BME_Edge *eed;
 	BME_Vert *eve;
+	BME_Tria *t;
 	float v[3][3], no[3][3], facedot[3];
 	float nor[3], vsize;
 	char high[4], vcol[3], svcol[3], ecol[3], secol[3], fcol[3], sfcol[3];
@@ -713,29 +831,30 @@
 		VecMulf(facedot, 1.0f/(float)i);
 		if (efa->flag & SELECT) emdm->cdraw->addFacePoint(emdm->cdraw, facedot, sfcol);
 		else emdm->cdraw->addFacePoint(emdm->cdraw, facedot, fcol);
-		
-		/*do face itself, triangulate via trangle-fan.*/
-		loop = efa->loopbase->next;
-		do {
-			VECCOPY(v[0], loop->v->co);
-			VECCOPY(v[1], loop->next->v->co);
-			VECCOPY(v[2], efa->loopbase->v->co);
-			if (efa->flag & ME_NSMOOTH) {
-				VECCOPY(no[0], loop->v->no);
-				VECCOPY(no[1], loop->next->v->no);
-				VECCOPY(no[2], efa->loopbase->v->no);
-			} else {
-				CalcNormFloat(efa->loopbase->v->co, efa->loopbase->next->v->co, 
-				              efa->loopbase->next->next->v->co, nor);
-				VECCOPY(no[0], nor);
-				VECCOPY(no[1], nor);
-				VECCOPY(no[2], nor);
-			}
-			emdm->cdraw->addTriangle(emdm->cdraw, v, no, NULL, high, efa->mat_nr);
-			loop=loop->next;
-		} while (loop != efa->loopbase->prev);
 	}
 	
+	BME_tesselate_polys(emdm->bmesh);
+	/*do n-gons in a seperate pass*/
+	for(i=0; i< emdm->bmesh->tottrias; i++){
+		t = &(emdm->bmesh->trias[i]);
+		
+		VECCOPY(v[0], t->l1->v->co);
+		VECCOPY(v[1], t->l2->v->co);
+		VECCOPY(v[2], t->l3->v->co);
+		
+		if(t->l1->f->flag & ME_NSMOOTH){
+			VECCOPY(no[0], t->l1->v->no);
+			VECCOPY(no[1], t->l2->v->no);
+			VECCOPY(no[2], t->l3->v->no);
+		} else {
+			VECCOPY(no[0], t->l1->f->no);
+			VECCOPY(no[1], t->l1->f->no);
+			VECCOPY(no[2], t->l1->f->no);
+		}
+		emdm->cdraw->addTriangle(emdm->cdraw, v, no, NULL, high, t->l1->f->mat_nr);
+	}	
+
+
 	for (eve=emdm->bmesh->verts.first; eve; eve=eve->next) {
 		if (eve->flag & SELECT) emdm->cdraw->addVertPoint(emdm->cdraw, eve->co, svcol);
 		else emdm->cdraw->addVertPoint(emdm->cdraw, eve->co, vcol);

Modified: branches/bmesh/source/blender/blenlib/BLI_blenlib.h
===================================================================

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list