[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