[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