Revision: 19286
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19286
Author:   joeedh
Date:     2009-03-14 14:16:35 +0100 (Sat, 14 Mar 2009)

Log Message:
-----------
connect verts now does geometric tests to perform valid splits.  it also 
supports multiple splits in a face, going around the face boundary in a loop 
and performing splits.

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/blenkernel/BKE_utildefines.h
    branches/bmesh/blender/source/blender/bmesh/bmesh.h
    branches/bmesh/blender/source/blender/bmesh/bmesh_queries.h
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_polygon.c
    branches/bmesh/blender/source/blender/bmesh/operators/connectops.c

Modified: branches/bmesh/blender/source/blender/blenkernel/BKE_utildefines.h
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/BKE_utildefines.h  
2009-03-14 13:12:11 UTC (rev 19285)
+++ branches/bmesh/blender/source/blender/blenkernel/BKE_utildefines.h  
2009-03-14 13:16:35 UTC (rev 19286)
@@ -113,6 +113,8 @@
 #define VECADD(v1,v2,v3)       {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + 
*(v3+1); *(v1+2)= *(v2+2) + *(v3+2);}
 #define VECSUB(v1,v2,v3)       {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - 
*(v3+1); *(v1+2)= *(v2+2) - *(v3+2);}
 #define VECSUB2D(v1,v2,v3)     {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - 
*(v3+1);}
+#define VECMUL(v1, fac) {v1[0] *= fac; v1[1] *= fac; v1[2] *= fac;}
+
 #define VECADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) 
+ *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac);}
 #define QUATADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) 
+ *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac); *(v1+3)= *(v2+3) + 
*(v3+3)*(fac);}
 

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh.h 2009-03-14 13:12:11 UTC 
(rev 19285)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh.h 2009-03-14 13:16:35 UTC 
(rev 19286)
@@ -52,8 +52,9 @@
 The API includes iterators, including many useful topological iterators;
 walkers, which walk over a mesh, without the risk of hitting the recursion
 limit; operators, which are logical, reusable mesh modules; topological
-"euler" functions, which are used for topological manipulations; and some
-(not yet finished) geometric utility functions.
+modification functions (like split face, join faces, etc), which are used for 
+topological manipulations; and some (not yet finished) geometric utility 
+functions.
 
 some definitions:
 

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_queries.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_queries.h 2009-03-14 
13:12:11 UTC (rev 19285)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_queries.h 2009-03-14 
13:16:35 UTC (rev 19286)
@@ -79,4 +79,11 @@
 
 /*checks if a face is valid in the data structure*/
 int BM_Validate_Face(BMesh *bm, BMFace *face, FILE *err);
+
+/*each pair of loops defines a new edge, a split.  this function goes
+  through and sets pairs that are geometrically invalid to null.  a
+  split is invalid, if it forms a concave angle or it intersects other
+  edges in the face.*/
+void BM_LegalSplits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len);
+
 #endif

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c     
2009-03-14 13:12:11 UTC (rev 19285)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c     
2009-03-14 13:16:35 UTC (rev 19286)
@@ -275,7 +275,7 @@
        BMFace *nf;
        nf = bmesh_sfme(bm,f,v1,v2,nl);
        
-       BM_Copy_Attributes(bm, bm, f, nf);
+       if (nf) BM_Copy_Attributes(bm, bm, f, nf);
 
        return nf;
 }

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_polygon.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_polygon.c  
2009-03-14 13:12:11 UTC (rev 19285)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_polygon.c  
2009-03-14 13:16:35 UTC (rev 19286)
@@ -133,9 +133,9 @@
        n[1] /= l;
        n[2] /= l;
        
-       normal[0] = n[0];
-       normal[1] = n[1];
-       normal[2] = n[2];
+       normal[0] = (float) n[0];
+       normal[1] = (float) n[1];
+       normal[2] = (float) n[2];
 }
 
 /*
@@ -249,77 +249,39 @@
   the list that bridges a concave region of the face or intersects
   any of the faces's edges.
 */
-static void shrink_edge(float *v1, float *v2, float fac)
+static void shrink_edged(double *v1, double *v2, double fac)
 {
-       float mid[3];
+       double mid[3];
 
-       VecAddf(mid, v1, v2);
-       VecMulf(mid, 0.5f);
+       VECADD(mid, v1, v2);
+       VECMUL(mid, 0.5);
 
-       VecSubf(v1, v1, mid);
-       VecSubf(v2, v2, mid);
+       VECSUB(v1, v1, mid);
+       VECSUB(v2, v2, mid);
 
-       VecMulf(v1, fac);
-       VecMulf(v2, fac);
+       VECMUL(v1, fac);
+       VECMUL(v2, fac);
 
-       VecAddf(v1, v1, mid);
-       VecAddf(v2, v2, mid);
-
+       VECADD(v1, v1, mid);
+       VECADD(v2, v2, mid);
 }
 
-#if 0
-void BM_LegalSplits(BMesh *bm, BMFace *f, BMLoop (*loops)[2], int len)
+static void shrink_edgef(float *v1, float *v2, float fac)
 {
-       BMIter iter;
-       BMLoop *l;
-       float v1[3], v2[3], no[3], *p1, *p2;
-       float projectverts[100][3];
-       float edgevertsstack[100][2][3];
-       float (*projverts)[3] = projectverts;
-       float (*edgeverts)[2][3] = edgevertsstack;
-       int i, nvert, j;
+       float mid[3];
 
-       if (f->len > 100) projverts = MEM_mallocN(sizeof(float)*3*f->len, 
"projvertsb");
-       if (len > 100) edgeverts = MEM_mallocN(sizeof(float)*3*2*len, 
"edgevertsb");
-       
-       i = 0;
-       l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f);
-       for (; l; l=BMIter_Step(&iter)) {
-               VECCOPY(projverts[i], l->v->co);
-               i++;
-       }
+       VECADD(mid, v1, v2);
+       VECMUL(mid, 0.5);
 
-       for (i=0; i<len; i++) {
-               VECCOPY(v1, loops[i][0]->v->co);
-               VECCOPY(v2, loops[i][0]->v->co);
+       VECSUB(v1, v1, mid);
+       VECSUB(v2, v2, mid);
 
-               shrink_edge(v1, v2, 0.9999f);
+       VECMUL(v1, fac);
+       VECMUL(v2, fac);
 
-               VECCOPY(edgeverts[i][0], v1);
-               VECCOPY(edgeverts[i][1], v2);
-       }
-       
-       compute_poly_normal(no, projverts, f->len);
-       poly_rotate_plane(no, projverts, f->len);
-       poly_rotate_plane(no, edgeverts, len);
-
-       for (i=0; i<len; i++) {
-               if (convexangle(
-       }
-
-       for (i=0; i<f->len; i++) {
-               for (j=0; j<len; j++) {
-                       p1 = projverts[i];
-                       p2 = projverts[(i+1)%f->len];
-                       if (convexangle(
-                       if (linecrosses(p1, p2, 
-               }
-       }
-       
-       if (projverts != projectverts) MEM_freeN(projverts);
-       if (edgeverts != edgevertsstack) MEM_freeN(edgeverts);
+       VECADD(v1, v1, mid);
+       VECADD(v2, v2, mid);
 }
-#endif
 
 /*
  * POLY ROTATE PLANE
@@ -337,8 +299,6 @@
        double angle;
        int i;
 
-       compute_poly_normal(normal, verts, nverts);
-
        Crossf(axis, up, normal);
        axis[0] *= -1;
        axis[1] *= -1;
@@ -512,6 +472,48 @@
        return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5;
 }
 
+int windingf(float *a, float *b, float *c)
+{
+       float v1[3], v2[3], v[3];
+       
+       VECSUB(v1, b, a);
+       VECSUB(v2, b, c);
+       
+       v1[2] = 0;
+       v2[2] = 0;
+       
+       Normalize(v1);
+       Normalize(v2);
+       
+       Crossf(v, v1, v2);
+
+       /*!! (turns nonzero into 1) is likely not necassary, 
+         since '>' I *think* should always
+         return 0 or 1, but I'm not totally sure. . .*/
+       return !!(v[2] > 0);
+}
+
+/* detects if two line segments cross each other (intersects).
+   note, there could be more winding cases then there needs to be. */
+int linecrossesf(float *v1, float *v2, float *v3, float *v4)
+{
+       int w1, w2, w3, w4, w5;
+       
+       /*w1 = winding(v1, v3, v4);
+       w2 = winding(v2, v3, v4);
+       w3 = winding(v3, v1, v2);
+       w4 = winding(v4, v1, v2);
+       
+       return (w1 == w2) && (w3 == w4);*/
+
+       w1 = windingf(v1, v3, v2);
+       w2 = windingf(v2, v4, v1);
+       w3 = !windingf(v1, v2, v3);
+       w4 = windingf(v3, v2, v4);
+       w5 = !windingf(v3, v1, v4);
+       return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5;
+}
+
 int goodline(float (*projectverts)[3], BMFace *f, int v1i,
             int v2i, int v3i, int nvert) {
        BMLoop *l = f->loopbase;
@@ -528,7 +530,7 @@
        do {
                i = l->v->head.eflag2;
                if (i == v1i || i == v2i || i == v3i) {
-                       l = l->head.next;
+                       l = (BMLoop*)l->head.next;
                        continue;
                }
                
@@ -539,7 +541,7 @@
                if (point_in_triangle(v1, v2, v3, pv1)) return 0;
                if (point_in_triangle(v3, v2, v1, pv1)) return 0;
 
-               l = l->head.next;
+               l = (BMLoop*)l->head.next;
        } while (l != f->loopbase);
        return 1;
 }
@@ -617,7 +619,6 @@
                         int newedgeflag, int newfaceflag)
 {
        int i, done, nvert;
-       float no[3];
        BMLoop *l, *newl, *nextloop;
        BMVert *v;
 
@@ -696,3 +697,122 @@
                }
        }
 }
+
+#if 1
+/*each pair of loops defines a new edge, a split.  this function goes
+  through and sets pairs that are geometrically invalid to null.  a
+  split is invalid, if it forms a concave angle or it intersects other
+  edges in the face, or it intersects another split.  in the case of
+  intersecting splits, only the first of the set of intersecting
+  splits survives.*/
+void BM_LegalSplits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
+{
+       BMIter iter;
+       BMLoop *l;
+       float v1[3], v2[3], v3[3], v4[3], no[3], mid[3], *p1, *p2;
+       float out[3] = {-234324.0f, -234324.0f, 0.0f};
+       float projectverts[100][3];
+       float edgevertsstack[200][3];
+       float (*projverts)[3] = projectverts;
+       float (*edgeverts)[3] = edgevertsstack;
+       int i, j, a=0, clen;
+
+       if (f->len > 100) projverts = MEM_mallocN(sizeof(float)*3*f->len, 
"projvertsb");
+       if (len > 100) edgeverts = MEM_mallocN(sizeof(float)*3*2*len, 
"edgevertsb");
+       
+       i = 0;
+       l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f);
+       for (; l; l=BMIter_Step(&iter)) {
+               l->head.eflag2 = i;
+               VECCOPY(projverts[i], l->v->co);
+               i++;
+       }
+       
+       for (i=0; i<len; i++) {
+               VECCOPY(v1, loops[i][0]->v->co);
+               VECCOPY(v2, loops[i][1]->v->co);
+
+               shrink_edgef(v1, v2, 0.9999f);
+               
+               VECCOPY(edgeverts[a], v1);
+               a++;
+               VECCOPY(edgeverts[a], v2);
+               a++;
+       }
+       
+       compute_poly_normal(no, projverts, f->len);
+       poly_rotate_plane(no, projverts, f->len);
+       poly_rotate_plane(no, edgeverts, len*2);
+       
+       for (i=0; i<f->len; i++) {
+               p1 = projverts[i];
+               out[0] = MAX2(out[0], p1[0]) + 0.001;
+               out[1] = MAX2(out[1], p1[1]) + 0.001;
+               out[2] = 0.0f;
+       }
+
+       /*do convexity test*/
+       for (i=0; i<len; i++) {
+               //l = (BMLoop*)loops[i][0]->head.prev;
+               //VECCOPY(v1, projverts[l->head.eflag2]);
+               
+               l = (BMLoop*)loops[i][0];
+               VECCOPY(v2, edgeverts[i*2]);
+               
+               l = (BMLoop*)loops[i][1];
+               VECCOPY(v3, edgeverts[i*2+1]);
+               
+               //l = (BMLoop*)loops[i][1]->head.next;
+               //VECCOPY(v4, projverts[l->head.eflag2]);
+
+               VecAddf(mid, v2, v3);
+               VecMulf(mid, 0.5f);
+               
+               clen = 0;
+               for (j=0; j<f->len; j++) {
+                       p1 = projverts[j];
+                       p2 = projverts[(j+1)%f->len];
+                       
+                       VECCOPY(v1, p1);
+                       VECCOPY(v2, p2);
+
+                       shrink_edgef(v1, v2, 1.001f);
+
+                       if (linecrossesf(p1, p2, mid, out)) clen++;
+                       else if (linecrossesf(p2, p1, out, mid)) clen++;
+                       else if (linecrossesf(p1, p2, out, mid)) clen++;
+
+               }
+               
+               if (clen%2 == 0) {
+                       loops[i][0] = NULL;
+               }
+               //if (testedgeside(v1, v2, v3)) { // || testedgeside(v2, v3, 
v4)) {
+               //      loops[i][0] = NULL;
+               //}
+       }
+       
+       /*do line crossing tests*/
+       for (i=0; i<f->len; i++) {
+               p1 = projverts[i];
+               p2 = projverts[(i+1)%f->len];

@@ 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