Revision: 44471
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44471
Author:   campbellbarton
Date:     2012-02-26 21:32:20 +0000 (Sun, 26 Feb 2012)
Log Message:
-----------
fix for a bmesh glitch when making a face (Fkey).

On a place, Ctrl+T, Fkey would create a quad overlapping the 2 Tris.

Now this case is checked for in a general way - if the bounds of the face are 
already filled in with faces (that _only_ use these edges-verts), then dont 
create the face.

This is an option for the 'edgenet_fill' operator, since creating the face isnt 
incorrect, just not-what-you-want mostly.

added functions
* BM_edge_share_vert - returns shared vert between 2 edges.
* BM_face_exists_multi, BM_face_exists_multi_edge - check if existing faces 
fill the edge bounds.
* also add BM_ELEM_INTERNAL_TAG so low level functions can tag without 
conflicting with higher level functions that also rely on tagging elements.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/bmesh.h
    trunk/blender/source/blender/bmesh/bmesh_queries.h
    trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
    trunk/blender/source/blender/bmesh/operators/bmo_create.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types.c

Modified: trunk/blender/source/blender/bmesh/bmesh.h
===================================================================
--- trunk/blender/source/blender/bmesh/bmesh.h  2012-02-26 19:46:12 UTC (rev 
44470)
+++ trunk/blender/source/blender/bmesh/bmesh.h  2012-02-26 21:32:20 UTC (rev 
44471)
@@ -108,8 +108,11 @@
  * only add new flags with care! - campbell */
 /* #define BM_ELEM_SPARE        (1<<5) */
 /* #define BM_ELEM_SPARE        (1<<6) */
-/* #define BM_ELEM_NONORMCALC (1<<7) */ /* UNUSED */
 
+#define BM_ELEM_INTERNAL_TAG (1<<7) /* for low level internal API tagging,
+                                     * since tools may want to tag verts and
+                                     * not have functions clobber them */
+
 /* Mesh Level Ops */
 extern int bm_mesh_allocsize_default[4];
 

Modified: trunk/blender/source/blender/bmesh/bmesh_queries.h
===================================================================
--- trunk/blender/source/blender/bmesh/bmesh_queries.h  2012-02-26 19:46:12 UTC 
(rev 44470)
+++ trunk/blender/source/blender/bmesh/bmesh_queries.h  2012-02-26 21:32:20 UTC 
(rev 44471)
@@ -97,6 +97,10 @@
 /* checks overlapping of existing faces with the verts in varr. */
 int BM_face_exists_overlap(struct BMesh *bm, struct BMVert **varr, int len, 
struct BMFace **existface);
 
+/* checks if many existing faces overlap the faces defined by varr */
+int BM_face_exists_multi(BMesh *bm, struct BMVert **varr, struct BMEdge 
**earr, int len);
+int BM_face_exists_multi_edge(BMesh *bm, BMEdge **earr, int len);
+
 /* checks if a face defined by varr already exists. */
 int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **existface);
 
@@ -110,6 +114,8 @@
 /* returns bool 1/0 if the edges share a vertex */
 int BM_edge_share_vert_count(struct BMEdge *e1, struct BMEdge *e2);
 
+BMVert *BM_edge_share_vert(struct BMEdge *e1, struct BMEdge *e2);
+
 /* edge verts in winding order from face */
 void BM_edge_ordered_verts(struct BMEdge *edge, struct BMVert **r_v1, struct 
BMVert **r_v2);
 

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2012-02-26 
19:46:12 UTC (rev 44470)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2012-02-26 
21:32:20 UTC (rev 44471)
@@ -422,6 +422,7 @@
        {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
         {BMO_OP_SLOT_MAPPING,     "restrict"}, /* restricts edges to groups.  
maps edges to integer */
         {BMO_OP_SLOT_BOOL,        "use_restrict"},
+        {BMO_OP_SLOT_BOOL,        "use_fill_check"},
         {BMO_OP_SLOT_ELEMENT_BUF, "excludefaces"}, /* list of faces to ignore 
for manifold check */
         {BMO_OP_SLOT_MAPPING,     "faceout_groupmap"}, /* maps new faces to 
the group numbers they came fro */
         {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.c   2012-02-26 
19:46:12 UTC (rev 44470)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.c   2012-02-26 
21:32:20 UTC (rev 44471)
@@ -31,6 +31,9 @@
  * of inspecting the mesh structure directly.
  */
 
+#include "MEM_guardedalloc.h"
+
+#include "BLI_array.h"
 #include "BLI_math.h"
 
 #include "bmesh.h"
@@ -510,6 +513,27 @@
 
 /**
  *
+ *           BMESH EDGE SHARE A VERTEX
+ *
+ *     Return the shared vertex between the two edges or NULL
+ *
+ */
+
+BMVert *BM_edge_share_vert(struct BMEdge *e1, struct BMEdge *e2)
+{
+       if (BM_vert_in_edge(e2, e1->v1)) {
+               return e1->v1;
+       }
+       else if (BM_vert_in_edge(e2, e1->v2)) {
+               return e1->v2;
+       }
+       else {
+               return NULL;
+       }
+}
+
+/**
+ *
  *           BMESH EDGE ORDERED VERTS
  *
  *     Returns the verts of an edge as used in a face
@@ -642,6 +666,163 @@
 }
 
 /*
+ * BMESH EXIST FACE MULTI
+ *
+ * Given a set of vertices and edges (varr, earr), find out if
+ * all those vertices are filled in by existing faces that _only_ use those 
vertices.
+ *
+ * This is for use in cases where creating a face is possible but would result 
in
+ * many overlapping faces.
+ *
+ * An example of how this is used: when 2 tri's are selected that share an 
edge,
+ * pressing Fkey would make a new overlapping quad (without a check like this)
+ *
+ * 'earr' and 'varr' can be in any order, however they _must_ form a closed 
loop.
+ *
+ * Returns:
+ * 0 for no overlap
+ * 1 for overlap
+ *
+ */
+
+int BM_face_exists_multi(BMesh *bm, BMVert **varr, BMEdge **earr, int len)
+{
+       BMFace *f;
+       BMEdge *e;
+       BMVert *v;
+       int ok;
+       int tot_tag;
+
+       BMIter fiter;
+       BMIter viter;
+
+       int i;
+
+       for (i = 0; i < len; i++) {
+               /* save some time by looping over edge faces rather then vert 
faces
+                * will still loop over some faces twice but not as many */
+               BM_ITER(f, &fiter, bm, BM_FACES_OF_EDGE, earr[i]) {
+                       BM_elem_flag_disable(f, BM_ELEM_INTERNAL_TAG);
+                       BM_ITER(v, &viter, bm, BM_VERTS_OF_FACE, f) {
+                               BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
+                       }
+               }
+
+               /* clear all edge tags */
+               BM_ITER(e, &fiter, bm, BM_EDGES_OF_VERT, varr[i]) {
+                       BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+               }
+       }
+
+       /* now tag all verts and edges in the boundry array as true so
+        * we can know if a face-vert is from our array */
+       for (i = 0; i < len; i++) {
+               BM_elem_flag_enable(varr[i], BM_ELEM_INTERNAL_TAG);
+               BM_elem_flag_enable(earr[i], BM_ELEM_INTERNAL_TAG);
+       }
+
+
+       /* so! boundry is tagged, everything else cleared */
+
+
+       /* 1) tag all faces connected to edges - if all their verts are boundry 
*/
+       tot_tag = 0;
+       for (i = 0; i < len; i++) {
+               BM_ITER(f, &fiter, bm, BM_FACES_OF_EDGE, earr[i]) {
+                       if (!BM_elem_flag_test(f, BM_ELEM_INTERNAL_TAG)) {
+                               ok = TRUE;
+                               BM_ITER(v, &viter, bm, BM_VERTS_OF_FACE, f) {
+                                       if (!BM_elem_flag_test(v, 
BM_ELEM_INTERNAL_TAG)) {
+                                               ok = FALSE;
+                                               break;
+                                       }
+                               }
+
+                               if (ok) {
+                                       /* we only use boundry verts */
+                                       BM_elem_flag_enable(f, 
BM_ELEM_INTERNAL_TAG);
+                                       tot_tag++;
+                               }
+                       }
+                       else {
+                               /* we already found! */
+                       }
+               }
+       }
+
+       if (tot_tag == 0) {
+               /* no faces use only boundry verts, quit early */
+               return FALSE;
+       }
+
+       /* 2) loop over non-boundry edges that use boundry verts,
+        *    check each have 2 tagges faces connected (faces that only use 
'varr' verts) */
+       ok = TRUE;
+       for (i = 0; i < len; i++) {
+               BM_ITER(e, &fiter, bm, BM_EDGES_OF_VERT, varr[i]) {
+
+                       if (/* non-boundry edge */
+                           BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) == FALSE 
&&
+                           /* ...using boundry verts */
+                           BM_elem_flag_test(e->v1, BM_ELEM_INTERNAL_TAG) == 
TRUE &&
+                           BM_elem_flag_test(e->v2, BM_ELEM_INTERNAL_TAG) == 
TRUE)
+                       {
+                               int tot_face_tag = 0;
+                               BM_ITER(f, &fiter, bm, BM_FACES_OF_EDGE, e) {
+                                       if (BM_elem_flag_test(f, 
BM_ELEM_INTERNAL_TAG)) {
+                                               tot_face_tag++;
+                                       }
+                               }
+
+                               if (tot_face_tag != 2) {
+                                       ok = FALSE;
+                                       break;
+                               }
+
+                       }
+               }
+
+               if (ok == FALSE) {
+                       break;
+               }
+       }
+
+       return ok;
+}
+
+/* same as 'BM_face_exists_multi' but built vert array from edges */
+int BM_face_exists_multi_edge(BMesh *bm, BMEdge **earr, int len)
+{
+       BMVert **varr;
+       BLI_array_fixedstack_declare(varr, BM_NGON_STACK_SIZE, len, __func__);
+
+       int ok;
+       int i, i_next;
+
+       /* first check if verts have edges, if not we can bail out early */
+       ok = TRUE;
+       for (i = len - 1, i_next = 0; i_next < len; (i=i_next++)) {
+               if (!(varr[i] = BM_edge_share_vert(earr[i], earr[i_next]))) {
+                       ok = FALSE;
+                       break;
+               }
+       }
+
+       if (ok == FALSE) {
+               BMESH_ASSERT(0);
+               BLI_array_fixedstack_free(varr);
+               return FALSE;
+       }
+
+       ok = BM_face_exists_multi(bm, varr, earr, len);
+
+       BLI_array_fixedstack_free(varr);
+
+       return ok;
+}
+
+
+/*
  * BMESH FACE EXISTS
  *
  * Given a set of vertices (varr), find out if

Modified: trunk/blender/source/blender/bmesh/operators/bmo_create.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_create.c   2012-02-26 
19:46:12 UTC (rev 44470)
+++ trunk/blender/source/blender/bmesh/operators/bmo_create.c   2012-02-26 
21:32:20 UTC (rev 44471)
@@ -872,7 +872,8 @@
        BMEdge **edges = NULL;
        PathBase *pathbase = edge_pathbase_new();
        BLI_array_declare(edges);
-       int use_restrict = BMO_slot_bool_get(op, "use_restrict");
+       int use_restrict   = BMO_slot_bool_get(op, "use_restrict");
+       int use_fill_check = BMO_slot_bool_get(op, "use_fill_check");
        int i, j, group = 0;
        unsigned int winding[2]; /* accumulte winding directions for each edge 
which has a face */
 
@@ -1014,13 +1015,19 @@
                                v2 = verts[0];
                        }
 
-                       f = BM_face_create_ngon(bm, v1, v2, edges, i, TRUE);
-                       if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
-                               BMO_elem_flag_enable(bm, f, FACE_NEW);
+                       if ((use_fill_check == FALSE) ||
+                           /* fairly expensive check - see if there are 
already faces filling this area */
+                           (BM_face_exists_multi_edge(bm, edges, i) == FALSE))
+                       {
+                               f = BM_face_create_ngon(bm, v1, v2, edges, i, 
TRUE);
+                               if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
+                                       BMO_elem_flag_enable(bm, f, FACE_NEW);
+                               }
+
+                               if (use_restrict) {
+                                       BMO_slot_map_int_insert(bm, op, 
"faceout_groupmap", f, path->group);
+                               }
                        }
-
-                       if (use_restrict)
-                               BMO_slot_map_int_insert(bm, op, 
"faceout_groupmap", f, path->group);
                }
                
                edge_free_path(pathbase, path);
@@ -1336,7 +1343,7 @@
        BMO_slot_buffer_flag_enable(bm, &op2, "edgeout", ELE_NEW, BM_EDGE);
        BMO_op_finish(bm, &op2);
 
-       BMO_op_initf(bm, &op2, "edgenet_fill edges=%fe", ELE_NEW);
+       BMO_op_initf(bm, &op2, "edgenet_fill edges=%fe use_fill_check=%b", 
ELE_NEW, TRUE);
        BMO_op_exec(bm, &op2);
 
        /* return if edge net create did somethin */

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types.c  2012-02-26 
19:46:12 UTC (rev 44470)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types.c  2012-02-26 
21:32:20 UTC (rev 44471)
@@ -1274,7 +1274,7 @@
                edge_array = (BMEdge **)PyMem_MALLOC(vert_seq_len * 
sizeof(BMEdge **));
 
                /* ensure edges */
-               for (i_next = 0, i = vert_seq_len - 1; i_next < vert_seq_len; 
(i=i_next++)) {
+               for (i = vert_seq_len - 1, i_next = 0; i_next < vert_seq_len; 
(i=i_next++)) {
                        edge_array[i] = BM_edge_create(bm, vert_array[i], 
vert_array[i_next], NULL, TRUE);
                }
 
@@ -2535,7 +2535,7 @@
                        alloc[i] = item->ele;
 

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to