Second step out of three for merging sketching subdivision methods with graph subdivi...
authorMartin Poirier <theeth@yahoo.com>
Mon, 24 Nov 2008 19:24:49 +0000 (19:24 +0000)
committerMartin Poirier <theeth@yahoo.com>
Mon, 24 Nov 2008 19:24:49 +0000 (19:24 +0000)
Graph subdivision uses graph arc iterators.

source/blender/blenlib/BLI_graph.h
source/blender/include/reeb.h
source/blender/src/editarmature.c
source/blender/src/editarmature_retarget.c
source/blender/src/reeb.c

index 12ca87577d544534145b85e3970498efe1ab87da..7629dbf6ba8b6bda6cd876584885810af2dd2236 100644 (file)
@@ -62,20 +62,23 @@ typedef struct BArc {
 
 struct BArcIterator;
 
-typedef float* (*PeekPointFct)(struct BArcIterator* iter, int n);
-typedef float* (*NextPointFct)(struct BArcIterator* iter);
-typedef float* (*CurrentPointFct)(struct BArcIterator* iter);
-typedef float* (*PreviousPointFct)(struct BArcIterator* iter);
-typedef int       (*StoppedFct)(struct BArcIterator* iter);
+typedef void* (*PeekFct)(void* iter, int n);
+typedef void* (*NextFct)(void* iter);
+typedef void* (*NextNFct)(void* iter, int n);
+typedef void* (*PreviousFct)(void* iter);
+typedef int    (*StoppedFct)(void* iter);
 
 typedef struct BArcIterator {
-       PeekPointFct            peek;
-       NextPointFct            next;
-       CurrentPointFct         current;
-       PreviousPointFct        previous;
-       StoppedFct                      stopped;
+       PeekFct         peek;
+       NextFct         next;
+       NextNFct        nextN;
+       PreviousFct     previous;
+       StoppedFct      stopped;
+       
+       float *p, *no;
        
        int length;
+       int index;
 } BArcIterator;
 
 /* Helper structure for radial symmetry */
index 927eded62d445c920515ff699272f6f8a0236444..21c57495fb040b0e4a3fbe70dcc194139129f92d 100644 (file)
@@ -28,7 +28,7 @@
 #ifndef REEB_H_
 #define REEB_H_
 
-//#define WITH_BF_REEB
+#define WITH_BF_REEB
 
 #include "DNA_listBase.h"
 
@@ -120,12 +120,21 @@ typedef struct ReebArc {
 } ReebArc;
 
 typedef struct ReebArcIterator {
-       struct ReebArc  *arc;
+       PeekFct         peek;
+       NextFct         next;
+       NextNFct        nextN;
+       PreviousFct     previous;
+       StoppedFct      stopped;
+       
+       float *p, *no;
+       
+       int length;
        int index;
+       /*********************************/
+       struct ReebArc  *arc;
        int start;
        int end;
-       int stride; 
-       int length;
+       int stride;
 } ReebArcIterator;
 
 struct EditMesh;
@@ -145,12 +154,6 @@ ReebGraph * newReebGraph();
 void initArcIterator(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head);
 void initArcIterator2(struct ReebArcIterator *iter, struct ReebArc *arc, int start, int end);
 void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start);
-struct EmbedBucket * nextBucket(struct ReebArcIterator *iter);
-struct EmbedBucket * nextNBucket(ReebArcIterator *iter, int n);
-struct EmbedBucket * peekBucket(ReebArcIterator *iter, int n);
-struct EmbedBucket * currentBucket(struct ReebArcIterator *iter);
-struct EmbedBucket * previousBucket(struct ReebArcIterator *iter);
-int iteratorStopped(struct ReebArcIterator *iter);
 
 /* Filtering */
 void filterNullReebGraph(ReebGraph *rg);
index 42053ee168b00b4c1b665825c51d08b58057d373..bae6fc5a0af3686940afb7538c137d03115d4a6e 100644 (file)
@@ -4656,8 +4656,7 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
        if (G.scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
        {
                ReebArcIterator iter;
-               EmbedBucket *current = NULL;
-               EmbedBucket *previous = NULL;
+               float *previous = NULL, *current = NULL;
                EditBone *child = NULL;
                EditBone *parent = NULL;
                EditBone *root = NULL;
@@ -4669,22 +4668,28 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
                
                root = parent;
                
-               for (initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter);
-                       current;
-                       previous = current, current = nextBucket(&iter))
+               initArcIterator(&iter, arc, head);
+               iter.next(&iter);
+               previous = iter.p;
+               
+               for (iter.next(&iter);
+                       iter.stopped(&iter) == 0;
+                       previous = iter.p, iter.next(&iter))
                {
                        float vec1[3], vec2[3];
                        float len1, len2;
+                       
+                       current = iter.p;
 
-                       VecSubf(vec1, previous->p, parent->head);
-                       VecSubf(vec2, current->p, previous->p);
+                       VecSubf(vec1, previous, parent->head);
+                       VecSubf(vec2, current, previous);
 
                        len1 = Normalize(vec1);
                        len2 = Normalize(vec2);
 
                        if (len1 > 0.0f && len2 > 0.0f && Inpf(vec1, vec2) < angleLimit)
                        {
-                               VECCOPY(parent->tail, previous->p);
+                               VECCOPY(parent->tail, previous);
 
                                child = add_editbone("Bone");
                                VECCOPY(child->head, parent->tail);
@@ -4718,19 +4723,18 @@ float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3])
        if (len > 2)
        {
                ReebArcIterator iter;
-               EmbedBucket *bucket = NULL;
                float avg_t = 0.0f;
                float s_t = 0.0f;
                float s_xyz = 0.0f;
                
                /* First pass, calculate average */
-               for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
-                       bucket;
-                       bucket = nextBucket(&iter))
+               for (initArcIterator2(&iter, arc, start, end), iter.next(&iter);
+                       iter.stopped(&iter) == 0;
+                       iter.next(&iter))
                {
                        float v[3];
                        
-                       VecSubf(v, bucket->p, v0);
+                       VecSubf(v, iter.p, v0);
                        avg_t += Inpf(v, n);
                }
                
@@ -4739,14 +4743,14 @@ float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3])
                avg_t /= len;
                
                /* Second pass, calculate s_xyz and s_t */
-               for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
-                       bucket;
-                       bucket = nextBucket(&iter))
+               for (initArcIterator2(&iter, arc, start, end), iter.next(&iter);
+                       iter.stopped(&iter) == 0;
+                       iter.next(&iter))
                {
                        float v[3], d[3];
                        float dt;
                        
-                       VecSubf(v, bucket->p, v0);
+                       VecSubf(v, iter.p, v0);
                        Projf(d, v, n);
                        VecSubf(v, v, d);
                        
@@ -4770,19 +4774,18 @@ float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3])
 float calcDistance(ReebArc *arc, int start, int end, float head[3], float tail[3])
 {
        ReebArcIterator iter;
-       EmbedBucket *bucket = NULL;
        float max_dist = 0;
        
        /* calculate maximum distance */
-       for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
-               bucket;
-               bucket = nextBucket(&iter))
+       for (initArcIterator2(&iter, arc, start, end), iter.next(&iter);
+               iter.stopped(&iter) == 0;
+               iter.next(&iter))
        {
                float v1[3], v2[3], c[3];
                float dist;
                
                VecSubf(v1, head, tail);
-               VecSubf(v2, bucket->p, tail);
+               VecSubf(v2, iter.p, tail);
 
                Crossf(c, v1, v2);
                
@@ -4810,8 +4813,6 @@ EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
        
        if (G.scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION)
        {
-               EmbedBucket *bucket = NULL;
-               EmbedBucket *previous = NULL;
                EditBone *child = NULL;
                EditBone *parent = NULL;
                float normal[3] = {0, 0, 0};
@@ -4823,23 +4824,21 @@ EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
                parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
                VECCOPY(parent->head, head->p);
                
-               for (previous = nextBucket(&iter), bucket = nextBucket(&iter);
-                       bucket;
-                       previous = bucket, bucket = nextBucket(&iter))
+               while(iter.next(&iter))
                {
                        float btail[3];
                        float value = 0;
 
                        if (G.scene->toolsettings->skgen_options & SKGEN_STICK_TO_EMBEDDING)
                        {
-                               VECCOPY(btail, bucket->p);
+                               VECCOPY(btail, iter.p);
                        }
                        else
                        {
                                float length;
                                
                                /* Calculate normal */
-                               VecSubf(n, bucket->p, parent->head);
+                               VecSubf(n, iter.p, parent->head);
                                length = Normalize(n);
                                
                                total += 1;
@@ -4923,8 +4922,7 @@ EditBone * subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
                arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio)
        {
                ReebArcIterator iter;
-               EmbedBucket *bucket = NULL;
-               EmbedBucket *previous = NULL;
+               float *previous = NULL;
                EditBone *child = NULL;
                EditBone *parent = NULL;
                float lengthLimit = G.scene->toolsettings->skgen_length_limit;
@@ -4936,12 +4934,12 @@ EditBone * subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
 
                initArcIterator(&iter, arc, head);
 
-               bucket = nextBucket(&iter);
+               iter.next(&iter);
                
-               while (bucket != NULL)
+               while (iter.stopped(&iter) == 0)
                {
                        float *vec0 = NULL;
-                       float *vec1 = bucket->p;
+                       float *vec1 = iter.p;
 
                        /* first bucket. Previous is head */
                        if (previous == NULL)
@@ -4951,7 +4949,7 @@ EditBone * subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
                        /* Previous is a valid bucket */
                        else
                        {
-                               vec0 = previous->p;
+                               vec0 = previous;
                        }
                        
                        /* If lengthLimit hits the current segment */
@@ -5009,8 +5007,8 @@ EditBone * subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
                        }
                        else
                        {
-                               previous = bucket;
-                               bucket = nextBucket(&iter);
+                               previous = iter.p;
+                               iter.next(&iter);
                                same = 0; // Reset same
                        }
                }
index 00cfafad0f558d813f4e1867c4d67f64e97b4a07..280292abaf031eca6c190dc258f045d2b767230b 100644 (file)
@@ -1683,9 +1683,9 @@ EditBone * generateBonesForArc(RigGraph *rigg, ReebArc *arc, ReebNode *head, Ree
                parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
                VECCOPY(parent->head, head->p);
                
-               for (previous = nextBucket(&iter), bucket = nextBucket(&iter);
+               for (previous = iter.next(&iter), bucket = iter.next(&iter);
                        bucket;
-                       previous = bucket, bucket = nextBucket(&iter))
+                       previous = bucket, bucket = iter.next(&iter))
                {
                        float btail[3];
                        float value = 0;
@@ -2068,7 +2068,7 @@ static float costDistance(ReebArcIterator *iter, float *vec0, float *vec1, int i
                        {
                                float dist;
                                
-                               bucket = peekBucket(iter, j);
+                               bucket = iter->peek(iter, j);
        
                                VecSubf(v2, bucket->p, vec1);
                
@@ -2336,7 +2336,7 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
 
                for (i = 1; i <= nb_positions; i++)
                {
-                       EmbedBucket *bucket = peekBucket(&iter, i);
+                       EmbedBucket *bucket = iter.peek(&iter, i);
                        positions_cache[i] = bucket->p;
                }
 
@@ -2443,7 +2443,7 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
                                        if (i < nb_joints)
                                        {
                                                i2 = positions[i];
-                                               bucket = peekBucket(&iter, positions[i]);
+                                               bucket = iter.peek(&iter, positions[i]);
                                                vec2 = bucket->p;
                                                vec_cache[i + 1] = vec2; /* update cache for updated position */
                                        }
@@ -2535,7 +2535,7 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
                float *no = NULL;
                if (i < nb_joints)
                {
-                       bucket = peekBucket(&iter, best_positions[i]);
+                       bucket = iter.peek(&iter, best_positions[i]);
                        vec1 = bucket->p;
                        no = bucket->no;
                }
@@ -2582,7 +2582,7 @@ static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_
        
        initArcIterator(&iter, earc, node_start);
 
-       bucket = nextBucket(&iter);
+       bucket = iter.next(&iter);
        
        vec0 = node_start->p;
        
@@ -2593,7 +2593,7 @@ static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_
                embedding_length += VecLenf(vec0, vec1);
                
                vec0 = vec1;
-               bucket = nextBucket(&iter);
+               bucket = iter.next(&iter);
        }
        
        embedding_length += VecLenf(node_end->p, vec1);
@@ -2601,7 +2601,7 @@ static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_
        /* fit bones */
        initArcIterator(&iter, earc, node_start);
 
-       bucket = nextBucket(&iter);
+       bucket = iter.next(&iter);
 
        vec0 = node_start->p;
        previous_vec = vec0;
@@ -2616,7 +2616,7 @@ static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_
                while (bucket && new_bone_length > length)
                {
                        length += VecLenf(previous_vec, vec1);
-                       bucket = nextBucket(&iter);
+                       bucket = iter.next(&iter);
                        previous_vec = vec1;
                        vec1 = bucket->p;
                        no = bucket->no;
index b37087064cb22516d5d015fa626c09a35a77ec5e..bb53269bf12863909811ce97a71b03352ab82bd5 100644 (file)
@@ -851,7 +851,8 @@ void fillArcEmptyBuckets(ReebArc *arc)
 static void ExtendArcBuckets(ReebArc *arc)
 {
        ReebArcIterator iter;
-       EmbedBucket *previous, *bucket, *last_bucket, *first_bucket;
+       EmbedBucket *last_bucket, *first_bucket;
+       float *previous = NULL;
        float average_length = 0, length;
        int padding_head = 0, padding_tail = 0;
        
@@ -861,13 +862,15 @@ static void ExtendArcBuckets(ReebArc *arc)
        }
        
        initArcIterator(&iter, arc, arc->head);
+       iter.next(&iter);
+       previous = iter.p;
        
-       for (   previous = nextBucket(&iter), bucket = nextBucket(&iter);
-                       bucket;
-                       previous = bucket, bucket = nextBucket(&iter)
+       for (   iter.next(&iter);
+                       iter.stopped(&iter) == 0;
+                       previous = iter.p, iter.next(&iter)
                )
        {
-               average_length += VecLenf(previous->p, bucket->p);
+               average_length += VecLenf(previous, iter.p);
        }
        average_length /= (arc->bcount - 1);
        
@@ -925,26 +928,22 @@ void extendGraphBuckets(ReebGraph *rg)
 void calculateArcLength(ReebArc *arc)
 {
        ReebArcIterator iter;
-       EmbedBucket *bucket = NULL;
        float *vec0, *vec1;
 
        arc->length = 0;
        
        initArcIterator(&iter, arc, arc->head);
 
-       bucket = nextBucket(&iter);
-       
        vec0 = arc->head->p;
        vec1 = arc->head->p; /* in case there's no embedding */
-       
-       while (bucket != NULL)
+
+       while (iter.next(&iter))        
        {
-               vec1 = bucket->p;
+               vec1 = iter.p;
                
                arc->length += VecLenf(vec0, vec1);
                
                vec0 = vec1;
-               bucket = nextBucket(&iter);
        }
        
        arc->length += VecLenf(arc->tail->p, vec1);     
@@ -1003,22 +1002,22 @@ void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count)
                        initArcIterator(&iter1, arc1, (ReebNode*)root_node);
                        initArcIterator(&iter2, arc2, (ReebNode*)root_node);
                        
-                       bucket1 = nextBucket(&iter1);
-                       bucket2 = nextBucket(&iter2);
+                       bucket1 = iter1.next(&iter1);
+                       bucket2 = iter2.next(&iter2);
                
                        /* Make sure they both start at the same value */       
-                       while(bucket1 && bucket1->val < bucket2->val)
+                       while(bucket1 && bucket2 && bucket1->val < bucket2->val)
                        {
-                               bucket1 = nextBucket(&iter1);
+                               bucket1 = iter1.next(&iter1);
                        }
                        
-                       while(bucket2 && bucket2->val < bucket1->val)
+                       while(bucket1 && bucket2 && bucket2->val < bucket1->val)
                        {
-                               bucket2 = nextBucket(&iter2);
+                               bucket2 = iter2.next(&iter2);
                        }
        
        
-                       for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
+                       for ( ;bucket1 && bucket2; bucket1 = iter1.next(&iter1), bucket2 = iter2.next(&iter2))
                        {
                                bucket2->nv += bucket1->nv; /* add counts */
                                
@@ -1063,22 +1062,22 @@ void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count)
                        initArcIterator(&iter1, arc1, node);
                        initArcIterator(&iter2, arc2, node);
                        
-                       bucket1 = nextBucket(&iter1);
-                       bucket2 = nextBucket(&iter2);
+                       bucket1 = iter1.next(&iter1);
+                       bucket2 = iter2.next(&iter2);
                
                        /* Make sure they both start at the same value */       
                        while(bucket1 && bucket1->val < bucket2->val)
                        {
-                               bucket1 = nextBucket(&iter1);
+                               bucket1 = iter1.next(&iter1);
                        }
                        
                        while(bucket2 && bucket2->val < bucket1->val)
                        {
-                               bucket2 = nextBucket(&iter2);
+                               bucket2 = iter2.next(&iter2);
                        }
        
        
-                       for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
+                       for ( ;bucket1 && bucket2; bucket1 = iter1.next(&iter1), bucket2 = iter1.next(&iter2))
                        {
                                /* copy and mirror back to bucket2 */                   
                                bucket2->nv = bucket1->nv;
@@ -1122,22 +1121,22 @@ void REEB_AxialSymmetry(BNode* root_node, BNode* node1, BNode* node2, struct BAr
                initArcIterator(&iter1, arc1, (ReebNode*)root_node);
                initArcIterator(&iter2, arc2, (ReebNode*)root_node);
                
-               bucket1 = nextBucket(&iter1);
-               bucket2 = nextBucket(&iter2);
+               bucket1 = iter1.next(&iter1);
+               bucket2 = iter2.next(&iter2);
        
                /* Make sure they both start at the same value */       
                while(bucket1 && bucket1->val < bucket2->val)
                {
-                       bucket1 = nextBucket(&iter1);
+                       bucket1 = iter1.next(&iter1);
                }
                
                while(bucket2 && bucket2->val < bucket1->val)
                {
-                       bucket2 = nextBucket(&iter2);
+                       bucket2 = iter1.next(&iter2);
                }
 
 
-               for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
+               for ( ;bucket1 && bucket2; bucket1 = iter2.next(&iter1), bucket2 = iter2.next(&iter2))
                {
                        bucket1->nv += bucket2->nv; /* add counts */
                        
@@ -3297,8 +3296,38 @@ void arcToVCol(ReebGraph *rg, EditMesh *em, int index)
 
 /****************************************** BUCKET ITERATOR **************************************************/
 
+void* nextBucket(void *arg);
+void* nextNBucket(void *arg, int n);
+void* peekBucket(void *arg, int n);
+void* previousBucket(void *arg);
+int iteratorStopped(void *arg);
+
+void initIteratorFct(ReebArcIterator *iter)
+{
+       iter->peek = peekBucket;
+       iter->next = nextBucket;
+       iter->nextN = nextNBucket;
+       iter->previous = previousBucket;
+       iter->stopped = iteratorStopped;        
+}
+
+void setIteratorValues(ReebArcIterator *iter, EmbedBucket *bucket)
+{
+       if (bucket)
+       {
+               iter->p = bucket->p;
+               iter->no = bucket->no;
+       }
+       else
+       {
+               iter->p = NULL;
+               iter->no = NULL;
+       }
+}
+
 void initArcIterator(ReebArcIterator *iter, ReebArc *arc, ReebNode *head)
 {
+       initIteratorFct(iter);
        iter->arc = arc;
        
        if (head == arc->head)
@@ -3321,6 +3350,7 @@ void initArcIterator(ReebArcIterator *iter, ReebArc *arc, ReebNode *head)
 
 void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start)
 {
+       initIteratorFct(iter);
        iter->arc = arc;
        
        if (head == arc->head)
@@ -3348,6 +3378,7 @@ void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, str
 
 void initArcIterator2(ReebArcIterator *iter, ReebArc *arc, int start, int end)
 {
+       initIteratorFct(iter);
        iter->arc = arc;
        
        iter->start = start;
@@ -3367,8 +3398,9 @@ void initArcIterator2(ReebArcIterator *iter, ReebArc *arc, int start, int end)
        iter->length = abs(iter->end - iter->start) + 1;
 }
 
-EmbedBucket * nextBucket(ReebArcIterator *iter)
+void* nextBucket(void *arg)
 {
+       ReebArcIterator *iter = (ReebArcIterator*)arg;
        EmbedBucket *result = NULL;
        
        if (iter->index != iter->end)
@@ -3377,13 +3409,15 @@ EmbedBucket * nextBucket(ReebArcIterator *iter)
                result = &(iter->arc->buckets[iter->index]);
        }
        
+       setIteratorValues(iter, result);
        return result;
 }
 
-EmbedBucket * nextNBucket(ReebArcIterator *iter, int n)
+void* nextNBucket(void *arg, int n)
 {
+       ReebArcIterator *iter = (ReebArcIterator*)arg;
        EmbedBucket *result = NULL;
-       
+               
        iter->index += n * iter->stride;
 
        /* check if passed end */
@@ -3398,11 +3432,13 @@ EmbedBucket * nextNBucket(ReebArcIterator *iter, int n)
                iter->index = iter->end; 
        }
        
+       setIteratorValues(iter, result);
        return result;
 }
 
-EmbedBucket * peekBucket(ReebArcIterator *iter, int n)
+void* peekBucket(void *arg, int n)
 {
+       ReebArcIterator *iter = (ReebArcIterator*)arg;
        EmbedBucket *result = NULL;
        int index = iter->index + n * iter->stride;
 
@@ -3412,12 +3448,14 @@ EmbedBucket * peekBucket(ReebArcIterator *iter, int n)
        {
                result = &(iter->arc->buckets[index]);
        }
-       
+
+       setIteratorValues(iter, result);
        return result;
 }
 
-EmbedBucket * previousBucket(struct ReebArcIterator *iter)
+void* previousBucket(void *arg)
 {
+       ReebArcIterator *iter = (ReebArcIterator*)arg;
        EmbedBucket *result = NULL;
        
        if (iter->index != iter->start)
@@ -3425,12 +3463,15 @@ EmbedBucket * previousBucket(struct ReebArcIterator *iter)
                iter->index -= iter->stride;
                result = &(iter->arc->buckets[iter->index]);
        }
-       
+
+       setIteratorValues(iter, result);
        return result;
 }
 
-int iteratorStopped(struct ReebArcIterator *iter)
+int iteratorStopped(void *arg)
 {
+       ReebArcIterator *iter = (ReebArcIterator*)arg;
+
        if (iter->index == iter->end)
        {
                return 1;
@@ -3441,18 +3482,6 @@ int iteratorStopped(struct ReebArcIterator *iter)
        }
 }
 
-struct EmbedBucket * currentBucket(struct ReebArcIterator *iter)
-{
-       EmbedBucket *result = NULL;
-       
-       if (iter->index != iter->end)
-       {
-               result = &(iter->arc->buckets[iter->index]);
-       }
-       
-       return result;
-}
-
 /************************ PUBLIC FUNCTIONS *********************************************/
 
 ReebGraph *BIF_ReebGraphMultiFromEditMesh(void)
@@ -3597,26 +3626,32 @@ ReebGraph *BIF_ReebGraphFromEditMesh(void)
        
        rg = generateReebGraph(em, G.scene->toolsettings->skgen_resolution);
 
-       REEB_exportGraph(rg, -1);
-
-       printf("GENERATED\n");
-       printf("%i subgraphs\n", BLI_FlagSubgraphs((BGraph*)rg));
 
        /* Remove arcs without embedding */
        filterNullReebGraph(rg);
 
-       BLI_freeAdjacencyList((BGraph*)rg);
+       /* smart filter and loop filter on basic level */
+       filterGraph(rg, SKGEN_FILTER_SMART, 0, 0);
 
-       printf("NULL FILTERED\n");
-       printf("%i subgraphs\n", BLI_FlagSubgraphs((BGraph*)rg));
+       repositionNodes(rg);
 
+       /* Filtering might have created degree 2 nodes, so remove them */
+       removeNormalNodes(rg);
+       
+       joinSubgraphs(rg, 1.0);
+
+       BLI_buildAdjacencyList((BGraph*)rg);
+       
+       /* calc length before copy, so we have same length on all levels */
+       BLI_calcGraphLength((BGraph*)rg);
+       
        filterGraph(rg, G.scene->toolsettings->skgen_options, G.scene->toolsettings->skgen_threshold_internal, G.scene->toolsettings->skgen_threshold_external);
 
        finalizeGraph(rg, G.scene->toolsettings->skgen_postpro_passes, G.scene->toolsettings->skgen_postpro);
 
+#ifdef DEBUG_REEB
        REEB_exportGraph(rg, -1);
        
-#ifdef DEBUG_REEB
        arcToVCol(rg, em, 0);
        //angleToVCol(em, 1);
 #endif
@@ -3677,7 +3712,6 @@ void REEB_draw()
        for (arc = rg->arcs.first; arc; arc = arc->next, i++)
        {
                ReebArcIterator iter;
-               EmbedBucket *bucket;
                float vec[3];
                char text[128];
                char *s = text;
@@ -3690,9 +3724,9 @@ void REEB_draw()
                        if (arc->bcount)
                        {
                                initArcIterator(&iter, arc, arc->head);
-                               for (bucket = nextBucket(&iter); bucket; bucket = nextBucket(&iter))
+                               for (iter.next(&iter); iter.stopped(&iter) == 0; iter.next(&iter))
                                {
-                                       glVertex3fv(bucket->p);
+                                       glVertex3fv(iter.p);
                                }
                        }
                        
@@ -3723,9 +3757,9 @@ void REEB_draw()
                        if (arc->bcount)
                        {
                                initArcIterator(&iter, arc, arc->head);
-                               for (bucket = nextBucket(&iter); bucket; bucket = nextBucket(&iter))
+                               for (iter.next(&iter); iter.stopped(&iter) == 0; iter.next(&iter))
                                {
-                                       glVertex3fv(bucket->p);
+                                       glVertex3fv(iter.p);
                                }
                        }
                        
@@ -3744,9 +3778,9 @@ void REEB_draw()
                                if (arc->bcount)
                                {
                                        initArcIterator(&iter, arc, arc->head);
-                                       for (bucket = nextBucket(&iter); bucket; bucket = nextBucket(&iter))
+                                       for (iter.next(&iter); iter.stopped(&iter) == 0; iter.next(&iter))
                                        {
-                                               glVertex3fv(bucket->p);
+                                               glVertex3fv(iter.p);
                                        }
                                }
                        glEnd();