[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35907] branches/bmesh/blender/source/ blender: =bmesh=

Joseph Eagar joeedh at gmail.com
Thu Mar 31 00:46:57 CEST 2011


Revision: 35907
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35907
Author:   joeedh
Date:     2011-03-30 22:46:56 +0000 (Wed, 30 Mar 2011)
Log Message:
-----------
=bmesh=

Multires interpolation now works on cases like 
simple cubes. (though it isn't perfect
when bevelling sharp corners).

Normal flipping is handled correctly, and
multires interpolation now works on 
normal-inconsistent meshes (so long as 
they are manifold, at least).

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/bmesh.h
    branches/bmesh/blender/source/blender/bmesh/bmesh_class.h
    branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_interp.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mesh.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_newcore.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators.c
    branches/bmesh/blender/source/blender/bmesh/operators/utils.c
    branches/bmesh/blender/source/blender/editors/mesh/bmesh_tools.c

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh.h	2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh.h	2011-03-30 22:46:56 UTC (rev 35907)
@@ -112,6 +112,7 @@
 #define BM_ACTIVE	(1<<6)
 #define BM_NONORMCALC	(1<<7)
 #define BM_PINNED	(1<<8)
+#define BM_FLIPPED	(1<<9) /*internal flag, used for ensuring correct normals during multires interpolation*/
 
 #include "bmesh_class.h"
 
@@ -149,6 +150,7 @@
 #define BM_TestHFlag(ele, f) (ele && (((BMHeader*)ele)->flag & (f)))
 #define BM_SetHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag | (f))
 #define BM_ClearHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag & ~(f))
+#define BM_ToggleHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag ^ (f))
 
 /*stuff for setting indices in elements.*/
 #define BMINDEX_SET(ele, i) (((BMHeader*)ele)->index = i)

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_class.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_class.h	2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_class.h	2011-03-30 22:46:56 UTC (rev 35907)
@@ -255,6 +255,8 @@
 
 	ListBase errorstack;
 	struct Object *ob; /*owner object*/
+	
+	int opflag; /*current operator flag*/
 } BMesh;
 
 BMFace *BM_Copy_Face(BMesh *bm, BMFace *f, int copyedges, int copyverts);

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h	2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h	2011-03-30 22:46:56 UTC (rev 35907)
@@ -119,6 +119,12 @@
 /*BMOpDefine->flag*/
 #define BMOP_UNTAN_MULTIRES 1 /*switch from multires tangent space to absolute coordinates*/
 
+/*ensures consistent normals before operator execution,
+  restoring the original ones windings/normals afterwards.
+  keep in mind, this won't work if the input mesh isn't
+  manifold.*/
+#define BMOP_RATIONALIZE_NORMALS 2
+
 /*------------- Operator API --------------*/
 
 /*data types that use pointers (arrays, etc) should never
@@ -147,6 +153,7 @@
 #define BMO_TestFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f & (flag))
 #define BMO_SetFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f |= (flag))
 #define BMO_ClearFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f &= ~(flag))
+#define BMO_ToggleFlag(bm, element, flag) (((BMHeader*)(element))->flags[bm->stackdepth-1].f ^= (flag))
 
 /*profiling showed a significant amount of time spent in BMO_TestFlag
 void BMO_SetFlag(struct BMesh *bm, void *element, int flag);

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_interp.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_interp.c	2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_interp.c	2011-03-30 22:46:56 UTC (rev 35907)
@@ -457,9 +457,9 @@
 
 int quad_co(double *x, double *y, double v1[3], double v2[3], double v3[3], double v4[3], double p[3], float n[3])
 {
-	float projverts[5][3];
-	double xn, yn, zn, dprojverts[4][3], origin[3]={0.0f, 0.0f, 0.0f};
-	int i, ax, ay;
+	float projverts[5][3], n2[3];
+	double dprojverts[4][3], origin[3]={0.0f, 0.0f, 0.0f};
+	int i;
 
 	/*project points into 2d along normal*/
 	VECCOPY(projverts[0], v1);
@@ -467,7 +467,12 @@
 	VECCOPY(projverts[2], v3);
 	VECCOPY(projverts[3], v4);
 	VECCOPY(projverts[4], p);
-	
+
+	normal_quad_v3(n2, projverts[0], projverts[1], projverts[2], projverts[3]);
+
+	if (INPR(n, n2) < -FLT_EPSILON)
+		return 0;
+
 	/*rotate*/	
 	poly_rotate_plane(n, projverts, 5);
 	
@@ -494,8 +499,8 @@
 }
 
 
-/*tl is loop to project onto, sl is loop whose internal displacement, co, is being
-  projected.  x and y are location in loop's mdisps grid of co.*/
+/*tl is loop to project onto, l is loop whose internal displacement, co, is being
+  projected.  x and y are location in loop's mdisps grid of point co.*/
 static int mdisp_in_mdispquad(BMesh *bm, BMLoop *l, BMLoop *tl, double p[3], double *x, double *y, int res)
 {
 	double v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3];
@@ -534,6 +539,10 @@
 	double x, y, d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3], e3[3], e4[3];
 	int ix, iy, res;
 	
+	/*ignore 2-edged faces*/
+	if (target->f->len < 3)
+		return;
+	
 	if (!CustomData_has_layer(&bm->ldata, CD_MDISPS))
 		return;
 	

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mesh.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mesh.c	2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mesh.c	2011-03-30 22:46:56 UTC (rev 35907)
@@ -294,18 +294,47 @@
 	MEM_freeN(projectverts);
 }
 
-/*	
- *	BMESH BEGIN/END EDIT
- *
- *	Functions for setting up a mesh for editing and cleaning up after 
- *  the editing operations are done. These are called by the tools/operator 
- *  API for each time a tool is executed.
- *
- *  Returns -
- *  Nothing
- *
+/*
+ This function ensures correct normals for the mesh, but
+ sets the flag BM_FLIPPED in flipped faces, to allow restoration
+ of original normals.
+ 
+ if undo is 0: calculate right normals
+ if undo is 1: restore original normals
 */
+//keep in sycn with utils.c!
+#define FACE_FLIP	8
+static void bmesh_rationalize_normals(BMesh *bm, int undo) {
+	BMOperator bmop;
+	BMFace *f;
+	BMIter iter;
+	
+	if (undo) {
+		BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
+			if (BM_TestHFlag(f, BM_FLIPPED)) {
+				BM_flip_normal(bm, f);
+			}
+			BM_ClearHFlag(f, BM_FLIPPED);
+		}
+		
+		return;
+	}
+	
+	BMO_InitOpf(bm, &bmop, "righthandfaces faces=%af doflip=%d", 0);
+	
+	BMO_push(bm, &bmop);
+	bmesh_righthandfaces_exec(bm, &bmop);
+	
+	BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
+		if (BMO_TestFlag(bm, f, FACE_FLIP))
+			BM_SetHFlag(f, BM_FLIPPED);
+		else BM_ClearHFlag(f, BM_FLIPPED);
+	}
 
+	BMO_pop(bm);
+	BMO_Finish_Op(bm, &bmop);
+}
+
 void bmesh_set_mdisps_space(BMesh *bm, int from, int to)
 {
 	/*switch multires data out of tangent space*/
@@ -357,18 +386,45 @@
 	}
 }
 
+/*	
+ *	BMESH BEGIN/END EDIT
+ *
+ *	Functions for setting up a mesh for editing and cleaning up after 
+ *  the editing operations are done. These are called by the tools/operator 
+ *  API for each time a tool is executed.
+ *
+ *  Returns -
+ *  Nothing
+ *
+*/
 void bmesh_begin_edit(BMesh *bm, int flag) {
+	bm->opflag = flag;
+	
 	/*switch multires data out of tangent space*/
-	if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS))
+	if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
 		bmesh_set_mdisps_space(bm, MULTIRES_SPACE_TANGENT, MULTIRES_SPACE_ABSOLUTE);
+
+		/*ensure correct normals, if possible*/
+		bmesh_rationalize_normals(bm, 0);
+		BM_Compute_Normals(bm);
+	} else if (flag & BMOP_RATIONALIZE_NORMALS) {
+		bmesh_rationalize_normals(bm, 0);
+	}
 }
 
 void bmesh_end_edit(BMesh *bm, int flag){
+	/*switch multires data into tangent space*/
+	if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
+		/*set normals to their previous winding*/
+		bmesh_rationalize_normals(bm, 1);
+		bmesh_set_mdisps_space(bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT);
+	} else if (flag & BMOP_RATIONALIZE_NORMALS) {
+		bmesh_rationalize_normals(bm, 1);
+	}
+
+	bm->opflag = 0;
+
 	/*compute normals, clear temp flags and flush selections*/
 	BM_Compute_Normals(bm);
 	BM_SelectMode_Flush(bm);
-
-	/*switch multires data into tangent space*/
-	if ((flag & BMOP_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS))
-		bmesh_set_mdisps_space(bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT);
 }

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_newcore.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_newcore.c	2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_newcore.c	2011-03-30 22:46:56 UTC (rev 35907)
@@ -665,15 +665,12 @@
 
 int bmesh_loop_reverse_loop(BMesh *bm, BMFace *f, BMLoopList *lst){
 	BMLoop *l = lst->first, *curloop, *oldprev, *oldnext;
-	BMEdge *staticedar[64], **edar;
-	int i, j, edok, len = 0;
+	BMEdge **edar = NULL;
+	MDisps *md;
+	BLI_array_staticdeclare(edar, 64);
+	int i, j, edok, len = 0, do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
 
 	len = bmesh_loop_length(l);
-	if(len >= 64){
-		edar = MEM_callocN(sizeof(BMEdge *)* len, "BM Edge pointer array");
-	} else {
-		edar = staticedar;
-	}
 
 	for(i=0, curloop = l; i< len; i++, curloop= ((BMLoop*)(curloop->next)) ){
 		curloop->e->head.eflag1 = 0;
@@ -681,7 +678,7 @@
 		bmesh_radial_remove_loop(curloop, curloop->e);
 		/*in case of border edges we HAVE to zero out curloop->radial Next/Prev*/
 		curloop->radial_next = curloop->radial_prev = NULL;
-		edar[i] = curloop->e;
+		BLI_array_append(edar, curloop->e);
 	}
 
 	/*actually reverse the loop.*/
@@ -691,6 +688,24 @@
 		curloop->next = (BMLoop*)oldprev;
 		curloop->prev = (BMLoop*)oldnext;
 		curloop = oldnext;
+		
+		if (do_disps) {
+			float (*co)[3];
+			int x, y, sides;
+			
+			md = CustomData_bmesh_get(&bm->ldata, curloop->head.data, CD_MDISPS);
+			if (!md->totdisp || !md->disps)
+				continue;
+					
+			sides=sqrt(md->totdisp);
+			co = md->disps;
+			
+			for (x=0; x<sides; x++) {
+				for (y=0; y<x; y++) {
+					swap_v3_v3(co[y*sides+x], co[sides*x + y]);
+				}
+			}
+		}
 	}
 
 	if(len == 2){ //two edged face
@@ -722,8 +737,7 @@
 		CHECK_ELEMENT(bm, curloop->f);
 	}
 
-	if (edar != staticedar)
-		MEM_freeN(edar);
+	BLI_array_free(edar);
 
 	CHECK_ELEMENT(bm, f);
 

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2011-03-30 16:44:18 UTC (rev 35906)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2011-03-30 22:46:56 UTC (rev 35907)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list