[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27006] branches/bmesh/blender/source/ blender: ported triangles to quads.

Joseph Eagar joeedh at gmail.com
Thu Feb 18 11:09:54 CET 2010


Revision: 27006
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27006
Author:   joeedh
Date:     2010-02-18 11:09:52 +0100 (Thu, 18 Feb 2010)

Log Message:
-----------
ported triangles to quads.

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h
    branches/bmesh/blender/source/blender/bmesh/operators/join_triangles.c
    branches/bmesh/blender/source/blender/bmesh/operators/primitiveops.c
    branches/bmesh/blender/source/blender/bmesh/operators/subdivideop.c
    branches/bmesh/blender/source/blender/editors/mesh/bmesh_tools.c
    branches/bmesh/blender/source/blender/editors/mesh/editbmesh_add.c

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2010-02-18 09:32:24 UTC (rev 27005)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2010-02-18 10:09:52 UTC (rev 27006)
@@ -341,6 +341,27 @@
 };
 
 /*
+  Join Triangles
+
+  Tries to intelligently join triangles according 
+  to various settings and stuff.
+
+  */
+BMOpDefine def_join_triangles= {
+	"join_triangles",
+	{{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input geometry.
+	 {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, //joined faces
+	 {BMOP_OPSLOT_INT, "compare_sharp"},
+	 {BMOP_OPSLOT_INT, "compare_uvs"},
+	 {BMOP_OPSLOT_INT, "compare_vcols"},
+	 {BMOP_OPSLOT_INT, "compare_materials"},
+	 {BMOP_OPSLOT_FLT, "limit"},
+	 {0, /*null-terminating sentinel*/}},
+	bmesh_jointriangles_exec,
+	0,
+};
+
+/*
   Contextual Create
 
   This is basically fkey, it creates
@@ -685,9 +706,9 @@
 };
 
 /*
-  Similar faces select
+  Similar faces search
 
-  Select similar faces (area/material/perimeter....).
+  Find similar faces (area/material/perimeter....).
 */
 BMOpDefine def_similarfaces = {
 	"similarfaces",
@@ -701,9 +722,9 @@
 };
 
 /*
-  Similar edges select
+  Similar edges search
 
-  Select similar edges (length, direction, edge, seam,....).
+  Find similar edges (length, direction, edge, seam,....).
 */
 BMOpDefine def_similaredges = {
 	"similaredges",
@@ -717,9 +738,9 @@
 };
 
 /*
-  Similar vertices select
+  Similar vertices search
 
-  Select similar vertices (normal, face, vertex group,....).
+  Find similar vertices (normal, face, vertex group,....).
 */
 BMOpDefine def_similarverts = {
 	"similarverts",
@@ -783,9 +804,9 @@
 };
 
 /*
-  Similar vertices select
+  Similar vertices search
 
-  Select similar vertices (normal, face, vertex group,....).
+  Find similar vertices (normal, face, vertex group,....).
 */
 BMOpDefine def_vertexshortestpath = {
 	"vertexshortestpath",
@@ -892,7 +913,7 @@
 	 {BMOP_OPSLOT_FLT, "depth"}, //distance between ends
 	 {BMOP_OPSLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
 	 {0, /*null-terminating sentinel*/}},
-	bmesh_create_monkey_exec,
+	bmesh_create_cone_exec,
 	0,
 };
 
@@ -969,6 +990,7 @@
 	&def_create_monkey,
 	&def_create_cone,
 	&def_create_cube,
+	&def_join_triangles,
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h	2010-02-18 09:32:24 UTC (rev 27005)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h	2010-02-18 10:09:52 UTC (rev 27006)
@@ -67,5 +67,6 @@
 void bmesh_create_uvsphere_exec(BMesh *bm, BMOperator *op);
 void bmesh_create_grid_exec(BMesh *bm, BMOperator *op);
 void bmesh_create_cube_exec(BMesh *bm, BMOperator *op);
+void bmesh_jointriangles_exec(BMesh *bm, BMOperator *op);
 
 #endif

Modified: branches/bmesh/blender/source/blender/bmesh/operators/join_triangles.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/join_triangles.c	2010-02-18 09:32:24 UTC (rev 27005)
+++ branches/bmesh/blender/source/blender/bmesh/operators/join_triangles.c	2010-02-18 10:09:52 UTC (rev 27006)
@@ -1,4 +1,4 @@
-#if 0
+#if 1
 #include "MEM_guardedalloc.h"
 #include "BKE_customdata.h" 
 #include "DNA_listBase.h"
@@ -35,13 +35,18 @@
  *
 */
 
+/*Bitflags for edges.*/
+#define T2QDELETE	1
+#define T2QCOMPLEX	2
+#define T2QJOIN		4
+
 /*assumes edges are validated before reaching this point*/
 static float measure_facepair(BMesh *bm, BMVert *v1, BMVert *v2, 
 							  BMVert *v3, BMVert *v4, float limit)
 {
 	/*gives a 'weight' to a pair of triangles that join an edge to decide how good a join they would make*/
 	/*Note: this is more complicated than it needs to be and should be cleaned up...*/
-	float no1[3], no2[3], measure = 0.0f, angle1, angle2, diff;
+	float n1[3], n2[3], measure = 0.0f, angle1, angle2, diff;
 	float edgeVec1[3], edgeVec2[3], edgeVec3[3], edgeVec4[3];
 	float minarea, maxarea, areaA, areaB;
 
@@ -49,16 +54,16 @@
 	normal_tri_v3(n1, v1->co, v2->co, v3->co);
 	normal_tri_v3(n2, v1->co, v3->co, v4->co);
 
-	if(no1[0] == no2[0] && no1[1] == no2[1] && no1[2] == no2[2]) angle1 = 0.0f;
-	else angle1 = angle_v2v2(no1, no2);
+	if(n1[0] == n2[0] && n1[1] == n2[1] && n1[2] == n2[2]) angle1 = 0.0f;
+	else angle1 = angle_v3v3(n1, n2);
 
 	normal_tri_v3(n1, v2->co, v3->co, v4->co);
 	normal_tri_v3(n2, v4->co, v1->co, v2->co);
 
-	if(no1[0] == no2[0] && no1[1] == no2[1] && no1[2] == no2[2]) angle2 = 0.0f;
-	else angle2 = angle_v2v2(no1, no2);
+	if(n1[0] == n2[0] && n1[1] == n2[1] && n1[2] == n2[2]) angle2 = 0.0f;
+	else angle2 = angle_v3v3(n1, n2);
 
-	measure += (angle1/360.0f) + (angle2/360.0f);
+	measure += angle1 + angle2;
 	if(measure > limit) return measure;
 
 	/*Second test: Colinearity*/
@@ -70,10 +75,10 @@
 	diff = 0.0;
 
 	diff = (
-		fabs(angle_v2v2(edgeVec1, edgeVec2) - 90) +
-		fabs(angle_v2v2(edgeVec2, edgeVec3) - 90) +
-		fabs(angle_v2v2(edgeVec3, edgeVec4) - 90) +
-		fabs(angle_v2v2(edgeVec4, edgeVec1) - 90)) / 360.0f;
+		fabs(angle_v3v3(edgeVec1, edgeVec2) - M_PI/2) +
+		fabs(angle_v3v3(edgeVec2, edgeVec3) - M_PI/2) +
+		fabs(angle_v3v3(edgeVec3, edgeVec4) - M_PI/2) +
+		fabs(angle_v3v3(edgeVec4, edgeVec1) - M_PI/2));
 	if(!diff) return 0.0;
 
 	measure +=  diff;
@@ -98,22 +103,256 @@
 #define T2QUV_LIMIT 0.005
 #define T2QCOL_LIMIT 3
 
-static int compareFaceAttribs(BMesh *bm, BMEdge *e)
+static int compareFaceAttribs(BMesh *bm, BMEdge *e, int douvs, int dovcols)
 {
 	MTexPoly *tp1, *tp2;
 	MLoopCol *lcol1, *lcol2, *lcol3, *lcol4;
 	MLoopUV *luv1, *luv2, *luv3, *luv4;
-	BMLoop *l1, *l2;
+	BMLoop *l1, *l2, *l3, *l4;
+	int mergeok_uvs=!douvs, mergeok_vcols=!dovcols;
 	
-	l1 = e->loop
-	l2 = (BMLoop*)e->loop->radial.next->data;
+	l1 = e->loop;
+	l3 = (BMLoop*)e->loop->radial.next->data;
+	
+	/*match up loops on each side of an edge corrusponding to each vert*/
+	if (l1->v == l3->v) {
+		l2 = (BMLoop*)l1->head.next;
+		l4 = (BMLoop*)l2->head.next;
+	} else {
+		l2 = (BMLoop*)l1->head.next;
 
+		l4 = l3;
+		l3 = (BMLoop*)l4->head.next;
+	}
 
+	lcol1 = CustomData_bmesh_get(&bm->ldata, l1->head.data, CD_MLOOPCOL);
+	lcol2 = CustomData_bmesh_get(&bm->ldata, l1->head.data, CD_MLOOPCOL);
+	lcol3 = CustomData_bmesh_get(&bm->ldata, l1->head.data, CD_MLOOPCOL);
+	lcol4 = CustomData_bmesh_get(&bm->ldata, l1->head.data, CD_MLOOPCOL);
+
+	luv1 = CustomData_bmesh_get(&bm->ldata, l1->head.data, CD_MLOOPUV);
+	luv2 = CustomData_bmesh_get(&bm->ldata, l1->head.data, CD_MLOOPUV);
+	luv3 = CustomData_bmesh_get(&bm->ldata, l1->head.data, CD_MLOOPUV);
+	luv4 = CustomData_bmesh_get(&bm->ldata, l1->head.data, CD_MLOOPUV);
+
+	tp1 = CustomData_bmesh_get(&bm->pdata, l1->f->head.data, CD_MTEXPOLY);
+	tp2 = CustomData_bmesh_get(&bm->pdata, l2->f->head.data, CD_MTEXPOLY);
+
+	if (!lcol1)
+		mergeok_vcols = 1;
+
+	if (!luv1)
+		mergeok_uvs = 1;
+
+	/*compare faceedges for each face attribute. Additional per face attributes can be added later*/
+
+	/*do VCOLs*/
+	if(lcol1 && dovcols){
+		char *cols[4] = {(char*)lcol1, (char*)lcol2, (char*)lcol3, (char*)lcol4};
+		int i;
+
+		for (i=0; i<3; i++) {
+			if (cols[0][i] + T2QCOL_LIMIT < cols[3][i] - T2QCOL_LIMIT)
+				break;
+			if (cols[1][i] + T2QCOL_LIMIT < cols[4][i] - T2QCOL_LIMIT)
+				break;
+		}
+
+		if (i == 3)
+			mergeok_vcols = 1;
+	}
+
+	/*do UVs*/
+	if (luv1 && douvs) {
+		if(tp1->tpage != tp2->tpage); /*do nothing*/
+		else {
+			int i;
+
+			for(i = 0; i < 2; i++) {
+				if(luv1->uv[0] + T2QUV_LIMIT > luv3->uv[0] && luv1->uv[0] - T2QUV_LIMIT < luv3->uv[0] &&
+					luv1->uv[1] + T2QUV_LIMIT > luv3->uv[1] && luv1->uv[1] - T2QUV_LIMIT < luv3->uv[1])
+				{
+					if(luv2->uv[0] + T2QUV_LIMIT > luv4->uv[0] && luv2->uv[0] - T2QUV_LIMIT < luv4->uv[0] &&
+						luv2->uv[1] + T2QUV_LIMIT > luv4->uv[1] && luv2->uv[1] - T2QUV_LIMIT < luv4->uv[1])
+					{
+						mergeok_uvs = 1;
+					}
+				}
+			}
+		}
+	}
+
+	if (douvs == mergeok_uvs && dovcols == mergeok_vcols)
+		return 1;
+	return 0;
 }
 
+typedef struct JoinEdge {
+	float weight;
+	BMEdge *e;
+} JoinEdge;
+
+#define EDGE_MARK	1
+#define EDGE_CHOSEN	2
+
+#define FACE_MARK	1
+#define FACE_INPUT	2
+
+static int fplcmp(const void *v1, const void *v2)
+{
+	const JoinEdge *e1= ((JoinEdge*)v1), *e2=((JoinEdge*)v2);
+
+	if( e1->weight > e2->weight) return 1;
+	else if( e1->weight < e2->weight) return -1;
+
+	return 0;
+}
+
 void bmesh_jointriangles_exec(BMesh *bm, BMOperator *op)
 {
+	BMIter iter, liter;
+	BMOIter siter;
+	BMFace *f1, *f2;
+	BMLoop *l;
+	BMEdge *e;
+	BLI_array_declare(jedges);
+	JoinEdge *jedges = NULL;
+	int dosharp = BMO_Get_Int(op, "compare_sharp"), douvs=BMO_Get_Int(op, "compare_uvs");
+	int dovcols = BMO_Get_Int(op, "compare_vcols"), domat=BMO_Get_Int(op, "compare_materials");
+	float limit = BMO_Get_Float(op, "limit")/180.0f*M_PI;
+	int i, totedge;
+
+	/*flag all edges of all input faces*/
+	BMO_ITER(f1, &siter, bm, op, "faces", BM_FACE) {
+		BMO_SetFlag(bm, f1, FACE_INPUT); 
+		BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f1) {
+			BMO_SetFlag(bm, l->e, EDGE_MARK);
+		}
+	}
+
+	/*unflag edges that are invalid; e.g. aren't surrounded by triangles*/
+	BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
+		if (!BMO_TestFlag(bm, e, EDGE_MARK))
+			continue;
+
+		if (BM_Edge_FaceCount(e) < 2) {
+			BMO_ClearFlag(bm, e, EDGE_MARK);
+			continue;
+		}
+
+		f1 = e->loop->f;
+		f2 = ((BMLoop*)e->loop->radial.next->data)->f;
+
+		if (f1->len != 3 || f2->len != 3) {
+			BMO_ClearFlag(bm, e, EDGE_MARK);
+			continue;
+		}
+
+		if (!BMO_TestFlag(bm, f1, FACE_INPUT) || !BMO_TestFlag(bm, f2, FACE_INPUT)) {
+			BMO_ClearFlag(bm, e, EDGE_MARK);
+			continue;
+		}
+	}
 	
+	i = 0;
+	BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
+		BMVert *v1, *v2, *v3, *v4;
+		BMFace *f1, *f2;
+		float measure;
+
+		if (!BMO_TestFlag(bm, e, EDGE_MARK))
+			continue;
+
+		f1 = e->loop->f;
+		f2 = ((BMLoop*)e->loop->radial.next->data)->f;
+
+		v1 = e->loop->v;
+		v2 = ((BMLoop*)e->loop->head.prev)->v;
+		v3 = ((BMLoop*)e->loop->head.next)->v;
+		v4 = ((BMLoop*)((BMLoop*)e->loop->radial.next->data)->head.prev)->v;
+
+		if (dosharp && BM_TestHFlag(e, BM_SHARP))
+			continue;
+		
+		if ((douvs || dovcols) && compareFaceAttribs(bm, e, douvs, dovcols))
+			continue;
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list