[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11179] branches/soc-2007-red_fox/source/ blender: Editmode bevel tool works now (to an extent)

Levi Schooley redfox at hhofministries.org
Fri Jul 6 06:03:58 CEST 2007


Revision: 11179
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11179
Author:   red_fox
Date:     2007-07-06 06:03:57 +0200 (Fri, 06 Jul 2007)

Log Message:
-----------
Editmode bevel tool works now (to an extent)

I added the bmesh-to-editmesh-and-back-again functions, and
replaced the editmode beveling tool. You access the tool
from the WKEY menu (like the old tool).

The bevel amount is currently hardcoded.

The topology for selection-based beveling is created
properly now, with the exception that non-manifold geometry
is not handled yet, and may crash the tool (as well as loose
verts or edges).

The tool still does not produce accurate offsets.

The tool seems to now handle open meshes correctly (as far
as my tests went).

Note: this is sort of an embarrassing commit. The code is
pretty patchy and needs better/updated documentation.

Levi

Modified Paths:
--------------
    branches/soc-2007-red_fox/source/blender/blenkernel/BKE_bmesh.h
    branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_mesh.c
    branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_tools.c
    branches/soc-2007-red_fox/source/blender/blenkernel/intern/modifier.c
    branches/soc-2007-red_fox/source/blender/src/editmesh_tools.c

Modified: branches/soc-2007-red_fox/source/blender/blenkernel/BKE_bmesh.h
===================================================================
--- branches/soc-2007-red_fox/source/blender/blenkernel/BKE_bmesh.h	2007-07-06 03:12:31 UTC (rev 11178)
+++ branches/soc-2007-red_fox/source/blender/blenkernel/BKE_bmesh.h	2007-07-06 04:03:57 UTC (rev 11179)
@@ -179,4 +179,8 @@
 struct BME_Loop *BME_inset_edge(struct BME_Mesh *bm, struct BME_Loop *l, struct BME_Poly *f);
 struct BME_Poly *BME_inset_poly(struct BME_Mesh *bm, struct BME_Poly *f);
 struct BME_Mesh *BME_bevel_mesh(struct BME_Mesh *bm, float value, int options);
+
+/*CONVERSION FUNCTIONS*/
+struct BME_Mesh *BME_editmesh_to_bmesh(struct EditMesh *em, struct BME_Mesh *bm);
+struct EditMesh *BME_bmesh_to_editmesh(struct BME_Mesh *bm);
 #endif

Modified: branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_mesh.c
===================================================================
--- branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_mesh.c	2007-07-06 03:12:31 UTC (rev 11178)
+++ branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_mesh.c	2007-07-06 04:03:57 UTC (rev 11179)
@@ -326,3 +326,177 @@
 void BME_error(void){
 	printf("BME modelling error!");
 }
+
+/* Conversion functions */
+
+BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, BME_Mesh *bm) {
+	BME_Vert *v1, *v2;
+	BME_Edge *e, *edar[4];
+	BME_Poly *f;
+
+	EditVert *eve;
+	EditEdge *eed;
+	EditFace *efa;
+
+	int len;
+
+	BME_model_begin(bm);
+	/*custom data*/
+	
+	/*add verts*/
+	CustomData_copy(&em->vdata, &bm->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+	eve= em->verts.first;
+	while(eve) {
+		v1 = BME_MV(bm,eve->co);
+		v1->flag = eve->f;
+		v1->h = eve->h;
+
+		/* link the verts for edge and face construction;
+		 * kind of a dangerous thing - remember to cast back to BME_Vert before using! */
+		eve->tmp.v = (EditVert*)v1;
+
+		CustomData_em_copy_data(&em->vdata, &bm->vdata, eve->data, &v1->data);
+		
+		eve = eve->next;
+	}
+	
+	/*add edges*/
+	CustomData_copy(&em->edata, &bm->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+	eed= em->edges.first;
+	while(eed) {
+		v1 = (BME_Vert*)eed->v1->tmp.l;
+		v2 = (BME_Vert*)eed->v2->tmp.l;
+		e = BME_ME(bm, v1, v2);
+		e->crease = eed->crease;
+		e->flag = eed->f & SELECT;
+		if(eed->sharp) e->flag |= ME_SHARP;
+		if(eed->seam) e->flag |= ME_SEAM;
+		if(eed->h & EM_FGON) e->flag |= ME_FGON;
+		if(eed->h & 1) e->flag |= ME_HIDE;
+		CustomData_em_copy_data(&em->edata, &bm->edata, eed->data, &e->data);
+
+		/* link the edges for face construction;
+		 * kind of a dangerous thing - remember to cast back to BME_Edge before using! */
+		eed->tmp.e = (EditEdge*)e;
+		eed = eed->next;
+	}
+
+	/*add faces.*/
+	CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+	efa= em->faces.first;
+	while(efa) {
+		if(efa->v4) len = 4;
+		else len = 3;
+		
+		edar[0] = (BME_Edge*)efa->e1->tmp.e;
+		edar[1] = (BME_Edge*)efa->e2->tmp.e;
+		edar[2] = (BME_Edge*)efa->e3->tmp.e;
+		if(len == 4){
+			edar[3] = (BME_Edge*)efa->e4->tmp.e;
+		}
+		
+		/*find v1 and v2*/
+		v1 = (BME_Vert*)efa->v1->tmp.v;
+		v2 = (BME_Vert*)efa->v2->tmp.v;
+		
+		f = BME_MF(bm,v1,v2,edar,len);
+		f->mat_nr = efa->mat_nr;
+		f->flag = efa->flag;
+		if(efa->h) {
+			f->flag |= ME_HIDE;
+			f->flag &= ~ME_FACE_SEL;
+		}
+		else {
+			if(efa->f & 1) f->flag |= ME_FACE_SEL;
+			else f->flag &= ~ME_FACE_SEL;
+		}
+		CustomData_em_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data);
+		
+		efa = efa->next;
+	}
+	BME_model_end(bm);
+	return bm;
+}
+
+EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm) {
+	BME_Vert *v1;
+	BME_Edge *e;
+	BME_Poly *f;
+
+	EditMesh *em, *tem;
+	EditVert *eve1, *eve2, *eve3, *eve4, **evlist;
+	EditEdge *eed;
+	EditFace *efa;
+
+	int totvert, len, i;
+
+	tem = G.editMesh; /* we'll want to restore this later */
+	em = MEM_callocN(sizeof(EditMesh), "newEditMesh");
+	G.editMesh = em; /* silly, but I'm doing this so I can use pre-existing add[vert/edge/face]list stuff */
+
+	/* convert to EditMesh */
+	/* NOTE: Custom data is NOT transferred yet! A big todo. */
+	/* make editverts */
+	CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+	totvert = BLI_countlist(&(bm->verts));
+	evlist= (EditVert **)MEM_mallocN(totvert*sizeof(void *),"evlist");
+	for (i=0,v1=bm->verts.first;v1;v1=v1->next,i++) {
+		v1->tflag1 = i;
+		eve1 = addvertlist(v1->co,NULL);
+		eve1->keyindex = i;
+		evlist[i]= eve1;
+		eve1->f = v1->flag;
+		eve1->h = v1->h;
+		CustomData_em_copy_data(&bm->vdata, &em->vdata, v1->data, &eve1->data);
+	}
+	
+	/* make edges */
+	CustomData_copy(&bm->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+	for (e=bm->edges.first;e;e=e->next) {
+		eed= addedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1], NULL);
+		eed->crease = e->crease;
+		if(e->flag & ME_SEAM) eed->seam = 1;
+		if(e->flag & ME_SHARP) eed->sharp = 1;
+		if(e->flag & SELECT) eed->f |= SELECT;
+		if(e->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
+		if(e->flag & ME_HIDE) eed->h |= 1;
+		if(G.scene->selectmode==SCE_SELECT_EDGE) 
+			EM_select_edge(eed, eed->f & SELECT);
+		CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
+	}
+
+	/* make faces */
+	CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+	for (f=bm->polys.first;f;f=f->next) {
+		len = BME_cycle_length(f->loopbase);
+		if (len==3 || len==4) {
+			eve1= evlist[f->loopbase->v->tflag1];
+			eve2= evlist[f->loopbase->next->v->tflag1];
+			eve3= evlist[f->loopbase->next->next->v->tflag1];
+			if (len == 4) {
+				eve4= evlist[f->loopbase->prev->v->tflag1];
+			}
+			else {
+				eve4= NULL;
+			}
+
+			efa = addfacelist(eve1, eve2, eve3, eve4, NULL, NULL);
+			CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data);
+			efa->mat_nr = f->mat_nr;
+			efa->flag= f->flag & ~ME_HIDE;
+			if(f->flag & ME_FACE_SEL) {
+				efa->f |= SELECT;
+			}
+			if(f->flag & ME_HIDE) efa->h= 1;
+			if((G.f & G_FACESELECT) && (efa->f & SELECT))
+				EM_select_face(efa, 1); /* flush down */
+		}
+	}
+
+	MEM_freeN(evlist);
+
+	/* make sure we restore this */
+	G.editMesh = tem;
+
+	return em;
+}

Modified: branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_tools.c
===================================================================
--- branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_tools.c	2007-07-06 03:12:31 UTC (rev 11178)
+++ branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_tools.c	2007-07-06 04:03:57 UTC (rev 11179)
@@ -206,7 +206,16 @@
 	VecCopyf(midvec, mid);
 }
 
+void bevel_slide_vec(float *midvec, float *v1, float *v2, float d) {
+	float mid[3];
 
+	VecSubf(mid, v2, v1);
+	Normalize(mid);
+	VecMulf(mid, -d);
+	VecAddf(mid, mid, v1);
+	VecCopyf(midvec, mid);
+}
+
 /**
  *			BME_bevel_poly
  *
@@ -222,12 +231,12 @@
 */
 
 BME_Poly *BME_bevel_poly(BME_Mesh *bm, BME_Poly *f, float value, int options) {
-	BME_Vert *v;
-	BME_Edge *e1, *e2;
+	BME_Vert *v, *v1;
+	BME_Edge *e1, *e2, *ne;
 	BME_Loop *l, *nextloop, *nl;
 	
 	int len, i;	
-	float vec[3],v1[3],v2[3],v3[3],no[3];
+	float vec[3],vec1[3],vec2[3],vec3[3],no[3];
 
 	len = f->len;
 	for(i=0,l=f->loopbase; i < len; i++) {
@@ -241,7 +250,7 @@
 				if (e1->tflag1 & BME_BEVEL_BEVEL) {
 					/* if this edge is an original, we'll need a new one to inset */
 					if (e1->tflag1 & BME_BEVEL_ORIG) {
-						f = BME_SFME(bm,l->f,l->prev->v,l->v,&nl); /* 2-eged face for an extra edge */
+						f = BME_SFME(bm,l->f,l->prev->v,l->v,&nl); /* 2-edged face for an extra edge */
 						/* mark this as being a beveled edge, but not an original! */
 						nl->e->tflag1 = BME_BEVEL_BEVEL;
 						/* may need to mark the opposing face for destruction here */
@@ -254,19 +263,19 @@
 					 * will need to separate geometrical transformations and the actual
 					 * topology later, right now it gives incorrect vertex locations.
 					 */
-					VECSUB(v1,l->prev->v->co,l->v->co);
-					VECSUB(v2,l->next->v->co,l->v->co);
-					Crossf(no, v1, v2);
-					VECCOPY(v1,l->prev->v->co);
-					VECCOPY(v2,l->v->co);
-					VECCOPY(v3,l->next->v->co);
+					VECSUB(vec1,l->prev->v->co,l->v->co);
+					VECSUB(vec2,l->next->v->co,l->v->co);
+					Crossf(no, vec1, vec2);
+					VECCOPY(vec1,l->prev->v->co);
+					VECCOPY(vec2,l->v->co);
+					VECCOPY(vec3,l->next->v->co);
 					/* split the previous edge, this is topology
 					 * (i.e. keep it even after the surrounding math is removed)
 					 * this vert will be inset
 					 */
 					v = BME_SEMV(bm,l->v,l->prev->e,NULL);
 					v->tflag1 = 0;
-					bevel_displace_vec(vec, v1, v2, v3, value, no);
+					bevel_displace_vec(vec, vec1, vec2, vec3, value, no);
 					VECCOPY(v->co, vec);
 					/* end broken design rule */
 					
@@ -286,24 +295,161 @@
 				}
 				else {
 					/* Split e1 */
+					if (((l->prev->v->tflag1 & BME_BEVEL_ORIG)==0
+							&& (l->prev->prev->v->tflag1 & BME_BEVEL_ORIG)
+							&& (l->prev->prev->v->tflag1 & BME_BEVEL_BEVEL)==0
+							&& (l->prev->prev->e->tflag1 & BME_BEVEL_ORIG))
+						|| ((l->prev->v->tflag1 & BME_BEVEL_ORIG)==0
+							&& (l->prev->prev->v->tflag1 & BME_BEVEL_ORIG)==0
+							&& (l->prev->prev->e->tflag1 & BME_BEVEL_ORIG))) {
+						/* e1 has already been split by another face */
+						/* just use the split vert */
+						v = l->prev->v;
+					}
+					else {
+						bevel_slide_vec(vec, l->v->co, l->prev->v->co, value);
+						v = BME_SEMV(bm,l->v,e1,&ne);
+						ne->tflag1 = BME_BEVEL_ORIG;
+						VECCOPY(v->co, vec);
+					}
+					/* if the edge is an original, we'll need a new one to inset */
+					if (e2->tflag1 & BME_BEVEL_ORIG) {
+						f = BME_SFME(bm,l->f,l->next->v,v,&nl); /* 3-edged face */
+						/* mark the new edge as being a beveled edge, but not an original! */
+						nl->e->tflag1 = BME_BEVEL_BEVEL;
+					}
+					else {
+						l = l->prev; /* go back a loop (we'll be destroying the one we were sitting on!) */
+						f = BME_JFKE(bm,l->f,((BME_Loop*)l->next->radial.next->data)->f,e2);
+						/* assumes we are forming a quad (we should be), keep an eye on this! */
+						f = BME_SFME(bm,l->f,v,l->next->next->next->v,NULL);
+						/* may need to mark the opposing face for destruction here */
+					}
 				}
 			}
 			else if (e1->tflag1 & BME_BEVEL_BEVEL) {
 				/* split e2 */
-				/* look for previously beveled vert to connect with */
+				if (((l->next->v->tflag1 & BME_BEVEL_ORIG)==0
+						&& (l->next->next->v->tflag1 & BME_BEVEL_ORIG)
+						&& (l->next->next->v->tflag1 & BME_BEVEL_BEVEL)==0
+						&& (l->next->e->tflag1 & BME_BEVEL_ORIG))

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list