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:
-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();