[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19213] branches/bmesh/blender/source/ blender/bmesh/intern: -> New Euler: "Unglue Face Region Make Vert"

Geoffrey Bantle hairbat at yahoo.com
Fri Mar 6 19:57:43 CET 2009


Revision: 19213
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19213
Author:   briggs
Date:     2009-03-06 19:57:43 +0100 (Fri, 06 Mar 2009)

Log Message:
-----------
-> New Euler: "Unglue Face Region Make Vert"

Added a new euler that will take as an argument a face
that is part of a disk and a vertex in the face. The euler
will then 'unglue' this region. An example of this would
be two cones joined at the tip...

Note that this code is untested and probably will have
bugs so shouldnt be trusted yet...

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_eulers.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_structure.h

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_eulers.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_eulers.c	2009-03-06 15:50:15 UTC (rev 19212)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_eulers.c	2009-03-06 18:57:43 UTC (rev 19213)
@@ -983,3 +983,171 @@
 	bmesh_free_poly(bm, f2);	
 	return f1;
 }
+
+/**
+*    bmesh_URMV
+*
+*    UNGLUE REGION MAKE VERT:
+*
+*    Takes a locally manifold disk of face corners and 'unglues' it
+*    creating a new vertex
+*
+**/
+
+#define URMV_VISIT    1
+#define URMV_VISIT2   2
+
+BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv)
+{
+    BMVert *nv = NULL;
+    BMLoop *l = NULL, *sl = NULL;
+    BMEdge *curedge = NULL;
+    int numloops = 0, numedges = 0, i, maxedges, maxloops;
+
+
+    /*Todo: Validation*/
+    /*validate radial cycle of all collected loops*/
+    /*validate the disk cycle of sv, and nv*/
+    /*validate the face length of all faces? overkill?*/
+    /*validate the l->e pointers of all affected faces, ie: l->v and l->next->v should be equivalent to l->e*/
+   
+    /*verify that sv has edges*/
+    if(sv->edge == NULL)
+        return NULL;
+   
+    /*first verify no wire edges on sv*/
+    curedge = sv->edge;
+    do{
+        if(curedge->loop == NULL)
+            return NULL;
+        curedge = bmesh_disk_nextedge(curedge, sv);
+    }while(curedge != sv->edge);
+   
+    /*next verify that sv is in sf*/
+    l = sf->loopbase;
+    do{
+        if(l->v == sv){
+            sl = l;
+            break;
+        }
+        l = (BMLoop*)(l->head.next);
+    }while(l != sf->loopbase);
+   
+    if(sl == NULL)
+        return NULL;
+   
+    /*clear euler flags*/
+    sv->head.eflag1 = 0;
+   
+    curedge = sv->edge;
+    do{
+        curedge->head.eflag1 = 0;
+        l = curedge->loop;
+        do{
+            l->head.eflag1 = 0;
+            l->f->head.eflag1 = 0;
+            l = bmesh_radial_nextloop(l);
+        }while(l != curedge->loop);
+        curedge = bmesh_disk_nextedge(curedge, sv);
+    }while(curedge != sv->edge);
+   
+    /*search through face disk and flag elements as we go.*/
+    /*Note, test this to make sure that it works correct on
+    non-manifold faces!
+    */
+    l = sl;
+    l->e->head.eflag1 |= URMV_VISIT;
+    l->f->head.eflag1 |= URMV_VISIT;
+    do{
+        if(l->v == sv)
+            l = bmesh_radial_nextloop((BMLoop*)(l->head.prev));
+        else
+            l = bmesh_radial_nextloop((BMLoop*)(l->head.next));
+        l->e->head.eflag1 |= URMV_VISIT;
+        l->f->head.eflag1 |= URMV_VISIT;
+    }while(l != sl && (bmesh_cycle_length(&(l->radial)) > 1) );
+   
+    /*Verify that all visited edges are at least 1 or 2 manifold*/
+    curedge = sv->edge;
+    do{
+        if(curedge->head.eflag1 && (bmesh_cycle_length(&(curedge->loop->radial)) > 2) )
+            return NULL;
+        curedge = bmesh_disk_nextedge(curedge, sv);
+    }while(curedge != sv->edge);
+
+	/*allocate temp storage - we overallocate here instead of trying to be clever*/
+	maxedges = 0;
+	maxloops = 0;
+	curedge = sv->edge;
+	do{
+		if(curedge->loop){
+			l = curedge->loop;
+			do{
+				maxloops += l->f->len;
+				l = bmesh_radial_nextloop(l);
+			}while(l != curedge->loop);
+		}
+		maxedges+= 1;
+		curedge = bmesh_disk_nextedge(curedge,sv);
+	}while(curedge != sv->edge);
+
+	if(bm->edarlen < maxedges){
+		MEM_freeN(bm->edar);
+		bm->edar = MEM_callocN(sizeof(BMEdge *) * maxedges, "BM Edge pointer array");
+		bm->edarlen = maxedges;
+	}
+	if(bm->lparlen < maxloops){
+		MEM_freeN(bm->lpar);
+		bm->lpar = MEM_callocN(sizeof(BMLoop *) * maxloops, "BM Loop pointer array");
+		bm->lparlen = maxloops;
+	}
+
+    /*first get loops by looping around edges and loops around that edges faces*/
+    curedge = sv->edge;
+    do{
+        if(curedge->loop){
+            l = curedge->loop;
+            do{
+                if( (l->head.eflag1 & URMV_VISIT) && (!(l->head.eflag1 & URMV_VISIT2)) ){
+                    bm->lpar[numloops] = l;
+                    l->head.eflag1 |= URMV_VISIT2;
+                    numloops++;
+                }
+                l = bmesh_radial_nextloop(l);
+            }while(l != curedge->loop);
+        }
+        curedge = bmesh_disk_nextedge(curedge, sv);
+    }while(curedge != sv->edge);
+
+    /*now collect edges by looping around edges and looking at visited flags*/
+    curedge = sv->edge;
+    do{
+        if(curedge->head.eflag1 & URMV_VISIT){
+            bm->edar[numedges] = curedge;
+            numedges++;
+        }
+        curedge = bmesh_disk_nextedge(curedge, sv);
+    }while(curedge != sv->edge);
+   
+    /*make new vertex*/
+    nv = bmesh_addvertlist(bm, sv);
+   
+    /*go through and relink edges*/
+    for(i = 0;  i <  numedges; i++){
+        curedge = bm->edar[i];
+        /*remove curedge from sv*/
+        bmesh_disk_remove_edge(curedge, sv);
+        /*swap out sv for nv in curedge*/
+        bmesh_edge_swapverts(curedge, sv, nv);
+        /*add curedge to nv's disk cycle*/
+        bmesh_disk_append_edge(curedge, nv);
+    }
+   
+    /*go through and relink loops*/
+    for(i = 0; i < numloops; i ++){
+        l = bm->lpar[i];
+        if(l->v == sv)
+            l->v = nv;
+	}
+	return nv;
+}

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_structure.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_structure.h	2009-03-06 15:50:15 UTC (rev 19212)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_structure.h	2009-03-06 18:57:43 UTC (rev 19213)
@@ -94,4 +94,7 @@
 int bmesh_loop_reverse(struct BMesh *bm, struct BMFace *f);
 struct BMFace *bmesh_jfke(struct BMesh *bm, struct BMFace *f1, BMFace *f2, BMEdge *e);
 
+struct BMVert *bmesh_urmv(struct BMesh *bm, struct BMFace *sf, struct BMVert *sv);
+//int *bmesh_grkv(struct BMesh *bm, struct BMFace *sf, struct BMVert *kv);
+
 #endif





More information about the Bf-blender-cvs mailing list