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:
authorMartin Poirier <theeth@yahoo.com>2008-11-29 23:37:10 +0300
committerMartin Poirier <theeth@yahoo.com>2008-11-29 23:37:10 +0300
commite2fb12ea18b4be8159fa14252af537d7dc01f585 (patch)
treec5eea0fac47da7b36c725c61bb87ca58b221803e
parentd467158158b92ac9e92482db00ee51b2c16597f3 (diff)
Step 3/3, merging subdivision/bone creation methods using iterators
This also adds a special Embedding option called "Peel Objects". This option makes the embedding snap consider objects as whole, taking the first and last hit of each of them to calculate the embedding point (instead of peeling with first/second, third/fourth and so on). This option is useful if you have mecanical pieces with lots of details (as single objects) and want to put bones in the middle (think of adding bones to a mecha, for example).
-rw-r--r--source/blender/blenlib/BLI_graph.h14
-rw-r--r--source/blender/blenlib/intern/graph.c55
-rw-r--r--source/blender/include/BIF_generate.h44
-rw-r--r--source/blender/include/reeb.h10
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/src/drawview.c4
-rw-r--r--source/blender/src/editarmature.c303
-rw-r--r--source/blender/src/editarmature_generate.c327
-rw-r--r--source/blender/src/editarmature_retarget.c142
-rw-r--r--source/blender/src/editarmature_sketch.c417
-rw-r--r--source/blender/src/reeb.c226
11 files changed, 849 insertions, 694 deletions
diff --git a/source/blender/blenlib/BLI_graph.h b/source/blender/blenlib/BLI_graph.h
index 7629dbf6ba8..f4fccfcbb2c 100644
--- a/source/blender/blenlib/BLI_graph.h
+++ b/source/blender/blenlib/BLI_graph.h
@@ -62,13 +62,25 @@ typedef struct BArc {
struct BArcIterator;
+void* IT_head(void* iter);
+void* IT_tail(void* iter);
+void* IT_peek(void* iter, int n);
+void* IT_next(void* iter);
+void* IT_nextN(void* iter, int n);
+void* IT_previous(void* iter);
+int IT_stopped(void* iter);
+
+typedef void* (*HeadFct)(void* iter);
+typedef void* (*TailFct)(void* 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 int (*StoppedFct)(void* iter);
typedef struct BArcIterator {
+ HeadFct head;
+ TailFct tail;
PeekFct peek;
NextFct next;
NextNFct nextN;
diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c
index e2ed8f11ee2..ca82fcac844 100644
--- a/source/blender/blenlib/intern/graph.c
+++ b/source/blender/blenlib/intern/graph.c
@@ -465,8 +465,6 @@ int subtreeShape(BNode *node, BArc *rootArc, int include_root)
int BLI_subtreeShape(BGraph *graph, BNode *node, BArc *rootArc, int include_root)
{
- BNode *test_node;
-
BLI_flagNodes(graph, 0);
return subtreeShape(node, rootArc, include_root);
}
@@ -1090,3 +1088,56 @@ void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit)
}
}
+void* IT_head(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->head(iter);
+}
+
+void* IT_tail(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->tail(iter);
+}
+
+void* IT_peek(void* arg, int n)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+
+ if (iter->index + n < 0)
+ {
+ return iter->head(iter);
+ }
+ else if (iter->index + n >= iter->length)
+ {
+ return iter->tail(iter);
+ }
+ else
+ {
+ return iter->peek(iter, n);
+ }
+}
+
+void* IT_next(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->next(iter);
+}
+
+void* IT_nextN(void* arg, int n)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->nextN(iter, n);
+}
+
+void* IT_previous(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->previous(iter);
+}
+
+int IT_stopped(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->stopped(iter);
+}
diff --git a/source/blender/include/BIF_generate.h b/source/blender/include/BIF_generate.h
new file mode 100644
index 00000000000..32d89d32f78
--- /dev/null
+++ b/source/blender/include/BIF_generate.h
@@ -0,0 +1,44 @@
+/**
+ * $Id: $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_GENERATE_H
+#define BIF_GENERATE_H
+
+struct EditBone;
+struct BArcIterator;
+struct bArmature;
+struct ListBase;
+
+typedef int(NextSubdivisionFunc)(struct BArcIterator*, int, int, float[3], float[3]);
+
+float calcArcCorrelation(struct BArcIterator *iter, int start, int end, float v0[3], float n[3]);
+
+int nextFixedSubdivision(struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
+int nextLengthSubdivision(struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
+int nextCorrelationSubdivision(struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
+
+struct EditBone * subdivideArcBy(struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion);
+
+void setBoneRollFromNormal(struct EditBone *bone, float *no, float invmat[][4], float tmat[][3]);
+
+
+#endif /* BIF_GENERATE_H */
diff --git a/source/blender/include/reeb.h b/source/blender/include/reeb.h
index 21c57495fb0..2f463d6194b 100644
--- a/source/blender/include/reeb.h
+++ b/source/blender/include/reeb.h
@@ -28,7 +28,7 @@
#ifndef REEB_H_
#define REEB_H_
-#define WITH_BF_REEB
+//#define WITH_BF_REEB
#include "DNA_listBase.h"
@@ -120,6 +120,8 @@ typedef struct ReebArc {
} ReebArc;
typedef struct ReebArcIterator {
+ HeadFct head;
+ TailFct tail;
PeekFct peek;
NextFct next;
NextNFct nextN;
@@ -151,9 +153,9 @@ void renormalizeWeight(struct EditMesh *em, float newmax);
ReebGraph * generateReebGraph(struct EditMesh *me, int subdivisions);
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);
+void initArcIterator(BArcIterator *iter, struct ReebArc *arc, struct ReebNode *head);
+void initArcIterator2(BArcIterator *iter, struct ReebArc *arc, int start, int end);
+void initArcIteratorStart(BArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start);
/* Filtering */
void filterNullReebGraph(ReebGraph *rg);
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 10e8c534ab2..a5491578115 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -728,6 +728,7 @@ typedef struct Scene {
/* scene->snap_flag */
#define SCE_SNAP 1
#define SCE_SNAP_ROTATE 2
+#define SCE_SNAP_PEEL_OBJECT 4
/* scene->snap_target */
#define SCE_SNAP_TARGET_CLOSEST 0
#define SCE_SNAP_TARGET_CENTER 1
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index e652ea989d1..3dfec925474 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -2294,7 +2294,7 @@ static void view3d_panel_bonesketch_spaces(short cntrl)
static char joint_label[32];
uiBlock *block;
uiBut *but;
- int yco = 70, height = 140;
+ int yco = 130, height = 140;
int nb_joints;
/* replace with check call to sketching lib */
@@ -2382,7 +2382,9 @@ static void view3d_panel_bonesketch_spaces(short cntrl)
BLI_snprintf(joint_label, 32, "%i joints", nb_joints);
uiDefBut(block, LABEL, 1, joint_label, 10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
+ yco -= 20;
+ uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_DIFF, "Peel Objects", 10, yco, 200, 20, &G.scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
if(yco < 0) uiNewPanelHeight(block, height-yco);
}
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index bae6fc5a0af..4521c9a8312 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -93,6 +93,7 @@
#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "BIF_transform.h"
+#include "BIF_generate.h"
#include "BDR_editobject.h"
#include "BDR_drawobject.h"
@@ -4655,7 +4656,8 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
EditBone *lastBone = NULL;
if (G.scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
{
- ReebArcIterator iter;
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
float *previous = NULL, *current = NULL;
EditBone *child = NULL;
EditBone *parent = NULL;
@@ -4668,18 +4670,18 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
root = parent;
- initArcIterator(&iter, arc, head);
- iter.next(&iter);
- previous = iter.p;
+ initArcIterator(iter, arc, head);
+ IT_next(iter);
+ previous = iter->p;
- for (iter.next(&iter);
- iter.stopped(&iter) == 0;
- previous = iter.p, iter.next(&iter))
+ for (IT_next(iter);
+ IT_stopped(iter) == 0;
+ previous = iter->p, IT_next(iter))
{
float vec1[3], vec2[3];
float len1, len2;
- current = iter.p;
+ current = iter->p;
VecSubf(vec1, previous, parent->head);
VecSubf(vec2, current, previous);
@@ -4716,173 +4718,26 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
return lastBone;
}
-float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3])
+EditBone * test_subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
{
- int len = 2 + abs(end - start);
-
- if (len > 2)
- {
- ReebArcIterator iter;
- 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), iter.next(&iter);
- iter.stopped(&iter) == 0;
- iter.next(&iter))
- {
- float v[3];
-
- VecSubf(v, iter.p, v0);
- avg_t += Inpf(v, n);
- }
-
- avg_t /= Inpf(n, n);
- avg_t += 1.0f; /* adding start (0) and end (1) values */
- avg_t /= len;
-
- /* Second pass, calculate s_xyz and s_t */
- 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, iter.p, v0);
- Projf(d, v, n);
- VecSubf(v, v, d);
-
- dt = VecLength(d) - avg_t;
-
- s_t += dt * dt;
- s_xyz += Inpf(v, v);
- }
-
- /* adding start(0) and end(1) values to s_t */
- s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
-
- return s_xyz / s_t;
- }
- else
- {
- return 0;
- }
-}
-
-float calcDistance(ReebArc *arc, int start, int end, float head[3], float tail[3])
-{
- ReebArcIterator iter;
- float max_dist = 0;
-
- /* calculate maximum distance */
- 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, iter.p, tail);
-
- Crossf(c, v1, v2);
-
- dist = Inpf(c, c) / Inpf(v1, v1);
-
- max_dist = dist > max_dist ? dist : max_dist;
- }
-
-
- return max_dist;
-}
-
-EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
-{
- ReebArcIterator iter;
- float n[3];
- float ADAPTIVE_THRESHOLD = G.scene->toolsettings->skgen_correlation_limit;
EditBone *lastBone = NULL;
-
- /* init iterator to get start and end from head */
- initArcIterator(&iter, arc, head);
-
- /* Calculate overall */
- VecSubf(n, arc->buckets[iter.end].p, head->p);
-
+
if (G.scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION)
{
- EditBone *child = NULL;
- EditBone *parent = NULL;
- float normal[3] = {0, 0, 0};
- float avg_normal[3];
- int total = 0;
- int boneStart = iter.start;
-
- parent = add_editbone("Bone");
- parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
- VECCOPY(parent->head, head->p);
+ float invmat[4][4] = { {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1}};
+ float tmat[3][3] = { {1, 0, 0},
+ {0, 1, 0},
+ {0, 0, 1}};
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ bArmature *arm= G.obedit->data;
- while(iter.next(&iter))
- {
- float btail[3];
- float value = 0;
-
- if (G.scene->toolsettings->skgen_options & SKGEN_STICK_TO_EMBEDDING)
- {
- VECCOPY(btail, iter.p);
- }
- else
- {
- float length;
-
- /* Calculate normal */
- VecSubf(n, iter.p, parent->head);
- length = Normalize(n);
-
- total += 1;
- VecAddf(normal, normal, n);
- VECCOPY(avg_normal, normal);
- VecMulf(avg_normal, 1.0f / total);
-
- VECCOPY(btail, avg_normal);
- VecMulf(btail, length);
- VecAddf(btail, btail, parent->head);
- }
-
- if (G.scene->toolsettings->skgen_options & SKGEN_ADAPTIVE_DISTANCE)
- {
- value = calcDistance(arc, boneStart, iter.index, parent->head, btail);
- }
- else
- {
- float n[3];
-
- VecSubf(n, btail, parent->head);
- value = calcVariance(arc, boneStart, iter.index, parent->head, n);
- }
-
- if (value > ADAPTIVE_THRESHOLD)
- {
- VECCOPY(parent->tail, btail);
-
- child = add_editbone("Bone");
- VECCOPY(child->head, parent->tail);
- child->parent = parent;
- child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-
- parent = child; // new child is next parent
- boneStart = iter.index; // start from end
-
- normal[0] = normal[1] = normal[2] = 0;
- total = 0;
- }
- }
-
- VECCOPY(parent->tail, tail->p);
+ initArcIterator(iter, arc, head);
- lastBone = parent; /* set last bone in the chain */
+ lastBone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextCorrelationSubdivision);
}
return lastBone;
@@ -4915,106 +4770,26 @@ float arcLengthRatio(ReebArc *arc)
return embedLength / arcLength;
}
-EditBone * subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
+EditBone * test_subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
{
EditBone *lastBone = NULL;
if ((G.scene->toolsettings->skgen_options & SKGEN_CUT_LENGTH) &&
arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio)
{
- ReebArcIterator iter;
- float *previous = NULL;
- EditBone *child = NULL;
- EditBone *parent = NULL;
- float lengthLimit = G.scene->toolsettings->skgen_length_limit;
- int same = 0;
-
- parent = add_editbone("Bone");
- parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
- VECCOPY(parent->head, head->p);
-
- initArcIterator(&iter, arc, head);
-
- iter.next(&iter);
+ float invmat[4][4] = { {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1}};
+ float tmat[3][3] = { {1, 0, 0},
+ {0, 1, 0},
+ {0, 0, 1}};
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ bArmature *arm= G.obedit->data;
- while (iter.stopped(&iter) == 0)
- {
- float *vec0 = NULL;
- float *vec1 = iter.p;
-
- /* first bucket. Previous is head */
- if (previous == NULL)
- {
- vec0 = head->p;
- }
- /* Previous is a valid bucket */
- else
- {
- vec0 = previous;
- }
-
- /* If lengthLimit hits the current segment */
- if (VecLenf(vec1, parent->head) > lengthLimit)
- {
- if (same == 0)
- {
- float dv[3], off[3];
- float a, b, c, f;
-
- /* Solve quadratic distance equation */
- VecSubf(dv, vec1, vec0);
- a = Inpf(dv, dv);
-
- VecSubf(off, vec0, parent->head);
- b = 2 * Inpf(dv, off);
-
- c = Inpf(off, off) - (lengthLimit * lengthLimit);
-
- f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
-
- //printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
-
- if (isnan(f) == 0 && f < 1.0f)
- {
- VECCOPY(parent->tail, dv);
- VecMulf(parent->tail, f);
- VecAddf(parent->tail, parent->tail, vec0);
- }
- else
- {
- VECCOPY(parent->tail, vec1);
- }
- }
- else
- {
- float dv[3];
-
- VecSubf(dv, vec1, vec0);
- Normalize(dv);
-
- VECCOPY(parent->tail, dv);
- VecMulf(parent->tail, lengthLimit);
- VecAddf(parent->tail, parent->tail, parent->head);
- }
-
- child = add_editbone("Bone");
- VECCOPY(child->head, parent->tail);
- child->parent = parent;
- child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-
- parent = child; // new child is next parent
-
- same = 1; // mark as same
- }
- else
- {
- previous = iter.p;
- iter.next(&iter);
- same = 0; // Reset same
- }
- }
- VECCOPY(parent->tail, tail->p);
+ initArcIterator(iter, arc, head);
- lastBone = parent; /* set last bone in the chain */
+ lastBone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextLengthSubdivision);
}
return lastBone;
@@ -5107,13 +4882,13 @@ void generateSkeletonFromReebGraph(ReebGraph *rg)
switch(G.scene->toolsettings->skgen_subdivisions[i])
{
case SKGEN_SUB_LENGTH:
- lastBone = subdivideByLength(arc, head, tail);
+ lastBone = test_subdivideByLength(arc, head, tail);
break;
case SKGEN_SUB_ANGLE:
lastBone = subdivideByAngle(arc, head, tail);
break;
case SKGEN_SUB_CORRELATION:
- lastBone = subdivideByCorrelation(arc, head, tail);
+ lastBone = test_subdivideByCorrelation(arc, head, tail);
break;
}
}
diff --git a/source/blender/src/editarmature_generate.c b/source/blender/src/editarmature_generate.c
new file mode 100644
index 00000000000..c6e77488212
--- /dev/null
+++ b/source/blender/src/editarmature_generate.c
@@ -0,0 +1,327 @@
+/**
+ * $Id: editarmature_generate.c $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * editarmature.c: Interface for creating and posing armature objects
+ */
+
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_scene_types.h"
+#include "DNA_armature_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_graph.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+
+#include "BIF_editarmature.h"
+#include "BIF_generate.h"
+
+void setBoneRollFromNormal(EditBone *bone, float *no, float invmat[][4], float tmat[][3])
+{
+ if (no != NULL && !VecIsNull(no))
+ {
+ float tangent[3], cotangent[3], normal[3];
+
+ VECCOPY(normal, no);
+ Mat3MulVecfl(tmat, normal);
+
+ VecSubf(tangent, bone->tail, bone->head);
+ Crossf(cotangent, tangent, normal);
+ Crossf(normal, cotangent, tangent);
+
+ Normalize(normal);
+
+ bone->roll = rollBoneToVector(bone, normal);
+ }
+}
+
+float calcArcCorrelation(BArcIterator *iter, int start, int end, float v0[3], float n[3])
+{
+ int len = 2 + abs(end - start);
+
+ if (len > 2)
+ {
+ float avg_t = 0.0f;
+ float s_t = 0.0f;
+ float s_xyz = 0.0f;
+ int i;
+
+ /* First pass, calculate average */
+ for (i = start; i <= end; i++)
+ {
+ float v[3];
+
+ IT_peek(iter, i);
+ VecSubf(v, iter->p, v0);
+ avg_t += Inpf(v, n);
+ }
+
+ avg_t /= Inpf(n, n);
+ avg_t += 1.0f; /* adding start (0) and end (1) values */
+ avg_t /= len;
+
+ /* Second pass, calculate s_xyz and s_t */
+ for (i = start; i <= end; i++)
+ {
+ float v[3], d[3];
+ float dt;
+
+ IT_peek(iter, i);
+ VecSubf(v, iter->p, v0);
+ Projf(d, v, n);
+ VecSubf(v, v, d);
+
+ dt = VecLength(d) - avg_t;
+
+ s_t += dt * dt;
+ s_xyz += Inpf(v, v);
+ }
+
+ /* adding start(0) and end(1) values to s_t */
+ s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
+
+ return 1.0f - s_xyz / s_t;
+ }
+ else
+ {
+ return 1.0f;
+ }
+}
+
+int nextFixedSubdivision(BArcIterator *iter, int start, int end, float head[3], float p[3])
+{
+ static float stroke_length = 0;
+ static float current_length;
+ static char n;
+ float *v1, *v2;
+ float length_threshold;
+ int i;
+
+ if (stroke_length == 0)
+ {
+ current_length = 0;
+
+ IT_peek(iter, start);
+ v1 = iter->p;
+
+ for (i = start + 1; i <= end; i++)
+ {
+ IT_peek(iter, i);
+ v2 = iter->p;
+
+ stroke_length += VecLenf(v1, v2);
+
+ v1 = v2;
+ }
+
+ n = 0;
+ current_length = 0;
+ }
+
+ n++;
+
+ length_threshold = n * stroke_length / G.scene->toolsettings->skgen_subdivision_number;
+
+ IT_peek(iter, start);
+ v1 = iter->p;
+
+ /* < and not <= because we don't care about end, it is P_EXACT anyway */
+ for (i = start + 1; i < end; i++)
+ {
+ IT_peek(iter, i);
+ v2 = iter->p;
+
+ current_length += VecLenf(v1, v2);
+
+ if (current_length >= length_threshold)
+ {
+ VECCOPY(p, v2);
+ return i;
+ }
+
+ v1 = v2;
+ }
+
+ stroke_length = 0;
+
+ return -1;
+}
+int nextCorrelationSubdivision(BArcIterator *iter, int start, int end, float head[3], float p[3])
+{
+ float correlation_threshold = G.scene->toolsettings->skgen_correlation_limit;
+ float *start_p;
+ float n[3];
+ int i;
+
+ IT_peek(iter, start);
+ start_p = iter->p;
+
+ for (i = start + 2; i <= end; i++)
+ {
+ /* Calculate normal */
+ IT_peek(iter, i);
+ VecSubf(n, iter->p, head);
+
+ if (calcArcCorrelation(iter, start, i, start_p, n) < correlation_threshold)
+ {
+ IT_peek(iter, i - 1);
+ VECCOPY(p, iter->p);
+ return i - 1;
+ }
+ }
+
+ return -1;
+}
+
+int nextLengthSubdivision(BArcIterator *iter, int start, int end, float head[3], float p[3])
+{
+ float lengthLimit = G.scene->toolsettings->skgen_length_limit;
+ int same = 1;
+ int i;
+
+ i = start + 1;
+ while (i <= end)
+ {
+ float *vec0;
+ float *vec1;
+
+ IT_peek(iter, i - 1);
+ vec0 = iter->p;
+
+ IT_peek(iter, i);
+ vec1 = iter->p;
+
+ /* If lengthLimit hits the current segment */
+ if (VecLenf(vec1, head) > lengthLimit)
+ {
+ if (same == 0)
+ {
+ float dv[3], off[3];
+ float a, b, c, f;
+
+ /* Solve quadratic distance equation */
+ VecSubf(dv, vec1, vec0);
+ a = Inpf(dv, dv);
+
+ VecSubf(off, vec0, head);
+ b = 2 * Inpf(dv, off);
+
+ c = Inpf(off, off) - (lengthLimit * lengthLimit);
+
+ f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
+
+ //printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
+
+ if (isnan(f) == 0 && f < 1.0f)
+ {
+ VECCOPY(p, dv);
+ VecMulf(p, f);
+ VecAddf(p, p, vec0);
+ }
+ else
+ {
+ VECCOPY(p, vec1);
+ }
+ }
+ else
+ {
+ float dv[3];
+
+ VecSubf(dv, vec1, vec0);
+ Normalize(dv);
+
+ VECCOPY(p, dv);
+ VecMulf(p, lengthLimit);
+ VecAddf(p, p, head);
+ }
+
+ return i - 1; /* restart at lower bound */
+ }
+ else
+ {
+ i++;
+ same = 0; // Reset same
+ }
+ }
+
+ return -1;
+}
+
+EditBone * subdivideArcBy(bArmature *arm, ListBase *editbones, BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion)
+{
+ EditBone *lastBone = NULL;
+ EditBone *child = NULL;
+ EditBone *parent = NULL;
+ int bone_start = 0;
+ int end = iter->length;
+ int index;
+
+ IT_head(iter);
+
+ parent = addEditBone("Bone", editbones, arm);
+ VECCOPY(parent->head, iter->p);
+
+ index = next_subdividion(iter, bone_start, end, parent->head, parent->tail);
+ while (index != -1)
+ {
+ IT_peek(iter, index);
+
+ child = addEditBone("Bone", editbones, arm);
+ VECCOPY(child->head, parent->tail);
+ child->parent = parent;
+ child->flag |= BONE_CONNECTED;
+
+ /* going to next bone, fix parent */
+ Mat4MulVecfl(invmat, parent->tail);
+ Mat4MulVecfl(invmat, parent->head);
+ setBoneRollFromNormal(parent, iter->no, invmat, tmat);
+
+ parent = child; // new child is next parent
+ bone_start = index; // start next bone from current index
+
+ index = next_subdividion(iter, bone_start, end, parent->head, parent->tail);
+ }
+
+ iter->tail(iter);
+
+ VECCOPY(parent->tail, iter->p);
+
+ /* fix last bone */
+ Mat4MulVecfl(invmat, parent->tail);
+ Mat4MulVecfl(invmat, parent->head);
+ setBoneRollFromNormal(parent, iter->no, invmat, tmat);
+ lastBone = parent;
+
+ return lastBone;
+}
diff --git a/source/blender/src/editarmature_retarget.c b/source/blender/src/editarmature_retarget.c
index 280292abaf0..bb0fc08905c 100644
--- a/source/blender/src/editarmature_retarget.c
+++ b/source/blender/src/editarmature_retarget.c
@@ -1655,100 +1655,6 @@ static EditBone *add_editbonetolist(char *name, ListBase *list)
return bone;
}
-EditBone * generateBonesForArc(RigGraph *rigg, ReebArc *arc, ReebNode *head, ReebNode *tail)
-{
- ReebArcIterator iter;
- float n[3];
- float ADAPTIVE_THRESHOLD = G.scene->toolsettings->skgen_correlation_limit;
- EditBone *lastBone = NULL;
-
- /* init iterator to get start and end from head */
- initArcIterator(&iter, arc, head);
-
- /* Calculate overall */
- VecSubf(n, arc->buckets[iter.end].p, head->p);
-
- if (1 /* 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};
- float avg_normal[3];
- int total = 0;
- int boneStart = iter.start;
-
- parent = add_editbonetolist("Bone", rigg->editbones);
- parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
- VECCOPY(parent->head, head->p);
-
- for (previous = iter.next(&iter), bucket = iter.next(&iter);
- bucket;
- previous = bucket, bucket = iter.next(&iter))
- {
- float btail[3];
- float value = 0;
-
- if (G.scene->toolsettings->skgen_options & SKGEN_STICK_TO_EMBEDDING)
- {
- VECCOPY(btail, bucket->p);
- }
- else
- {
- float length;
-
- /* Calculate normal */
- VecSubf(n, bucket->p, parent->head);
- length = Normalize(n);
-
- total += 1;
- VecAddf(normal, normal, n);
- VECCOPY(avg_normal, normal);
- VecMulf(avg_normal, 1.0f / total);
-
- VECCOPY(btail, avg_normal);
- VecMulf(btail, length);
- VecAddf(btail, btail, parent->head);
- }
-
- if (G.scene->toolsettings->skgen_options & SKGEN_ADAPTIVE_DISTANCE)
- {
- value = calcDistance(arc, boneStart, iter.index, parent->head, btail);
- }
- else
- {
- float n[3];
-
- VecSubf(n, btail, parent->head);
- value = calcVariance(arc, boneStart, iter.index, parent->head, n);
- }
-
- if (value > ADAPTIVE_THRESHOLD)
- {
- VECCOPY(parent->tail, btail);
-
- child = add_editbonetolist("Bone", rigg->editbones);
- VECCOPY(child->head, parent->tail);
- child->parent = parent;
- child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-
- parent = child; // new child is next parent
- boneStart = iter.index; // start from end
-
- normal[0] = normal[1] = normal[2] = 0;
- total = 0;
- }
- }
-
- VECCOPY(parent->tail, tail->p);
-
- lastBone = parent; /* set last bone in the chain */
- }
-
- return lastBone;
-}
-
void generateMissingArcsFromNode(RigGraph *rigg, ReebNode *node, int multi_level_limit)
{
while (node->multi_level > multi_level_limit && node->link_up)
@@ -1775,7 +1681,7 @@ void generateMissingArcsFromNode(RigGraph *rigg, ReebNode *node, int multi_level
earc->flag = ARC_USED;
- generateBonesForArc(rigg, earc, node, other);
+ //generateBonesForArc(rigg, earc, node, other);
generateMissingArcsFromNode(rigg, other, multi_level_limit);
}
}
@@ -2048,7 +1954,7 @@ static void printPositions(int *positions, int nb_positions)
#define MAX_COST FLT_MAX /* FIX ME */
-static float costDistance(ReebArcIterator *iter, float *vec0, float *vec1, int i0, int i1)
+static float costDistance(BArcIterator *iter, float *vec0, float *vec1, int i0, int i1)
{
EmbedBucket *bucket = NULL;
float max_dist = 0;
@@ -2068,7 +1974,7 @@ static float costDistance(ReebArcIterator *iter, float *vec0, float *vec1, int i
{
float dist;
- bucket = iter->peek(iter, j);
+ bucket = IT_peek(iter, j);
VecSubf(v2, bucket->p, vec1);
@@ -2128,7 +2034,7 @@ static float costLength(float original_length, float current_length)
}
}
-static float calcCostLengthDistance(ReebArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec1, float *vec2, int i1, int i2)
+static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec1, float *vec2, int i1, int i2)
{
float vec[3];
float length;
@@ -2139,7 +2045,7 @@ static float calcCostLengthDistance(ReebArcIterator *iter, float **vec_cache, Ri
return costLength(edge->length, length) + costDistance(iter, vec1, vec2, i1, i2);
}
-static float calcCostAngleLengthDistance(ReebArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec0, float *vec1, float *vec2, int i1, int i2)
+static float calcCostAngleLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec0, float *vec1, float *vec2, int i1, int i2)
{
float vec_second[3], vec_first[3];
float length2;
@@ -2189,7 +2095,7 @@ static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions,
}
}
-static MemoNode * solveJoints(MemoNode *table, ReebArcIterator *iter, float **vec_cache, int nb_joints, int nb_positions, int previous, int current, RigEdge *edge, int joints_left)
+static MemoNode * solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache, int nb_joints, int nb_positions, int previous, int current, RigEdge *edge, int joints_left)
{
MemoNode *node;
int index = indexMemoNode(nb_positions, previous, current, joints_left);
@@ -2277,7 +2183,8 @@ static int testFlipArc(RigArc *iarc, RigNode *inode_start)
static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
{
- ReebArcIterator iter;
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
RigEdge *edge;
EmbedBucket *bucket = NULL;
ReebNode *node_start, *node_end;
@@ -2332,15 +2239,15 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
positions_cache[0] = node_start->p;
positions_cache[nb_positions + 1] = node_end->p;
- initArcIterator(&iter, earc, node_start);
+ initArcIterator(iter, earc, node_start);
for (i = 1; i <= nb_positions; i++)
{
- EmbedBucket *bucket = iter.peek(&iter, i);
+ EmbedBucket *bucket = IT_peek(iter, i);
positions_cache[i] = bucket->p;
}
- result = solveJoints(table, &iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints);
+ result = solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints);
min_cost = result->weight;
copyMemoPositions(best_positions, table, earc->bcount, nb_joints);
@@ -2422,7 +2329,7 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
}
/* calculating cost */
- initArcIterator(&iter, earc, node_start);
+ initArcIterator(iter, earc, node_start);
vec0 = NULL;
vec1 = node_start->p;
@@ -2443,13 +2350,13 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
if (i < nb_joints)
{
i2 = positions[i];
- bucket = iter.peek(&iter, positions[i]);
+ bucket = IT_peek(iter, positions[i]);
vec2 = bucket->p;
vec_cache[i + 1] = vec2; /* update cache for updated position */
}
else
{
- i2 = iter.length;
+ i2 = iter->length;
vec2 = node_end->p;
}
@@ -2485,7 +2392,7 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
new_cost += costLength(edge->length, length2);
/* Distance Cost */
- new_cost += costDistance(&iter, vec1, vec2, i1, i2);
+ new_cost += costDistance(iter, vec1, vec2, i1, i2);
cost_cache[i] = new_cost;
}
@@ -2518,7 +2425,7 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
}
vec0 = node_start->p;
- initArcIterator(&iter, earc, node_start);
+ initArcIterator(iter, earc, node_start);
#ifndef USE_THREADS
printPositions(best_positions, nb_joints);
@@ -2535,7 +2442,7 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
float *no = NULL;
if (i < nb_joints)
{
- bucket = iter.peek(&iter, best_positions[i]);
+ bucket = IT_peek(iter, best_positions[i]);
vec1 = bucket->p;
no = bucket->no;
}
@@ -2558,7 +2465,8 @@ static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *ino
static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
{
- ReebArcIterator iter;
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
ReebArc *earc = iarc->link_mesh;
ReebNode *node_start, *node_end;
RigEdge *edge;
@@ -2580,9 +2488,9 @@ static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_
node_end = (ReebNode*)earc->tail;
}
- initArcIterator(&iter, earc, node_start);
+ initArcIterator(iter, earc, node_start);
- bucket = iter.next(&iter);
+ bucket = IT_next(iter);
vec0 = node_start->p;
@@ -2593,15 +2501,15 @@ static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_
embedding_length += VecLenf(vec0, vec1);
vec0 = vec1;
- bucket = iter.next(&iter);
+ bucket = IT_next(iter);
}
embedding_length += VecLenf(node_end->p, vec1);
/* fit bones */
- initArcIterator(&iter, earc, node_start);
+ initArcIterator(iter, earc, node_start);
- bucket = iter.next(&iter);
+ bucket = IT_next(iter);
vec0 = node_start->p;
previous_vec = vec0;
@@ -2616,7 +2524,7 @@ static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_
while (bucket && new_bone_length > length)
{
length += VecLenf(previous_vec, vec1);
- bucket = iter.next(&iter);
+ bucket = IT_next(iter);
previous_vec = vec1;
vec1 = bucket->p;
no = bucket->no;
diff --git a/source/blender/src/editarmature_sketch.c b/source/blender/src/editarmature_sketch.c
index d558445dec6..78af0a726c2 100644
--- a/source/blender/src/editarmature_sketch.c
+++ b/source/blender/src/editarmature_sketch.c
@@ -54,6 +54,7 @@
#include "BIF_editarmature.h"
#include "BIF_sketch.h"
#include "BIF_retarget.h"
+#include "BIF_generate.h"
#include "blendef.h"
#include "mydevice.h"
@@ -117,6 +118,26 @@ typedef struct SK_Sketch
SK_Point next_point;
} SK_Sketch;
+typedef struct SK_StrokeIterator {
+ HeadFct head;
+ TailFct tail;
+ PeekFct peek;
+ NextFct next;
+ NextNFct nextN;
+ PreviousFct previous;
+ StoppedFct stopped;
+
+ float *p, *no;
+
+ int length;
+ int index;
+ /*********************************/
+ SK_Stroke *stroke;
+ int start;
+ int end;
+ int stride;
+} SK_StrokeIterator;
+
SK_Sketch *GLOBAL_sketch = NULL;
SK_Point boneSnap;
@@ -124,7 +145,7 @@ SK_Point boneSnap;
/******************** PROTOTYPES ******************************/
-typedef int(NextSubdivisionFunc)(SK_Stroke*, int, int, float[3], float[3]);
+void initStrokeIterator(BArcIterator *iter, SK_Stroke *stk, int start, int end);
void sk_deleteSelectedStrokes(SK_Sketch *sketch);
@@ -133,10 +154,6 @@ void sk_freeSketch(SK_Sketch *sketch);
SK_Point *sk_lastStrokePoint(SK_Stroke *stk);
-int nextFixedSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3]);
-int nextLengthSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3]);
-int nextCorrelationSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3]);
-
/******************** TEMPLATES UTILS *************************/
char *TEMPLATES_MENU = NULL;
@@ -990,18 +1007,20 @@ void sk_drawStroke(SK_Stroke *stk, int id, float color[3])
// glEnd();
}
-void drawSubdividedStrokeBy(SK_Stroke *stk, int start, int end, NextSubdivisionFunc next_subdividion)
+void drawSubdividedStrokeBy(BArcIterator *iter, NextSubdivisionFunc next_subdividion)
{
float head[3], tail[3];
- int bone_start = start;
+ int bone_start = 0;
+ int end = iter->length;
int index;
- VECCOPY(head, stk->points[start].p);
+ iter->head(iter);
+ VECCOPY(head, iter->p);
glColor3f(0, 1, 1);
glBegin(GL_POINTS);
- index = next_subdividion(stk, bone_start, end, head, tail);
+ index = next_subdividion(iter, bone_start, end, head, tail);
while (index != -1)
{
glVertex3fv(tail);
@@ -1009,7 +1028,7 @@ void drawSubdividedStrokeBy(SK_Stroke *stk, int start, int end, NextSubdivisionF
VECCOPY(head, tail);
bone_start = index; // start next bone from current index
- index = next_subdividion(stk, bone_start, end, head, tail);
+ index = next_subdividion(iter, bone_start, end, head, tail);
}
glEnd();
@@ -1040,17 +1059,22 @@ void sk_drawStrokeSubdivision(SK_Stroke *stk)
{
if (i - head_index > 1)
{
+ SK_StrokeIterator sk_iter;
+ BArcIterator *iter = (BArcIterator*)&sk_iter;
+
+ initStrokeIterator(iter, stk, head_index, i);
+
if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_CORRELATION)
{
- drawSubdividedStrokeBy(stk, head_index, i, nextCorrelationSubdivision);
+ drawSubdividedStrokeBy(iter, nextCorrelationSubdivision);
}
else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
{
- drawSubdividedStrokeBy(stk, head_index, i, nextLengthSubdivision);
+ drawSubdividedStrokeBy(iter, nextLengthSubdivision);
}
else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
{
- drawSubdividedStrokeBy(stk, head_index, i, nextFixedSubdivision);
+ drawSubdividedStrokeBy(iter, nextFixedSubdivision);
}
}
@@ -1354,13 +1378,29 @@ int sk_getStrokeEmbedPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_D
float vec[3];
float new_dist;
- p1->flag = 0;
-
- for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next)
+ p1->flag = 1;
+
+ /* if peeling objects, take the first and last from each object */
+ if (G.scene->snap_flag & SCE_SNAP_PEEL_OBJECT)
{
- /* nothing to do here */
+ SK_DepthPeel *peel;
+ for (peel = p1->next; peel; peel = peel->next)
+ {
+ if (peel->ob == p1->ob)
+ {
+ peel->flag = 1;
+ p2 = peel;
+ }
+ }
+ }
+ /* otherwise, pair first with second and so on */
+ else
+ {
+ for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next)
+ {
+ /* nothing to do here */
+ }
}
-
if (p2)
{
@@ -1528,250 +1568,175 @@ void sk_initDrawData(SK_DrawData *dd)
}
/********************************************/
-/* bone is assumed to be in GLOBAL space */
-void setBoneRollFromPoint(EditBone *bone, SK_Point *pt, float invmat[][4], float tmat[][3])
-{
- float tangent[3], cotangent[3], normal[3];
-
- VecSubf(tangent, bone->tail, bone->head);
- Crossf(cotangent, tangent, pt->no);
- Crossf(normal, cotangent, tangent);
-
- Mat3MulVecfl(tmat, normal);
- Normalize(normal);
-
- bone->roll = rollBoneToVector(bone, normal);
+static void* headPoint(void *arg);
+static void* tailPoint(void *arg);
+static void* nextPoint(void *arg);
+static void* nextNPoint(void *arg, int n);
+static void* peekPoint(void *arg, int n);
+static void* previousPoint(void *arg);
+static int iteratorStopped(void *arg);
+static void initIteratorFct(SK_StrokeIterator *iter)
+{
+ iter->head = headPoint;
+ iter->tail = tailPoint;
+ iter->peek = peekPoint;
+ iter->next = nextPoint;
+ iter->nextN = nextNPoint;
+ iter->previous = previousPoint;
+ iter->stopped = iteratorStopped;
}
-float calcStrokeCorrelation(SK_Stroke *stk, int start, int end, float v0[3], float n[3])
+static SK_Point* setIteratorValues(SK_StrokeIterator *iter, int index)
{
- int len = 2 + abs(end - start);
+ SK_Point *pt = NULL;
- if (len > 2)
+ if (index >= 0 && index < iter->length)
{
- float avg_t = 0.0f;
- float s_t = 0.0f;
- float s_xyz = 0.0f;
- int i;
-
- /* First pass, calculate average */
- for (i = start; i <= end; i++)
- {
- float v[3];
-
- VecSubf(v, stk->points[i].p, v0);
- avg_t += Inpf(v, n);
- }
-
- avg_t /= Inpf(n, n);
- avg_t += 1.0f; /* adding start (0) and end (1) values */
- avg_t /= len;
-
- /* Second pass, calculate s_xyz and s_t */
- for (i = start; i <= end; i++)
- {
- float v[3], d[3];
- float dt;
-
- VecSubf(v, stk->points[i].p, v0);
- Projf(d, v, n);
- VecSubf(v, v, d);
-
- dt = VecLength(d) - avg_t;
-
- s_t += dt * dt;
- s_xyz += Inpf(v, v);
- }
-
- /* adding start(0) and end(1) values to s_t */
- s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
-
- return 1.0f - s_xyz / s_t;
+ pt = &(iter->stroke->points[iter->start + (iter->stride * index)]);
+ iter->p = pt->p;
+ iter->no = pt->no;
}
else
{
- return 1.0f;
+ iter->p = NULL;
+ iter->no = NULL;
}
+
+ return pt;
}
-int nextFixedSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3])
+void initStrokeIterator(BArcIterator *arg, SK_Stroke *stk, int start, int end)
{
- static float stroke_length = 0;
- static float current_length;
- static char n;
- float length_threshold;
- int i;
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+
+ initIteratorFct(iter);
+ iter->stroke = stk;
- if (stroke_length == 0)
+ if (start < end)
{
- current_length = 0;
- for (i = start + 1; i <= end; i++)
- {
- stroke_length += VecLenf(stk->points[i].p, stk->points[i - 1].p);
- }
-
- n = 0;
- current_length = 0;
+ iter->start = start + 1;
+ iter->end = end - 1;
+ iter->stride = 1;
}
-
- n++;
-
- length_threshold = n * stroke_length / G.scene->toolsettings->skgen_subdivision_number;
-
- /* < and not <= because we don't care about end, it is P_EXACT anyway */
- for (i = start + 1; i < end; i++)
+ else
{
- current_length += VecLenf(stk->points[i].p, stk->points[i - 1].p);
-
- if (current_length >= length_threshold)
- {
- VECCOPY(p, stk->points[i].p);
- return i;
- }
+ iter->start = start - 1;
+ iter->end = end + 1;
+ iter->stride = -1;
}
- stroke_length = 0;
+ iter->length = iter->stride * (iter->end - iter->start + 1);
- return -1;
+ iter->index = -1;
}
-int nextCorrelationSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3])
+
+
+static void* headPoint(void *arg)
{
- float correlation_threshold = G.scene->toolsettings->skgen_correlation_limit;
- float n[3];
- int i;
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
- for (i = start + 2; i <= end; i++)
- {
- /* Calculate normal */
- VecSubf(n, stk->points[i].p, head);
-
- if (calcStrokeCorrelation(stk, start, i, stk->points[start].p, n) < correlation_threshold)
- {
- VECCOPY(p, stk->points[i - 1].p);
- return i - 1;
- }
- }
+ result = &(iter->stroke->points[iter->start - iter->stride]);
+ iter->p = result->p;
+ iter->no = result->no;
- return -1;
+ return result;
}
-int nextLengthSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3])
+static void* tailPoint(void *arg)
{
- float lengthLimit = G.scene->toolsettings->skgen_length_limit;
- int same = 1;
- int i;
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
- i = start + 1;
- while (i <= end)
- {
- float *vec0 = stk->points[i - 1].p;
- float *vec1 = stk->points[i].p;
-
- /* If lengthLimit hits the current segment */
- if (VecLenf(vec1, head) > lengthLimit)
- {
- if (same == 0)
- {
- float dv[3], off[3];
- float a, b, c, f;
-
- /* Solve quadratic distance equation */
- VecSubf(dv, vec1, vec0);
- a = Inpf(dv, dv);
-
- VecSubf(off, vec0, head);
- b = 2 * Inpf(dv, off);
-
- c = Inpf(off, off) - (lengthLimit * lengthLimit);
-
- f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
-
- //printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
-
- if (isnan(f) == 0 && f < 1.0f)
- {
- VECCOPY(p, dv);
- VecMulf(p, f);
- VecAddf(p, p, vec0);
- }
- else
- {
- VECCOPY(p, vec1);
- }
- }
- else
- {
- float dv[3];
-
- VecSubf(dv, vec1, vec0);
- Normalize(dv);
-
- VECCOPY(p, dv);
- VecMulf(p, lengthLimit);
- VecAddf(p, p, head);
- }
-
- return i - 1; /* restart at lower bound */
- }
- else
- {
- i++;
- same = 0; // Reset same
- }
- }
+ result = &(iter->stroke->points[iter->end + iter->stride]);
+ iter->p = result->p;
+ iter->no = result->no;
- return -1;
+ return result;
}
-EditBone * subdivideStrokeBy(SK_Stroke *stk, int start, int end, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion)
+static void* nextPoint(void *arg)
{
- bArmature *arm = G.obedit->data;
- EditBone *lastBone = NULL;
- EditBone *child = NULL;
- EditBone *parent = NULL;
- int bone_start = start;
- int index;
-
- parent = addEditBone("Bone", &G.edbo, arm);
- VECCOPY(parent->head, stk->points[start].p);
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
- index = next_subdividion(stk, bone_start, end, parent->head, parent->tail);
- while (index != -1)
+ if (iter->index < iter->length)
{
- setBoneRollFromPoint(parent, &stk->points[index], invmat, tmat);
+ iter->index++;
+ result = setIteratorValues(iter, iter->index);
+ }
- child = addEditBone("Bone", &G.edbo, arm);
- VECCOPY(child->head, parent->tail);
- child->parent = parent;
- child->flag |= BONE_CONNECTED;
-
- /* going to next bone, fix parent */
- Mat4MulVecfl(invmat, parent->tail);
- Mat4MulVecfl(invmat, parent->head);
+ return result;
+}
- parent = child; // new child is next parent
- bone_start = index; // start next bone from current index
+static void* nextNPoint(void *arg, int n)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
+
+ iter->index += n;
- index = next_subdividion(stk, bone_start, end, parent->head, parent->tail);
+ /* check if passed end */
+ if (iter->index < iter->length)
+ {
+ result = setIteratorValues(iter, iter->index);
+ }
+ else
+ {
+ /* stop iterator if passed end */
+ iter->index = iter->length;
}
- VECCOPY(parent->tail, stk->points[end].p);
+ return result;
+}
- setBoneRollFromPoint(parent, &stk->points[end], invmat, tmat);
+static void* peekPoint(void *arg, int n)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
+ int index = iter->index + n;
- /* fix last bone */
- Mat4MulVecfl(invmat, parent->tail);
- Mat4MulVecfl(invmat, parent->head);
- lastBone = parent;
+ /* check if passed end */
+ if (index < iter->length)
+ {
+ result = setIteratorValues(iter, index);
+ }
+
+ return result;
+}
+
+static void* previousPoint(void *arg)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
- return lastBone;
+ if (iter->index > 0)
+ {
+ iter->index--;
+ result = setIteratorValues(iter, iter->index);
+ }
+
+ return result;
}
+static int iteratorStopped(void *arg)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+
+ if (iter->index == iter->length)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
void sk_convertStroke(SK_Stroke *stk)
{
- bArmature *arm= G.obedit->data;
+ bArmature *arm = G.obedit->data;
SK_Point *head;
EditBone *parent = NULL;
float invmat[4][4]; /* move in caller function */
@@ -1804,17 +1769,22 @@ void sk_convertStroke(SK_Stroke *stk)
if (i - head_index > 1)
{
+ SK_StrokeIterator sk_iter;
+ BArcIterator *iter = (BArcIterator*)&sk_iter;
+
+ initStrokeIterator(iter, stk, head_index, i);
+
if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_CORRELATION)
{
- bone = subdivideStrokeBy(stk, head_index, i, invmat, tmat, nextCorrelationSubdivision);
+ bone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextCorrelationSubdivision);
}
else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
{
- bone = subdivideStrokeBy(stk, head_index, i, invmat, tmat, nextLengthSubdivision);
+ bone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextLengthSubdivision);
}
else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
{
- bone = subdivideStrokeBy(stk, head_index, i, invmat, tmat, nextFixedSubdivision);
+ bone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextFixedSubdivision);
}
}
@@ -1824,10 +1794,10 @@ void sk_convertStroke(SK_Stroke *stk)
VECCOPY(bone->head, head->p);
VECCOPY(bone->tail, pt->p);
- setBoneRollFromPoint(bone, pt, invmat, tmat);
-
+
Mat4MulVecfl(invmat, bone->head);
Mat4MulVecfl(invmat, bone->tail);
+ setBoneRollFromNormal(bone, pt->no, invmat, tmat);
}
new_parent = bone;
@@ -1995,6 +1965,9 @@ int sk_getIntersections(ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
{
+ SK_StrokeIterator sk_iter;
+ BArcIterator *iter = (BArcIterator*)&sk_iter;
+
float CORRELATION_THRESHOLD = 0.99f;
float *vec;
int i, j;
@@ -2002,6 +1975,8 @@ int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
sk_appendStrokePoint(segments, &gesture->points[0]);
vec = segments->points[segments->nb_points - 1].p;
+ initStrokeIterator(iter, gesture, 0, gesture->nb_points - 1);
+
for (i = 1, j = 0; i < gesture->nb_points; i++)
{
float n[3];
@@ -2009,7 +1984,7 @@ int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
/* Calculate normal */
VecSubf(n, gesture->points[i].p, vec);
- if (calcStrokeCorrelation(gesture, j, i, vec, n) < CORRELATION_THRESHOLD)
+ if (calcArcCorrelation(iter, j, i, vec, n) < CORRELATION_THRESHOLD)
{
j = i - 1;
sk_appendStrokePoint(segments, &gesture->points[j]);
diff --git a/source/blender/src/reeb.c b/source/blender/src/reeb.c
index bb53269bf12..553a758c9d5 100644
--- a/source/blender/src/reeb.c
+++ b/source/blender/src/reeb.c
@@ -850,7 +850,8 @@ void fillArcEmptyBuckets(ReebArc *arc)
static void ExtendArcBuckets(ReebArc *arc)
{
- ReebArcIterator iter;
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
EmbedBucket *last_bucket, *first_bucket;
float *previous = NULL;
float average_length = 0, length;
@@ -861,16 +862,16 @@ static void ExtendArcBuckets(ReebArc *arc)
return; /* failsafe, shouldn't happen */
}
- initArcIterator(&iter, arc, arc->head);
- iter.next(&iter);
- previous = iter.p;
+ initArcIterator(iter, arc, arc->head);
+ IT_next(iter);
+ previous = iter->p;
- for ( iter.next(&iter);
- iter.stopped(&iter) == 0;
- previous = iter.p, iter.next(&iter)
+ for ( IT_next(iter);
+ IT_stopped(iter) == 0;
+ previous = iter->p, IT_next(iter)
)
{
- average_length += VecLenf(previous, iter.p);
+ average_length += VecLenf(previous, iter->p);
}
average_length /= (arc->bcount - 1);
@@ -927,19 +928,20 @@ void extendGraphBuckets(ReebGraph *rg)
void calculateArcLength(ReebArc *arc)
{
- ReebArcIterator iter;
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
float *vec0, *vec1;
arc->length = 0;
- initArcIterator(&iter, arc, arc->head);
+ initArcIterator(iter, arc, arc->head);
vec0 = arc->head->p;
vec1 = arc->head->p; /* in case there's no embedding */
- while (iter.next(&iter))
+ while (IT_next(iter))
{
- vec1 = iter.p;
+ vec1 = iter->p;
arc->length += VecLenf(vec0, vec1);
@@ -996,28 +998,30 @@ void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count)
* */
if (arc1->bcount > 0 && arc2->bcount > 0)
{
- ReebArcIterator iter1, iter2;
+ ReebArcIterator arc_iter1, arc_iter2;
+ BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
+ BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
- initArcIterator(&iter1, arc1, (ReebNode*)root_node);
- initArcIterator(&iter2, arc2, (ReebNode*)root_node);
+ initArcIterator(iter1, arc1, (ReebNode*)root_node);
+ initArcIterator(iter2, arc2, (ReebNode*)root_node);
- bucket1 = iter1.next(&iter1);
- bucket2 = iter2.next(&iter2);
+ bucket1 = IT_next(iter1);
+ bucket2 = IT_next(iter2);
/* Make sure they both start at the same value */
while(bucket1 && bucket2 && bucket1->val < bucket2->val)
{
- bucket1 = iter1.next(&iter1);
+ bucket1 = IT_next(iter1);
}
while(bucket1 && bucket2 && bucket2->val < bucket1->val)
{
- bucket2 = iter2.next(&iter2);
+ bucket2 = IT_next(iter2);
}
- for ( ;bucket1 && bucket2; bucket1 = iter1.next(&iter1), bucket2 = iter2.next(&iter2))
+ for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
{
bucket2->nv += bucket1->nv; /* add counts */
@@ -1056,28 +1060,30 @@ void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count)
* */
if (arc1->bcount > 0 && arc2->bcount > 0)
{
- ReebArcIterator iter1, iter2;
+ ReebArcIterator arc_iter1, arc_iter2;
+ BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
+ BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
- initArcIterator(&iter1, arc1, node);
- initArcIterator(&iter2, arc2, node);
+ initArcIterator(iter1, arc1, node);
+ initArcIterator(iter2, arc2, node);
- bucket1 = iter1.next(&iter1);
- bucket2 = iter2.next(&iter2);
+ bucket1 = IT_next(iter1);
+ bucket2 = IT_next(iter2);
/* Make sure they both start at the same value */
while(bucket1 && bucket1->val < bucket2->val)
{
- bucket1 = iter1.next(&iter1);
+ bucket1 = IT_next(iter1);
}
while(bucket2 && bucket2->val < bucket1->val)
{
- bucket2 = iter2.next(&iter2);
+ bucket2 = IT_next(iter2);
}
- for ( ;bucket1 && bucket2; bucket1 = iter1.next(&iter1), bucket2 = iter1.next(&iter2))
+ for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
{
/* copy and mirror back to bucket2 */
bucket2->nv = bucket1->nv;
@@ -1115,28 +1121,30 @@ void REEB_AxialSymmetry(BNode* root_node, BNode* node1, BNode* node2, struct BAr
* */
if (arc1->bcount > 0 && arc2->bcount > 0)
{
- ReebArcIterator iter1, iter2;
+ ReebArcIterator arc_iter1, arc_iter2;
+ BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
+ BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
- initArcIterator(&iter1, arc1, (ReebNode*)root_node);
- initArcIterator(&iter2, arc2, (ReebNode*)root_node);
+ initArcIterator(iter1, arc1, (ReebNode*)root_node);
+ initArcIterator(iter2, arc2, (ReebNode*)root_node);
- bucket1 = iter1.next(&iter1);
- bucket2 = iter2.next(&iter2);
+ bucket1 = IT_next(iter1);
+ bucket2 = IT_next(iter2);
/* Make sure they both start at the same value */
while(bucket1 && bucket1->val < bucket2->val)
{
- bucket1 = iter1.next(&iter1);
+ bucket1 = IT_next(iter1);
}
while(bucket2 && bucket2->val < bucket1->val)
{
- bucket2 = iter1.next(&iter2);
+ bucket2 = IT_next(iter2);
}
- for ( ;bucket1 && bucket2; bucket1 = iter2.next(&iter1), bucket2 = iter2.next(&iter2))
+ for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
{
bucket1->nv += bucket2->nv; /* add counts */
@@ -1763,15 +1771,16 @@ int filterSmartReebGraph(ReebGraph *rg, float threshold)
EditFace *efa = BLI_ghashIterator_getValue(&ghi);
#if 0
- ReebArcIterator iter;
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
EmbedBucket *bucket = NULL;
EmbedBucket *previous = NULL;
float min_distance = -1;
float angle = 0;
- initArcIterator(&iter, arc, arc->head);
+ initArcIterator(iter, arc, arc->head);
- bucket = nextBucket(&iter);
+ bucket = nextBucket(iter);
while (bucket != NULL)
{
@@ -1806,7 +1815,7 @@ int filterSmartReebGraph(ReebGraph *rg, float threshold)
}
previous = bucket;
- bucket = nextBucket(&iter);
+ bucket = nextBucket(iter);
}
avg_angle += saacos(fabs(angle));
@@ -3296,14 +3305,18 @@ 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);
+static void* headNode(void *arg);
+static void* tailNode(void *arg);
+static void* nextBucket(void *arg);
+static void* nextNBucket(void *arg, int n);
+static void* peekBucket(void *arg, int n);
+static void* previousBucket(void *arg);
+static int iteratorStopped(void *arg);
-void initIteratorFct(ReebArcIterator *iter)
+static void initIteratorFct(ReebArcIterator *iter)
{
+ iter->head = headNode;
+ iter->tail = tailNode;
iter->peek = peekBucket;
iter->next = nextBucket;
iter->nextN = nextNBucket;
@@ -3311,7 +3324,7 @@ void initIteratorFct(ReebArcIterator *iter)
iter->stopped = iteratorStopped;
}
-void setIteratorValues(ReebArcIterator *iter, EmbedBucket *bucket)
+static void setIteratorValues(ReebArcIterator *iter, EmbedBucket *bucket)
{
if (bucket)
{
@@ -3325,8 +3338,10 @@ void setIteratorValues(ReebArcIterator *iter, EmbedBucket *bucket)
}
}
-void initArcIterator(ReebArcIterator *iter, ReebArc *arc, ReebNode *head)
+void initArcIterator(BArcIterator *arg, ReebArc *arc, ReebNode *head)
{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+
initIteratorFct(iter);
iter->arc = arc;
@@ -3345,11 +3360,13 @@ void initArcIterator(ReebArcIterator *iter, ReebArc *arc, ReebNode *head)
iter->length = arc->bcount;
- iter->index = iter->start - iter->stride;
+ iter->index = -1;
}
-void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start)
+void initArcIteratorStart(BArcIterator *arg, struct ReebArc *arc, struct ReebNode *head, int start)
{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+
initIteratorFct(iter);
iter->arc = arc;
@@ -3366,7 +3383,7 @@ void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, str
iter->stride = -1;
}
- iter->index = iter->start - iter->stride;
+ iter->index = -1;
iter->length = arc->bcount - start;
@@ -3376,8 +3393,10 @@ void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, str
}
}
-void initArcIterator2(ReebArcIterator *iter, ReebArc *arc, int start, int end)
+void initArcIterator2(BArcIterator *arg, ReebArc *arc, int start, int end)
{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+
initIteratorFct(iter);
iter->arc = arc;
@@ -3393,86 +3412,124 @@ void initArcIterator2(ReebArcIterator *iter, ReebArc *arc, int start, int end)
iter->stride = -1;
}
- iter->index = iter->start - iter->stride;
+ iter->index = -1;
iter->length = abs(iter->end - iter->start) + 1;
}
-void* nextBucket(void *arg)
+static void* headNode(void *arg)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+ ReebNode *node;
+
+ if (iter->start < iter->end)
+ {
+ node = iter->arc->head;
+ }
+ else
+ {
+ node = iter->arc->tail;
+ }
+
+ iter->p = node->p;
+ iter->no = node->no;
+
+ return node;
+}
+
+static void* tailNode(void *arg)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+ ReebNode *node;
+
+ if (iter->start < iter->end)
+ {
+ node = iter->arc->tail;
+ }
+ else
+ {
+ node = iter->arc->head;
+ }
+
+ iter->p = node->p;
+ iter->no = node->no;
+
+ return node;
+}
+
+static void* nextBucket(void *arg)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
EmbedBucket *result = NULL;
- if (iter->index != iter->end)
+ if (iter->index < iter->length)
{
- iter->index += iter->stride;
- result = &(iter->arc->buckets[iter->index]);
+ iter->index++;
+ result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
}
setIteratorValues(iter, result);
return result;
}
-void* nextNBucket(void *arg, int n)
+static void* nextNBucket(void *arg, int n)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
EmbedBucket *result = NULL;
- iter->index += n * iter->stride;
+ iter->index += n;
/* check if passed end */
- if ((iter->stride == 1 && iter->index <= iter->end) ||
- (iter->stride == -1 && iter->index >= iter->end))
+ if (iter->index < iter->length)
{
- result = &(iter->arc->buckets[iter->index]);
+ result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
}
else
{
/* stop iterator if passed end */
- iter->index = iter->end;
+ iter->index = iter->length;
}
setIteratorValues(iter, result);
return result;
}
-void* peekBucket(void *arg, int n)
+static void* peekBucket(void *arg, int n)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
EmbedBucket *result = NULL;
- int index = iter->index + n * iter->stride;
+ int index = iter->index + n;
/* check if passed end */
- if ((iter->stride == 1 && index <= iter->end && index >= iter->start) ||
- (iter->stride == -1 && index >= iter->end && index <= iter->start))
+ if (index < iter->length)
{
- result = &(iter->arc->buckets[index]);
+ result = &(iter->arc->buckets[iter->start + (iter->stride * index)]);
}
setIteratorValues(iter, result);
return result;
}
-void* previousBucket(void *arg)
+static void* previousBucket(void *arg)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
EmbedBucket *result = NULL;
- if (iter->index != iter->start)
+ if (iter->index > 0)
{
- iter->index -= iter->stride;
- result = &(iter->arc->buckets[iter->index]);
+ iter->index--;
+ result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
}
setIteratorValues(iter, result);
return result;
}
-int iteratorStopped(void *arg)
+static int iteratorStopped(void *arg)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
- if (iter->index == iter->end)
+ if (iter->index == iter->length)
{
return 1;
}
@@ -3711,7 +3768,8 @@ void REEB_draw()
glDisable(GL_DEPTH_TEST);
for (arc = rg->arcs.first; arc; arc = arc->next, i++)
{
- ReebArcIterator iter;
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
float vec[3];
char text[128];
char *s = text;
@@ -3723,10 +3781,10 @@ void REEB_draw()
if (arc->bcount)
{
- initArcIterator(&iter, arc, arc->head);
- for (iter.next(&iter); iter.stopped(&iter) == 0; iter.next(&iter))
+ initArcIterator(iter, arc, arc->head);
+ for (IT_next(iter); IT_stopped(iter) == 0; IT_next(iter))
{
- glVertex3fv(iter.p);
+ glVertex3fv(iter->p);
}
}
@@ -3756,10 +3814,10 @@ void REEB_draw()
if (arc->bcount)
{
- initArcIterator(&iter, arc, arc->head);
- for (iter.next(&iter); iter.stopped(&iter) == 0; iter.next(&iter))
+ initArcIterator(iter, arc, arc->head);
+ for (iter->next(iter); IT_stopped(iter) == 0; iter->next(iter))
{
- glVertex3fv(iter.p);
+ glVertex3fv(iter->p);
}
}
@@ -3777,10 +3835,10 @@ void REEB_draw()
glColor3f(0.5f, 0.5f, 1);
if (arc->bcount)
{
- initArcIterator(&iter, arc, arc->head);
- for (iter.next(&iter); iter.stopped(&iter) == 0; iter.next(&iter))
+ initArcIterator(iter, arc, arc->head);
+ for (iter->next(iter); IT_stopped(iter) == 0; iter->next(iter))
{
- glVertex3fv(iter.p);
+ glVertex3fv(iter->p);
}
}
glEnd();