Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2009-09-12 12:41:39 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-09-12 12:41:39 +0400
commita54a9d5d4e2d06a95e4f1ca01fc0857d2bef6602 (patch)
tree4cdfb3095d7acb95a04e4011264b008db854aff5 /source/blender
parent186603c2ff1e41b75d9b9eee33b88fa804c75207 (diff)
fkey on two broken edge loops will create an ngon now, as will fkey on one broken edge loop
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/bmesh/bmesh_operator_api.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c21
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c19
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h1
-rw-r--r--source/blender/bmesh/operators/createops.c218
5 files changed, 244 insertions, 19 deletions
diff --git a/source/blender/bmesh/bmesh_operator_api.h b/source/blender/bmesh/bmesh_operator_api.h
index 393d71992ce..67daa323129 100644
--- a/source/blender/bmesh/bmesh_operator_api.h
+++ b/source/blender/bmesh/bmesh_operator_api.h
@@ -255,6 +255,10 @@ void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, char *slotn
int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, char *slotname);
int BMO_CountSlotMap(struct BMesh *bm, struct BMOperator *op, char *slotname);
+/*Counts the number of edges with tool flag toolflag around
+ v*/
+int BMO_Vert_CountEdgeFlags(BMesh *bm, BMVert *v, int toolflag);
+
/*inserts a key/value mapping into a mapping slot. note that it copies the
value, it doesn't store a reference to it.*/
//BM_INLINE void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, char *slotname,
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index d297a95799d..3b914e769ce 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -343,7 +343,6 @@ BMOpDefine def_contextual_create= {
0,
};
-/*this may be unimplemented*/
BMOpDefine def_edgenet_fill= {
"edgenet_fill",
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
@@ -354,6 +353,25 @@ BMOpDefine def_edgenet_fill= {
};
/*
+ Edgenet Prepare
+
+ Identifies several useful edge loop cases and modifies them so
+ they'll become a face when edgenet_fill is called. The cases covered are:
+
+ * One single loop; an edge is added to connect the ends
+ * Two loops; two edges are added to connect the endpoints (based on the
+ shortest distance between each endpont).
+*/
+BMOpDefine def_edgenet_prepare= {
+ "edgenet_prepare",
+ {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
+ {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //new edges
+ {0, /*null-terminating sentinel*/}},
+ bmesh_edgenet_prepare,
+ 0,
+};
+
+/*
Rotate
Rotate vertices around a center, using a 3x3 rotation
@@ -777,6 +795,7 @@ BMOpDefine *opdefines[] = {
&def_meshrotateuvs,
&def_bmesh_to_mesh,
&def_meshreverseuvs,
+ &def_edgenet_prepare,
};
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 55a413c82dc..37b9ce389ec 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -679,6 +679,25 @@ void BMO_UnHeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag
}
}
+int BMO_Vert_CountEdgeFlags(BMesh *bm, BMVert *v, int toolflag)
+{
+ BMNode *diskbase;
+ BMEdge *curedge;
+ int i, len=0, count=0;
+
+ if(v->edge){
+ diskbase = bmesh_disk_getpointer(v->edge, v);
+ len = bmesh_cycle_length(diskbase);
+
+ for(i = 0, curedge=v->edge; i<len; i++){
+ if (BMO_TestFlag(bm, curedge, toolflag))
+ count++;
+ curedge = bmesh_disk_nextedge(curedge, v);
+ }
+ }
+
+ return count;
+}
/*
*
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index efdf6a6602e..b5201ae17d6 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -54,5 +54,6 @@ void bmesh_vert_average_facedata_exec(BMesh *bm, BMOperator *op);
void bmesh_rotateuvs_exec(BMesh *bm, BMOperator *op);
void object_load_bmesh_exec(BMesh *bm, BMOperator *op);
void bmesh_reverseuvs_exec(BMesh *bm, BMOperator *op);
+void bmesh_edgenet_prepare(BMesh *bm, BMOperator *op);
#endif
diff --git a/source/blender/bmesh/operators/createops.c b/source/blender/bmesh/operators/createops.c
index 95ebf12ba14..56382d18b00 100644
--- a/source/blender/bmesh/operators/createops.c
+++ b/source/blender/bmesh/operators/createops.c
@@ -38,8 +38,6 @@ typedef struct EdgeData {
#define EDGE_MARK 1
#define EDGE_VIS 2
-#define VERT_VIS 1
-
#define FACE_NEW 1
PathBase *edge_pathbase_new(void)
@@ -195,10 +193,9 @@ EPath *edge_find_shortest_path(BMesh *bm, BMEdge *edge, EdgeData *edata, PathBas
void bmesh_edgenet_fill_exec(BMesh *bm, BMOperator *op)
{
- BMIter iter, liter;
+ BMIter iter;
BMOIter siter;
BMEdge *e, *edge;
- BMLoop *l;
BMFace *f;
EPath *path;
EPathNode *node;
@@ -206,7 +203,7 @@ void bmesh_edgenet_fill_exec(BMesh *bm, BMOperator *op)
BMEdge **edges = NULL;
PathBase *pathbase = edge_pathbase_new();
V_DECLARE(edges);
- int i, j;
+ int i;
if (!bm->totvert || !bm->totedge)
return;
@@ -314,16 +311,195 @@ static int convex(float *v1, float *v2, float *v3, float *v4)
return 0;
}
+BMEdge *edge_next(BMesh *bm, BMEdge *e)
+{
+ BMIter iter;
+ BMEdge *e2;
+ int i;
+
+ for (i=0; i<2; i++) {
+ BM_ITER(e2, &iter, bm, BM_EDGES_OF_VERT, i?e->v2:e->v1) {
+ if (BMO_TestFlag(bm, e2, EDGE_MARK)
+ && !BMO_TestFlag(bm, e2, EDGE_VIS) && e2 != e)
+ {
+ return e2;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void bmesh_edgenet_prepare(BMesh *bm, BMOperator *op)
+{
+ BMOIter siter;
+ BMIter iter;
+ BMEdge *e, *e2;
+ BMEdge **edges1 = NULL, **edges2 = NULL, **edges;
+ V_DECLARE(edges1);
+ V_DECLARE(edges2);
+ V_DECLARE(edges);
+ int ok = 1;
+ int i, count;
+
+ BMO_Flag_Buffer(bm, op, "edges", EDGE_MARK, BM_EDGE);
+
+ /*validate that each edge has at most one other tagged edge in the
+ disk cycle around each of it's vertices*/
+ BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
+ for (i=0; i<2; i++) {
+ count = BMO_Vert_CountEdgeFlags(bm, i?e->v2:e->v1, EDGE_MARK);
+ if (count > 2) {
+ ok = 0;
+ break;
+ }
+ }
+
+ if (!ok) break;
+ }
+
+ /*we don't have valid edge layouts, return*/
+ if (!ok)
+ return;
+
+
+ /*find connected loops within the input edges*/
+ count = 0;
+ while (1) {
+ BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
+ if (!BMO_TestFlag(bm, e, EDGE_VIS)) {
+ if (BMO_Vert_CountEdgeFlags(bm, e->v1, EDGE_MARK)==1)
+ break;
+ if (BMO_Vert_CountEdgeFlags(bm, e->v2, EDGE_MARK)==1)
+ break;
+ }
+ }
+
+ if (!e) break;
+
+ if (!count)
+ edges = edges1;
+ else if (count==1)
+ edges = edges2;
+ else break;
+
+ i = 0;
+ while (e) {
+ BMO_SetFlag(bm, e, EDGE_VIS);
+ V_GROW(edges);
+ edges[i] = e;
+
+ e = edge_next(bm, e);
+ i++;
+ }
+
+ if (!count) {
+ edges1 = edges;
+ V_SETCOUNT(edges1, V_COUNT(edges));
+ } else {
+ edges2 = edges;
+ V_SETCOUNT(edges2, V_COUNT(edges));
+ }
+
+ V_RESET(edges);
+ count++;
+ }
+
+#define EDGECON(e1, e2) (e1->v1 == e2->v1 || e1->v2 == e2->v2 || e1->v1 == e2->v2)
+
+ if (edges1 && V_COUNT(edges1) > 2 && EDGECON(edges1[0], edges1[V_COUNT(edges1)-1])) {
+ if (edges2 && V_COUNT(edges2) > 2 && EDGECON(edges2[0], edges2[V_COUNT(edges2)-1])) {
+ V_FREE(edges1);
+ V_FREE(edges2);
+ return;
+ } else {
+ edges1 = edges2;
+ edges2 = NULL;
+ }
+ }
+
+ if (edges2 && V_COUNT(edges2) > 2 && EDGECON(edges2[0], edges2[V_COUNT(edges2)-1])) {
+ edges2 = NULL;
+ }
+
+ /*two unconnected loops, connect them*/
+ if (edges1 && edges2) {
+ BMVert *v1, *v2, *v3, *v4;
+
+ if (V_COUNT(edges1)==1) {
+ v1 = edges1[0]->v1;
+ v2 = edges1[0]->v2;
+ } else {
+ if (BM_Vert_In_Edge(edges1[1], edges1[0]->v1))
+ v1 = edges1[0]->v2;
+ else v1 = edges1[0]->v1;
+
+ i = V_COUNT(edges1)-1;
+ if (BM_Vert_In_Edge(edges1[i-1], edges1[i]->v1))
+ v2 = edges1[i]->v2;
+ else v2 = edges1[i]->v1;
+ }
+
+ if (V_COUNT(edges2)==1) {
+ v3 = edges2[0]->v1;
+ v4 = edges2[0]->v2;
+ } else {
+ if (BM_Vert_In_Edge(edges2[1], edges2[0]->v1))
+ v3 = edges2[0]->v2;
+ else v3 = edges2[0]->v1;
+
+ i = V_COUNT(edges2)-1;
+ if (BM_Vert_In_Edge(edges2[i-1], edges2[i]->v1))
+ v4 = edges2[i]->v2;
+ else v4 = edges2[i]->v1;
+ }
+
+ if (VecLenf(v1->co, v3->co) > VecLenf(v1->co, v4->co)) {
+ BMVert *v;
+ v = v3;
+ v3 = v4;
+ v4 = v;
+ }
+
+ e = BM_Make_Edge(bm, v1, v3, NULL, 1);
+ BMO_SetFlag(bm, e, ELE_NEW);
+ e = BM_Make_Edge(bm, v2, v4, NULL, 1);
+ BMO_SetFlag(bm, e, ELE_NEW);
+ } else if (edges1) {
+ BMVert *v1, *v2;
+
+ if (V_COUNT(edges1) > 1) {
+ if (BM_Vert_In_Edge(edges1[1], edges1[0]->v1))
+ v1 = edges1[0]->v2;
+ else v1 = edges1[0]->v1;
+
+ i = V_COUNT(edges1)-1;
+ if (BM_Vert_In_Edge(edges1[i-1], edges1[i]->v1))
+ v2 = edges1[i]->v2;
+ else v2 = edges1[i]->v1;
+
+ e = BM_Make_Edge(bm, v1, v2, NULL, 1);
+ BMO_SetFlag(bm, e, ELE_NEW);
+ }
+ }
+
+ BMO_Flag_To_Slot(bm, op, "edgeout", ELE_NEW, BM_EDGE);
+
+ V_FREE(edges1);
+ V_FREE(edges2);
+
+#undef EDGECON
+}
+
/*this is essentially new fkey*/
void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op)
{
BMOperator op2;
BMOIter oiter;
- BMIter iter, liter;
+ BMIter iter;
BMHeader *h;
BMVert *v, *verts[4];
BMEdge *e;
- BMLoop *l;
BMFace *f;
int totv=0, tote=0, totf=0, amount;
@@ -338,20 +514,13 @@ void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op)
BMO_SetFlag(bm, h, ELE_NEW);
}
- /*first call dissolve faces*/
- BMO_InitOpf(bm, &op2, "dissolvefaces faces=%ff", ELE_NEW);
+ /*call edgenet create*/
+ /* call edgenet prepare op so additional face creation cases work*/
+ BMO_InitOpf(bm, &op2, "edgenet_prepare edges=%fe", ELE_NEW);
BMO_Exec_Op(bm, &op2);
-
- /*if we dissolved anything, then return.*/
- if (BMO_CountSlotBuf(bm, &op2, "regionout")) {
- BMO_CopySlot(&op2, op, "regionout", "faceout");
- BMO_Finish_Op(bm, &op2);
- return;
- }
-
+ BMO_Flag_Buffer(bm, &op2, "edgeout", ELE_NEW, BM_EDGE);
BMO_Finish_Op(bm, &op2);
- /*call edgenet create*/
BMO_InitOpf(bm, &op2, "edgenet_fill edges=%fe", ELE_NEW);
BMO_Exec_Op(bm, &op2);
@@ -364,6 +533,19 @@ void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op)
BMO_Finish_Op(bm, &op2);
+ /*now call dissolve faces*/
+ BMO_InitOpf(bm, &op2, "dissolvefaces faces=%ff", ELE_NEW);
+ BMO_Exec_Op(bm, &op2);
+
+ /*if we dissolved anything, then return.*/
+ if (BMO_CountSlotBuf(bm, &op2, "regionout")) {
+ BMO_CopySlot(&op2, op, "regionout", "faceout");
+ BMO_Finish_Op(bm, &op2);
+ return;
+ }
+
+ BMO_Finish_Op(bm, &op2);
+
/*now, count how many verts we have*/
amount = 0;
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {