[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11518] branches/soc-2007-red_fox/source/ blender: Editmesh tool interaction working, memleaks fixed, etc.

Levi Schooley redfox at hhofministries.org
Wed Aug 8 20:02:24 CEST 2007


Revision: 11518
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11518
Author:   red_fox
Date:     2007-08-08 20:02:24 +0200 (Wed, 08 Aug 2007)

Log Message:
-----------
Editmesh tool interaction working, memleaks fixed, etc.

First off, I removed all memory leaks (as far as I can tell).
I did this by correctly handling editmesh, adding 
CustomData_free() functions to BME_free_mesh() in BME_Mesh.c, 
and changing the CustomData_copy() functions to 
CustomData_merge() in BME_bmesh_to_derivedmesh().

Second, I wrapped BME_SFME() with BME_split_face() so that 
face and edge flags were propagated to the new geometry.

Third, and this is the big one, I infiltrated the Transform() 
system so that the editmode tool now works interactively. The 
tool uses the horizontal mouse position to determine the 
bevel distance. Also, you can click the middle mouse button 
during transform to toggle between vert-only and edge-based 
methods of beveling.
To do this, I added a new global struct, editBMesh, to Global 
G that holds pointers to all of the information I need. I 
capture events during Transform(), and if they change a 
significant option, the option is set globally, and 
Transform() is cancelled. Trans.state and the global options 
are tested by the calling function, bevel_menu(), after 
Transform() completes. If they signal an option change during 
Transform(), the tool is reset with the new options.

Fourth, and last (except for some other little stuff, like to 
fix warnings), I added a limiting value (that only works to 
the fullest in special circumstances) that prevents the bevel 
from "overshooting." This definitely needs some more math and 
tweaking work, though.

Levi

Modified Paths:
--------------
    branches/soc-2007-red_fox/source/blender/blenkernel/BKE_bmesh.h
    branches/soc-2007-red_fox/source/blender/blenkernel/BKE_global.h
    branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_conversions.c
    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/include/BIF_transform.h
    branches/soc-2007-red_fox/source/blender/include/transform.h
    branches/soc-2007-red_fox/source/blender/src/buttons_editing.c
    branches/soc-2007-red_fox/source/blender/src/editmesh_tools.c
    branches/soc-2007-red_fox/source/blender/src/transform.c
    branches/soc-2007-red_fox/source/blender/src/transform_conversions.c
    branches/soc-2007-red_fox/source/blender/src/transform_generics.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-08-08 07:14:27 UTC (rev 11517)
+++ branches/soc-2007-red_fox/source/blender/blenkernel/BKE_bmesh.h	2007-08-08 18:02:24 UTC (rev 11518)
@@ -43,6 +43,7 @@
 #include "DNA_customdata_types.h"
 #include "BLI_editVert.h"
 #include "BKE_DerivedMesh.h"
+#include "transform.h"
 
 struct BME_Vert;
 struct BME_Edge;
@@ -199,26 +200,41 @@
 #define BME_BEVEL_PERCENT		(1<<6)
 #define BME_BEVEL_EMIN			(1<<7)
 #define BME_BEVEL_EMAX			(1<<8)
+#define BME_BEVEL_RUNNING		(1<<9)
+
 typedef struct BME_TransData {
 	BME_Mesh *bm; /* the bmesh the vert belongs to */
 	BME_Vert *v;  /* pointer to the vert this tdata applies to */
 	float co[3];  /* the original coordinate */
 	float org[3]; /* the origin */
 	float vec[3]; /* a directional vector; always, always normalize! */
-	float weight; /* a scaling factor */
-	float factor; /* another scaling factor */
+	float factor; /* primary scaling factor; also accumulates number of weighted edges for beveling tool */
+	float weight; /* another scaling factor; used primarily for propogating vertex weights to transforms */
+	void *loc;    /* a pointer to the data to transform */
 } BME_TransData;
 
 typedef struct BME_TransData_Head {
 	GHash *gh;       /* the hash structure for element lookup */
 	MemArena *ma;    /* the memory "pool" we will be drawing individual elements from */
+	int len;
+	float max;       /* the maximum bevel value that can be applied during transform */
 } BME_TransData_Head;
 
+typedef struct BME_Glob { /* stored in Global G for Transform() purposes */
+	BME_Mesh *bm;
+	BME_TransData_Head *td;
+	struct TransInfo *Trans; /* a pointer to the global Trans struct */
+	int imval[2]; /* for restoring original mouse co when initTransform() is called multiple times */
+	int options;
+} BME_Glob;
+
+struct BME_TransData *BME_get_transdata(struct BME_TransData_Head *td, struct BME_Vert *v);
+void BME_free_transdata(struct BME_TransData_Head *td);
 struct BME_Mesh *BME_bevel_mesh(struct BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head **rtd);
 
 /*CONVERSION FUNCTIONS*/
 struct BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, struct BME_Mesh *bm);
-struct EditMesh *BME_bmesh_to_editmesh(struct BME_Mesh *bm);
+struct EditMesh *BME_bmesh_to_editmesh(struct BME_Mesh *bm, BME_TransData_Head *td);
 struct BME_Mesh *BME_derivedmesh_to_bmesh(struct DerivedMesh *dm, struct BME_Mesh *bm);
 struct DerivedMesh *BME_bmesh_to_derivedmesh(struct BME_Mesh *bm, struct DerivedMesh *dm);
 #endif

Modified: branches/soc-2007-red_fox/source/blender/blenkernel/BKE_global.h
===================================================================
--- branches/soc-2007-red_fox/source/blender/blenkernel/BKE_global.h	2007-08-08 07:14:27 UTC (rev 11517)
+++ branches/soc-2007-red_fox/source/blender/blenkernel/BKE_global.h	2007-08-08 18:02:24 UTC (rev 11518)
@@ -62,6 +62,7 @@
 struct bSoundListener;
 struct BMF_Font;
 struct EditMesh;
+struct BME_Glob;
 
 typedef struct Global {
 
@@ -111,6 +112,9 @@
 
 	/* Editmode lists */
 	struct EditMesh *editMesh;
+	
+	/* Used for BMesh transformations */
+	struct BME_Glob *editBMesh;
     
 	float textcurs[4][2];
     

Modified: branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_conversions.c
===================================================================
--- branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_conversions.c	2007-08-08 07:14:27 UTC (rev 11517)
+++ branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_conversions.c	2007-08-08 18:02:24 UTC (rev 11518)
@@ -55,6 +55,8 @@
 #include "editmesh.h"
 #include "bmesh_private.h"
 
+#include "BSE_edit.h"
+
 BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, BME_Mesh *bm) {
 	BME_Vert *v1, *v2;
 	BME_Edge *e, *edar[4];
@@ -144,24 +146,27 @@
 	return bm;
 }
 
-EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm) {
+/* adds the geometry in the bmesh to G.editMesh (does not free G.editMesh)
+ * if td != NULL, the transdata will be mapped to the EditVert's co */
+EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
 	BME_Vert *v1;
 	BME_Edge *e;
 	BME_Poly *f;
+	
+	BME_TransData *vtd;
 
-	EditMesh *em, *tem;
+	EditMesh *em;
 	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 */
+	em = G.editMesh;
 
+	if (em == NULL) return NULL;
+
 	/* 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));
@@ -169,6 +174,9 @@
 	for (i=0,v1=bm->verts.first;v1;v1=v1->next,i++) {
 		v1->tflag1 = i;
 		eve1 = addvertlist(v1->co,NULL);
+		if (td && (vtd = BME_get_transdata(td,v1))) {
+			vtd->loc = eve1->co;
+		}
 		eve1->keyindex = i;
 		evlist[i]= eve1;
 		eve1->f = (unsigned char)v1->flag;
@@ -221,8 +229,7 @@
 
 	MEM_freeN(evlist);
 
-	/* make sure we restore this */
-	G.editMesh = tem;
+	countall();
 
 	return em;
 }
@@ -330,11 +337,11 @@
 	result = CDDM_from_template(dm,totvert,totedge,totface);
 	/*custom data*/
 	/* NOTE: I haven't tested whether or not custom data is being copied correctly */
-	CustomData_copy(&bm->vdata, &result->vertData, CD_MASK_DERIVEDMESH,
+	CustomData_merge(&bm->vdata, &result->vertData, CD_MASK_DERIVEDMESH,
 	                CD_CALLOC, totvert);
-	CustomData_copy(&bm->edata, &result->edgeData, CD_MASK_DERIVEDMESH,
+	CustomData_merge(&bm->edata, &result->edgeData, CD_MASK_DERIVEDMESH,
 	                CD_CALLOC, totedge);
-	CustomData_copy(&bm->pdata, &result->faceData, CD_MASK_DERIVEDMESH,
+	CustomData_merge(&bm->pdata, &result->faceData, CD_MASK_DERIVEDMESH,
 	                CD_CALLOC, totface);
 	/*Make Verts*/
 	mvert = CDDM_get_verts(result);

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-08-08 07:14:27 UTC (rev 11517)
+++ branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_mesh.c	2007-08-08 18:02:24 UTC (rev 11518)
@@ -125,6 +125,12 @@
 	
 	for(loopref=bm->loops.first;loopref;loopref=loopref->next) BME_delete_loop(bm,loopref->data);
 	BLI_freelistN(&(bm->loops));
+	
+	CustomData_free(&bm->vdata, 0);
+	CustomData_free(&bm->edata, 0);
+	CustomData_free(&bm->ldata, 0);
+	CustomData_free(&bm->pdata, 0);
+	
 	MEM_freeN(bm);	
 }
 

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-08-08 07:14:27 UTC (rev 11517)
+++ branches/soc-2007-red_fox/source/blender/blenkernel/intern/BME_tools.c	2007-08-08 18:02:24 UTC (rev 11518)
@@ -203,6 +203,7 @@
 	if ((vtd = BLI_ghash_lookup(td->gh, v)) == NULL && bm != NULL) {
 		vtd = BLI_memarena_alloc(td->ma, sizeof(*vtd));
 		BLI_ghash_insert(td->gh, v, vtd);
+		td->len++;
 		is_new = 1;
 	}
 
@@ -230,6 +231,25 @@
 	return vtd;
 }
 
+/* tests an edge to see how "long" it is, and lowers the max if it is smaller */
+float BME_bevel_set_max(BME_Edge *e,float *max) {
+	float len;
+	
+	if ((e->v1->tflag1 & BME_BEVEL_BEVEL) && (e->v2->tflag1 & BME_BEVEL_BEVEL)) {
+		len = VecLenf(e->v1->co,e->v2->co)/2.0f;
+	}
+	else if ((e->v1->tflag1 & BME_BEVEL_BEVEL)==0 && (e->v2->tflag1 & BME_BEVEL_BEVEL)==0) {
+		return -1;
+	}
+	else {
+		len = VecLenf(e->v1->co,e->v2->co);
+	}
+	if (len < *max || *max < 0) {
+		*max = len;
+	}
+	return len;
+}
+
 float inset_corner_vec(float *vec, float *v1, float *v2, float *v3, float *no) {
 	float a[3], c[3], n_a[3], n_c[3], tno[3], ac, ac2, fac;
 
@@ -262,6 +282,21 @@
 	return fac;
 }
 
+BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Loop **nl, BME_Edge *example) {
+	BME_Poly *nf;
+	nf = BME_SFME(bm,f,v1,v2,nl);
+	nf->flag = f->flag;
+	nf->h = f->h;
+	nf->mat_nr = f->mat_nr;
+	if (nl && example) {
+		(*nl)->e->flag = example->flag;
+		(*nl)->e->h = example->h;
+		(*nl)->e->crease = example->crease;
+	}
+
+	return nf;
+}
+
 BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
 	BME_Vert *nv, *v2;
 	float len;
@@ -273,8 +308,9 @@
 	len = VecLength(nv->co);
 	VECADDFAC(nv->co,v->co,nv->co,len*percent);
 	nv->flag = v->flag;
+	(*ne)->flag = e->flag;
+	(*ne)->h = e->h;
 	(*ne)->crease = e->crease;
-	(*ne)->flag = e->flag;
 
 	return nv;
 }
@@ -396,7 +432,7 @@
 	return 0;
 }
 
-BME_Loop *BME_bevel_corner(BME_Mesh *bm, BME_Loop *l, float value, int options, BME_TransData_Head *td) {
+BME_Loop *BME_bevel_corner(BME_Mesh *bm, BME_Loop *l, float value, int options, BME_TransData_Head *td, float *max) {
 	BME_TransData *vtd;
 	BME_Vert *v;
 	BME_Edge *ne;
@@ -406,7 +442,7 @@
 
 	/* if the previous edge is an original, we'll need a new one to inset */
 	if (l->prev->e->tflag1 & BME_BEVEL_ORIG) {
-		f = BME_SFME(bm,l->f,l->prev->v,l->v,&nl); /* 2-edged face for an extra edge */
+		f = BME_split_face(bm,l->f,l->prev->v,l->v,&nl,l->prev->e); /* 2-edged face for an extra edge */
 		/* mark this as being a beveled edge, but not an original! */
 		nl->e->tflag1 = BME_BEVEL_BEVEL;
 	}
@@ -421,11 +457,13 @@
 		factor = 1;
 	}
 	factor = factor*inset_corner_vec(vec,l->prev->v->co,l->v->co,l->next->v->co,NULL);
+	BME_bevel_set_max(l->prev->e,max);
+	BME_bevel_set_max(l->e,max);
 	v = BME_split_edge(bm,l->v,l->prev->e,&ne,0);
 	BME_assign_transdata(td, bm, v, v->co, v->co, vec, 1, factor);
 
 	if (l->e->tflag1 & BME_BEVEL_ORIG) {
-		f = BME_SFME(bm,l->f,l->prev->v,l->next->v,&l); /* 3-edged face this time */
+		f = BME_split_face(bm,l->f,l->prev->v,l->next->v,&l,l->e); /* 3-edged face this time */
 		/* mark this as being a beveled edge, but not an original! */
 		l->e->tflag1 = BME_BEVEL_BEVEL;
 	}
@@ -433,20 +471,20 @@
 		l = l->prev; /* go back a loop (we might be destroying the one we were sitting on!) */
 		f = BME_JFKE(bm,l->f,((BME_Loop*)l->next->radial.next->data)->f,l->next->e);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list