Remove Armature Sketching & Retarget
authorCampbell Barton <ideasman42@gmail.com>
Fri, 20 Apr 2018 08:18:25 +0000 (10:18 +0200)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 20 Apr 2018 08:34:48 +0000 (10:34 +0200)
While the feature is interesting, it's not much from what we can tell.

Retargeting is an important feature but needs
to fit in better with typical animation work-flows.

See: T52809

33 files changed:
release/scripts/presets/keyconfig/3dsmax.py
release/scripts/presets/keyconfig/maya.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/BKE_sketch.h [deleted file]
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/library_query.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/sketch.c [deleted file]
source/blender/blenlib/BLI_graph.h [deleted file]
source/blender/blenlib/CMakeLists.txt
source/blender/blenlib/intern/graph.c [deleted file]
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/versioning_legacy.c
source/blender/editors/armature/BIF_generate.h [deleted file]
source/blender/editors/armature/BIF_retarget.h [deleted file]
source/blender/editors/armature/CMakeLists.txt
source/blender/editors/armature/armature_intern.h
source/blender/editors/armature/armature_ops.c
source/blender/editors/armature/armature_select.c
source/blender/editors/armature/armature_skinning.c
source/blender/editors/armature/armature_utils.c
source/blender/editors/armature/editarmature_generate.c [deleted file]
source/blender/editors/armature/editarmature_retarget.c [deleted file]
source/blender/editors/armature/editarmature_sketch.c [deleted file]
source/blender/editors/armature/reeb.c [deleted file]
source/blender/editors/armature/reeb.h [deleted file]
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_armature.h
source/blender/makesdna/DNA_armature_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c
source/blender/windowmanager/intern/wm_init_exit.c

index c77ad6c..d65ecaa 100644 (file)
@@ -2278,17 +2278,6 @@ kmi.properties.value_2 = 'CONNECTED'
 # Map Armature
 km = kc.keymaps.new('Armature', space_type='EMPTY', region_type='WINDOW', modal=False)
 
-kmi = km.keymap_items.new('sketch.delete', 'X', 'PRESS')
-kmi = km.keymap_items.new('sketch.delete', 'DEL', 'PRESS')
-kmi = km.keymap_items.new('sketch.finish_stroke', 'RIGHTMOUSE', 'PRESS')
-kmi = km.keymap_items.new('sketch.cancel_stroke', 'ESC', 'PRESS')
-kmi = km.keymap_items.new('sketch.gesture', 'LEFTMOUSE', 'PRESS', shift=True)
-kmi = km.keymap_items.new('sketch.draw_stroke', 'LEFTMOUSE', 'PRESS')
-kmi = km.keymap_items.new('sketch.draw_stroke', 'LEFTMOUSE', 'PRESS', ctrl=True)
-kmi.properties.snap = True
-kmi = km.keymap_items.new('sketch.draw_preview', 'MOUSEMOVE', 'ANY')
-kmi = km.keymap_items.new('sketch.draw_preview', 'MOUSEMOVE', 'ANY', ctrl=True)
-kmi.properties.snap = True
 kmi = km.keymap_items.new('armature.hide', 'H', 'PRESS')
 kmi.properties.unselected = False
 kmi = km.keymap_items.new('armature.hide', 'H', 'PRESS', shift=True)
index 7c88444..09371e7 100644 (file)
@@ -770,17 +770,6 @@ kmi.properties.value_2 = 'CONNECTED'
 # Map Armature
 km = kc.keymaps.new('Armature', space_type='EMPTY', region_type='WINDOW', modal=False)
 
-kmi = km.keymap_items.new('sketch.delete', 'BACK_SPACE', 'PRESS')
-kmi = km.keymap_items.new('sketch.delete', 'DEL', 'PRESS')
-kmi = km.keymap_items.new('sketch.finish_stroke', 'RIGHTMOUSE', 'PRESS')
-kmi = km.keymap_items.new('sketch.cancel_stroke', 'ESC', 'PRESS')
-kmi = km.keymap_items.new('sketch.gesture', 'LEFTMOUSE', 'PRESS', shift=True)
-kmi = km.keymap_items.new('sketch.draw_stroke', 'LEFTMOUSE', 'PRESS')
-kmi = km.keymap_items.new('sketch.draw_stroke', 'LEFTMOUSE', 'PRESS', ctrl=True)
-kmi.properties.snap = True
-kmi = km.keymap_items.new('sketch.draw_preview', 'MOUSEMOVE', 'ANY')
-kmi = km.keymap_items.new('sketch.draw_preview', 'MOUSEMOVE', 'ANY', ctrl=True)
-kmi.properties.snap = True
 kmi = km.keymap_items.new('armature.hide', 'H', 'PRESS', ctrl=True)
 kmi.properties.unselected = False
 kmi = km.keymap_items.new('armature.hide', 'H', 'PRESS', alt=True)
index d211d8b..ce43904 100644 (file)
@@ -3716,63 +3716,6 @@ class VIEW3D_PT_transform_orientations(Panel):
             row.operator("transform.delete_orientation", text="", icon='X')
 
 
-class VIEW3D_PT_etch_a_ton(Panel):
-    bl_space_type = 'VIEW_3D'
-    bl_region_type = 'UI'
-    bl_label = "Skeleton Sketching"
-    bl_options = {'DEFAULT_CLOSED'}
-
-    @classmethod
-    def poll(cls, context):
-        scene = context.space_data
-        ob = context.active_object
-        return scene and ob and ob.type == 'ARMATURE' and ob.mode == 'EDIT'
-
-    def draw_header(self, context):
-        layout = self.layout
-        toolsettings = context.scene.tool_settings
-
-        layout.prop(toolsettings, "use_bone_sketching", text="")
-
-    def draw(self, context):
-        layout = self.layout
-
-        toolsettings = context.scene.tool_settings
-
-        col = layout.column()
-
-        col.prop(toolsettings, "use_etch_quick")
-        col.prop(toolsettings, "use_etch_overdraw")
-
-        col.separator()
-
-        col.prop(toolsettings, "etch_convert_mode")
-
-        if toolsettings.etch_convert_mode == 'LENGTH':
-            col.prop(toolsettings, "etch_length_limit")
-        elif toolsettings.etch_convert_mode == 'ADAPTIVE':
-            col.prop(toolsettings, "etch_adaptive_limit")
-        elif toolsettings.etch_convert_mode == 'FIXED':
-            col.prop(toolsettings, "etch_subdivision_number")
-        elif toolsettings.etch_convert_mode == 'RETARGET':
-            col.prop(toolsettings, "etch_template")
-            col.prop(toolsettings, "etch_roll_mode")
-
-            col.separator()
-
-            colsub = col.column(align=True)
-            colsub.prop(toolsettings, "use_etch_autoname")
-            sub = colsub.column(align=True)
-            sub.enabled = not toolsettings.use_etch_autoname
-            sub.prop(toolsettings, "etch_number")
-            sub.prop(toolsettings, "etch_side")
-
-        col.separator()
-
-        col.operator("sketch.convert", text="Convert to Bones")
-        col.operator("sketch.delete", text="Delete Strokes")
-
-
 class VIEW3D_PT_context_properties(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
@@ -3948,7 +3891,6 @@ classes = (
     VIEW3D_PT_view3d_meshstatvis,
     VIEW3D_PT_view3d_curvedisplay,
     VIEW3D_PT_transform_orientations,
-    VIEW3D_PT_etch_a_ton,
     VIEW3D_PT_context_properties,
 )
 
diff --git a/source/blender/blenkernel/BKE_sketch.h b/source/blender/blenkernel/BKE_sketch.h
deleted file mode 100644 (file)
index 9b9c125..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef __BKE_SKETCH_H__
-#define __BKE_SKETCH_H__
-
-/** \file BKE_sketch.h
- *  \ingroup bke
- */
-
-typedef enum SK_PType {
-       PT_CONTINUOUS,
-       PT_EXACT,
-} SK_PType;
-
-typedef enum SK_PMode {
-       PT_SNAP,
-       PT_PROJECT,
-} SK_PMode;
-
-typedef struct SK_Point {
-       float p[3];
-       short p2d[2];
-       float no[3];
-       float size;
-       SK_PType type;
-       SK_PMode mode;
-} SK_Point;
-
-typedef struct SK_Stroke {
-       struct SK_Stroke *next, *prev;
-
-       SK_Point *points;
-       int nb_points;
-       int buf_size;
-       int selected;
-} SK_Stroke;
-
-#define SK_OVERDRAW_LIMIT   5
-
-typedef struct SK_Overdraw {
-       SK_Stroke *target;
-       int start, end;
-       int count;
-} SK_Overdraw;
-
-#define SK_Stroke_BUFFER_INIT_SIZE 20
-
-typedef struct SK_DrawData {
-       int mval[2];
-       int previous_mval[2];
-       SK_PType type;
-} SK_DrawData;
-
-typedef struct SK_Intersection {
-       struct SK_Intersection *next, *prev;
-       SK_Stroke *stroke;
-       int        before;
-       int        after;
-       int        gesture_index;
-       float      p[3];
-       float      lambda;       /* used for sorting intersection points */
-} SK_Intersection;
-
-typedef struct SK_Sketch {
-       ListBase   strokes;
-       SK_Stroke *active_stroke;
-       SK_Stroke *gesture;
-       SK_Point   next_point;
-       SK_Overdraw over;
-} SK_Sketch;
-
-
-typedef struct SK_Gesture {
-       SK_Stroke   *stk;
-       SK_Stroke   *segments;
-
-       ListBase     intersections;
-       ListBase     self_intersections;
-
-       int          nb_self_intersections;
-       int          nb_intersections;
-       int          nb_segments;
-} SK_Gesture;
-
-
-/************************************************/
-
-void freeSketch(SK_Sketch *sketch);
-SK_Sketch *createSketch(void);
-
-void sk_removeStroke(SK_Sketch *sketch, SK_Stroke *stk);
-
-void sk_freeStroke(SK_Stroke *stk);
-SK_Stroke *sk_createStroke(void);
-
-SK_Point *sk_lastStrokePoint(SK_Stroke *stk);
-
-void sk_allocStrokeBuffer(SK_Stroke *stk);
-void sk_shrinkStrokeBuffer(SK_Stroke *stk);
-void sk_growStrokeBuffer(SK_Stroke *stk);
-void sk_growStrokeBufferN(SK_Stroke *stk, int n);
-
-void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n);
-void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n);
-void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt);
-void sk_insertStrokePoints(SK_Stroke *stk, SK_Point *pts, int len, int start, int end);
-
-void sk_trimStroke(SK_Stroke *stk, int start, int end);
-void sk_straightenStroke(SK_Stroke *stk, int start, int end, float p_start[3], float p_end[3]);
-void sk_polygonizeStroke(SK_Stroke *stk, int start, int end);
-void sk_flattenStroke(SK_Stroke *stk, int start, int end);
-void sk_reverseStroke(SK_Stroke *stk);
-
-void sk_filterLastContinuousStroke(SK_Stroke *stk);
-void sk_filterStroke(SK_Stroke *stk, int start, int end);
-
-void sk_initPoint(SK_Point *pt, SK_DrawData *dd, const float no[3]);
-void sk_copyPoint(SK_Point *dst, SK_Point *src);
-
-int sk_stroke_filtermval(SK_DrawData *dd);
-void sk_endContinuousStroke(SK_Stroke *stk);
-
-void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk);
-
-void sk_initDrawData(SK_DrawData *dd, const int mval[2]);
-
-void sk_deleteSelectedStrokes(SK_Sketch *sketch);
-void sk_selectAllSketch(SK_Sketch *sketch, int mode);
-
-#endif
index 4191580..d908316 100644 (file)
@@ -176,7 +176,6 @@ set(SRC
        intern/seqmodifier.c
        intern/sequencer.c
        intern/shrinkwrap.c
-       intern/sketch.c
        intern/smoke.c
        intern/softbody.c
        intern/sound.c
@@ -296,7 +295,6 @@ set(SRC
        BKE_screen.h
        BKE_sequencer.h
        BKE_shrinkwrap.h
-       BKE_sketch.h
        BKE_smoke.h
        BKE_softbody.h
        BKE_sound.h
index 6daaa10..d1b0269 100644 (file)
@@ -73,7 +73,6 @@
 #include "BKE_scene.h"
 
 #include "BIK_api.h"
-#include "BKE_sketch.h"
 
 /* **************** Generic Functions, data level *************** */
 
@@ -135,12 +134,6 @@ void BKE_armature_free(bArmature *arm)
                MEM_freeN(arm->edbo);
                arm->edbo = NULL;
        }
-
-       /* free sketch */
-       if (arm->sketch) {
-               freeSketch(arm->sketch);
-               arm->sketch = NULL;
-       }
 }
 
 void BKE_armature_make_local(Main *bmain, bArmature *arm, const bool lib_local)
@@ -204,7 +197,6 @@ void BKE_armature_copy_data(Main *UNUSED(bmain), bArmature *arm_dst, const bArma
 
        arm_dst->edbo = NULL;
        arm_dst->act_edbone = NULL;
-       arm_dst->sketch = NULL;
 }
 
 bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm)
index 9c015ce..ebf286c 100644 (file)
@@ -445,8 +445,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
                                }
 
                                if (toolsett) {
-                                       CALLBACK_INVOKE(toolsett->skgen_template, IDWALK_CB_NOP);
-
                                        CALLBACK_INVOKE(toolsett->particle.scene, IDWALK_CB_NOP);
                                        CALLBACK_INVOKE(toolsett->particle.object, IDWALK_CB_NOP);
                                        CALLBACK_INVOKE(toolsett->particle.shape_object, IDWALK_CB_NOP);
index 27ebbad..91ff3c1 100644 (file)
@@ -659,21 +659,6 @@ void BKE_scene_init(Scene *sce)
 
        sce->toolsettings->snap_node_mode = SCE_SNAP_MODE_GRID;
 
-       sce->toolsettings->skgen_resolution = 100;
-       sce->toolsettings->skgen_threshold_internal     = 0.01f;
-       sce->toolsettings->skgen_threshold_external     = 0.01f;
-       sce->toolsettings->skgen_angle_limit            = 45.0f;
-       sce->toolsettings->skgen_length_ratio           = 1.3f;
-       sce->toolsettings->skgen_length_limit           = 1.5f;
-       sce->toolsettings->skgen_correlation_limit      = 0.98f;
-       sce->toolsettings->skgen_symmetry_limit         = 0.1f;
-       sce->toolsettings->skgen_postpro = SKGEN_SMOOTH;
-       sce->toolsettings->skgen_postpro_passes = 1;
-       sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL | SKGEN_FILTER_EXTERNAL | SKGEN_FILTER_SMART | SKGEN_HARMONIC | SKGEN_SUB_CORRELATION | SKGEN_STICK_TO_EMBEDDING;
-       sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
-       sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
-       sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
-
        sce->toolsettings->curve_paint_settings.curve_type = CU_BEZIER;
        sce->toolsettings->curve_paint_settings.flag |= CURVE_PAINT_FLAG_CORNERS_DETECT;
        sce->toolsettings->curve_paint_settings.error_threshold = 8;
diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c
deleted file mode 100644 (file)
index 6f5c264..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/blenkernel/intern/sketch.c
- *  \ingroup bke
- */
-
-
-#include <string.h>
-#include <math.h>
-#include <float.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_utildefines.h"
-
-#include "BKE_sketch.h"
-
-
-#include "DNA_userdef_types.h"
-
-void freeSketch(SK_Sketch *sketch)
-{
-       SK_Stroke *stk, *next;
-
-       for (stk = sketch->strokes.first; stk; stk = next) {
-               next = stk->next;
-
-               sk_freeStroke(stk);
-       }
-
-       MEM_freeN(sketch);
-}
-
-SK_Sketch *createSketch(void)
-{
-       SK_Sketch *sketch;
-
-       sketch = MEM_callocN(sizeof(SK_Sketch), "SK_Sketch");
-
-       sketch->active_stroke = NULL;
-       sketch->gesture = NULL;
-
-       BLI_listbase_clear(&sketch->strokes);
-
-       return sketch;
-}
-
-void sk_initPoint(SK_Point *pt, SK_DrawData *dd, const float no[3])
-{
-       if (no) {
-               normalize_v3_v3(pt->no, no);
-       }
-       else {
-               pt->no[0] = 0.0f;
-               pt->no[1] = 0.0f;
-               pt->no[2] = 1.0f;
-       }
-       pt->p2d[0] = dd->mval[0];
-       pt->p2d[1] = dd->mval[1];
-
-       pt->size = 0.0f;
-       pt->type = PT_CONTINUOUS;
-       pt->mode = PT_SNAP;
-       /* more init code here */
-}
-
-void sk_copyPoint(SK_Point *dst, SK_Point *src)
-{
-       memcpy(dst, src, sizeof(SK_Point));
-}
-
-void sk_allocStrokeBuffer(SK_Stroke *stk)
-{
-       stk->points = MEM_callocN(sizeof(SK_Point) * stk->buf_size, "SK_Point buffer");
-}
-
-void sk_freeStroke(SK_Stroke *stk)
-{
-       MEM_freeN(stk->points);
-       MEM_freeN(stk);
-}
-
-SK_Stroke *sk_createStroke(void)
-{
-       SK_Stroke *stk;
-
-       stk = MEM_callocN(sizeof(SK_Stroke), "SK_Stroke");
-
-       stk->selected = 0;
-       stk->nb_points = 0;
-       stk->buf_size = SK_Stroke_BUFFER_INIT_SIZE;
-
-       sk_allocStrokeBuffer(stk);
-
-       return stk;
-}
-
-void sk_shrinkStrokeBuffer(SK_Stroke *stk)
-{
-       if (stk->nb_points < stk->buf_size) {
-               SK_Point *old_points = stk->points;
-
-               stk->buf_size = stk->nb_points;
-
-               sk_allocStrokeBuffer(stk);
-
-               memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
-
-               MEM_freeN(old_points);
-       }
-}
-
-void sk_growStrokeBuffer(SK_Stroke *stk)
-{
-       if (stk->nb_points == stk->buf_size) {
-               SK_Point *old_points = stk->points;
-
-               stk->buf_size *= 2;
-
-               sk_allocStrokeBuffer(stk);
-
-               memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
-
-               MEM_freeN(old_points);
-       }
-}
-
-void sk_growStrokeBufferN(SK_Stroke *stk, int n)
-{
-       if (stk->nb_points + n > stk->buf_size) {
-               SK_Point *old_points = stk->points;
-
-               while (stk->nb_points + n > stk->buf_size) {
-                       stk->buf_size *= 2;
-               }
-
-               sk_allocStrokeBuffer(stk);
-
-               memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
-
-               MEM_freeN(old_points);
-       }
-}
-
-
-void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
-{
-       memcpy(stk->points + n, pt, sizeof(SK_Point));
-}
-
-void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
-{
-       int size = stk->nb_points - n;
-
-       sk_growStrokeBuffer(stk);
-
-       memmove(stk->points + n + 1, stk->points + n, size * sizeof(SK_Point));
-
-       memcpy(stk->points + n, pt, sizeof(SK_Point));
-
-       stk->nb_points++;
-}
-
-void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt)
-{
-       sk_growStrokeBuffer(stk);
-
-       memcpy(stk->points + stk->nb_points, pt, sizeof(SK_Point));
-
-       stk->nb_points++;
-}
-
-void sk_insertStrokePoints(SK_Stroke *stk, SK_Point *pts, int len, int start, int end)
-{
-       int size = end - start;
-
-       sk_growStrokeBufferN(stk, len - size);
-
-       if (len != size) {
-               int tail_size = stk->nb_points - end;
-
-               memmove(stk->points + start + len, stk->points + end, tail_size * sizeof(SK_Point));
-       }
-
-       memcpy(stk->points + start, pts, len * sizeof(SK_Point));
-
-       stk->nb_points += len - size;
-}
-
-void sk_trimStroke(SK_Stroke *stk, int start, int end)
-{
-       int size = end - start + 1;
-
-       if (start > 0) {
-               memmove(stk->points, stk->points + start, size * sizeof(SK_Point));
-       }
-
-       stk->nb_points = size;
-}
-
-void sk_straightenStroke(SK_Stroke *stk, int start, int end, float p_start[3], float p_end[3])
-{
-       SK_Point pt1, pt2;
-       SK_Point *prev, *next;
-       float delta_p[3];
-       int i, total;
-
-       total = end - start;
-
-       sub_v3_v3v3(delta_p, p_end, p_start);
-
-       prev = stk->points + start;
-       next = stk->points + end;
-
-       copy_v3_v3(pt1.p, p_start);
-       copy_v3_v3(pt1.no, prev->no);
-       pt1.mode = prev->mode;
-       pt1.type = prev->type;
-
-       copy_v3_v3(pt2.p, p_end);
-       copy_v3_v3(pt2.no, next->no);
-       pt2.mode = next->mode;
-       pt2.type = next->type;
-
-       sk_insertStrokePoint(stk, &pt1, start + 1); /* insert after start */
-       sk_insertStrokePoint(stk, &pt2, end + 1); /* insert before end (since end was pushed back already) */
-
-       for (i = 1; i < total; i++) {
-               float delta = (float)i / (float)total;
-               float *p = stk->points[start + 1 + i].p;
-
-               mul_v3_v3fl(p, delta_p, delta);
-               add_v3_v3(p, p_start);
-       }
-}
-
-void sk_polygonizeStroke(SK_Stroke *stk, int start, int end)
-{
-       int offset;
-       int i;
-
-       /* find first exact points outside of range */
-       for (; start > 0; start--) {
-               if (stk->points[start].type == PT_EXACT) {
-                       break;
-               }
-       }
-
-       for (; end < stk->nb_points - 1; end++) {
-               if (stk->points[end].type == PT_EXACT) {
-                       break;
-               }
-       }
-
-       offset = start + 1;
-
-       for (i = start + 1; i < end; i++) {
-               if (stk->points[i].type == PT_EXACT) {
-                       if (offset != i) {
-                               memcpy(stk->points + offset, stk->points + i, sizeof(SK_Point));
-                       }
-
-                       offset++;
-               }
-       }
-
-       /* some points were removes, move end of array */
-       if (offset < end) {
-               int size = stk->nb_points - end;
-               memmove(stk->points + offset, stk->points + end, size * sizeof(SK_Point));
-               stk->nb_points = offset + size;
-       }
-}
-
-void sk_flattenStroke(SK_Stroke *stk, int start, int end)
-{
-       float normal[3], distance[3];
-       float limit;
-       int i, total;
-
-       total = end - start + 1;
-
-       copy_v3_v3(normal, stk->points[start].no);
-
-       sub_v3_v3v3(distance, stk->points[end].p, stk->points[start].p);
-       project_v3_v3v3(normal, distance, normal);
-       limit = normalize_v3(normal);
-
-       for (i = 1; i < total - 1; i++) {
-               float d = limit * i / total;
-               float offset[3];
-               float *p = stk->points[start + i].p;
-
-               sub_v3_v3v3(distance, p, stk->points[start].p);
-               project_v3_v3v3(distance, distance, normal);
-
-               copy_v3_v3(offset, normal);
-               mul_v3_fl(offset, d);
-
-               sub_v3_v3(p, distance);
-               add_v3_v3(p, offset);
-       }
-}
-
-void sk_removeStroke(SK_Sketch *sketch, SK_Stroke *stk)
-{
-       if (sketch->active_stroke == stk) {
-               sketch->active_stroke = NULL;
-       }
-
-       BLI_remlink(&sketch->strokes, stk);
-       sk_freeStroke(stk);
-}
-
-void sk_reverseStroke(SK_Stroke *stk)
-{
-       SK_Point *old_points = stk->points;
-       int i = 0;
-
-       sk_allocStrokeBuffer(stk);
-
-       for (i = 0; i < stk->nb_points; i++) {
-               sk_copyPoint(stk->points + i, old_points + stk->nb_points - 1 - i);
-       }
-
-       MEM_freeN(old_points);
-}
-
-
-/* Ramer-Douglas-Peucker algorithm for line simplification */
-void sk_filterStroke(SK_Stroke *stk, int start, int end)
-{
-       SK_Point *old_points = stk->points;
-       int nb_points = stk->nb_points;
-       char *marked = NULL;
-       char work;
-       int i;
-
-       if (start == -1) {
-               start = 0;
-               end = stk->nb_points - 1;
-       }
-
-       sk_allocStrokeBuffer(stk);
-       stk->nb_points = 0;
-
-       /* adding points before range */
-       for (i = 0; i < start; i++) {
-               sk_appendStrokePoint(stk, old_points + i);
-       }
-
-       marked = MEM_callocN(nb_points, "marked array");
-       marked[start] = 1;
-       marked[end] = 1;
-       
-       work = 1;
-       
-       /* while still reducing */
-       while (work) {
-               int ls, le;
-               work = 0;
-               
-               ls = start;
-               le = start + 1;
-               
-               /* while not over interval */
-               while (ls < end) {
-                       int max_i = 0;
-                       short v1[2];
-                       float max_dist = 16; /* more than 4 pixels */
-                       
-                       /* find the next marked point */
-                       while (marked[le] == 0) {
-                               le++;
-                       }
-                       
-                       /* perpendicular vector to ls-le */
-                       v1[1] = old_points[le].p2d[0] - old_points[ls].p2d[0]; 
-                       v1[0] = old_points[ls].p2d[1] - old_points[le].p2d[1]; 
-                       
-
-                       for (i = ls + 1; i < le; i++) {
-                               float mul;
-                               float dist;
-                               short v2[2];
-                               
-                               v2[0] = old_points[i].p2d[0] - old_points[ls].p2d[0]; 
-                               v2[1] = old_points[i].p2d[1] - old_points[ls].p2d[1];
-                               
-                               if (v2[0] == 0 && v2[1] == 0) {
-                                       continue;
-                               }
-
-                               mul = (float)(v1[0] * v2[0] + v1[1] * v2[1]) / (float)(v2[0] * v2[0] + v2[1] * v2[1]);
-                               
-                               dist = mul * mul * (v2[0] * v2[0] + v2[1] * v2[1]);
-                               
-                               if (dist > max_dist) {
-                                       max_dist = dist;
-                                       max_i = i;
-                               }
-                       }
-                       
-                       if (max_i != 0) {
-                               work = 1;
-                               marked[max_i] = 1;
-                       }
-                       
-                       ls = le;
-                       le = ls + 1;
-               }
-       }
-       
-
-       /* adding points after range */
-       for (i = start; i <= end; i++) {
-               if (marked[i]) {
-                       sk_appendStrokePoint(stk, old_points + i);
-               }
-       }
-
-       MEM_freeN(marked);
-
-       /* adding points after range */
-       for (i = end + 1; i < nb_points; i++) {
-               sk_appendStrokePoint(stk, old_points + i);
-       }
-
-       MEM_freeN(old_points);
-
-       sk_shrinkStrokeBuffer(stk);
-}
-
-
-void sk_filterLastContinuousStroke(SK_Stroke *stk)
-{
-       int start, end;
-
-       end = stk->nb_points - 1;
-
-       for (start = end - 1; start > 0 && stk->points[start].type == PT_CONTINUOUS; start--) {
-               /* nothing to do here*/
-       }
-
-       if (end - start > 1) {
-               sk_filterStroke(stk, start, end);
-       }
-}
-
-SK_Point *sk_lastStrokePoint(SK_Stroke *stk)
-{
-       SK_Point *pt = NULL;
-
-       if (stk->nb_points > 0) {
-               pt = stk->points + (stk->nb_points - 1);
-       }
-
-       return pt;
-}
-
-void sk_endContinuousStroke(SK_Stroke *stk)
-{
-       stk->points[stk->nb_points - 1].type = PT_EXACT;
-}
-
-void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk)
-{
-       if (stk) {
-               memcpy(&(sketch->next_point), &(stk->points[stk->nb_points - 1]), sizeof(SK_Point));
-       }
-}
-
-int sk_stroke_filtermval(SK_DrawData *dd)
-{
-       int retval = 0;
-       if (ABS(dd->mval[0] - dd->previous_mval[0]) + ABS(dd->mval[1] - dd->previous_mval[1]) > U.gp_manhattendist) {
-               retval = 1;
-       }
-
-       return retval;
-}
-
-void sk_initDrawData(SK_DrawData *dd, const int mval[2])
-{
-       dd->mval[0] = mval[0];
-       dd->mval[1] = mval[1];
-       dd->previous_mval[0] = -1;
-       dd->previous_mval[1] = -1;
-       dd->type = PT_EXACT;
-}
-
-
-void sk_deleteSelectedStrokes(SK_Sketch *sketch)
-{
-       SK_Stroke *stk, *next;
-
-       for (stk = sketch->strokes.first; stk; stk = next) {
-               next = stk->next;
-
-               if (stk->selected == 1) {
-                       sk_removeStroke(sketch, stk);
-               }
-       }
-}
-
-void sk_selectAllSketch(SK_Sketch *sketch, int mode)
-{
-       SK_Stroke *stk = NULL;
-
-       if (mode == -1) {
-               for (stk = sketch->strokes.first; stk; stk = stk->next) {
-                       stk->selected = 0;
-               }
-       }
-       else if (mode == 0) {
-               for (stk = sketch->strokes.first; stk; stk = stk->next) {
-                       stk->selected = 1;
-               }
-       }
-       else if (mode == 1) {
-               int selected = 1;
-
-               for (stk = sketch->strokes.first; stk; stk = stk->next) {
-                       selected &= stk->selected;
-               }
-
-               selected ^= 1;
-
-               for (stk = sketch->strokes.first; stk; stk = stk->next) {
-                       stk->selected = selected;
-               }
-       }
-}
diff --git a/source/blender/blenlib/BLI_graph.h b/source/blender/blenlib/BLI_graph.h
deleted file mode 100644 (file)
index 7936f5a..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2008 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Joshua Leung
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef __BLI_GRAPH_H__
-#define __BLI_GRAPH_H__
-
-/** \file BLI_graph.h
- *  \ingroup bli
- */
-
-#include "DNA_listBase.h"
-
-struct BGraph;
-struct BNode;
-struct BArc;
-
-struct RadialArc;
-
-typedef void (*FreeArc)(struct BArc *);
-typedef void (*FreeNode)(struct BNode *);
-typedef void (*RadialSymmetry)(struct BNode *root_node, struct RadialArc *ring, int total);
-typedef void (*AxialSymmetry)(struct BNode *root_node, struct BNode *node1, struct BNode *node2, struct BArc *arc1, struct BArc *arc2);
-
-/* IF YOU MODIFY THOSE TYPES, YOU NEED TO UPDATE ALL THOSE THAT "INHERIT" FROM THEM
- * 
- * RigGraph, ReebGraph
- * 
- * */
-
-typedef struct BGraph {
-       ListBase arcs;
-       ListBase nodes;
-       
-       float length;
-       
-       /* function pointer to deal with custom fonctionnality */
-       FreeArc         free_arc;
-       FreeNode        free_node;
-       RadialSymmetry  radial_symmetry;
-       AxialSymmetry   axial_symmetry;
-} BGraph;
-
-typedef struct BNode {
-       void *next, *prev;
-       float p[3];
-       int flag;
-
-       int degree;
-       struct BArc **arcs;
-       
-       int subgraph_index;
-
-       int symmetry_level;
-       int symmetry_flag;
-       float symmetry_axis[3];
-} BNode;
-
-typedef struct BArc {
-       void *next, *prev;
-       struct BNode *head, *tail;
-       int flag;
-
-       float length;
-
-       int symmetry_level;
-       int symmetry_group;
-       int symmetry_flag;
-} 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 struct BArcIterator {
-       HeadFct head;
-       TailFct tail;
-       PeekFct peek;
-       NextFct next;
-       NextNFct nextN;
-       PreviousFct previous;
-       StoppedFct stopped;
-       
-       float *p, *no;
-       float size;
-       
-       int length;
-       int index;
-} BArcIterator;
-
-/* Helper structure for radial symmetry */
-typedef struct RadialArc {
-       struct BArc *arc; 
-       float n[3]; /* normalized vector joining the nodes of the arc */
-} RadialArc;
-
-BNode *BLI_otherNode(BArc *arc, BNode *node);
-
-void BLI_freeNode(BGraph *graph, BNode *node);
-void BLI_removeNode(BGraph *graph, BNode *node);
-
-void BLI_removeArc(BGraph *graph, BArc *arc);
-
-void BLI_flagNodes(BGraph *graph, int flag);
-void BLI_flagArcs(BGraph *graph, int flag);
-
-bool BLI_hasAdjacencyList(BGraph *rg);
-void BLI_buildAdjacencyList(BGraph *rg);
-void BLI_rebuildAdjacencyListForNode(BGraph *rg, BNode *node);
-void BLI_freeAdjacencyList(BGraph *rg);
-
-int BLI_FlagSubgraphs(BGraph *graph);
-void BLI_ReflagSubgraph(BGraph *graph, int old_subgraph, int new_subgraph);
-
-#define SHAPE_RADIX 10 /* each shape level is encoded this base */
-
-int BLI_subtreeShape(BGraph *graph, BNode *node, BArc *rootArc, int include_root);
-float BLI_subtreeLength(BNode *node);
-void BLI_calcGraphLength(BGraph *graph);
-
-void BLI_replaceNode(BGraph *graph, BNode *node_src, BNode *node_replaced);
-void BLI_replaceNodeInArc(BGraph *graph, BArc *arc, BNode *node_src, BNode *node_replaced);
-void BLI_removeDoubleNodes(BGraph *graph, float limit);
-BNode *BLI_FindNodeByPosition(BGraph *graph, const float p[3], const float limit);
-
-BArc  *BLI_findConnectedArc(BGraph *graph, BArc *arc, BNode *v);
-
-bool   BLI_isGraphCyclic(BGraph *graph);
-
-/*------------ Symmetry handling ------------*/
-void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit);
-
-void BLI_mirrorAlongAxis(float v[3], float center[3], float axis[3]);
-
-/* BNode symmetry flags */
-#define SYM_TOPOLOGICAL 1
-#define SYM_PHYSICAL    2
-
-/* the following two are exclusive */
-#define SYM_AXIAL       4
-#define SYM_RADIAL      8
-
-/* BArc symmetry flags
- * 
- * axial symmetry sides */
-#define SYM_SIDE_POSITIVE       1
-#define SYM_SIDE_NEGATIVE       2
-/* Anything higher is the order in radial symmetry */
-#define SYM_SIDE_RADIAL         3
-
-#endif /*__BLI_GRAPH_H__*/
index 80a8ef9..31abf25 100644 (file)
@@ -71,7 +71,6 @@ set(SRC
        intern/fileops.c
        intern/fnmatch.c
        intern/freetypefont.c
-       intern/graph.c
        intern/gsqueue.c
        intern/hash_md5.c
        intern/hash_mm2a.c
@@ -154,7 +153,6 @@ set(SRC
        BLI_fileops_types.h
        BLI_fnmatch.h
        BLI_ghash.h
-       BLI_graph.h
        BLI_gsqueue.h
        BLI_hash.h
        BLI_hash_md5.h
diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c
deleted file mode 100644 (file)
index 911e8aa..0000000
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): Martin Poirier
- *
- * ***** END GPL LICENSE BLOCK *****
- * graph.c: Common graph interface and methods
- */
-
-/** \file blender/blenlib/intern/graph.c
- *  \ingroup bli
- */
-
-#include <float.h>
-#include <math.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_utildefines.h"
-#include "BLI_listbase.h"
-#include "BLI_graph.h"
-#include "BLI_math.h"
-
-
-static void testRadialSymmetry(BGraph *graph, BNode *root_node, RadialArc *ring, int total, float axis[3], float limit, int group);
-
-static void handleAxialSymmetry(BGraph *graph, BNode *root_node, int depth, float axis[3], float limit);
-static void testAxialSymmetry(BGraph *graph, BNode *root_node, BNode *node1, BNode *node2, BArc *arc1, BArc *arc2, float axis[3], float limit, int group);
-static void flagAxialSymmetry(BNode *root_node, BNode *end_node, BArc *arc, int group);
-
-void BLI_freeNode(BGraph *graph, BNode *node)
-{
-       if (node->arcs) {
-               MEM_freeN(node->arcs);
-       }
-       
-       if (graph->free_node) {
-               graph->free_node(node);
-       }
-}
-
-void BLI_removeNode(BGraph *graph, BNode *node)
-{
-       BLI_freeNode(graph, node);
-       BLI_freelinkN(&graph->nodes, node);
-}
-
-BNode *BLI_otherNode(BArc *arc, BNode *node)
-{
-       return (arc->head == node) ? arc->tail : arc->head;
-}
-
-void BLI_removeArc(BGraph *graph, BArc *arc)
-{
-       if (graph->free_arc) {
-               graph->free_arc(arc);
-       }
-
-       BLI_freelinkN(&graph->arcs, arc);
-}
-
-void BLI_flagNodes(BGraph *graph, int flag)
-{
-       BNode *node;
-       
-       for (node = graph->nodes.first; node; node = node->next) {
-               node->flag = flag;
-       }
-}
-
-void BLI_flagArcs(BGraph *graph, int flag)
-{
-       BArc *arc;
-       
-       for (arc = graph->arcs.first; arc; arc = arc->next) {
-               arc->flag = flag;
-       }
-}
-
-static void addArcToNodeAdjacencyList(BNode *node, BArc *arc)
-{
-       node->arcs[node->flag] = arc;
-       node->flag++;
-}
-
-void BLI_buildAdjacencyList(BGraph *graph)
-{
-       BNode *node;
-       BArc *arc;
-
-       for (node = graph->nodes.first; node; node = node->next) {
-               if (node->arcs != NULL) {
-                       MEM_freeN(node->arcs);
-               }
-               
-               node->arcs = MEM_callocN((node->degree) * sizeof(BArc *), "adjacency list");
-               
-               /* temporary use to indicate the first index available in the lists */
-               node->flag = 0;
-       }
-
-       for (arc = graph->arcs.first; arc; arc = arc->next) {
-               addArcToNodeAdjacencyList(arc->head, arc);
-               addArcToNodeAdjacencyList(arc->tail, arc);
-       }
-
-       for (node = graph->nodes.first; node; node = node->next) {
-               if (node->degree != node->flag) {
-                       printf("error in node [%p]. Added only %i arcs out of %i\n", (void *)node, node->flag, node->degree);
-               }
-       }
-}
-
-void BLI_rebuildAdjacencyListForNode(BGraph *graph, BNode *node)
-{
-       BArc *arc;
-
-       if (node->arcs != NULL) {
-               MEM_freeN(node->arcs);
-       }
-       
-       node->arcs = MEM_callocN((node->degree) * sizeof(BArc *), "adjacency list");
-       
-       /* temporary use to indicate the first index available in the lists */
-       node->flag = 0;
-
-       for (arc = graph->arcs.first; arc; arc = arc->next) {
-               if (arc->head == node) {
-                       addArcToNodeAdjacencyList(arc->head, arc);
-               }
-               else if (arc->tail == node) {
-                       addArcToNodeAdjacencyList(arc->tail, arc);
-               }
-       }
-
-       if (node->degree != node->flag) {
-               printf("error in node [%p]. Added only %i arcs out of %i\n", (void *)node, node->flag, node->degree);
-       }
-}
-
-void BLI_freeAdjacencyList(BGraph *graph)
-{
-       BNode *node;
-
-       for (node = graph->nodes.first; node; node = node->next) {
-               if (node->arcs != NULL) {
-                       MEM_freeN(node->arcs);
-                       node->arcs = NULL;
-               }
-       }
-}
-
-bool BLI_hasAdjacencyList(BGraph *graph)
-{
-       BNode *node;
-       
-       for (node = graph->nodes.first; node; node = node->next) {
-               if (node->arcs == NULL) {
-                       return false;
-               }
-       }
-       
-       return true;
-}
-
-void BLI_replaceNodeInArc(BGraph *graph, BArc *arc, BNode *node_src, BNode *node_replaced)
-{
-       if (arc->head == node_replaced) {
-               arc->head = node_src;
-               node_src->degree++;
-       }
-
-       if (arc->tail == node_replaced) {
-               arc->tail = node_src;
-               node_src->degree++;
-       }
-       
-       if (arc->head == arc->tail) {
-               node_src->degree -= 2;
-               
-               graph->free_arc(arc);
-               BLI_freelinkN(&graph->arcs, arc);
-       }
-
-       if (node_replaced->degree == 0) {
-               BLI_removeNode(graph, node_replaced);
-       }
-}
-
-void BLI_replaceNode(BGraph *graph, BNode *node_src, BNode *node_replaced)
-{
-       BArc *arc, *next_arc;
-       
-       for (arc = graph->arcs.first; arc; arc = next_arc) {
-               next_arc = arc->next;
-               
-               if (arc->head == node_replaced) {
-                       arc->head = node_src;
-                       node_replaced->degree--;
-                       node_src->degree++;
-               }
-
-               if (arc->tail == node_replaced) {
-                       arc->tail = node_src;
-                       node_replaced->degree--;
-                       node_src->degree++;
-               }
-               
-               if (arc->head == arc->tail) {
-                       node_src->degree -= 2;
-                       
-                       graph->free_arc(arc);
-                       BLI_freelinkN(&graph->arcs, arc);
-               }
-       }
-       
-       if (node_replaced->degree == 0) {
-               BLI_removeNode(graph, node_replaced);
-       }
-}
-
-void BLI_removeDoubleNodes(BGraph *graph, float limit)
-{
-       const float limit_sq = limit * limit;
-       BNode *node_src, *node_replaced;
-       
-       for (node_src = graph->nodes.first; node_src; node_src = node_src->next) {
-               for (node_replaced = graph->nodes.first; node_replaced; node_replaced = node_replaced->next) {
-                       if (node_replaced != node_src && len_squared_v3v3(node_replaced->p, node_src->p) <= limit_sq) {
-                               BLI_replaceNode(graph, node_src, node_replaced);
-                       }
-               }
-       }
-       
-}
-
-BNode *BLI_FindNodeByPosition(BGraph *graph, const float p[3], const float limit)
-{
-       const float limit_sq = limit * limit;
-       BNode *closest_node = NULL, *node;
-       float min_distance = 0.0f;
-       
-       for (node = graph->nodes.first; node; node = node->next) {
-               float distance = len_squared_v3v3(p, node->p);
-               if (distance <= limit_sq && (closest_node == NULL || distance < min_distance)) {
-                       closest_node = node;
-                       min_distance = distance;
-               }
-       }
-       
-       return closest_node;
-}
-/************************************* SUBGRAPH DETECTION **********************************************/
-
-static void flagSubgraph(BNode *node, int subgraph)
-{
-       if (node->subgraph_index == 0) {
-               BArc *arc;
-               int i;
-               
-               node->subgraph_index = subgraph;
-               
-               for (i = 0; i < node->degree; i++) {
-                       arc = node->arcs[i];
-                       flagSubgraph(BLI_otherNode(arc, node), subgraph);
-               }
-       }
-} 
-
-int BLI_FlagSubgraphs(BGraph *graph)
-{
-       BNode *node;
-       int subgraph = 0;
-
-       if (BLI_hasAdjacencyList(graph) == 0) {
-               BLI_buildAdjacencyList(graph);
-       }
-       
-       for (node = graph->nodes.first; node; node = node->next) {
-               node->subgraph_index = 0;
-       }
-       
-       for (node = graph->nodes.first; node; node = node->next) {
-               if (node->subgraph_index == 0) {
-                       subgraph++;
-                       flagSubgraph(node, subgraph);
-               }
-       }
-       
-       return subgraph;
-}
-
-void BLI_ReflagSubgraph(BGraph *graph, int old_subgraph, int new_subgraph)
-{
-       BNode *node;
-
-       for (node = graph->nodes.first; node; node = node->next) {
-               if (node->flag == old_subgraph) {
-                       node->flag = new_subgraph;
-               }
-       }
-}
-
-/*************************************** CYCLE DETECTION ***********************************************/
-
-static bool detectCycle(BNode *node, BArc *src_arc)
-{
-       bool value = false;
-       
-       if (node->flag == 0) {
-               int i;
-
-               /* mark node as visited */
-               node->flag = 1;
-
-               for (i = 0; i < node->degree && value == 0; i++) {
-                       BArc *arc = node->arcs[i];
-                       
-                       /* don't go back on the source arc */
-                       if (arc != src_arc) {
-                               value = detectCycle(BLI_otherNode(arc, node), arc);
-                       }
-               }
-       }
-       else {
-               value = true;
-       }
-       
-       return value;
-}
-
-bool BLI_isGraphCyclic(BGraph *graph)
-{
-       BNode *node;
-       bool value = false;
-       
-       /* NEED TO CHECK IF ADJACENCY LIST EXIST */
-       
-       /* Mark all nodes as not visited */
-       BLI_flagNodes(graph, 0);
-
-       /* detectCycles in subgraphs */
-       for (node = graph->nodes.first; node && value == false; node = node->next) {
-               /* only for nodes in subgraphs that haven't been visited yet */
-               if (node->flag == 0) {
-                       value = value || detectCycle(node, NULL);
-               }
-       }
-       
-       return value;
-}
-
-BArc *BLI_findConnectedArc(BGraph *graph, BArc *arc, BNode *v)
-{
-       BArc *nextArc;
-       
-       for (nextArc = graph->arcs.first; nextArc; nextArc = nextArc->next) {
-               if (arc != nextArc && (nextArc->head == v || nextArc->tail == v)) {
-                       break;
-               }
-       }
-       
-       return nextArc;
-}
-
-/*********************************** GRAPH AS TREE FUNCTIONS *******************************************/
-
-static int subtreeShape(BNode *node, BArc *rootArc, int include_root)
-{
-       int depth = 0;
-       
-       node->flag = 1;
-       
-       if (include_root) {
-               BNode *newNode = BLI_otherNode(rootArc, node);
-               return subtreeShape(newNode, rootArc, 0);
-       }
-       else {
-               /* Base case, no arcs leading away */
-               if (node->arcs == NULL || *(node->arcs) == NULL) {
-                       return 0;
-               }
-               else {
-                       int i;
-       
-                       for (i = 0; i < node->degree; i++) {
-                               BArc *arc = node->arcs[i];
-                               BNode *newNode = BLI_otherNode(arc, node);
-                               
-                               /* stop immediate and cyclic backtracking */
-                               if (arc != rootArc && newNode->flag == 0) {
-                                       depth += subtreeShape(newNode, arc, 0);
-                               }
-                       }
-               }
-               
-               return SHAPE_RADIX * depth + 1;
-       }
-}
-
-int BLI_subtreeShape(BGraph *graph, BNode *node, BArc *rootArc, int include_root)
-{
-       BLI_flagNodes(graph, 0);
-       return subtreeShape(node, rootArc, include_root);
-}
-
-float BLI_subtreeLength(BNode *node)
-{
-       float length = 0;
-       int i;
-
-       node->flag = 0; /* flag node as visited */
-
-       for (i = 0; i < node->degree; i++) {
-               BArc *arc = node->arcs[i];
-               BNode *other_node = BLI_otherNode(arc, node);
-               
-               if (other_node->flag != 0) {
-                       float subgraph_length = arc->length + BLI_subtreeLength(other_node); 
-                       length = MAX2(length, subgraph_length);
-               }
-       }
-       
-       return length;
-}
-
-void BLI_calcGraphLength(BGraph *graph)
-{
-       float length = 0;
-       int nb_subgraphs;
-       int i;
-       
-       nb_subgraphs = BLI_FlagSubgraphs(graph);
-       
-       for (i = 1; i <= nb_subgraphs; i++) {
-               BNode *node;
-               
-               for (node = graph->nodes.first; node; node = node->next) {
-                       /* start on an external node  of the subgraph */
-                       if (node->subgraph_index == i && node->degree == 1) {
-                               float subgraph_length = BLI_subtreeLength(node);
-                               length = MAX2(length, subgraph_length);
-                               break;
-                       }
-               }
-       }
-       
-       graph->length = length;
-}
-
-/********************************* SYMMETRY DETECTION **************************************************/
-
-static void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit);
-
-void BLI_mirrorAlongAxis(float v[3], float center[3], float axis[3])
-{
-       float dv[3], pv[3];
-       
-       sub_v3_v3v3(dv, v, center);
-       project_v3_v3v3(pv, dv, axis);
-       mul_v3_fl(pv, -2);
-       add_v3_v3(v, pv);
-}
-
-static void testRadialSymmetry(BGraph *graph, BNode *root_node, RadialArc *ring, int total, float axis[3], float limit, int group)
-{
-       const float limit_sq = limit * limit;
-       int symmetric = 1;
-       int i;
-       
-       /* sort ring by angle */
-       for (i = 0; i < total - 1; i++) {
-               float minAngle = FLT_MAX;
-               int minIndex = -1;
-               int j;
-
-               for (j = i + 1; j < total; j++) {
-                       float angle = dot_v3v3(ring[i].n, ring[j].n);
-
-                       /* map negative values to 1..2 */
-                       if (angle < 0) {
-                               angle = 1 - angle;
-                       }
-
-                       if (angle < minAngle) {
-                               minIndex = j;
-                               minAngle = angle;
-                       }
-               }
-
-               /* swap if needed */
-               if (minIndex != i + 1) {
-                       RadialArc tmp;
-                       tmp = ring[i + 1];
-                       ring[i + 1] = ring[minIndex];
-                       ring[minIndex] = tmp;
-               }
-       }
-
-       for (i = 0; i < total && symmetric; i++) {
-               BNode *node1, *node2;
-               float tangent[3];
-               float normal[3];
-               float p[3];
-               int j = (i + 1) % total; /* next arc in the circular list */
-
-               add_v3_v3v3(tangent, ring[i].n, ring[j].n);
-               cross_v3_v3v3(normal, tangent, axis);
-               
-               node1 = BLI_otherNode(ring[i].arc, root_node);
-               node2 = BLI_otherNode(ring[j].arc, root_node);
-
-               copy_v3_v3(p, node2->p);
-               BLI_mirrorAlongAxis(p, root_node->p, normal);
-               
-               /* check if it's within limit before continuing */
-               if (len_squared_v3v3(node1->p, p) > limit_sq) {
-                       symmetric = 0;
-               }
-
-       }
-
-       if (symmetric) {
-               /* mark node as symmetric physically */
-               copy_v3_v3(root_node->symmetry_axis, axis);
-               root_node->symmetry_flag |= SYM_PHYSICAL;
-               root_node->symmetry_flag |= SYM_RADIAL;
-               
-               /* FLAG SYMMETRY GROUP */
-               for (i = 0; i < total; i++) {
-                       ring[i].arc->symmetry_group = group;
-                       ring[i].arc->symmetry_flag = SYM_SIDE_RADIAL + i;
-               }
-
-               if (graph->radial_symmetry) {
-                       graph->radial_symmetry(root_node, ring, total);
-               }
-       }
-}
-
-static void handleRadialSymmetry(BGraph *graph, BNode *root_node, int depth, float axis[3], float limit)
-{
-       RadialArc *ring = NULL;
-       RadialArc *unit;
-       int total = 0;
-       int group;
-       int first;
-       int i;
-
-       /* mark topological symmetry */
-       root_node->symmetry_flag |= SYM_TOPOLOGICAL;
-
-       /* total the number of arcs in the symmetry ring */
-       for (i = 0; i < root_node->degree; i++) {
-               BArc *connectedArc = root_node->arcs[i];
-               
-               /* depth is store as a negative in flag. symmetry level is positive */
-               if (connectedArc->symmetry_level == -depth) {
-                       total++;
-               }
-       }
-
-       ring = MEM_callocN(sizeof(RadialArc) * total, "radial symmetry ring");
-       unit = ring;
-
-       /* fill in the ring */
-       for (i = 0; i < root_node->degree; i++) {
-               BArc *connectedArc = root_node->arcs[i];
-               
-               /* depth is store as a negative in flag. symmetry level is positive */
-               if (connectedArc->symmetry_level == -depth) {
-                       BNode *otherNode = BLI_otherNode(connectedArc, root_node);
-                       float vec[3];
-
-                       unit->arc = connectedArc;
-
-                       /* project the node to node vector on the symmetry plane */
-                       sub_v3_v3v3(unit->n, otherNode->p, root_node->p);
-                       project_v3_v3v3(vec, unit->n, axis);
-                       sub_v3_v3v3(unit->n, unit->n, vec);
-
-                       normalize_v3(unit->n);
-
-                       unit++;
-               }
-       }
-
-       /* sort ring by arc length
-        * using a rather bogus insertion sort
-        * but rings will never get too big to matter
-        * */
-       for (i = 0; i < total; i++) {
-               int j;
-
-               for (j = i - 1; j >= 0; j--) {
-                       BArc *arc1, *arc2;
-                       
-                       arc1 = ring[j].arc;
-                       arc2 = ring[j + 1].arc;
-                       
-                       if (arc1->length > arc2->length) {
-                               /* swap with smaller */
-                               RadialArc tmp;
-                               
-                               tmp = ring[j + 1];
-                               ring[j + 1] = ring[j];
-                               ring[j] = tmp;
-                       }
-                       else {
-                               break;
-                       }
-               }
-       }
-
-       /* Dispatch to specific symmetry tests */
-       first = 0;
-       group = 0;
-       
-       for (i = 1; i < total; i++) {
-               int dispatch = 0;
-               int last = i - 1;
-               
-               if (fabsf(ring[first].arc->length - ring[i].arc->length) > limit) {
-                       dispatch = 1;
-               }
-
-               /* if not dispatching already and on last arc
-                * Dispatch using current arc as last
-                */
-               if (dispatch == 0 && i == total - 1) {
-                       last = i;
-                       dispatch = 1;
-               }
-               
-               if (dispatch) {
-                       int sub_total = last - first + 1; 
-
-                       group += 1;
-
-                       if (sub_total == 1) {
-                               group -= 1; /* not really a group so decrement */
-                               /* NOTHING TO DO */
-                       }
-                       else if (sub_total == 2) {
-                               BArc *arc1, *arc2;
-                               BNode *node1, *node2;
-                               
-                               arc1 = ring[first].arc;
-                               arc2 = ring[last].arc;
-                               
-                               node1 = BLI_otherNode(arc1, root_node);
-                               node2 = BLI_otherNode(arc2, root_node);
-                               
-                               testAxialSymmetry(graph, root_node, node1, node2, arc1, arc2, axis, limit, group);
-                       }
-                       else if (sub_total != total) /* allocate a new sub ring if needed */ {
-                               RadialArc *sub_ring = MEM_callocN(sizeof(RadialArc) * sub_total, "radial symmetry ring");
-                               int sub_i;
-                               
-                               /* fill in the sub ring */
-                               for (sub_i = 0; sub_i < sub_total; sub_i++) {
-                                       sub_ring[sub_i] = ring[first + sub_i];
-                               }
-                               
-                               testRadialSymmetry(graph, root_node, sub_ring, sub_total, axis, limit, group);
-                       
-                               MEM_freeN(sub_ring);
-                       }
-                       else if (sub_total == total) {
-                               testRadialSymmetry(graph, root_node, ring, total, axis, limit, group);
-                       }
-                       
-                       first = i;
-               }
-       }
-
-
-       MEM_freeN(ring);
-}
-
-static void flagAxialSymmetry(BNode *root_node, BNode *end_node, BArc *arc, int group)
-{
-       float vec[3];
-       
-       arc->symmetry_group = group;
-       
-       sub_v3_v3v3(vec, end_node->p, root_node->p);
-       
-       if (dot_v3v3(vec, root_node->symmetry_axis) < 0) {
-               arc->symmetry_flag |= SYM_SIDE_NEGATIVE;
-       }
-       else {
-               arc->symmetry_flag |= SYM_SIDE_POSITIVE;
-       }
-}
-
-static void testAxialSymmetry(BGraph *graph, BNode *root_node, BNode *node1, BNode *node2, BArc *arc1, BArc *arc2, float axis[3], float limit, int group)
-{
-       const float limit_sq = limit * limit;
-       float nor[3], vec[3], p[3];
-
-       sub_v3_v3v3(p, node1->p, root_node->p);
-       cross_v3_v3v3(nor, p, axis);
-
-       sub_v3_v3v3(p, root_node->p, node2->p);
-       cross_v3_v3v3(vec, p, axis);
-       add_v3_v3(vec, nor);
-       
-       cross_v3_v3v3(nor, vec, axis);
-       
-       if (fabsf(nor[0]) > fabsf(nor[1]) && fabsf(nor[0]) > fabsf(nor[2]) && nor[0] < 0) {
-               negate_v3(nor);
-       }
-       else if (fabsf(nor[1]) > fabsf(nor[0]) && fabsf(nor[1]) > fabsf(nor[2]) && nor[1] < 0) {
-               negate_v3(nor);
-       }
-       else if (fabsf(nor[2]) > fabsf(nor[1]) && fabsf(nor[2]) > fabsf(nor[0]) && nor[2] < 0) {
-               negate_v3(nor);
-       }
-       
-       /* mirror node2 along axis */
-       copy_v3_v3(p, node2->p);
-       BLI_mirrorAlongAxis(p, root_node->p, nor);
-       
-       /* check if it's within limit before continuing */
-       if (len_squared_v3v3(node1->p, p) <= limit_sq) {
-               /* mark node as symmetric physically */
-               copy_v3_v3(root_node->symmetry_axis, nor);
-               root_node->symmetry_flag |= SYM_PHYSICAL;
-               root_node->symmetry_flag |= SYM_AXIAL;
-
-               /* flag side on arcs */
-               flagAxialSymmetry(root_node, node1, arc1, group);
-               flagAxialSymmetry(root_node, node2, arc2, group);
-               
-               if (graph->axial_symmetry) {
-                       graph->axial_symmetry(root_node, node1, node2, arc1, arc2);
-               }
-       }
-       else {
-               /* NOT SYMMETRIC */
-       }
-}
-
-static void handleAxialSymmetry(BGraph *graph, BNode *root_node, int depth, float axis[3], float limit)
-{
-       BArc *arc1 = NULL, *arc2 = NULL;
-       BNode *node1 = NULL, *node2 = NULL;
-       int i;
-       
-       /* mark topological symmetry */
-       root_node->symmetry_flag |= SYM_TOPOLOGICAL;
-
-       for (i = 0; i < root_node->degree; i++) {
-               BArc *connectedArc = root_node->arcs[i];
-               
-               /* depth is store as a negative in flag. symmetry level is positive */
-               if (connectedArc->symmetry_level == -depth) {
-                       if (arc1 == NULL) {
-                               arc1 = connectedArc;
-                               node1 = BLI_otherNode(arc1, root_node);
-                       }
-                       else {
-                               arc2 = connectedArc;
-                               node2 = BLI_otherNode(arc2, root_node);
-                               break; /* Can stop now, the two arcs have been found */
-                       }
-               }
-       }
-       
-       /* shouldn't happen, but just to be sure */
-       if (node1 == NULL || node2 == NULL) {
-               return;
-       }
-       
-       testAxialSymmetry(graph, root_node, node1, node2, arc1, arc2, axis, limit, 1);
-}
-
-static void markdownSecondarySymmetry(BGraph *graph, BNode *node, int depth, int level, float limit)
-{
-       float axis[3] = {0, 0, 0};
-       int count = 0;
-       int i;
-       
-       /* count the number of branches in this symmetry group
-        * and determinate the axis of symmetry
-        */
-       for (i = 0; i < node->degree; i++) {
-               BArc *connectedArc = node->arcs[i];
-               
-               /* depth is store as a negative in flag. symmetry level is positive */
-               if (connectedArc->symmetry_level == -depth) {
-                       count++;
-               }
-               /* If arc is on the axis */
-               else if (connectedArc->symmetry_level == level) {
-                       add_v3_v3(axis, connectedArc->head->p);
-                       sub_v3_v3v3(axis, axis, connectedArc->tail->p);
-               }
-       }
-
-       normalize_v3(axis);
-
-       /* Split between axial and radial symmetry */
-       if (count == 2) {
-               handleAxialSymmetry(graph, node, depth, axis, limit);
-       }
-       else {
-               handleRadialSymmetry(graph, node, depth, axis, limit);
-       }
-               
-       /* markdown secondary symetries */
-       for (i = 0; i < node->degree; i++) {
-               BArc *connectedArc = node->arcs[i];
-               
-               if (connectedArc->symmetry_level == -depth) {
-                       /* markdown symmetry for branches corresponding to the depth */
-                       markdownSymmetryArc(graph, connectedArc, node, level + 1, limit);
-               }
-       }
-}
-
-static void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit)
-{
-       int i;
-
-       /* if arc is null, we start straight from a node */
-       if (arc) {
-               arc->symmetry_level = level;
-               
-               node = BLI_otherNode(arc, node);
-       }
-       
-       for (i = 0; i < node->degree; i++) {
-               BArc *connectedArc = node->arcs[i];
-               
-               if (connectedArc != arc) {
-                       BNode *connectedNode = BLI_otherNode(connectedArc, node);
-                       
-                       /* symmetry level is positive value, negative values is subtree depth */
-                       connectedArc->symmetry_level = -BLI_subtreeShape(graph, connectedNode, connectedArc, 0);
-               }
-       }
-
-       arc = NULL;
-
-       for (i = 0; i < node->degree; i++) {
-               int issymmetryAxis = 0;
-               BArc *connectedArc = node->arcs[i];
-               
-               /* only arcs not already marked as symetric */
-               if (connectedArc->symmetry_level < 0) {
-                       int j;
-                       
-                       /* true by default */
-                       issymmetryAxis = 1;
-                       
-                       for (j = 0; j < node->degree; j++) {
-                               BArc *otherArc = node->arcs[j];
-                               
-                               /* different arc, same depth */
-                               if (otherArc != connectedArc && otherArc->symmetry_level == connectedArc->symmetry_level) {
-                                       /* not on the symmetry axis */
-                                       issymmetryAxis = 0;
-                                       break;
-                               }
-                       }
-               }
-               
-               /* arc could be on the symmetry axis */
-               if (issymmetryAxis == 1) {
-                       /* no arc as been marked previously, keep this one */
-                       if (arc == NULL) {
-                               arc = connectedArc;
-                       }
-                       else if (connectedArc->symmetry_level < arc->symmetry_level) {
-                               /* go with more complex subtree as symmetry arc */
-                               arc = connectedArc;
-                       }
-               }
-       }
-       
-       /* go down the arc continuing the symmetry axis */
-       if (arc) {
-               markdownSymmetryArc(graph, arc, node, level, limit);
-       }
-
-       
-       /* secondary symmetry */
-       for (i = 0; i < node->degree; i++) {
-               BArc *connectedArc = node->arcs[i];
-               
-               /* only arcs not already marked as symetric and is not the next arc on the symmetry axis */
-               if (connectedArc->symmetry_level < 0) {
-                       /* subtree depth is store as a negative value in the symmetry */
-                       markdownSecondarySymmetry(graph, node, -connectedArc->symmetry_level, level, limit);
-               }
-       }
-}
-
-void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit)
-{
-       BNode *node;
-       BArc *arc;
-       
-       if (root_node == NULL) {
-               return;
-       }
-       
-       if (BLI_isGraphCyclic(graph)) {
-               return;
-       }
-       
-       /* mark down all arcs as non-symetric */
-       BLI_flagArcs(graph, 0);
-       
-       /* mark down all nodes as not on the symmetry axis */
-       BLI_flagNodes(graph, 0);
-
-       node = root_node;
-       
-       /* sanity check REMOVE ME */
-       if (node->degree > 0) {
-               arc = node->arcs[0];
-               
-               if (node->degree == 1) {
-                       markdownSymmetryArc(graph, arc, node, 1, limit);
-               }
-               else {
-                       markdownSymmetryArc(graph, NULL, node, 1, limit);
-               }
-               
-
-
-               /* mark down non-symetric arcs */
-               for (arc = graph->arcs.first; arc; arc = arc->next) {
-                       if (arc->symmetry_level < 0) {
-                               arc->symmetry_level = 0;
-                       }
-                       else {
-                               /* mark down nodes with the lowest level symmetry axis */
-                               if (arc->head->symmetry_level == 0 || arc->head->symmetry_level > arc->symmetry_level) {
-                                       arc->head->symmetry_level = arc->symmetry_level;
-                               }
-                               if (arc->tail->symmetry_level == 0 || arc->tail->symmetry_level > arc->symmetry_level) {
-                                       arc->tail->symmetry_level = arc->symmetry_level;
-                               }
-                       }
-               }
-       }
-}
-
-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);
-}
index 82994eb..ba91dac 100644 (file)
@@ -3556,7 +3556,6 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
        
        link_list(fd, &arm->bonebase);
        arm->edbo = NULL;
-       arm->sketch = NULL;
        
        arm->adt = newdataadr(fd, arm->adt);
        direct_link_animdata(fd, arm->adt);
@@ -5680,8 +5679,6 @@ static void lib_link_scene(FileData *fd, Main *main)
                                sce->toolsettings->imapaint.canvas =
                                        newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.canvas);
                        
-                       sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
-                       
                        sce->toolsettings->particle.shape_object = newlibadr(fd, sce->id.lib, sce->toolsettings->particle.shape_object);
                        
                        for (Base *base_legacy_next, *base_legacy = sce->base.first; base_legacy; base_legacy = base_legacy_next) {
index 9ac2f92..b31aa70 100644 (file)
@@ -2176,22 +2176,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
                }
        }
 
-       /* sanity check for skgen */
-       {
-               Scene *sce;
-               for (sce = main->scene.first; sce; sce = sce->id.next) {
-                       if (sce->toolsettings->skgen_subdivisions[0] == sce->toolsettings->skgen_subdivisions[1] ||
-                           sce->toolsettings->skgen_subdivisions[0] == sce->toolsettings->skgen_subdivisions[2] ||
-                           sce->toolsettings->skgen_subdivisions[1] == sce->toolsettings->skgen_subdivisions[2])
-                       {
-                               sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
-                               sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
-                               sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
-                       }
-               }
-       }
-
-
        if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 2)) {
                Image *ima;
 
@@ -2569,31 +2553,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
                for (sce = main->scene.first; sce; sce = sce->id.next) {
                        sce->toolsettings->imapaint.seam_bleed = 2;
                        sce->toolsettings->imapaint.normal_angle = 80;
-
-                       /* initialize skeleton generation toolsettings */
-                       sce->toolsettings->skgen_resolution = 250;
-                       sce->toolsettings->skgen_threshold_internal     = 0.1f;
-                       sce->toolsettings->skgen_threshold_external     = 0.1f;
-                       sce->toolsettings->skgen_angle_limit                    = 30.0f;
-                       sce->toolsettings->skgen_length_ratio                   = 1.3f;
-                       sce->toolsettings->skgen_length_limit                   = 1.5f;
-                       sce->toolsettings->skgen_correlation_limit              = 0.98f;
-                       sce->toolsettings->skgen_symmetry_limit                 = 0.1f;
-                       sce->toolsettings->skgen_postpro = SKGEN_SMOOTH;
-                       sce->toolsettings->skgen_postpro_passes = 3;
-                       sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL|SKGEN_FILTER_EXTERNAL|SKGEN_FILTER_SMART|SKGEN_SUB_CORRELATION|SKGEN_HARMONIC;
-                       sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
-                       sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
-                       sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
-
-
-                       sce->toolsettings->skgen_retarget_angle_weight = 1.0f;
-                       sce->toolsettings->skgen_retarget_length_weight = 1.0f;
-                       sce->toolsettings->skgen_retarget_distance_weight = 1.0f;
-
-                       /* Skeleton Sketching */
-                       sce->toolsettings->bone_sketching = 0;
-                       sce->toolsettings->skgen_retarget_roll = SK_RETARGET_ROLL_VIEW;
                }
        }
 
diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h
deleted file mode 100644 (file)
index 7110957..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/armature/BIF_generate.h
- *  \ingroup edarmature
- */
-
-#ifndef __BIF_GENERATE_H__
-#define __BIF_GENERATE_H__
-
-struct ToolSettings;
-struct EditBone;
-struct BArcIterator;
-struct bArmature;
-struct ListBase;
-
-typedef int (NextSubdivisionFunc)(struct ToolSettings *, 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 ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
-int nextLengthSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
-int nextAdaptativeSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
-
-struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter,
-                                float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion);
-
-void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[4][4], float tmat[3][3]);
-
-#endif /* __BIF_GENERATE_H__ */
diff --git a/source/blender/editors/armature/BIF_retarget.h b/source/blender/editors/armature/BIF_retarget.h
deleted file mode 100644 (file)
index aa56f84..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/armature/BIF_retarget.h
- *  \ingroup edarmature
- */
-
-#ifndef __BIF_RETARGET_H__
-#define __BIF_RETARGET_H__
-
-#include "DNA_listBase.h"
-
-#include "BLI_graph.h"
-#include "BLI_ghash.h"
-#include "BLI_task.h"
-#include "BLI_threads.h"
-
-#include "reeb.h"
-
-struct Object;
-struct bArmature;
-struct bContext;
-
-struct EditBone;
-
-struct RigGraph;
-struct RigNode;
-struct RigArc;
-struct RigEdge;
-
-#define USE_THREADS
-
-typedef struct RigGraph {
-       ListBase arcs;
-       ListBase nodes;
-
-       float length;
-       
-       FreeArc         free_arc;
-       FreeNode        free_node;
-       RadialSymmetry  radial_symmetry;
-       AxialSymmetry   axial_symmetry;
-       /*********************************/
-       
-       int flag;
-
-       ListBase   controls;
-       ListBase  *editbones;
-       
-       struct RigNode *head;
-       ReebGraph *link_mesh;
-       
-       
-       TaskScheduler *task_scheduler;
-       TaskPool *task_pool;
-       
-       GHash *bones_map;     /* map of editbones by name */
-       GHash *controls_map;  /* map of rigcontrols by bone pointer */
-       
-       struct Object *ob;
-} RigGraph;
-
-typedef struct RigNode {
-       void *next, *prev;
-       float p[3];
-       int flag;
-
-       int degree;
-       struct BArc **arcs;
-
-       int subgraph_index;
-
-       int symmetry_level;
-       int symmetry_flag;
-       float symmetry_axis[3];
-       /*********************************/
-
-       ReebNode *link_mesh;
-} RigNode;
-
-typedef struct RigArc {
-       void *next, *prev;
-       RigNode *head, *tail;
-       int flag;
-
-       float length;
-
-       int symmetry_level;
-       int symmetry_group;
-       int symmetry_flag;
-       /*********************************/
-       
-       ListBase edges;
-       int count;
-       ReebArc *link_mesh;
-} RigArc;
-
-typedef struct RigEdge {
-       struct RigEdge *next, *prev;
-       float head[3], tail[3];
-       float length;
-       float angle; /* angle to next edge */
-       float up_angle; /* angle between up_axis and the joint normal (defined as Previous edge CrossProduct Current edge */
-       struct EditBone *bone;
-       float up_axis[3];
-} RigEdge;
-
-/* Graph flags */
-#define RIG_FREE_BONELIST       1
-
-/* Control flags */
-#define RIG_CTRL_HEAD_DONE      1
-#define RIG_CTRL_TAIL_DONE      2
-#define RIG_CTRL_PARENT_DEFORM  4
-#define RIG_CTRL_FIT_ROOT       8
-#define RIG_CTRL_FIT_BONE       16
-
-#define RIG_CTRL_DONE   (RIG_CTRL_HEAD_DONE | RIG_CTRL_TAIL_DONE)
-
-/* Control tail flags */
-typedef enum {
-       TL_NONE = 0,
-       TL_TAIL,
-       TL_HEAD
-} LinkTailMode;
-
-typedef struct RigControl {
-       struct RigControl *next, *prev;
-       float head[3], tail[3];
-       struct EditBone *bone;
-       struct EditBone *link;
-       struct EditBone *link_tail;
-       float  up_axis[3];
-       float  offset[3];
-       float  qrot[4];   /* for dual linked bones, store the rotation of the linked bone for the finalization */
-       int    flag;
-       LinkTailMode tail_mode;
-} RigControl;
-
-void BIF_retargetArc(struct bContext *C, ReebArc *earc, RigGraph *template_rigg);
-RigGraph *RIG_graphFromArmature(const struct bContext *C, struct Object *ob, struct bArmature *arm);
-int RIG_nbJoints(RigGraph *rg);
-const char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index);
-void RIG_freeRigGraph(BGraph *rg);
-
-/* UNUSED */
-void BIF_retargetArmature(bContext *C);
-void BIF_adjustRetarget(bContext *C);
-/* UNUSED / print funcs */
-void RIG_printArc(struct RigGraph *rg, struct RigArc *arc);
-void RIG_printGraph(struct RigGraph *rg);
-void RIG_printArcBones(struct RigArc *arc);
-
-#endif /* __BIF_RETARGET_H__ */
index 8a40ea3..96467ee 100644 (file)
@@ -47,9 +47,6 @@ set(SRC
        armature_select.c
        armature_skinning.c
        armature_utils.c
-       editarmature_generate.c
-       editarmature_retarget.c
-       editarmature_sketch.c
        editarmature_undo.c
        meshlaplacian.c
        pose_edit.c
@@ -59,13 +56,9 @@ set(SRC
        pose_slide.c
        pose_transform.c
        pose_utils.c
-       reeb.c
 
-       BIF_generate.h
-       BIF_retarget.h
        armature_intern.h
        meshlaplacian.h
-       reeb.h
 )
 
 if(WITH_INTERNATIONAL)
index 575d159..7bc8764 100644 (file)
@@ -138,18 +138,6 @@ void POSE_OT_quaternions_flip(struct wmOperatorType *ot);
 
 void POSE_OT_bone_layers(struct wmOperatorType *ot);
 
-/* ******************************************************* */
-/* Etch-A-Ton (Skeleton Sketching) Operators */
-
-void SKETCH_OT_gesture(struct wmOperatorType *ot);
-void SKETCH_OT_delete(struct wmOperatorType *ot);
-void SKETCH_OT_draw_stroke(struct wmOperatorType *ot);
-void SKETCH_OT_draw_preview(struct wmOperatorType *ot);
-void SKETCH_OT_finish_stroke(struct wmOperatorType *ot);
-void SKETCH_OT_cancel_stroke(struct wmOperatorType *ot);
-void SKETCH_OT_convert(struct wmOperatorType *ot);
-void SKETCH_OT_select(struct wmOperatorType *ot);
-
 /* ******************************************************* */
 /* Pose Tool Utilities (for PoseLib, Pose Sliding, etc.) */
 /* pose_utils.c */
@@ -225,7 +213,6 @@ void POSE_OT_propagate(struct wmOperatorType *ot);
  */
 
 EditBone *make_boneList(struct ListBase *edbo, struct ListBase *bones, struct EditBone *parent, struct Bone *actBone);
-bool BIF_sk_selectStroke(struct bContext *C, const int mval[2], const bool extend);
 
 /* duplicate method */
 void preEditBoneDuplicate(struct ListBase *editbones);
index 5622cd0..c9cebad 100644 (file)
@@ -85,16 +85,6 @@ void ED_operatortypes_armature(void)
        WM_operatortype_append(ARMATURE_OT_armature_layers);
        WM_operatortype_append(ARMATURE_OT_bone_layers);
 
-       /* SKETCH */
-       WM_operatortype_append(SKETCH_OT_gesture);
-       WM_operatortype_append(SKETCH_OT_delete);
-       WM_operatortype_append(SKETCH_OT_draw_stroke);
-       WM_operatortype_append(SKETCH_OT_draw_preview);
-       WM_operatortype_append(SKETCH_OT_finish_stroke);
-       WM_operatortype_append(SKETCH_OT_cancel_stroke);
-       WM_operatortype_append(SKETCH_OT_convert);
-       WM_operatortype_append(SKETCH_OT_select);
-
        /* POSE */
        WM_operatortype_append(POSE_OT_hide);
        WM_operatortype_append(POSE_OT_reveal);
@@ -203,23 +193,6 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
        /* Armature ------------------------ */
        keymap = WM_keymap_find(keyconf, "Armature", 0, 0);
        keymap->poll = ED_operator_editarmature;
-       
-       /* Armature -> Etch-A-Ton ------------------------ */
-       WM_keymap_add_item(keymap, "SKETCH_OT_delete", XKEY, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "SKETCH_OT_delete", DELKEY, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "SKETCH_OT_finish_stroke", RIGHTMOUSE, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "SKETCH_OT_cancel_stroke", ESCKEY, KM_PRESS, 0, 0);
-       /* Already part of view3d select */
-       //WM_keymap_add_item(keymap, "SKETCH_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
-
-       /* sketch poll checks mode */
-       WM_keymap_add_item(keymap, "SKETCH_OT_gesture", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
-       WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
-       kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
-       RNA_boolean_set(kmi->ptr, "snap", true);
-       WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0);
-       kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0);
-       RNA_boolean_set(kmi->ptr, "snap", true);
 
        /* only set in editmode armature, by space_view3d listener */
        kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0);
index 2c6b84c..af0483c 100644 (file)
@@ -625,10 +625,6 @@ bool ED_armature_edit_select_pick(bContext *C, const int mval[2], bool extend, b
        vc.mval[0] = mval[0];
        vc.mval[1] = mval[1];
 
-       if (BIF_sk_selectStroke(C, mval, extend)) {
-               return true;
-       }
-
        nearBone = get_nearest_editbonepoint(&vc, true, true, &basact, &selmask);
        if (nearBone) {
                ED_view3d_viewcontext_init_object(&vc, basact->object);
index c98eb92..1722cbd 100644 (file)
 #include "armature_intern.h"
 #include "meshlaplacian.h"
 
-#if 0
-#include "reeb.h"
-#endif
-
 /* ********************************** Bone Skinning *********************************************** */
 
 static int bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap)
index c4580a3..ffa8b9f 100644 (file)
@@ -716,8 +716,6 @@ void ED_armature_to_edit(bArmature *arm)
        ED_armature_edit_free(arm);
        arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature");
        arm->act_edbone = make_boneList(arm->edbo, &arm->bonebase, NULL, arm->act_bone);
-
-//     BIF_freeTemplates(); /* force template update when entering editmode */
 }
 
 /* *************************************************************** */
diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
deleted file mode 100644 (file)
index 5784326..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/armature/editarmature_generate.c
- *  \ingroup edarmature
- */
-
-#include "DNA_scene_types.h"
-#include "DNA_armature_types.h"
-
-#include "BLI_math.h"
-#include "BLI_graph.h"
-
-#include "ED_armature.h"
-#include "BIF_generate.h"
-
-void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[4][4]), float tmat[3][3])
-{
-       if (no != NULL && !is_zero_v3(no)) {
-               float normal[3];
-
-               copy_v3_v3(normal, no);
-               mul_m3_v3(tmat, normal);
-               
-               bone->roll = ED_armature_ebone_roll_to_vector(bone, normal, false);
-       }
-}
-
-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);
-                       sub_v3_v3v3(v, iter->p, v0);
-                       avg_t += dot_v3v3(v, n);
-               }
-               
-               avg_t /= dot_v3v3(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);
-                       sub_v3_v3v3(v, iter->p, v0);
-                       project_v3_v3v3(d, v, n);
-                       sub_v3_v3(v, d);
-                       
-                       dt = len_v3(d) - avg_t;
-                       
-                       s_t += dt * dt;
-                       s_xyz += dot_v3v3(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(ToolSettings *toolsettings, BArcIterator *iter, int start, int end, float UNUSED(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 += len_v3v3(v1, v2);
-                       
-                       v1 = v2;
-               }
-               
-               n = 0;
-               current_length = 0;
-       }
-       
-       n++;
-       
-       length_threshold = n * stroke_length / 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 += len_v3v3(v1, v2);
-
-               if (current_length >= length_threshold) {
-                       copy_v3_v3(p, v2);
-                       return i;
-               }
-               
-               v1 = v2;
-       }
-       
-       stroke_length = 0;
-       
-       return -1;
-}
-int nextAdaptativeSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int start, int end, float head[3], float p[3])
-{
-       float correlation_threshold = 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);
-               sub_v3_v3v3(n, iter->p, head);
-
-               if (calcArcCorrelation(iter, start, i, start_p, n) < correlation_threshold) {
-                       IT_peek(iter, i - 1);
-                       copy_v3_v3(p, iter->p);
-                       return i - 1;
-               }
-       }
-       
-       return -1;
-}
-
-int nextLengthSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int start, int end, float head[3], float p[3])
-{
-       float lengthLimit = 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 (len_v3v3(vec1, head) > lengthLimit) {
-                       if (same == 0) {
-                               float dv[3], off[3];
-                               float a, b, c, f;
-                               
-                               /* Solve quadratic distance equation */
-                               sub_v3_v3v3(dv, vec1, vec0);
-                               a = dot_v3v3(dv, dv);
-                               
-                               sub_v3_v3v3(off, vec0, head);
-                               b = 2 * dot_v3v3(dv, off);
-                               
-                               c = dot_v3v3(off, off) - (lengthLimit * lengthLimit);
-                               
-                               f = (-b + sqrtf(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) {
-                                       copy_v3_v3(p, dv);
-                                       mul_v3_fl(p, f);
-                                       add_v3_v3(p, vec0);
-                               }
-                               else {
-                                       copy_v3_v3(p, vec1);
-                               }
-                       }
-                       else {
-                               float dv[3];
-                               
-                               sub_v3_v3v3(dv, vec1, vec0);
-                               normalize_v3(dv);
-                                
-                               copy_v3_v3(p, dv);
-                               mul_v3_fl(p, lengthLimit);
-                               add_v3_v3(p, head);
-                       }
-                       
-                       return i - 1; /* restart at lower bound */
-               }
-               else {
-                       i++;
-                       same = 0; // Reset same
-               }
-       }
-       
-       return -1;
-}
-
-EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter,
-                         float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion)
-{
-       EditBone *lastBone = NULL;
-       EditBone *child = NULL;
-       EditBone *parent = NULL;
-       float *normal = NULL;
-       float size_buffer = 1.2;
-       int bone_start = 0;
-       int end = iter->length;
-       int index;
-       
-       IT_head(iter);
-       
-       parent = ED_armature_ebone_add(arm, "Bone");
-       copy_v3_v3(parent->head, iter->p);
-       
-       if (iter->size > FLT_EPSILON) {
-               parent->rad_head = iter->size * size_buffer;
-       }
-       
-       normal = iter->no;
-       
-       index = next_subdividion(toolsettings, iter, bone_start, end, parent->head, parent->tail);
-       while (index != -1) {
-               IT_peek(iter, index);
-
-               child = ED_armature_ebone_add(arm, "Bone");
-               copy_v3_v3(child->head, parent->tail);
-               child->parent = parent;
-               child->flag |= BONE_CONNECTED;
-               
-               if (iter->size > FLT_EPSILON) {
-                       child->rad_head = iter->size * size_buffer;
-                       parent->rad_tail = iter->size * size_buffer;
-               }
-
-               /* going to next bone, fix parent */
-               mul_m4_v3(invmat, parent->tail);
-               mul_m4_v3(invmat, parent->head);
-               setBoneRollFromNormal(parent, normal, invmat, tmat);
-
-               parent = child; // new child is next parent
-               bone_start = index; // start next bone from current index
-
-               normal = iter->no; /* use normal at head, not tail */
-
-               index = next_subdividion(toolsettings, iter, bone_start, end, parent->head, parent->tail);
-       }
-       
-       iter->tail(iter);
-
-       copy_v3_v3(parent->tail, iter->p);
-       if (iter->size > FLT_EPSILON) {
-               parent->rad_tail = iter->size * size_buffer;
-       }
-               
-       /* fix last bone */
-       mul_m4_v3(invmat, parent->tail);
-       mul_m4_v3(invmat, parent->head);
-       setBoneRollFromNormal(parent, iter->no, invmat, tmat);
-       lastBone = parent;
-       
-       return lastBone;
-}
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
deleted file mode 100644 (file)
index 6b28937..0000000
+++ /dev/null
@@ -1,2641 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): Martin Poirier
- *
- * ***** END GPL LICENSE BLOCK *****
- * autoarmature.c: Interface for automagically manipulating armature (retarget, created, ...)
- */
-
-/** \file blender/editors/armature/editarmature_retarget.c
- *  \ingroup edarmature
- */
-
-#include "MEM_guardedalloc.h"
-
-#include "PIL_time.h"
-
-#include "DNA_armature_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_object_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
-#include "BKE_constraint.h"
-#include "BKE_armature.h"
-#include "BKE_context.h"
-
-#include "ED_armature.h"
-#include "ED_undo.h"
-
-#include "BIF_retarget.h"
-
-#include "armature_intern.h"
-
-/************ RIG RETARGET DATA STRUCTURES ***************/
-
-typedef struct MemoNode {
-       float weight;
-       int next;
-} MemoNode;
-
-typedef struct RetargetParam {
-       RigGraph    *rigg;
-       RigArc      *iarc;
-       RigNode     *inode_start;
-       bContext    *context;
-} RetargetParam;
-
-typedef enum  {
-       RETARGET_LENGTH,
-       RETARGET_AGGRESSIVE
-} RetargetMode; 
-
-typedef enum {
-       METHOD_BRUTE_FORCE = 0,
-       METHOD_MEMOIZE = 1
-} RetargetMethod;
-
-typedef enum {
-       ARC_FREE = 0,
-       ARC_TAKEN = 1,
-       ARC_USED = 2
-} ArcUsageFlags;
-
-static RigGraph *GLOBAL_RIGG = NULL;
-
-/*******************************************************************************************************/
-
-void exec_retargetArctoArc(TaskPool * __restrict pool, void *taskdata, int threadid);
-
-static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second);
-float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]);
-
-/* two levels */
-#define SHAPE_LEVELS (SHAPE_RADIX * SHAPE_RADIX) 
-
-/*********************************** EDITBONE UTILS ****************************************************/
-
-static int countEditBoneChildren(ListBase *list, EditBone *parent)
-{
-       EditBone *ebone;
-       int count = 0;
-       
-       for (ebone = list->first; ebone; ebone = ebone->next) {
-               if (ebone->parent == parent) {
-                       count++;
-               }
-       }
-       
-       return count;
-}
-
-static EditBone *nextEditBoneChild(ListBase *list, EditBone *parent, int n)
-{
-       EditBone *ebone;
-       
-       for (ebone = list->first; ebone; ebone = ebone->next) {
-               if (ebone->parent == parent) {
-                       if (n == 0) {
-                               return ebone;
-                       }
-                       n--;
-               }
-       }
-       
-       return NULL;
-}
-
-static void getEditBoneRollUpAxis(EditBone *bone, float roll, float up_axis[3])
-{
-       float mat[3][3], nor[3];
-
-       sub_v3_v3v3(nor, bone->tail, bone->head);
-       
-       vec_roll_to_mat3(nor, roll, mat);
-       copy_v3_v3(up_axis, mat[2]);
-}
-
-static float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4], float qroll[4], float aligned_axis[3])
-{
-       float nor[3], new_up_axis[3], x_axis[3], z_axis[3];
-       
-       copy_v3_v3(new_up_axis, old_up_axis);
-       mul_qt_v3(qrot, new_up_axis);
-       
-       sub_v3_v3v3(nor, bone->tail, bone->head);
-       
-       cross_v3_v3v3(x_axis, nor, aligned_axis);
-       cross_v3_v3v3(z_axis, x_axis, nor);
-       
-       normalize_v3(new_up_axis);
-       normalize_v3(x_axis);
-       normalize_v3(z_axis);
-       
-       if (dot_v3v3(new_up_axis, x_axis) < 0) {
-               negate_v3(x_axis);
-       }
-       
-       if (dot_v3v3(new_up_axis, z_axis) < 0) {
-               negate_v3(z_axis);
-       }
-       
-       if (angle_normalized_v3v3(x_axis, new_up_axis) < angle_normalized_v3v3(z_axis, new_up_axis)) {
-               rotation_between_vecs_to_quat(qroll, new_up_axis, x_axis); /* set roll rotation quat */
-               return ED_armature_ebone_roll_to_vector(bone, x_axis, false);
-       }
-       else {
-               rotation_between_vecs_to_quat(qroll, new_up_axis, z_axis); /* set roll rotation quat */
-               return ED_armature_ebone_roll_to_vector(bone, z_axis, false);
-       }
-}
-
-static float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4], float up_axis[3])
-{
-       if (previous == NULL) {
-               /* default to up_axis if no previous */
-               return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis);
-       }
-       else {
-               float new_up_axis[3];
-               float vec_first[3], vec_second[3], normal[3];
-               
-               if (previous->bone) {
-                       sub_v3_v3v3(vec_first, previous->bone->tail, previous->bone->head);
-               }
-               else if (previous->prev->bone) {
-                       sub_v3_v3v3(vec_first, edge->bone->head, previous->prev->bone->tail);
-               }
-               else {
-                       /* default to up_axis if first bone in the chain is an offset */
-                       return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis);
-               }
-               
-               sub_v3_v3v3(vec_second, edge->bone->tail, edge->bone->head);
-       
-               normalize_v3(vec_first);
-               normalize_v3(vec_second);
-               
-               cross_v3_v3v3(normal, vec_first, vec_second);
-               normalize_v3(normal);
-               
-               axis_angle_to_quat(qroll, vec_second, edge->up_angle);
-               
-               mul_qt_v3(qroll, normal);
-                       
-               copy_v3_v3(new_up_axis, edge->up_axis);
-               mul_qt_v3(qrot, new_up_axis);
-               
-               normalize_v3(new_up_axis);
-               
-               /* real qroll between normal and up_axis */
-               rotation_between_vecs_to_quat(qroll, new_up_axis, normal);
-
-               return ED_armature_ebone_roll_to_vector(edge->bone, normal, false);
-       }
-}
-
-float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4])
-{
-       float new_up_axis[3];
-       
-       copy_v3_v3(new_up_axis, old_up_axis);
-       mul_qt_v3(qrot, new_up_axis);
-       
-       return ED_armature_ebone_roll_to_vector(bone, new_up_axis, false);
-}
-
-/************************************ DESTRUCTORS ******************************************************/
-
-static void RIG_freeRigArc(BArc *arc)
-{
-       BLI_freelistN(&((RigArc *)arc)->edges);
-}
-
-void RIG_freeRigGraph(BGraph *rg)
-{
-       RigGraph *rigg = (RigGraph *)rg;
-       BNode *node;
-       BArc *arc;
-       
-       BLI_task_pool_free(rigg->task_pool);
-       BLI_task_scheduler_free(rigg->task_scheduler);
-       
-       if (rigg->link_mesh) {
-               REEB_freeGraph(rigg->link_mesh);
-       }
-       
-       for (arc = rg->arcs.first; arc; arc = arc->next) {
-               RIG_freeRigArc(arc);
-       }
-       BLI_freelistN(&rg->arcs);
-       
-       for (node = rg->nodes.first; node; node = node->next) {
-               BLI_freeNode(rg, (BNode *)node);
-       }
-       BLI_freelistN(&rg->nodes);
-       
-       BLI_freelistN(&rigg->controls);
-
-       BLI_ghash_free(rigg->bones_map, NULL, NULL);
-       BLI_ghash_free(rigg->controls_map, NULL, NULL);
-       
-       if (rigg->flag & RIG_FREE_BONELIST) {
-               BLI_freelistN(rigg->editbones);
-               MEM_freeN(rigg->editbones);
-       }
-       
-       MEM_freeN(rg);
-}
-
-/************************************* ALLOCATORS ******************************************************/
-
-static RigGraph *newRigGraph(void)
-{
-       RigGraph *rg;
-       int totthread;
-       
-       rg = MEM_callocN(sizeof(RigGraph), "rig graph");
-       
-       rg->head = NULL;
-       
-       rg->bones_map = BLI_ghash_str_new("newRigGraph bones gh");
-       rg->controls_map = BLI_ghash_str_new("newRigGraph cont gh");
-       
-       rg->free_arc = RIG_freeRigArc;
-       rg->free_node = NULL;
-       
-#ifdef USE_THREADS
-       totthread = TASK_SCHEDULER_AUTO_THREADS;
-#else
-       totthread = TASK_SCHEDULER_SINGLE_THREAD;
-#endif
-
-       rg->task_scheduler = BLI_task_scheduler_create(totthread);
-       rg->task_pool = BLI_task_pool_create(rg->task_scheduler, NULL);
-
-       return rg;
-}
-
-static RigArc *newRigArc(RigGraph *rg)
-{
-       RigArc *arc;
-       
-       arc = MEM_callocN(sizeof(RigArc), "rig arc");
-       arc->count = 0;
-       BLI_addtail(&rg->arcs, arc);
-       
-       return arc;
-}
-
-static RigControl *newRigControl(RigGraph *rg)
-{
-       RigControl *ctrl;
-       
-       ctrl = MEM_callocN(sizeof(RigControl), "rig control");
-       
-       BLI_addtail(&rg->controls, ctrl);
-       
-       return ctrl;
-}
-
-static RigNode *newRigNodeHead(RigGraph *rg, RigArc *arc, float p[3])
-{
-       RigNode *node;
-       node = MEM_callocN(sizeof(RigNode), "rig node");
-       BLI_addtail(&rg->nodes, node);
-
-       copy_v3_v3(node->p, p);
-       node->degree = 1;
-       node->arcs = NULL;
-       
-       arc->head = node;
-       
-       return node;
-}
-
-static void addRigNodeHead(RigGraph *UNUSED(rg), RigArc *arc, RigNode *node)
-{
-       node->degree++;
-
-       arc->head = node;
-}
-
-static RigNode *newRigNode(RigGraph *rg, float p[3])
-{
-       RigNode *node;
-       node = MEM_callocN(sizeof(RigNode), "rig node");
-       BLI_addtail(&rg->nodes, node);
-
-       copy_v3_v3(node->p, p);
-       node->degree = 0;
-       node->arcs = NULL;
-       
-       return node;
-}
-
-static RigNode *newRigNodeTail(RigGraph *rg, RigArc *arc, float p[3])
-{
-       RigNode *node = newRigNode(rg, p);
-       
-       node->degree = 1;
-       arc->tail = node;
-
-       return node;
-}
-
-static void RIG_appendEdgeToArc(RigArc *arc, RigEdge *edge)
-{
-       BLI_addtail(&arc->edges, edge);
-
-       if (edge->prev == NULL) {
-               copy_v3_v3(edge->head, arc->head->p);
-       }
-       else {
-               RigEdge *last_edge = edge->prev;
-               copy_v3_v3(edge->head, last_edge->tail);
-               RIG_calculateEdgeAngles(last_edge, edge);
-       }
-       
-       edge->length = len_v3v3(edge->head, edge->tail);
-       
-       arc->length += edge->length;
-       
-       arc->count += 1;
-}
-
-static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone)
-{
-       RigEdge *edge;
-
-       edge = MEM_callocN(sizeof(RigEdge), "rig edge");
-
-       copy_v3_v3(edge->tail, tail);
-       edge->bone = bone;
-       
-       if (bone) {
-               getEditBoneRollUpAxis(bone, bone->roll, edge->up_axis);
-       }
-       
-       RIG_appendEdgeToArc(arc, edge);
-}
-/************************************** CLONING TEMPLATES **********************************************/
-
-static void renameTemplateBone(char *name, char *template_name, ListBase *editbones, char *side_string, char *num_string)
-{
-       int i, j;
-       
-       for (i = 0, j = 0; i < (MAXBONENAME - 1) && j < (MAXBONENAME - 1) && template_name[i] != '\0'; i++) {
-               if (template_name[i] == '&') {
-                       if (template_name[i + 1] == 'S' || template_name[i + 1] == 's') {
-                               j += BLI_strncpy_rlen(name + j, side_string, MAXBONENAME);
-                               i++;
-                       }
-                       else if (template_name[i + 1] == 'N' || template_name[i + 1] == 'n') {
-                               j += BLI_strncpy_rlen(name + j, num_string, MAXBONENAME);
-                               i++;
-                       }
-                       else {
-                               name[j] = template_name[i];
-                               j++;
-                       }
-               }
-               else {
-                       name[j] = template_name[i];
-                       j++;
-               }
-       }
-       
-       name[j] = '\0';
-       
-       ED_armature_ebone_unique_name(editbones, name, NULL);
-}
-
-static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash, char *side_string, char *num_string)
-{
-       RigControl *ctrl;
-       char name[MAXBONENAME];
-       
-       ctrl = newRigControl(rg);
-       
-       copy_v3_v3(ctrl->head, src_ctrl->head);
-       copy_v3_v3(ctrl->tail, src_ctrl->tail);
-       copy_v3_v3(ctrl->up_axis, src_ctrl->up_axis);
-       copy_v3_v3(ctrl->offset, src_ctrl->offset);
-       
-       ctrl->tail_mode = src_ctrl->tail_mode;
-       ctrl->flag = src_ctrl->flag;
-
-       renameTemplateBone(name, src_ctrl->bone->name, rg->editbones, side_string, num_string);
-       ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, name, rg->editbones, src_rg->ob, rg->ob);
-       ctrl->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
-       BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone);
-       
-       ctrl->link = src_ctrl->link;
-       ctrl->link_tail = src_ctrl->link_tail;
-       
-       return ctrl;
-}
-
-static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *ptr_hash, char *side_string, char *num_string)
-{
-       RigEdge *src_edge;
-       RigArc  *arc;
-       
-       arc = newRigArc(rg);
-       
-       arc->head = BLI_ghash_lookup(ptr_hash, src_arc->head);
-       arc->tail = BLI_ghash_lookup(ptr_hash, src_arc->tail);
-       
-       arc->head->degree++;
-       arc->tail->degree++;
-       
-       arc->length = src_arc->length;
-
-       arc->count = src_arc->count;
-       
-       for (src_edge = src_arc->edges.first; src_edge; src_edge = src_edge->next) {
-               RigEdge *edge;
-       
-               edge = MEM_callocN(sizeof(RigEdge), "rig edge");
-
-               copy_v3_v3(edge->head, src_edge->head);
-               copy_v3_v3(edge->tail, src_edge->tail);
-               copy_v3_v3(edge->up_axis, src_edge->up_axis);
-               
-               edge->length = src_edge->length;
-               edge->angle = src_edge->angle;
-               edge->up_angle = src_edge->up_angle;
-               
-               if (src_edge->bone != NULL) {
-                       char name[MAXBONENAME];
-                       renameTemplateBone(name, src_edge->bone->name, rg->editbones, side_string, num_string);
-                       edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob);
-                       edge->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
-                       BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone);
-               }
-
-               BLI_addtail(&arc->edges, edge);
-       }
-       
-       return arc;
-}
-
-static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob, char *side_string, char *num_string)
-{
-       GHash   *ptr_hash;
-       RigNode *node;
-       RigArc  *arc;
-       RigControl *ctrl;
-       RigGraph *rg;
-       
-       ptr_hash = BLI_ghash_ptr_new("cloneRigGraph gh");
-
-       rg = newRigGraph();
-       
-       rg->ob = ob;
-       rg->editbones = editbones;
-       
-       preEditBoneDuplicate(rg->editbones); /* prime bones for duplication */
-       preEditBoneDuplicate(src->editbones); /* prime bones for duplication */
-       
-       /* Clone nodes */
-       for (node = src->nodes.first; node; node = node->next) {
-               RigNode *cloned_node = newRigNode(rg, node->p);
-               BLI_ghash_insert(ptr_hash, node, cloned_node);
-       }
-       
-       rg->head = BLI_ghash_lookup(ptr_hash, src->head);
-       
-       /* Clone arcs */
-       for (arc = src->arcs.first; arc; arc = arc->next) {
-               cloneArc(rg, src, arc, ptr_hash, side_string, num_string);
-       }
-       
-       /* Clone controls */
-       for (ctrl = src->controls.first; ctrl; ctrl = ctrl->next) {
-               cloneControl(rg, src, ctrl, ptr_hash, side_string, num_string);
-       }
-       
-       /* Relink bones properly */
-       for (arc = rg->arcs.first; arc; arc = arc->next) {
-               RigEdge *edge;
-               
-               for (edge = arc->edges.first; edge; edge = edge->next) {
-                       if (edge->bone != NULL) {
-                               EditBone *bone;
-                               
-                               updateDuplicateSubtargetObjects(edge->bone, src->editbones, src->ob, rg->ob);
-
-                               if (edge->bone->parent) {
-                                       bone = BLI_ghash_lookup(ptr_hash, edge->bone->parent);
-               
-                                       if (bone != NULL) {
-                                               edge->bone->parent = bone;
-                                       }
-                                       else {
-                                               /* disconnect since parent isn't cloned
-                                                * this will only happen when cloning from selected bones 
-                                                * */
-                                               edge->bone->flag &= ~BONE_CONNECTED;
-                                       }
-                               }
-                       }
-               }
-       }
-       
-       for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
-               EditBone *bone;
-               
-               updateDuplicateSubtargetObjects(ctrl->bone, src->editbones, src->ob, rg->ob);
-
-               if (ctrl->bone->parent) {
-                       bone = BLI_ghash_lookup(ptr_hash, ctrl->bone->parent);
-                       
-                       if (bone != NULL) {
-                               ctrl->bone->parent = bone;
-                       }
-                       else {
-                               /* disconnect since parent isn't cloned
-                                * this will only happen when cloning from selected bones 
-                                * */
-                               ctrl->bone->flag &= ~BONE_CONNECTED;
-                       }
-               }
-
-               ctrl->link = BLI_ghash_lookup(ptr_hash, ctrl->link);
-               ctrl->link_tail = BLI_ghash_lookup(ptr_hash, ctrl->link_tail);
-       }
-       
-       BLI_ghash_free(ptr_hash, NULL, NULL);
-       
-       return rg;
-}
-
-
-/*******************************************************************************************************/
-
-static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second)
-{
-       float vec_first[3], vec_second[3];
-       
-       sub_v3_v3v3(vec_first, edge_first->tail, edge_first->head); 
-       sub_v3_v3v3(vec_second, edge_second->tail, edge_second->head);
-
-       normalize_v3(vec_first);
-       normalize_v3(vec_second);
-       
-       edge_first->angle = angle_normalized_v3v3(vec_first, vec_second);
-       
-       if (edge_second->bone != NULL) {
-               float normal[3];
-
-               cross_v3_v3v3(normal, vec_first, vec_second);
-               normalize_v3(normal);
-
-               edge_second->up_angle = angle_normalized_v3v3(normal, edge_second->up_axis);
-       }
-}
-
-/************************************ CONTROL BONES ****************************************************/
-
-static void RIG_addControlBone(RigGraph *rg, EditBone *bone)
-{
-       RigControl *ctrl = newRigControl(rg);
-       ctrl->bone = bone;
-       copy_v3_v3(ctrl->head, bone->head);
-       copy_v3_v3(ctrl->tail, bone->tail);
-       getEditBoneRollUpAxis(bone, bone->roll, ctrl->up_axis);
-       ctrl->tail_mode = TL_NONE;
-       
-       BLI_ghash_insert(rg->controls_map, bone->name, ctrl);
-}
-
-static int RIG_parentControl(RigControl *ctrl, EditBone *link)
-{
-       if (link) {
-               float offset[3];
-               int flag = 0;
-               
-               sub_v3_v3v3(offset, ctrl->bone->head, link->head);
-
-               /* if root matches, check for direction too */
-               if (dot_v3v3(offset, offset) < 0.0001f) {
-                       float vbone[3], vparent[3];
-                       
-                       flag |= RIG_CTRL_FIT_ROOT;
-                       
-                       sub_v3_v3v3(vbone, ctrl->bone->tail, ctrl->bone->head);
-                       sub_v3_v3v3(vparent, link->tail, link->head);
-                       
-                       /* test for opposite direction */
-                       if (dot_v3v3(vbone, vparent) > 0) {
-                               float nor[3];
-                               float len;
-                               
-                               cross_v3_v3v3(nor, vbone, vparent);
-                               
-                               len = dot_v3v3(nor, nor);
-                               if (len < 0.0001f) {
-                                       flag |= RIG_CTRL_FIT_BONE;
-                               }
-                       }
-               }
-               
-               /* Bail out if old one is automatically better */
-               if (flag < ctrl->flag) {
-                       return 0;
-               }
-               
-               /* if there's already a link
-                *  overwrite only if new link is higher in the chain */
-               if (ctrl->link && flag == ctrl->flag) {
-                       EditBone *bone = NULL;
-                       
-                       for (bone = ctrl->link; bone; bone = bone->parent) {
-                               /* if link is in the chain, break and use that one */
-                               if (bone == link) {
-                                       break;
-                               }
-                       }
-                       
-                       /* not in chain, don't update link */
-                       if (bone == NULL) {
-                               return 0;
-                       }
-               }
-               
-               
-               ctrl->link = link;
-               ctrl->flag = flag;
-               
-               copy_v3_v3(ctrl->offset, offset);
-               
-               return 1;
-       }
-       
-       return 0;
-}
-
-static void RIG_reconnectControlBones(RigGraph *rg)
-{
-       RigControl *ctrl;
-       bool changed = true;
-       
-       /* first pass, link to deform bones */
-       for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
-               bPoseChannel *pchan;
-               bConstraint *con;
-               int found = 0;
-               
-               /* DO SOME MAGIC HERE */
-               for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
-                       for (con = pchan->constraints.first; con; con = con->next) {
-                               const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
-                               ListBase targets = {NULL, NULL};
-                               bConstraintTarget *ct;
-                               
-                               /* constraint targets */
-                               if (cti && cti->get_constraint_targets) {
-                                       int target_index;
-                                       
-                                       cti->get_constraint_targets(con, &targets);
-                                       
-                                       for (target_index = 0, ct = targets.first; ct; target_index++, ct = ct->next) {
-                                               if ((ct->tar == rg->ob) && STREQ(ct->subtarget, ctrl->bone->name)) {
-                                                       /* SET bone link to bone corresponding to pchan */
-                                                       EditBone *link = BLI_ghash_lookup(rg->bones_map, pchan->name);
-                                                       
-                                                       /* Making sure bone is in this armature */
-                                                       if (link != NULL) {
-                                                               /* for pole targets, link to parent bone instead, if possible */
-                                                               if (con->type == CONSTRAINT_TYPE_KINEMATIC && target_index == 1) {
-                                                                       if (link->parent && BLI_ghash_haskey(rg->bones_map, link->parent->name)) {
-                                                                               link = link->parent;
-                                                                       }
-                                                               }
-                                                               
-                                                               found = RIG_parentControl(ctrl, link);
-                                                       }
-                                               }
-                                       }
-                                       
-                                       if (cti->flush_constraint_targets)
-                                               cti->flush_constraint_targets(con, &targets, 0);
-                               }
-                       }
-               }
-
-               /* if not found yet, check parent */
-               if (found == 0) {
-                       if (ctrl->bone->parent) {
-                               /* make sure parent is a deforming bone
-                                * NULL if not
-                                *  */
-                               EditBone *link = BLI_ghash_lookup(rg->bones_map, ctrl->bone->parent->name);
-                               
-                               found = RIG_parentControl(ctrl, link);
-                       }
-                       
-                       /* check if bone is not superposed on another one */
-                       {
-                               RigArc *arc;
-                               RigArc *best_arc = NULL;
-                               EditBone *link = NULL;
-                               
-                               for (arc = rg->arcs.first; arc; arc = arc->next) {
-                                       RigEdge *edge;
-                                       for (edge = arc->edges.first; edge; edge = edge->next) {
-                                               if (edge->bone) {
-                                                       int fit = 0;
-                                                       
-                                                       fit = len_v3v3(ctrl->bone->head, edge->bone->head) < 0.0001f;
-                                                       fit = fit || len_v3v3(ctrl->bone->tail, edge->bone->tail) < 0.0001f;
-                                                       
-                                                       if (fit) {
-                                                               /* pick the bone on the arc with the lowest symmetry level
-                                                                * means you connect control to the trunk of the skeleton */
-                                                               if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level) {
-                                                                       best_arc = arc;
-                                                                       link = edge->bone;
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                               
-                               found = RIG_parentControl(ctrl, link);
-                       }
-               }
-               
-               /* if not found yet, check child */
-               if (found == 0) {
-                       RigArc *arc;
-                       RigArc *best_arc = NULL;
-                       EditBone *link = NULL;
-                       
-                       for (arc = rg->arcs.first; arc; arc = arc->next) {
-                               RigEdge *edge;
-                               for (edge = arc->edges.first; edge; edge = edge->next) {
-                                       if (edge->bone && edge->bone->parent == ctrl->bone) {
-                                               /* pick the bone on the arc with the lowest symmetry level
-                                                * means you connect control to the trunk of the skeleton */
-                                               if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level) {
-                                                       best_arc = arc;
-                                                       link = edge->bone;
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       found = RIG_parentControl(ctrl, link);
-               }
-
-       }
-       
-       
-       /* second pass, make chains in control bones */
-       while (changed) {
-               changed = false;
-               
-               for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
-                       /* if control is not linked yet */
-                       if (ctrl->link == NULL) {
-                               bPoseChannel *pchan;
-                               bConstraint *con;
-                               RigControl *ctrl_parent = NULL;
-                               RigControl *ctrl_child;
-                               int found = 0;
-
-                               if (ctrl->bone->parent) {
-                                       ctrl_parent = BLI_ghash_lookup(rg->controls_map, ctrl->bone->parent->name);
-                               }
-
-                               /* check constraints first */
-                               
-                               /* DO SOME MAGIC HERE */
-                               for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
-                                       for (con = pchan->constraints.first; con; con = con->next) {
-                                               const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
-                                               ListBase targets = {NULL, NULL};
-                                               bConstraintTarget *ct;
-                                               
-                                               /* constraint targets */
-                                               if (cti && cti->get_constraint_targets) {
-                                                       cti->get_constraint_targets(con, &targets);
-                                                       
-                                                       for (ct = targets.first; ct; ct = ct->next) {
-                                                               if ((ct->tar == rg->ob) && STREQ(ct->subtarget, ctrl->bone->name)) {
-                                                                       /* SET bone link to ctrl corresponding to pchan */
-                                                                       RigControl *link = BLI_ghash_lookup(rg->controls_map, pchan->name);
-
-                                                                       /* if owner is a control bone, link with it */
-                                                                       if (link && link->link) {
-                                                                               RIG_parentControl(ctrl, link->bone);
-                                                                               found = 1;
-                                                                               break;
-                                                                       }
-                                                               }
-                                                       }
-                                                       
-                                                       if (cti->flush_constraint_targets)
-                                                               cti->flush_constraint_targets(con, &targets, 0);
-                                               }
-                                       }
-                               }
-
-                               if (found == 0) {
-                                       /* check if parent is already linked */
-                                       if (ctrl_parent && ctrl_parent->link) {
-                                               RIG_parentControl(ctrl, ctrl_parent->bone);
-                                               changed = true;
-                                       }
-                                       else {
-                                               /* check childs */
-                                               for (ctrl_child = rg->controls.first; ctrl_child; ctrl_child = ctrl_child->next) {
-                                                       /* if a child is linked, link to that one */
-                                                       if (ctrl_child->link && ctrl_child->bone->parent == ctrl->bone) {
-                                                               RIG_parentControl(ctrl, ctrl_child->bone);
-                                                               changed = true;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-       
-       /* third pass, link control tails */
-       for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
-               /* fit bone already means full match, so skip those */
-               if ((ctrl->flag & RIG_CTRL_FIT_BONE) == 0) {
-                       GHashIterator ghi;
-                       
-                       /* look on deform bones first */
-                       BLI_ghashIterator_init(&ghi, rg->bones_map);
-                       
-                       for (; !BLI_ghashIterator_done(&ghi); BLI_ghashIterator_step(&ghi)) {
-                               EditBone *bone = (EditBone *)BLI_ghashIterator_getValue(&ghi);
-                               
-                               /* don't link with parent */
-                               if (bone->parent != ctrl->bone) {
-                                       if (len_v3v3(ctrl->bone->tail, bone->head) < 0.01f) {
-                                               ctrl->tail_mode = TL_HEAD;
-                                               ctrl->link_tail = bone;
-                                               break;
-                                       }
-                                       else if (len_v3v3(ctrl->bone->tail, bone->tail) < 0.01f) {
-                                               ctrl->tail_mode = TL_TAIL;
-                                               ctrl->link_tail = bone;
-                                               break;
-                                       }
-                               }
-                       }
-                       
-                       /* if we haven't found one yet, look in control bones */
-                       if (ctrl->tail_mode == TL_NONE) {
-                               /* pass */
-                       }
-               }
-       }
-       
-}
-
-/*******************************************************************************************************/
-
-static void RIG_joinArcs(RigGraph *rg, RigNode *node, RigArc *joined_arc1, RigArc *joined_arc2)
-{
-       RigEdge *edge, *next_edge;
-       
-       /* ignore cases where joint is at start or end */
-       if (joined_arc1->head == joined_arc2->head || joined_arc1->tail == joined_arc2->tail) {
-               return;
-       }
-       
-       /* swap arcs to make sure arc1 is before arc2 */
-       if (joined_arc1->head == joined_arc2->tail) {
-               RigArc *tmp = joined_arc1;
-               joined_arc1 = joined_arc2;
-               joined_arc2 = tmp;
-       }
-       
-       for (edge = joined_arc2->edges.first; edge; edge = next_edge) {
-               next_edge = edge->next;
-               
-               RIG_appendEdgeToArc(joined_arc1, edge);
-       }
-       
-       joined_arc1->tail = joined_arc2->tail;
-       
-       BLI_listbase_clear(&joined_arc2->edges);
-       
-       BLI_removeArc((BGraph *)rg, (BArc *)joined_arc2);
-       
-       BLI_removeNode((BGraph *)rg, (BNode *)node);
-}
-
-static void RIG_removeNormalNodes(RigGraph *rg)
-{
-       RigNode *node, *next_node;
-       
-       for (node = rg->nodes.first; node; node = next_node) {
-               next_node = node->next;
-               
-               if (node->degree == 2) {
-                       RigArc *arc, *joined_arc1 = NULL, *joined_arc2 = NULL;
-                       
-                       for (arc = rg->arcs.first; arc; arc = arc->next) {
-                               if (arc->head == node || arc->tail == node) {
-                                       if (joined_arc1 == NULL) {
-                                               joined_arc1 = arc;
-                                       }
-                                       else {
-                                               joined_arc2 = arc;
-                                               break;
-                                       }
-                               }
-                       }
-                       
-                       RIG_joinArcs(rg, node, joined_arc1, joined_arc2);
-               }
-       }
-}
-
-static void RIG_removeUneededOffsets(RigGraph *rg)
-{
-       RigArc *arc;
-       
-       for (arc = rg->arcs.first; arc; arc = arc->next) {
-               RigEdge *first_edge, *last_edge;
-               
-               first_edge = arc->edges.first;
-               last_edge = arc->edges.last;
-               
-               if (first_edge->bone == NULL) {
-                       if (first_edge->bone == NULL && len_v3v3(first_edge->tail, arc->head->p) <= 0.001f) {
-                               BLI_remlink(&arc->edges, first_edge);
-                               MEM_freeN(first_edge);
-                       }
-                       else if (arc->head->degree == 1) {
-                               RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, first_edge->tail, 0.001f);
-                               
-                               if (new_node) {
-                                       BLI_remlink(&arc->edges, first_edge);
-                                       MEM_freeN(first_edge);
-                                       BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->head);
-                               }
-                               else {
-                                       RigEdge *next_edge = first_edge->next;
-       
-                                       if (next_edge) {
-                                               BLI_remlink(&arc->edges, first_edge);
-                                               MEM_freeN(first_edge);
-                                               
-                                               copy_v3_v3(arc->head->p, next_edge->head);
-                                       }
-                               }
-                       }
-                       else {
-                               /* check if all arc connected start with a null edge */
-                               RigArc *other_arc;
-                               for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) {
-                                       if (other_arc != arc) {
-                                               RigEdge *test_edge;
-                                               if (other_arc->head == arc->head) {
-                                                       test_edge = other_arc->edges.first;
-                                                       
-                                                       if (test_edge->bone != NULL) {
-                                                               break;
-                                                       }
-                                               }
-                                               else if (other_arc->tail == arc->head) {
-                                                       test_edge = other_arc->edges.last;
-                                                       
-                                                       if (test_edge->bone != NULL) {
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               }
-                               
-                               if (other_arc == NULL) {
-                                       RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, first_edge->tail, 0.001);
-                                       
-                                       if (new_node) {
-                                               /* remove null edge in other arcs too */
-                                               for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) {
-                                                       if (other_arc != arc) {
-                                                               RigEdge *test_edge;
-                                                               if (other_arc->head == arc->head) {
-                                                                       BLI_replaceNodeInArc((BGraph *)rg, (BArc *)other_arc, (BNode *)new_node, (BNode *)other_arc->head);
-                                                                       test_edge = other_arc->edges.first;
-                                                                       BLI_remlink(&other_arc->edges, test_edge);
-                                                                       MEM_freeN(test_edge);
-                                                               }
-                                                               else if (other_arc->tail == arc->head) {
-                                                                       BLI_replaceNodeInArc((BGraph *)rg, (BArc *)other_arc, (BNode *)new_node, (BNode *)other_arc->tail);
-                                                                       test_edge = other_arc->edges.last;
-                                                                       BLI_remlink(&other_arc->edges, test_edge);
-                                                                       MEM_freeN(test_edge);
-                                                               }
-                                                       }
-                                               }
-                                               
-                                               BLI_remlink(&arc->edges, first_edge);
-                                               MEM_freeN(first_edge);
-                                               BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->head);
-                                       }
-                                       else {
-                                               RigEdge *next_edge = first_edge->next;
-               
-                                               if (next_edge) {
-                                                       BLI_remlink(&arc->edges, first_edge);
-                                                       MEM_freeN(first_edge);
-                                                       
-                                                       copy_v3_v3(arc->head->p, next_edge->head);
-                                                       
-                                                       /* remove null edge in other arcs too */
-                                                       for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) {
-                                                               if (other_arc != arc) {
-                                                                       RigEdge *test_edge;
-                                                                       if (other_arc->head == arc->head) {
-                                                                               test_edge = other_arc->edges.first;
-                                                                               BLI_remlink(&other_arc->edges, test_edge);
-                                                                               MEM_freeN(test_edge);
-                                                                       }
-                                                                       else if (other_arc->tail == arc->head) {
-                                                                               test_edge = other_arc->edges.last;
-                                                                               BLI_remlink(&other_arc->edges, test_edge);
-                                                                               MEM_freeN(test_edge);
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-               
-               if (last_edge->bone == NULL) {
-                       if (len_v3v3(last_edge->head, arc->tail->p) <= 0.001f) {
-                               BLI_remlink(&arc->edges, last_edge);
-                               MEM_freeN(last_edge);
-                       }
-                       else if (arc->tail->degree == 1) {
-                               RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, last_edge->head, 0.001f);
-                               
-                               if (new_node) {
-                                       RigEdge *previous_edge = last_edge->prev;
-                                       
-                                       BLI_remlink(&arc->edges, last_edge);
-                                       MEM_freeN(last_edge);
-                                       BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->tail);
-                                       
-                                       /* set previous angle to 0, since there's no following edges */
-                                       if (previous_edge) {
-                                               previous_edge->angle = 0;
-                                       }
-                               }
-                               else {
-                                       RigEdge *previous_edge = last_edge->prev;
-       
-                                       if (previous_edge) {
-                                               BLI_remlink(&arc->edges, last_edge);
-                                               MEM_freeN(last_edge);
-                                               
-                                               copy_v3_v3(arc->tail->p, previous_edge->tail);
-                                               previous_edge->angle = 0;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node, bool selected)
-{
-       EditBone *bone, *last_bone = root_bone;
-       RigArc *arc = NULL;
-       int contain_head = 0;
-       
-       for (bone = root_bone; bone; bone = nextEditBoneChild(list, bone, 0)) {
-               int nb_children;
-               
-               if (selected == 0 || (bone->flag & BONE_SELECTED)) {
-                       if ((bone->flag & BONE_NO_DEFORM) == 0) {
-                               BLI_ghash_insert(rg->bones_map, bone->name, bone);
-                       
-                               if (arc == NULL) {
-                                       arc = newRigArc(rg);
-                                       
-                                       if (starting_node == NULL) {
-                                               starting_node = newRigNodeHead(rg, arc, root_bone->head);
-                                       }
-                                       else {
-                                               addRigNodeHead(rg, arc, starting_node);
-                                       }
-                               }
-                               
-                               if (bone->parent && (bone->flag & BONE_CONNECTED) == 0) {
-                                       RIG_addEdgeToArc(arc, bone->head, NULL);
-                               }
-                               
-                               RIG_addEdgeToArc(arc, bone->tail, bone);
-                               
-                               last_bone = bone;
-                               
-                               if (STREQ(bone->name, "head")) {
-                                       contain_head = 1;
-                               }
-                       }
-                       else if ((bone->flag & BONE_EDITMODE_LOCKED) == 0) { /* ignore locked bones */
-                               RIG_addControlBone(rg, bone);
-                       }
-               }
-               
-               nb_children = countEditBoneChildren(list, bone);
-               if (nb_children > 1) {
-                       RigNode *end_node = NULL;
-                       int i;
-                       
-                       if (arc != NULL) {
-                               end_node = newRigNodeTail(rg, arc, bone->tail);
-                       }
-                       else {
-                               end_node = newRigNode(rg, bone->tail);
-                       }
-
-                       for (i = 0; i < nb_children; i++) {
-                               root_bone = nextEditBoneChild(list, bone, i);
-                               RIG_arcFromBoneChain(rg, list, root_bone, end_node, selected);
-                       }
-                       
-                       /* arc ends here, break */
-                       break;
-               }
-       }
-       
-       /* If the loop exited without forking */
-       if (arc != NULL && bone == NULL) {
-               newRigNodeTail(rg, arc, last_bone->tail);
-       }
-
-       if (contain_head) {
-               rg->head = arc->tail;
-       }
-}
-
-/*******************************************************************************************************/
-static void RIG_findHead(RigGraph *rg)
-{
-       if (rg->head == NULL) {
-               if (BLI_listbase_is_single(&rg->arcs)) {
-                       RigArc *arc = rg->arcs.first;
-                       
-                       rg->head = (RigNode *)arc->head;
-               }
-               else {
-                       RigArc *arc;
-                       
-                       for (arc = rg->arcs.first; arc; arc = arc->next) {
-                               RigEdge *edge = arc->edges.last;
-                               
-                               if (edge->bone->flag & (BONE_TIPSEL | BONE_SELECTED)) {
-                                       rg->head = arc->tail;
-                                       break;
-                               }
-                       }
-               }
-               
-               if (rg->head == NULL) {
-                       rg->head = rg->nodes.first;
-               }
-       }
-}
-
-/*******************************************************************************************************/
-
-static void RIG_printNode(RigNode *node, const char name[])
-{
-       printf("%s %p %i <%0.3f, %0.3f, %0.3f>\n", name, (void *)node, node->degree, node->p[0], node->p[1], node->p[2]);
-       
-       if (node->symmetry_flag & SYM_TOPOLOGICAL) {
-               if (node->symmetry_flag & SYM_AXIAL)
-                       printf("Symmetry AXIAL\n");
-               else if (node->symmetry_flag & SYM_RADIAL)
-                       printf("Symmetry RADIAL\n");
-                       
-               print_v3("symmetry axis", node->symmetry_axis);
-       }
-}
-
-void RIG_printArcBones(RigArc *arc)
-{
-       RigEdge *edge;
-
-       for (edge = arc->edges.first; edge; edge = edge->next) {
-               if (edge->bone)
-                       printf("%s ", edge->bone->name);
-               else
-                       printf("---- ");
-       }
-       printf("\n");
-}
-
-static void RIG_printCtrl(RigControl *ctrl, char *indent)
-{
-       char text[128];
-       
-       printf("%sBone: %s\n", indent, ctrl->bone->name);
-       printf("%sLink: %s\n", indent, ctrl->link ? ctrl->link->name : "!NONE!");
-       
-       BLI_snprintf(text, sizeof(text), "%soffset", indent);
-       print_v3(text, ctrl->offset);
-       
-       printf("%sFlag: %i\n", indent, ctrl->flag);
-}
-
-static void RIG_printLinkedCtrl(RigGraph *rg, EditBone *bone, int tabs)
-{
-       RigControl *ctrl;
-       char indent[64];
-       char *s = indent;
-       int i;
-       
-       for (i = 0; i < tabs; i++) {
-               s[0] = '\t';
-               s++;
-       }
-       s[0] = 0;
-       
-       for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
-               if (ctrl->link == bone) {
-                       RIG_printCtrl(ctrl, indent);
-                       RIG_printLinkedCtrl(rg, ctrl->bone, tabs + 1);
-               }
-       }
-}
-
-void RIG_printArc(RigGraph *rg, RigArc *arc)
-{
-       RigEdge *edge;
-
-       RIG_printNode((RigNode *)arc->head, "head");
-
-       for (edge = arc->edges.first; edge; edge = edge->next) {
-               printf("\tinner joints %0.3f %0.3f %0.3f\n", edge->tail[0], edge->tail[1], edge->tail[2]);
-               printf("\t\tlength %f\n", edge->length);
-               printf("\t\tangle %f\n", edge->angle * (float)(180 / M_PI));
-               if (edge->bone) {
-                       printf("\t\t%s\n", edge->bone->name);
-                       RIG_printLinkedCtrl(rg, edge->bone, 3);
-               }
-       }
-       printf("symmetry level: %i flag: %i group %i\n", arc->symmetry_level, arc->symmetry_flag, arc->symmetry_group);
-
-       RIG_printNode((RigNode *)arc->tail, "tail");
-}
-
-void RIG_printGraph(RigGraph *rg)
-{
-       RigArc *arc;
-
-       printf("---- ARCS ----\n");
-       for (arc = rg->arcs.first; arc; arc = arc->next) {
-               RIG_printArc(rg, arc);
-               printf("\n");
-       }
-
-       if (rg->head) {
-               RIG_printNode(rg->head, "HEAD NODE:");
-       }
-       else {
-               printf("HEAD NODE: NONE\n");
-       }
-}
-
-/*******************************************************************************************************/
-
-RigGraph *RIG_graphFromArmature(const bContext *C, Object *ob, bArmature *arm)
-{
-       Object *obedit = CTX_data_edit_object(C);
-       Scene *scene = CTX_data_scene(C);
-       EditBone *ebone;
-       RigGraph *rg;
-
-       rg = newRigGraph();
-       
-       if (obedit == ob) {
-               rg->editbones = ((bArmature *)obedit->data)->edbo;
-       }
-       else {
-               rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
-               make_boneList(rg->editbones, &arm->bonebase, NULL, NULL);
-               rg->flag |= RIG_FREE_BONELIST;
-       }
-       
-       rg->ob = ob;
-
-       /* Do the rotations */
-       for (ebone = rg->editbones->first; ebone; ebone = ebone->next) {
-               if (ebone->parent == NULL) {
-                       RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 0);
-               }
-       }
-       
-       BLI_removeDoubleNodes((BGraph *)rg, 0.001);
-       
-       RIG_removeNormalNodes(rg);
-       
-       RIG_removeUneededOffsets(rg);
-       
-       BLI_buildAdjacencyList((BGraph *)rg);
-       
-       RIG_findHead(rg);
-
-       BLI_markdownSymmetry((BGraph *)rg, (BNode *)rg->head, scene->toolsettings->skgen_symmetry_limit);
-       
-       RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
-       
-       if (BLI_isGraphCyclic((BGraph *)rg)) {
-               printf("armature cyclic\n");
-       }
-       
-       return rg;
-}
-
-static RigGraph *armatureSelectedToGraph(bContext *C, Object *ob, bArmature *arm)
-{
-       Object *obedit = CTX_data_edit_object(C);
-       Scene *scene = CTX_data_scene(C);
-       EditBone *ebone;
-       RigGraph *rg;
-
-       rg = newRigGraph();
-       
-       if (obedit == ob) {
-               rg->editbones = arm->edbo;
-       }
-       else {
-               rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
-               make_boneList(rg->editbones, &arm->bonebase, NULL, NULL);
-               rg->flag |= RIG_FREE_BONELIST;
-       }
-
-       rg->ob = ob;
-
-       /* Do the rotations */
-       for (ebone = rg->editbones->first; ebone; ebone = ebone->next) {
-               if (ebone->parent == NULL) {
-                       RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 1);
-               }
-       }
-       
-       BLI_removeDoubleNodes((BGraph *)rg, 0.001);
-       
-       RIG_removeNormalNodes(rg);
-       
-       RIG_removeUneededOffsets(rg);
-       
-       BLI_buildAdjacencyList((BGraph *)rg);
-       
-       RIG_findHead(rg);
-
-       BLI_markdownSymmetry((BGraph *)rg, (BNode *)rg->head, scene->toolsettings->skgen_symmetry_limit);
-       
-       RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
-       
-       if (BLI_isGraphCyclic((BGraph *)rg)) {
-               printf("armature cyclic\n");
-       }
-       
-       return rg;
-}
-/************************************ GENERATING *****************************************************/
-
-#if 0
-static EditBone *add_editbonetolist(char *name, ListBase *list)
-{
-       EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone");
-       
-       BLI_strncpy(bone->name, name, sizeof(bone->name));
-       ED_armature_ebone_unique_name(list, bone->name, NULL);
-       
-       BLI_addtail(list, bone);
-       
-       bone->flag |= BONE_TIPSEL;
-       bone->weight = 1.0F;
-       bone->dist = 0.25F;
-       bone->xwidth = 0.1;
-       bone->zwidth = 0.1;
-       bone->rad_head = 0.10;
-       bone->rad_tail = 0.05;
-       bone->segments = 1;
-       bone->layer =  1; //arm->layer;
-       
-       /* Bendy-Bone parameters */
-       bone->roll1 = 0.0f;
-       bone->roll2 = 0.0f;
-       bone->curveInX = 0.0f;
-       bone->curveInY = 0.0f;
-       bone->curveOutX = 0.0f;
-       bone->curveOutY = 0.0f;
-       bone->ease1 = 1.0f;
-       bone->ease2 = 1.0f;
-       bone->scaleIn = 1.0f;
-       bone->scaleOut = 1.0f;
-
-       return bone;
-}
-#endif
-
-#if 0 /* UNUSED */
-static void generateMissingArcsFromNode(RigGraph *rigg, ReebNode *node, int multi_level_limit)
-{
-       while (node->multi_level > multi_level_limit && node->link_up)
-       {
-               node = node->link_up;
-       }
-       
-       while (node->multi_level < multi_level_limit && node->link_down)
-       {
-               node = node->link_down;
-       }
-       
-       if (node->multi_level == multi_level_limit)
-       {
-               int i;
-               
-               for (i = 0; i < node->degree; i++)
-               {
-                       ReebArc *earc = node->arcs[i];
-                       
-                       if (earc->flag == ARC_FREE && earc->head == node)
-                       {
-                               ReebNode *other = BIF_otherNodeFromIndex(earc, node);
-                               
-                               earc->flag = ARC_USED;
-                               
-                               //generateBonesForArc(rigg, earc, node, other);
-                               generateMissingArcsFromNode(rigg, other, multi_level_limit);
-                       }
-               }
-       }
-}
-
-static void generateMissingArcs(RigGraph *rigg)
-{
-       ReebGraph *reebg;
-       int multi_level_limit = 5;
-       
-       for (reebg = rigg->link_mesh; reebg; reebg = reebg->link_up)
-       {
-               ReebArc *earc;
-               
-               for (earc = reebg->arcs.first; earc; earc = earc->next)
-               {
-                       if (earc->flag == ARC_USED)
-                       {
-                               generateMissingArcsFromNode(rigg, earc->head, multi_level_limit);
-                               generateMissingArcsFromNode(rigg, earc->tail, multi_level_limit);
-                       }
-               }
-       }
-}
-#endif
-
-/************************************ RETARGETTING *****************************************************/
-
-static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize);
-
-static void repositionTailControl(RigGraph *rigg, RigControl *ctrl);
-
-static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float resize)
-{
-       if ((ctrl->flag & RIG_CTRL_DONE) == RIG_CTRL_DONE) {
-               RigControl *ctrl_child;
-
-#if 0          
-               printf("CTRL: %s LINK: %s", ctrl->bone->name, ctrl->link->name);
-               
-               if (ctrl->link_tail)
-               {
-                       printf(" TAIL: %s", ctrl->link_tail->name);
-               }
-               
-               printf("\n");
-#endif
-               
-               /* if there was a tail link: apply link, recalc resize factor and qrot */
-               if (ctrl->tail_mode != TL_NONE) {
-                       float *tail_vec = NULL;
-                       float v1[3], v2[3], qtail[4];
-                       
-                       if (ctrl->tail_mode == TL_TAIL) {
-                               tail_vec = ctrl->link_tail->tail;
-                       }
-                       else if (ctrl->tail_mode == TL_HEAD) {
-                               tail_vec = ctrl->link_tail->head;
-                       }
-                       
-                       sub_v3_v3v3(v1, ctrl->bone->tail, ctrl->bone->head);
-                       sub_v3_v3v3(v2, tail_vec, ctrl->bone->head);
-                       
-                       copy_v3_v3(ctrl->bone->tail, tail_vec);
-                       
-                       rotation_between_vecs_to_quat(qtail, v1, v2);
-                       mul_qt_qtqt(ctrl->qrot, qtail, ctrl->qrot);
-                       
-                       resize = len_v3(v2) / len_v3v3(ctrl->head, ctrl->tail);
-               }
-               
-               ctrl->bone->roll = rollBoneByQuat(ctrl->bone, ctrl->up_axis, ctrl->qrot);
-       
-               /* Cascade to connected control bones */
-               for (ctrl_child = rigg->controls.first; ctrl_child; ctrl_child = ctrl_child->next) {
-                       if (ctrl_child->link == ctrl->bone) {
-                               repositionControl(rigg, ctrl_child, ctrl->bone->head, ctrl->bone->tail, ctrl->qrot, resize);
-                       }
-                       if (ctrl_child->link_tail == ctrl->bone) {
-                               repositionTailControl(rigg, ctrl_child);
-                       }
-               }
-       }
-}
-
-static void repositionTailControl(RigGraph *rigg, RigControl *ctrl)
-{
-       ctrl->flag |= RIG_CTRL_TAIL_DONE;
-
-       finalizeControl(rigg, ctrl, 1); /* resize will be recalculated anyway so we don't need it */
-}
-
-static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float UNUSED(tail[3]), float qrot[4], float resize)
-{
-       float parent_offset[3], tail_offset[3];
-       
-       copy_v3_v3(parent_offset, ctrl->offset);
-       mul_v3_fl(parent_offset, resize);
-       mul_qt_v3(qrot, parent_offset);
-       
-       add_v3_v3v3(ctrl->bone->head, head, parent_offset); 
-
-       ctrl->flag |= RIG_CTRL_HEAD_DONE;
-
-       copy_qt_qt(ctrl->qrot, qrot);
-
-       if (ctrl->tail_mode == TL_NONE) {
-               sub_v3_v3v3(tail_offset, ctrl->tail, ctrl->head);
-               mul_v3_fl(tail_offset, resize);
-               mul_qt_v3(qrot, tail_offset);
-
-               add_v3_v3v3(ctrl->bone->tail, ctrl->bone->head, tail_offset);
-               
-               ctrl->flag |= RIG_CTRL_TAIL_DONE;
-       }
-
-       finalizeControl(rigg, ctrl, resize);
-}
-
-static void repositionBone(bContext *C, RigGraph *rigg, RigEdge *edge, float vec0[3], float vec1[3], float up_axis[3])
-{
-       Scene *scene = CTX_data_scene(C);
-       EditBone *bone;
-       RigControl *ctrl;
-       float qrot[4], resize;
-       float v1[3], v2[3];
-       float l1, l2;
-       
-       bone = edge->bone;
-       
-       sub_v3_v3v3(v1, edge->tail, edge->head);
-       sub_v3_v3v3(v2, vec1, vec0);
-       
-       l1 = normalize_v3(v1);
-       l2 = normalize_v3(v2);
-
-       resize = l2 / l1;
-       
-       rotation_between_vecs_to_quat(qrot, v1, v2);
-       
-       copy_v3_v3(bone->head, vec0);
-       copy_v3_v3(bone->tail, vec1);
-       
-       if (!is_zero_v3(up_axis)) {
-               float qroll[4];
-
-               if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_VIEW) {
-                       bone->roll = rollBoneByQuatAligned(bone, edge->up_axis, qrot, qroll, up_axis);
-               }
-               else if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_JOINT) {
-                       bone->roll = rollBoneByQuatJoint(edge, edge->prev, qrot, qroll, up_axis);
-               }
-               else {
-                       unit_qt(qroll);
-               }
-               
-               mul_qt_qtqt(qrot, qroll, qrot);
-       }
-       else {
-               bone->roll = rollBoneByQuat(bone, edge->up_axis, qrot);
-       }
-
-       for (ctrl = rigg->controls.first; ctrl; ctrl = ctrl->next) {
-               if (ctrl->link == bone) {
-                       repositionControl(rigg, ctrl, vec0, vec1, qrot, resize);
-               }
-               if (ctrl->link_tail == bone) {
-                       repositionTailControl(rigg, ctrl);
-               }
-       }
-}
-
-static RetargetMode detectArcRetargetMode(RigArc *arc);
-static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start);
-
-
-static RetargetMode detectArcRetargetMode(RigArc *iarc)
-{
-       RetargetMode mode = RETARGET_AGGRESSIVE;
-       ReebArc *earc = iarc->link_mesh;
-       RigEdge *edge;
-       int large_angle = 0;
-       float avg_angle = 0;
-       /* float avg_length = 0; */ /* UNUSED */
-       int nb_edges = 0;
-       
-       
-       for (edge = iarc->edges.first; edge; edge = edge->next) {
-               avg_angle += edge->angle;
-               nb_edges++;
-       }
-       
-       avg_angle /= nb_edges - 1; /* -1 because last edge doesn't have an angle */
-
-       /* avg_length = iarc->length / nb_edges; */  /* UNUSED */
-       
-       
-       if (nb_edges > 2) {
-               for (edge = iarc->edges.first; edge; edge = edge->next) {
-                       if (fabsf(edge->angle - avg_angle) > (float)(M_PI / 6)) {
-                               large_angle = 1;
-                       }
-               }
-       }
-       else if (nb_edges == 2 && avg_angle > 0) {
-               large_angle = 1;
-       }
-               
-       
-       if (large_angle == 0) {
-               mode = RETARGET_LENGTH;
-       }
-       
-       if (earc->bcount <= (iarc->count - 1)) {
-               mode = RETARGET_LENGTH;
-       }
-       
-       return mode;
-}
-
-#ifndef USE_THREADS
-static void printMovesNeeded(int *positions, int nb_positions)
-{
-       int moves = 0;
-       int i;
-       
-       for (i = 0; i < nb_positions; i++) {
-               moves += positions[i] - (i + 1);
-       }
-       
-       printf("%i moves needed\n", moves);
-}
-
-static void printPositions(int *positions, int nb_positions)
-{
-       int i;
-       
-       for (i = 0; i < nb_positions; i++) {
-               printf("%i ", positions[i]);
-       }
-       printf("\n");
-}
-#endif
-
-#define MAX_COST FLT_MAX /* FIX ME */
-
-static float costDistance(BArcIterator *iter, float *vec0, float *vec1, int i0, int i1, float distance_weight)
-{
-       EmbedBucket *bucket = NULL;
-       float max_dist = 0;
-       float v1[3], v2[3], c[3];
-       float v1_inpf;
-
-       if (distance_weight > 0) {
-               sub_v3_v3v3(v1, vec0, vec1);
-               
-               v1_inpf = dot_v3v3(v1, v1);
-               
-               if (v1_inpf > 0) {
-                       int j;
-                       for (j = i0 + 1; j < i1 - 1; j++) {
-                               float dist;
-                               
-                               bucket = IT_peek(iter, j);
-       
-                               sub_v3_v3v3(v2, bucket->p, vec1);
-               
-                               cross_v3_v3v3(c, v1, v2);
-                               
-                               dist = dot_v3v3(c, c) / v1_inpf;
-                               
-                               max_dist = dist > max_dist ? dist : max_dist;
-                       }
-                       
-                       return distance_weight * max_dist;
-               }
-               else {
-                       return MAX_COST;
-               }
-       }
-       else {
-               return 0;
-       }
-}
-
-static float costAngle(float original_angle, float vec_first[3], float vec_second[3], float angle_weight)
-{
-       if (angle_weight > 0) {
-               float current_angle;
-               
-               if (!is_zero_v3(vec_first) && !is_zero_v3(vec_second)) {
-                       current_angle = saacos(dot_v3v3(vec_first, vec_second));
-
-                       return angle_weight * fabsf(current_angle - original_angle);
-               }
-               else {
-                       return angle_weight * (float)M_PI;
-               }
-       }
-       else {
-               return 0;
-       }
-}
-
-static float costLength(float original_length, float current_length, float length_weight)
-{
-       if (current_length == 0) {
-               return MAX_COST;
-       }
-       else {
-               float length_ratio = fabsf((current_length - original_length) / original_length);
-               return length_weight * length_ratio * length_ratio;
-       }
-}
-
-#if 0
-static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec1, float *vec2, int i1, int i2)
-{
-       float vec[3];
-       float length;
-
-       sub_v3_v3v3(vec, vec2, vec1);
-       length = normalize_v3(vec);
-
-       return costLength(edge->length, length) + costDistance(iter, vec1, vec2, i1, i2);
-}
-#endif
-
-static float calcCostAngleLengthDistance(BArcIterator *iter, float **UNUSED(vec_cache), RigEdge *edge,
-                                         float *vec0, float *vec1, float *vec2, int i1, int i2,
-                                         float angle_weight, float length_weight, float distance_weight)
-{
-       float vec_second[3], vec_first[3];
-       float length2;
-       float new_cost = 0;
-
-       sub_v3_v3v3(vec_second, vec2, vec1);
-       length2 = normalize_v3(vec_second);
-
-
-       /* Angle cost */
-       if (edge->prev) {
-               sub_v3_v3v3(vec_first, vec1, vec0); 
-               normalize_v3(vec_first);
-               
-               new_cost += costAngle(edge->prev->angle, vec_first, vec_second, angle_weight);
-       }
-
-       /* Length cost */
-       new_cost += costLength(edge->length, length2, length_weight);
-
-       /* Distance cost */
-       new_cost += costDistance(iter, vec1, vec2, i1, i2, distance_weight);
-
-       return new_cost;
-}
-
-static int indexMemoNode(int nb_positions, int previous, int current, int joints_left)
-{
-       return joints_left * nb_positions * nb_positions + current * nb_positions + previous;
-}
-
-static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions, int joints_left)
-{
-       int previous = 0, current = 0;
-       int i = 0;
-       
-       for (i = 0; joints_left > 0; joints_left--, i++) {
-               MemoNode *node;
-               node = table + indexMemoNode(nb_positions, previous, current, joints_left);
-               
-               positions[i] = node->next;
-               
-               previous = current;
-               current = node->next;
-       }
-}
-
-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, float angle_weight, float length_weight, float distance_weight)
-{
-       MemoNode *node;
-       int index = indexMemoNode(nb_positions, previous, current, joints_left);
-       
-       node = table + index;
-       
-       if (node->weight != 0) {
-               return node;
-       }
-       else if (joints_left == 0) {
-               float *vec0 = vec_cache[previous];
-               float *vec1 = vec_cache[current];
-               float *vec2 = vec_cache[nb_positions + 1];
-
-               node->weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, iter->length, angle_weight, length_weight, distance_weight);
-
-               return node;
-       }
-       else {
-               MemoNode *min_node = NULL;
-               float *vec0 = vec_cache[previous];
-               float *vec1 = vec_cache[current];
-               float min_weight = 0.0f;
-               int min_next = 0;
-               int next;
-               
-               for (next = current + 1; next <= nb_positions - (joints_left - 1); next++) {
-                       MemoNode *next_node;
-                       float *vec2 = vec_cache[next];
-                       float weight = 0.0f;
-                       
-                       /* ADD WEIGHT OF PREVIOUS - CURRENT - NEXT triple */
-                       weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, next, angle_weight, length_weight, distance_weight);
-                       
-                       if (weight >= MAX_COST) {
-                               continue;
-                       }
-                       
-                       /* add node weight */
-                       next_node = solveJoints(table, iter, vec_cache, nb_joints, nb_positions, current, next, edge->next, joints_left - 1, angle_weight, length_weight, distance_weight);
-                       weight += next_node->weight;
-                       
-                       if (min_node == NULL || weight < min_weight) {
-                               min_weight = weight;
-                               min_node = next_node;
-                               min_next = next;
-                       }
-               }
-               
-               if (min_node) {
-                       node->weight = min_weight;
-                       node->next = min_next;
-                       return node;
-               }
-               else {
-                       node->weight = MAX_COST;
-                       return node;
-               }
-       }
-       
-}
-
-static int testFlipArc(RigArc *iarc, RigNode *inode_start)
-{
-       ReebArc *earc = iarc->link_mesh;
-       ReebNode *enode_start = BIF_NodeFromIndex(earc, inode_start->link_mesh);
-       
-       /* no flip needed if both nodes are the same */
-       if ((enode_start == earc->head && inode_start == iarc->head) ||
-           (enode_start == earc->tail && inode_start == iarc->tail))
-       {
-               return 0;
-       }
-       else {
-               return 1;
-       }
-}
-
-static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
-{
-       ReebArcIterator arc_iter;
-       BArcIterator *iter = (BArcIterator *)&arc_iter;
-       RigEdge *edge;
-       ReebNode *node_start, *node_end;
-       ReebArc *earc = iarc->link_mesh;
-       float angle_weight = 1.0; // GET FROM CONTEXT
-       float length_weight = 1.0;
-       float distance_weight = 1.0;
-#ifndef USE_THREADS
-       float min_cost = FLT_MAX;
-#endif
-       float *vec0, *vec1;
-       int *best_positions;
-       int nb_edges = BLI_listbase_count(&iarc->edges);
-       int nb_joints = nb_edges - 1;
-       RetargetMethod method = METHOD_MEMOIZE;
-       int i;
-       
-       if (nb_joints > earc->bcount) {
-               printf("NOT ENOUGH BUCKETS!\n");
-               return;
-       }
-
-       best_positions = MEM_callocN(sizeof(int) * nb_joints, "Best positions");
-       
-       if (testFlipArc(iarc, inode_start)) {
-               node_start = earc->tail;
-               node_end = earc->head;
-       }
-       else {
-               node_start = earc->head;
-               node_end = earc->tail;
-       }
-
-       /* equal number of joints and potential position, just fill them in */
-       if (nb_joints == earc->bcount) {
-               /* init with first values */
-               for (i = 0; i < nb_joints; i++) {
-                       best_positions[i] = i + 1;
-               }
-       }
-       if (method == METHOD_MEMOIZE) {
-               int nb_positions = earc->bcount;
-               int nb_memo_nodes = nb_positions * nb_positions * (nb_joints + 1);
-               MemoNode *table = MEM_callocN(nb_memo_nodes * sizeof(MemoNode), "memoization table");
-#ifndef USE_THREADS
-               MemoNode *result;
-#endif
-               float **positions_cache = MEM_callocN(sizeof(float *) * (nb_positions + 2), "positions cache");
-               
-               positions_cache[0] = node_start->p;
-               positions_cache[nb_positions + 1] = node_end->p;
-               
-               initArcIterator(iter, earc, node_start);
-
-               for (i = 1; i <= nb_positions; i++) {
-                       EmbedBucket *bucket = IT_peek(iter, i);
-                       positions_cache[i] = bucket->p;
-               }
-
-#ifndef USE_THREADS
-               result = solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight);
-               min_cost = result->weight;
-#else
-               solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight);
-#endif
-
-               copyMemoPositions(best_positions, table, earc->bcount, nb_joints);
-
-               MEM_freeN(table);
-               MEM_freeN(positions_cache);
-       }
-
-       vec0 = node_start->p;
-       initArcIterator(iter, earc, node_start);
-       
-#ifndef USE_THREADS
-       printPositions(best_positions, nb_joints);
-       printMovesNeeded(best_positions, nb_joints);
-       printf("min_cost %f\n", min_cost);
-       printf("buckets: %i\n", earc->bcount);
-#endif
-
-       /* set joints to best position */
-       for (edge = iarc->edges.first, i = 0;
-            edge;
-            edge = edge->next, i++)
-       {
-               float *no = NULL;
-               if (i < nb_joints) {
-                       EmbedBucket *bucket = IT_peek(iter, best_positions[i]);
-                       vec1 = bucket->p;
-                       no = bucket->no;
-               }
-               else {
-                       vec1 = node_end->p;
-                       no = node_end->no;
-               }
-               
-               if (edge->bone) {
-                       repositionBone(C, rigg, edge, vec0, vec1, no);
-               }
-               
-               vec0 = vec1;
-       }
-
-       MEM_freeN(best_positions);
-}
-
-static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
-{
-       ReebArcIterator arc_iter;
-       BArcIterator *iter = (BArcIterator *)&arc_iter;
-       ReebArc *earc = iarc->link_mesh;
-       ReebNode *node_start, *node_end;
-       RigEdge *edge;
-       EmbedBucket *bucket = NULL;
-       float embedding_length = 0;
-       float *vec0 = NULL;
-       float *vec1 = NULL;
-       float *previous_vec = NULL;
-
-       
-       if (testFlipArc(iarc, inode_start)) {
-               node_start = (ReebNode *)earc->tail;
-               node_end = (ReebNode *)earc->head;
-       }
-       else {
-               node_start = (ReebNode *)earc->head;
-               node_end = (ReebNode *)earc->tail;
-       }
-       
-       initArcIterator(iter, earc, node_start);
-
-       bucket = IT_next(iter);
-       
-       vec0 = node_start->p;
-       
-       while (bucket != NULL) {
-               vec1 = bucket->p;
-               
-               embedding_length += len_v3v3(vec0, vec1);
-               
-               vec0 = vec1;
-               bucket = IT_next(iter);
-       }
-       
-       embedding_length += len_v3v3(node_end->p, vec1);
-       
-       /* fit bones */
-       initArcIterator(iter, earc, node_start);
-
-       bucket = IT_next(iter);
-
-       vec0 = node_start->p;
-       previous_vec = vec0;
-       vec1 = bucket->p;
-       
-       for (edge = iarc->edges.first; edge; edge = edge->next) {
-               float new_bone_length = edge->length / iarc->length * embedding_length;
-               float *no = NULL;
-               float length = 0;
-
-               while (bucket && new_bone_length > length) {
-                       length += len_v3v3(previous_vec, vec1);
-                       bucket = IT_next(iter);
-                       previous_vec = vec1;
-                       vec1 = bucket->p;
-                       no = bucket->no;
-               }
-               
-               if (bucket == NULL) {
-                       vec1 = node_end->p;
-                       no = node_end->no;
-               }
-
-               /* no need to move virtual edges (space between unconnected bones) */
-               if (edge->bone) {
-                       repositionBone(C, rigg, edge, vec0, vec1, no);
-               }
-               
-               vec0 = vec1;
-               previous_vec = vec1;
-       }
-}
-
-static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
-{
-       RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam");
-       
-       p->rigg = rigg;
-       p->iarc = iarc;
-       p->inode_start = inode_start;
-       p->context = C;
-       
-       BLI_task_pool_push(rigg->task_pool, exec_retargetArctoArc, p, true, TASK_PRIORITY_HIGH);
-}
-
-void exec_retargetArctoArc(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid))
-{
-       RetargetParam *p = (RetargetParam *)taskdata;
-       RigGraph *rigg = p->rigg;
-       RigArc *iarc = p->iarc;
-       bContext *C = p->context;
-       RigNode *inode_start = p->inode_start;
-       ReebArc *earc = iarc->link_mesh;
-       
-       if (BLI_listbase_is_single(&iarc->edges)) {
-               RigEdge *edge = iarc->edges.first;
-
-               if (testFlipArc(iarc, inode_start)) {
-                       repositionBone(C, rigg, edge, earc->tail->p, earc->head->p, earc->head->no);
-               }
-               else {
-                       repositionBone(C, rigg, edge, earc->head->p, earc->tail->p, earc->tail->no);
-               }
-       }
-       else {
-               RetargetMode mode = detectArcRetargetMode(iarc);
-               
-               if (mode == RETARGET_AGGRESSIVE) {
-                       retargetArctoArcAggresive(C, rigg, iarc, inode_start);
-               }
-               else {
-                       retargetArctoArcLength(C, rigg, iarc, inode_start);
-               }
-       }
-}
-
-static void matchMultiResolutionNode(RigGraph *rigg, RigNode *inode, ReebNode *top_node)
-{
-       ReebNode *enode = top_node;
-       ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode);
-       int ishape, eshape;
-       
-       ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)inode, NULL, 0) % SHAPE_LEVELS;
-       eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS;
-       
-       inode->link_mesh = enode;
-
-       while (ishape == eshape && enode->link_down) {
-               inode->link_mesh = enode;
-
-               enode = enode->link_down;
-               reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); /* replace with call to link_down once that exists */
-               eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS;
-       }
-}
-
-static void markMultiResolutionChildArc(ReebNode *end_enode, ReebNode *enode)
-{
-       int i;
-       
-       for (i = 0; i < enode->degree; i++) {
-               ReebArc *earc = (ReebArc *)enode->arcs[i];
-               
-               if (earc->flag == ARC_FREE) {
-                       earc->flag = ARC_TAKEN;
-                       
-                       if (earc->tail->degree > 1 && earc->tail != end_enode) {
-                               markMultiResolutionChildArc(end_enode, earc->tail);
-                       }
-                       break;
-               }
-       }
-}
-
-static void markMultiResolutionArc(ReebArc *start_earc)
-{
-       if (start_earc->link_up) {
-               ReebArc *earc;
-               for (earc = start_earc->link_up; earc; earc = earc->link_up) {
-                       earc->flag = ARC_TAKEN;
-                       
-                       if (earc->tail->index != start_earc->tail->index) {
-                               markMultiResolutionChildArc(earc->tail, earc->tail);
-                       }
-               }
-       }
-}
-
-static void matchMultiResolutionArc(RigGraph *rigg, RigNode *start_node, RigArc *next_iarc, ReebArc *next_earc)
-{
-       ReebNode *enode = next_earc->head;
-       ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode);
-       int ishape, eshape;
-
-       ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)start_node, (BArc *)next_iarc, 1) % SHAPE_LEVELS;
-       eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, (BArc *)next_earc, 1) % SHAPE_LEVELS;
-       
-       while (ishape != eshape && next_earc->link_up) {
-               next_earc->flag = ARC_TAKEN; // mark previous as taken, to prevent backtrack on lower levels
-               
-               next_earc = next_earc->link_up;
-               reebg = reebg->link_up;
-               enode = next_earc->head;
-               eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, (BArc *)next_earc, 1) % SHAPE_LEVELS;
-       }
-
-       next_earc->flag = ARC_USED;
-       next_iarc->link_mesh = next_earc;
-       
-       /* mark all higher levels as taken too */
-       markMultiResolutionArc(next_earc);
-//     while (next_earc->link_up)
-//     {
-//             next_earc = next_earc->link_up;
-//             next_earc->flag = ARC_TAKEN;
-//     }
-}
-
-static void matchMultiResolutionStartingNode(RigGraph *rigg, ReebGraph *reebg, RigNode *inode)
-{
-       ReebNode *enode;
-       int ishape, eshape;
-       
-       enode = reebg->nodes.first;
-       
-       ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)inode, NULL, 0) % SHAPE_LEVELS;
-       eshape = BLI_subtreeShape((BGraph *)rigg->link_mesh, (BNode *)enode, NULL, 0) % SHAPE_LEVELS;
-       
-       while (ishape != eshape && reebg->link_up) {
-               reebg = reebg->link_up;
-               
-               enode = reebg->nodes.first;
-               
-               eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS;
-       }
-
-       inode->link_mesh = enode;
-}
-
-static void findCorrespondingArc(RigGraph *rigg, RigArc *start_arc, RigNode *start_node, RigArc *next_iarc, int root)
-{
-       ReebNode *enode = start_node->link_mesh;
-       ReebArc *next_earc;
-       int symmetry_level = next_iarc->symmetry_level;
-       int symmetry_group = next_iarc->symmetry_group;
-       int symmetry_flag = next_iarc->symmetry_flag;
-       int i;
-       
-       next_iarc->link_mesh = NULL;
-               
-//     if (root)
-//     {
-//             printf("-----------------------\n");
-//             printf("MATCHING LIMB\n");
-//             RIG_printArcBones(next_iarc);
-//     }
-       
-       for (i = 0; i < enode->degree; i++) {
-               next_earc = (ReebArc *)enode->arcs[i];
-               
-//             if (next_earc->flag == ARC_FREE)
-//             {
-//                     printf("candidate (level %i ?= %i) (flag %i ?= %i) (group %i ?= %i)\n",
-//                     symmetry_level, next_earc->symmetry_level,
-//                     symmetry_flag, next_earc->symmetry_flag, 
-//                     symmetry_group, next_earc->symmetry_flag);
-//             }
-               
-               if (next_earc->flag == ARC_FREE &&
-                   next_earc->symmetry_flag == symmetry_flag &&
-                   next_earc->symmetry_group == symmetry_group &&
-                   next_earc->symmetry_level == symmetry_level)
-               {
-//                     printf("CORRESPONDING ARC FOUND\n");
-//                     printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
-                       
-                       matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc);
-                       break;
-               }
-       }
-       
-       /* not found, try at higher nodes (lower node might have filtered internal arcs, messing shape of tree */
-       if (next_iarc->link_mesh == NULL) {
-//             printf("NO CORRESPONDING ARC FOUND - GOING TO HIGHER LEVELS\n");
-               
-               if (enode->link_up) {
-                       start_node->link_mesh = enode->link_up;
-                       findCorrespondingArc(rigg, start_arc, start_node, next_iarc, 0);
-               }
-       }
-
-       /* still not found, print debug info */
-       if (root && next_iarc->link_mesh == NULL) {
-               start_node->link_mesh = enode; /* linking back with root node */
-               
-//             printf("NO CORRESPONDING ARC FOUND\n");
-//             RIG_printArcBones(next_iarc);
-//             
-//             printf("ON NODE %i, multilevel %i\n", enode->index, enode->multi_level);
-//             
-//             printf("LOOKING FOR\n");
-//             printf("flag %i -- level %i -- flag %i -- group %i\n", ARC_FREE, symmetry_level, symmetry_flag, symmetry_group);
-//             
-//             printf("CANDIDATES\n");
-//             for (i = 0; i < enode->degree; i++)
-//             {
-//                     next_earc = (ReebArc *)enode->arcs[i];
-//                     printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
-//             }
-               
-               /* Emergency matching */
-               for (i = 0; i < enode->degree; i++) {
-                       next_earc = (ReebArc *)enode->arcs[i];
-                       
-                       if (next_earc->flag == ARC_FREE && next_earc->symmetry_level == symmetry_level) {
-//                             printf("USING:\n");
-//                             printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
-                               matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc);
-                               break;
-                       }
-               }
-       }
-
-}
-
-static void retargetSubgraph(bContext *C, RigGraph *rigg, RigArc *start_arc, RigNode *start_node)
-{
-       RigNode *inode = start_node;
-       int i;
-
-       /* no start arc on first node */
-       if (start_arc) {
-               ReebNode *enode = start_node->link_mesh;
-               ReebArc *earc = start_arc->link_mesh;
-               
-               retargetArctoArc(C, rigg, start_arc, start_node);
-               
-               enode = BIF_otherNodeFromIndex(earc, enode);
-               inode = (RigNode *)BLI_otherNode((BArc *)start_arc, (BNode *)inode);
-       
-               /* match with lowest node with correct shape */
-               matchMultiResolutionNode(rigg, inode, enode);
-       }
-       
-       for (i = 0; i < inode->degree; i++) {
-               RigArc *next_iarc = (RigArc *)inode->arcs[i];
-               
-               /* no back tracking */
-               if (next_iarc != start_arc) {
-                       findCorrespondingArc(rigg, start_arc, inode, next_iarc, 1);
-                       if (next_iarc->link_mesh) {
-                               retargetSubgraph(C, rigg, next_iarc, inode);
-                       }
-               }
-       }
-}
-
-static void finishRetarget(RigGraph *rigg)
-{
-       BLI_task_pool_work_and_wait(rigg->task_pool);
-}
-
-static void adjustGraphs(bContext *C, RigGraph *rigg)
-{
-       bArmature *arm = rigg->ob->data;
-       RigArc *arc;
-       
-       for (arc = rigg->arcs.first; arc; arc = arc->next) {
-               if (arc->link_mesh) {
-                       retargetArctoArc(C, rigg, arc, arc->head);
-               }
-       }
-
-       finishRetarget(rigg);
-
-       /* Turn the list into an armature */
-       arm->edbo = rigg->editbones;
-       ED_armature_from_edit(arm);
-       
-       ED_undo_push(C, "Retarget Skeleton");
-}
-
-static void retargetGraphs(bContext *C, RigGraph *rigg)
-{
-       bArmature *arm = rigg->ob->data;
-       ReebGraph *reebg = rigg->link_mesh;
-       RigNode *inode;
-       
-       /* flag all ReebArcs as free */
-       BIF_flagMultiArcs(reebg, ARC_FREE);
-       
-       /* return to first level */
-       inode = rigg->head;
-       
-       matchMultiResolutionStartingNode(rigg, reebg, inode);
-
-       retargetSubgraph(C, rigg, NULL, inode);
-       
-       //generateMissingArcs(rigg);
-       
-       finishRetarget(rigg);
-
-       /* Turn the list into an armature */
-       arm->edbo = rigg->editbones;
-       ED_armature_from_edit(arm);
-}
-
-const char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index)
-{
-       RigArc *arc = BLI_findlink(&rg->arcs, arc_index);
-       RigEdge *iedge;
-
-       if (arc == NULL) {
-               return "None";
-       }
-       
-       if (bone_index == BLI_listbase_count(&arc->edges)) {
-               return "Last joint";
-       }
-
-       iedge = BLI_findlink(&arc->edges, bone_index);
-       
-       if (iedge == NULL) {
-               return "Done";
-       }
-       
-       if (iedge->bone == NULL) {
-               return "Bone offset";
-       }
-       
-       return iedge->bone->name;
-}
-
-int RIG_nbJoints(RigGraph *rg)
-{
-       RigArc *arc;
-       int total = 0;
-       
-       total += BLI_listbase_count(&rg->nodes);
-       
-       for (arc = rg->arcs.first; arc; arc = arc->next) {
-               total += BLI_listbase_count(&arc->edges) - 1; /* -1 because end nodes are already counted */
-       }
-       
-       return total;
-}
-
-static void BIF_freeRetarget(void)
-{
-       if (GLOBAL_RIGG) {
-               RIG_freeRigGraph((BGraph *)GLOBAL_RIGG);
-               GLOBAL_RIGG = NULL;
-       }
-}
-
-void BIF_retargetArmature(bContext *C)
-{
-       ReebGraph *reebg;
-       double start_time, end_time;
-       double gstart_time, gend_time;
-       double reeb_time, rig_time = 0.0, retarget_time = 0.0, total_time;
-       
-       gstart_time = start_time = PIL_check_seconds_timer();
-       
-       reebg = BIF_ReebGraphMultiFromEditMesh(C);
-       
-       end_time = PIL_check_seconds_timer();
-       reeb_time = end_time - start_time;
-       
-       printf("Reeb Graph created\n");
-
-       CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
-       {
-               Object *ob = base->object;
-
-               if (ob->type == OB_ARMATURE) {
-                       RigGraph *rigg;
-                       bArmature *arm;
-
-                       arm = ob->data;
-               
-                       /* Put the armature into editmode */
-                       
-               
-                       start_time = PIL_check_seconds_timer();
-
-                       rigg = RIG_graphFromArmature(C, ob, arm);
-                       
-                       end_time = PIL_check_seconds_timer();
-                       rig_time = end_time - start_time;
-
-                       printf("Armature graph created\n");
-       
-                       //RIG_printGraph(rigg);
-                       
-                       rigg->link_mesh = reebg;
-                       
-                       printf("retargetting %s\n", ob->id.name);
-                       
-                       start_time = PIL_check_seconds_timer();
-
-                       retargetGraphs(C, rigg);
-                       
-                       end_time = PIL_check_seconds_timer();
-                       retarget_time = end_time - start_time;
-
-                       BIF_freeRetarget();
-                       
-                       GLOBAL_RIGG = rigg;
-                       
-                       break; /* only one armature at a time */
-               }
-       }
-       CTX_DATA_END;
-
-       
-       gend_time = PIL_check_seconds_timer();
-
-       total_time = gend_time - gstart_time;
-
-       printf("-----------\n");
-       printf("runtime: \t%.3f\n", total_time);
-       printf("reeb: \t\t%.3f (%.1f%%)\n", reeb_time, reeb_time / total_time * 100);
-       printf("rig: \t\t%.3f (%.1f%%)\n", rig_time, rig_time / total_time * 100);
-       printf("retarget: \t%.3f (%.1f%%)\n", retarget_time, retarget_time / total_time * 100);
-       printf("-----------\n");
-       
-       ED_undo_push(C, "Retarget Skeleton");
-
-       // XXX
-//     allqueue(REDRAWVIEW3D, 0);
-}
-
-void BIF_retargetArc(bContext *C, ReebArc *earc, RigGraph *template_rigg)
-{
-       Object *obedit = CTX_data_edit_object(C);
-       Scene *scene = CTX_data_scene(C);
-       bArmature *armedit = obedit->data;
-       Object *ob;
-       RigGraph *rigg;
-       RigArc *iarc;
-       char *side_string = scene->toolsettings->skgen_side_string;
-       char *num_string = scene->toolsettings->skgen_num_string;
-       int free_template = 0;
-       
-       if (template_rigg) {
-               ob = template_rigg->ob;
-       }
-       else {
-               free_template = 1;
-               ob = obedit;
-               template_rigg = armatureSelectedToGraph(C, ob, ob->data);
-       }
-       
-       if (BLI_listbase_is_empty(&template_rigg->arcs)) {
-//             XXX
-//             error("No Template and no deforming bones selected");
-               return;
-       }
-       
-       rigg = cloneRigGraph(template_rigg, armedit->edbo, obedit, side_string, num_string);
-       
-       iarc = rigg->arcs.first;
-       
-       iarc->link_mesh = earc;
-       iarc->head->link_mesh = earc->head;
-       iarc->tail->link_mesh = earc->tail;
-       
-       retargetArctoArc(C, rigg, iarc, iarc->head);
-       
-       finishRetarget(rigg);
-       
-       /* free template if it comes from the edit armature */
-       if (free_template) {
-               RIG_freeRigGraph((BGraph *)template_rigg);
-       }
-       RIG_freeRigGraph((BGraph *)rigg);
-       
-       ED_armature_edit_validate_active(armedit);
-
-//     XXX
-//     allqueue(REDRAWVIEW3D, 0);
-}
-
-void BIF_adjustRetarget(bContext *C)
-{
-       if (GLOBAL_RIGG) {
-               adjustGraphs(C, GLOBAL_RIGG);
-       }
-}
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
deleted file mode 100644 (file)
index 753d400..0000000
+++ /dev/null
@@ -1,2651 +0,0 @@
-/*
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/armature/editarmature_sketch.c
- *  \ingroup edarmature
- */
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_armature_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
-#include "BKE_context.h"
-#include "BKE_sketch.h"
-#include "BKE_layer.h"
-
-#include "RNA_define.h"
-#include "RNA_access.h"
-
-#include "ED_view3d.h"
-#include "ED_screen.h"
-
-#include "BIF_gl.h"
-#include "ED_armature.h"
-#include "armature_intern.h"
-#include "BIF_retarget.h"
-#include "BIF_generate.h"
-
-#include "ED_transform.h"
-#include "ED_transform_snap_object_context.h"
-
-#include "DEG_depsgraph.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "GPU_select.h"
-#include "GPU_matrix.h"
-#include "GPU_batch.h"
-#include "GPU_immediate.h"
-#include "GPU_immediate_util.h"
-
-typedef int (*GestureDetectFct)(bContext *, SK_Gesture *, SK_Sketch *);
-typedef void (*GestureApplyFct)(bContext *, SK_Gesture *, SK_Sketch *);
-
-typedef struct SK_GestureAction {
-       char name[64];
-       GestureDetectFct detect;
-       GestureApplyFct apply;
-} SK_GestureAction;
-
-#if 0 /* UNUSED 2.5 */
-static SK_Point boneSnap;
-#endif
-
-static int LAST_SNAP_POINT_VALID = 0;
-static float LAST_SNAP_POINT[3];
-
-
-typedef struct SK_StrokeIterator {
-       HeadFct     head;
-       TailFct     tail;
-       PeekFct     peek;
-       NextFct     next;
-       NextNFct    nextN;
-       PreviousFct previous;
-       StoppedFct  stopped;
-
-       float *p, *no;
-       float size;
-
-       int length;
-       int index;
-       /*********************************/
-       SK_Stroke *stroke;
-       int start;
-       int end;
-       int stride;
-} SK_StrokeIterator;
-
-/******************** PROTOTYPES ******************************/
-
-void initStrokeIterator(BArcIterator *iter, SK_Stroke *stk, int start, int end);
-
-int sk_detectCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-void sk_applyCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-void sk_applyTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-int sk_detectCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-void sk_applyCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-void sk_applyDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-void sk_applyMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-void sk_applyReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-int sk_detectConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-void sk_applyConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
-
-SK_Sketch *contextSketch(const bContext *c, int create);
-SK_Sketch *viewcontextSketch(ViewContext *vc, int create);
-
-void sk_resetOverdraw(SK_Sketch *sketch);
-int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk);
-
-/******************** GESTURE ACTIONS ******************************/
-
-static SK_GestureAction GESTURE_ACTIONS[] = {
-       {"Cut", sk_detectCutGesture, sk_applyCutGesture},
-       {"Trim", sk_detectTrimGesture, sk_applyTrimGesture},
-       {"Command", sk_detectCommandGesture, sk_applyCommandGesture},
-       {"Delete", sk_detectDeleteGesture, sk_applyDeleteGesture},
-       {"Merge", sk_detectMergeGesture, sk_applyMergeGesture},
-       {"Reverse", sk_detectReverseGesture, sk_applyReverseGesture},
-       {"Convert", sk_detectConvertGesture, sk_applyConvertGesture},
-       {"", NULL, NULL}
-};
-
-/******************** TEMPLATES UTILS *************************/
-
-static char  *TEMPLATES_MENU = NULL;
-static int TEMPLATES_CURRENT = 0;
-static GHash *TEMPLATES_HASH = NULL;
-static RigGraph *TEMPLATE_RIGG = NULL;
-
-void BIF_makeListTemplates(const bContext *C)
-{
-       Object *obedit = CTX_data_edit_object(C);
-       ViewLayer *view_layer = CTX_data_view_layer(C);
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       int index = 0;
-
-       if (TEMPLATES_HASH != NULL) {
-               BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
-       }
-
-       TEMPLATES_HASH = BLI_ghash_int_new("makeListTemplates gh");
-       TEMPLATES_CURRENT = 0;
-
-       FOREACH_OBJECT_BEGIN(view_layer, ob)
-       {
-               if (ob != obedit && ob->type == OB_ARMATURE) {
-                       index++;
-                       BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob);
-
-                       if (ob == ts->skgen_template) {
-                               TEMPLATES_CURRENT = index;
-                       }
-               }
-       }
-       FOREACH_OBJECT_END;
-}
-
-#if 0  /* UNUSED */
-const char *BIF_listTemplates(const bContext *UNUSED(C))
-{
-       GHashIterator ghi;
-       const char *menu_header = IFACE_("Template %t|None %x0|");
-       char *p;
-       const size_t template_size = (BLI_ghash_len(TEMPLATES_HASH) * 32 + 30);
-
-       if (TEMPLATES_MENU != NULL) {
-               MEM_freeN(TEMPLATES_MENU);
-       }
-
-       TEMPLATES_MENU = MEM_callocN(sizeof(char) * template_size, "skeleton template menu");
-
-       p = TEMPLATES_MENU;
-       p += BLI_strncpy_rlen(p, menu_header, template_size);
-
-       BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
-
-       while (!BLI_ghashIterator_done(&ghi)) {
-               Object *ob = BLI_ghashIterator_getValue(&ghi);
-               int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
-
-               p += sprintf(p, "|%s %%x%i", ob->id.name + 2, key);
-
-               BLI_ghashIterator_step(&ghi);
-       }
-
-       return TEMPLATES_MENU;
-}
-#endif
-
-int   BIF_currentTemplate(const bContext *C)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-
-       if (TEMPLATES_CURRENT == 0 && ts->skgen_template != NULL) {
-               GHashIterator ghi;
-               BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
-
-               while (!BLI_ghashIterator_done(&ghi)) {
-                       Object *ob = BLI_ghashIterator_getValue(&ghi);
-                       int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
-
-                       if (ob == ts->skgen_template) {
-                               TEMPLATES_CURRENT = key;
-                               break;
-                       }
-
-                       BLI_ghashIterator_step(&ghi);
-               }
-       }
-
-       return TEMPLATES_CURRENT;
-}
-
-static RigGraph *sk_makeTemplateGraph(const bContext *C, Object *ob)
-{
-       Object *obedit = CTX_data_edit_object(C);
-       if (ob == obedit) {
-               return NULL;
-       }
-
-       if (ob != NULL) {
-               if (TEMPLATE_RIGG && TEMPLATE_RIGG->ob != ob) {
-                       RIG_freeRigGraph((BGraph *)TEMPLATE_RIGG);
-                       TEMPLATE_RIGG = NULL;
-               }
-
-               if (TEMPLATE_RIGG == NULL) {
-                       bArmature *arm;
-
-                       arm = ob->data;
-
-                       TEMPLATE_RIGG = RIG_graphFromArmature(C, ob, arm);
-               }
-       }
-
-       return TEMPLATE_RIGG;
-}
-
-int BIF_nbJointsTemplate(const bContext *C)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       RigGraph *rg = sk_makeTemplateGraph(C, ts->skgen_template);
-
-       if (rg) {
-               return RIG_nbJoints(rg);
-       }
-       else {
-               return -1;
-       }
-}
-
-const char *BIF_nameBoneTemplate(const bContext *C)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       SK_Sketch *stk = contextSketch(C, 1);
-       RigGraph *rg;
-       int index = 0;
-
-       if (stk && stk->active_stroke != NULL) {
-               index = stk->active_stroke->nb_points;
-       }
-
-       rg = sk_makeTemplateGraph(C, ts->skgen_template);
-
-       if (rg == NULL) {
-               return "";
-       }
-
-       return RIG_nameBone(rg, 0, index);
-}
-
-void  BIF_freeTemplates(bContext *UNUSED(C))
-{
-       if (TEMPLATES_MENU != NULL) {
-               MEM_freeN(TEMPLATES_MENU);
-               TEMPLATES_MENU = NULL;
-       }
-
-       if (TEMPLATES_HASH != NULL) {
-               BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
-               TEMPLATES_HASH = NULL;
-       }
-
-       if (TEMPLATE_RIGG != NULL) {
-               RIG_freeRigGraph((BGraph *)TEMPLATE_RIGG);
-               TEMPLATE_RIGG = NULL;
-       }
-}
-
-void  BIF_setTemplate(bContext *C, int index)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       if (index > 0) {
-               ts->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
-       }
-       else {
-               ts->skgen_template = NULL;
-
-               if (TEMPLATE_RIGG != NULL) {
-                       RIG_freeRigGraph((BGraph *)TEMPLATE_RIGG);
-               }
-               TEMPLATE_RIGG = NULL;
-       }
-}
-
-/*********************** CONVERSION ***************************/
-
-static void sk_autoname(bContext *C, ReebArc *arc)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       if (ts->skgen_retarget_options & SK_RETARGET_AUTONAME) {
-               if (arc == NULL) {
-                       char *num = ts->skgen_num_string;
-                       int i = atoi(num);
-                       i++;
-                       BLI_snprintf(num, 8, "%i", i);
-               }
-               else {
-                       char *side = ts->skgen_side_string;
-                       int valid = 0;
-                       int caps = 0;
-
-                       if (side[0] == '\0') {
-                               valid = 1;
-                       }
-                       else if (STREQ(side, "R") || STREQ(side, "L")) {
-                               valid = 1;
-                               caps = 1;
-                       }
-                       else if (STREQ(side, "r") || STREQ(side, "l")) {
-                               valid = 1;
-                               caps = 0;
-                       }
-
-                       if (valid) {
-                               if (arc->head->p[0] < 0) {
-                                       BLI_snprintf(side, 8, caps ? "R" : "r");
-                               }
-                               else {
-                                       BLI_snprintf(side, 8, caps ? "L" : "l");
-                               }
-                       }
-               }
-       }
-}
-
-static ReebNode *sk_pointToNode(SK_Point *pt, float imat[4][4], float tmat[3][3])
-{
-       ReebNode *node;
-
-       node = MEM_callocN(sizeof(ReebNode), "reeb node");
-       copy_v3_v3(node->p, pt->p);
-       mul_m4_v3(imat, node->p);
-
-       copy_v3_v3(node->no, pt->no);
-       mul_m3_v3(tmat, node->no);
-
-       return node;
-}
-
-static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[4][4], float tmat[3][3])
-{
-       ReebArc *arc;
-       int i;
-
-       arc = MEM_callocN(sizeof(ReebArc), "reeb arc");
-       arc->head = sk_pointToNode(stk->points, imat, tmat);
-       arc->tail = sk_pointToNode(sk_lastStrokePoint(stk), imat, tmat);
-
-       arc->bcount = stk->nb_points - 2; /* first and last are nodes, don't count */
-       arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "Buckets");
-
-       for (i = 0; i < arc->bcount; i++) {
-               copy_v3_v3(arc->buckets[i].p, stk->points[i + 1].p);
-               mul_m4_v3(imat, arc->buckets[i].p);
-
-               copy_v3_v3(arc->buckets[i].no, stk->points[i + 1].no);
-               mul_m3_v3(tmat, arc->buckets[i].no);
-       }
-
-       return arc;
-}
-
-static void sk_retargetStroke(bContext *C, SK_Stroke *stk)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       Object *obedit = CTX_data_edit_object(C);
-       float imat[4][4];
-       float tmat[3][3];
-       ReebArc *arc;
-       RigGraph *rg;
-
-       invert_m4_m4(imat, obedit->obmat);
-       transpose_m3_m4(tmat, obedit->obmat);
-
-       arc = sk_strokeToArc(stk, imat, tmat);
-
-       sk_autoname(C, arc);
-
-       rg = sk_makeTemplateGraph(C, ts->skgen_template);
-
-       BIF_retargetArc(C, arc, rg);
-
-       sk_autoname(C, NULL);
-
-       MEM_freeN(arc->head);
-       MEM_freeN(arc->tail);
-       REEB_freeArc((BArc *)arc);
-}
-
-/**************************************************************/
-static void sk_cancelStroke(SK_Sketch *sketch)
-{
-       if (sketch->active_stroke != NULL) {
-               sk_resetOverdraw(sketch);
-               sk_removeStroke(sketch, sketch->active_stroke);
-       }
-}
-
-
-static float sk_clampPointSize(SK_Point *pt, float size)
-{
-       return max_ff(size * pt->size, size / 2);
-}
-
-static void sk_drawPoint(SK_Point *pt, float size, float color[4])
-{
-       Gwn_Batch *batch = NULL;
-
-       gpuTranslate3fv(pt->p);
-
-       gpuPushMatrix();
-
-       gpuScaleUniform(sk_clampPointSize(pt, size));
-
-       batch = GPU_batch_preset_sphere(0);
-       GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
-       GWN_batch_uniform_4fv(batch, "color", color);
-
-       GWN_batch_draw(batch);
-
-       gpuPopMatrix();
-}
-
-static void sk_drawEdge(SK_Point *pt0, SK_Point *pt1, float size, float color[4])
-{
-       float vec1[3], vec2[3] = { 0, 0, 1 }, axis[3];
-       float angle, length;
-
-       Gwn_VertFormat *format = immVertexFormat();
-       unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
-
-       sub_v3_v3v3(vec1, pt1->p, pt0->p);
-       length = normalize_v3(vec1);
-       cross_v3_v3v3(axis, vec2, vec1);
-
-       if (is_zero_v3(axis)) {
-               axis[1] = 1;
-       }
-
-       immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-       immUniformColor4fv(color);
-
-       angle = angle_normalized_v3v3(vec2, vec1);
-       gpuRotate3fv(angle * (float)(180.0 / M_PI) + 180.0f, axis);
-       imm_draw_cylinder_fill_3d(pos, sk_clampPointSize(pt1, size), sk_clampPointSize(pt0, size), length, 8, 8);
-
-       immUnbindProgram();
-}
-
-static void sk_drawNormal(SK_Point *pt, float size, float height)
-{
-       float vec2[3] = { 0, 0, 1 }, axis[3];
-       float angle;
-       float color[3] = { 0.0f, 1.0f, 1.0f };
-
-       Gwn_VertFormat *format = immVertexFormat();
-       unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
-
-       gpuPushMatrix();
-
-       cross_v3_v3v3(axis, vec2, pt->no);
-
-       if (is_zero_v3(axis)) {
-               axis[1] = 1;
-       }
-
-       immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-       immUniformColor4fv(color);
-
-       angle = angle_normalized_v3v3(vec2, pt->no);
-       gpuRotate3fv(angle * (float)(180.0 / M_PI), axis);
-
-       imm_draw_cylinder_fill_3d(pos, sk_clampPointSize(pt, size), 0, sk_clampPointSize(pt, height), 10, 2);
-
-       immUnbindProgram();
-
-       gpuPopMatrix();
-}
-
-static void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int end)
-{
-       float rgb[3];
-       float zero_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
-       int i;
-
-       if (id != -1) {
-               GPU_select_load_id(id);
-
-               for (i = 0; i < stk->nb_points; i++) {
-                       gpuPushMatrix();
-
-                       sk_drawPoint(stk->points + i, 0.1, zero_color);
-
-                       if (i > 0) {
-                               sk_drawEdge(stk->points + i - 1, stk->points + i, 0.1, zero_color);
-                       }
-
-                       gpuPopMatrix();
-               }
-
-       }
-       else {
-               float d_rgb[3] = { 1, 1, 1 };
-               float tmp_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
-
-               copy_v3_v3(rgb, color);
-               sub_v3_v3(d_rgb, rgb);
-               mul_v3_fl(d_rgb, 1.0f / (float)stk->nb_points);
-
-               for (i = 0; i < stk->nb_points; i++) {
-                       SK_Point *pt = stk->points + i;
-
-                       gpuPushMatrix();
-
-                       if (pt->type == PT_EXACT) {
-                               sk_drawPoint(pt, 0.15, zero_color);
-                               sk_drawNormal(pt, 0.05, 0.9);
-                       }
-
-                       if (i >= start && i <= end) {
-                               copy_v4_fl4(tmp_color, 0.3f, 0.3f, 0.3f, 1.0f);
-                       }
-                       else {
-                               copy_v4_fl4(tmp_color, rgb[0], rgb[1], rgb[2], 1.0f);
-                       }
-
-                       if (pt->type != PT_EXACT) {
-                               sk_drawPoint(pt, 0.1, tmp_color);
-                       }
-
-                       if (i > 0) {
-                               sk_drawEdge(pt - 1, pt, 0.1, tmp_color);
-                       }
-
-                       gpuPopMatrix();
-
-                       add_v3_v3(rgb, d_rgb);
-               }
-       }
-
-}
-
-static void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *iter, NextSubdivisionFunc next_subdividion)
-{
-       SK_Stroke *stk = ((SK_StrokeIterator *)iter)->stroke;
-       float head[3], tail[3];
-       float color[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
-       int bone_start = 0;
-       int end = iter->length;
-       int index;
-
-       iter->head(iter);
-       copy_v3_v3(head, iter->p);
-
-       index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
-       while (index != -1) {
-               SK_Point *pt = stk->points + index;
-
-               gpuPushMatrix();
-
-               sk_drawPoint(pt, 0.15, color);
-
-               sk_drawNormal(pt, 0.05, 0.9);
-
-               gpuPopMatrix();
-
-               copy_v3_v3(head, tail);
-               bone_start = index; // start next bone from current index
-
-               index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
-       }
-}
-
-static void sk_drawStrokeSubdivision(ToolSettings *toolsettings, SK_Stroke *stk)
-{
-       int head_index = -1;
-       int i;
-
-       if (toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET) {
-               return;
-       }
-
-
-       for (i = 0; i < stk->nb_points; i++) {
-               SK_Point *pt = stk->points + i;
-
-               if (pt->type == PT_EXACT || i == stk->nb_points - 1) /* stop on exact or on last point */ {
-                       if (head_index == -1) {
-                               head_index = i;
-                       }
-                       else {
-                               if (i - head_index > 1) {
-                                       SK_StrokeIterator sk_iter;
-                                       BArcIterator *iter = (BArcIterator *)&sk_iter;
-
-                                       initStrokeIterator(iter, stk, head_index, i);
-
-                                       if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE) {
-                                               drawSubdividedStrokeBy(toolsettings, iter, nextAdaptativeSubdivision);
-                                       }
-                                       else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH) {
-                                               drawSubdividedStrokeBy(toolsettings, iter, nextLengthSubdivision);
-                                       }
-                                       else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED) {
-                                               drawSubdividedStrokeBy(toolsettings, iter, nextFixedSubdivision);
-                                       }
-
-                               }
-
-                               head_index = i;
-                       }
-               }
-       }
-}
-
-static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], float *r_dist_px, int *index, int all_pts)
-{
-       ARegion *ar = CTX_wm_region(C);
-       SK_Point *pt = NULL;
-       int i;
-
-       for (i = 0; i < stk->nb_points; i++) {
-               if (all_pts || stk->points[i].type == PT_EXACT) {
-                       short pval[2];
-                       int pdist;
-
-                       if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
-
-                               pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
-
-                               if (pdist < *r_dist_px) {
-                                       *r_dist_px = pdist;
-                                       pt = stk->points + i;
-
-                                       if (index != NULL) {
-                                               *index = i;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       return pt;
-}
-
-#if 0 /* UNUSED 2.5 */
-static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, int mval[2], int *dist)
-{
-       ARegion *ar = CTX_wm_region(C);
-       SK_Point *pt = NULL;
-       EditBone *bone;
-
-       for (bone = ebones->first; bone; bone = bone->next)
-       {
-               float vec[3];
-               short pval[2];
-               int pdist;
-
-               if ((bone->flag & BONE_CONNECTED) == 0)
-               {
-                       copy_v3_v3(vec, bone->head);
-                       mul_m4_v3(ob->obmat, vec);
-                       if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
-
-                               pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
-
-                               if (pdist < *dist)
-                               {
-                                       *dist = pdist;
-                                       pt = &boneSnap;
-                                       copy_v3_v3(pt->p, vec);
-                                       pt->type = PT_EXACT;
-                               }
-                       }
-               }
-
-
-               copy_v3_v3(vec, bone->tail);
-               mul_m4_v3(ob->obmat, vec);
-               if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
-
-                       pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
-
-                       if (pdist < *dist)
-                       {
-                               *dist = pdist;
-                               pt = &boneSnap;
-                               copy_v3_v3(pt->p, vec);
-                               pt->type = PT_EXACT;
-                       }
-               }
-       }
-
-       return pt;
-}
-#endif
-
-void sk_resetOverdraw(SK_Sketch *sketch)
-{
-       sketch->over.target = NULL;
-       sketch->over.start = -1;
-       sketch->over.end = -1;
-       sketch->over.count = 0;
-}
-
-int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk)
-{
-       return sketch->over.target &&
-              sketch->over.count >= SK_OVERDRAW_LIMIT &&
-              (sketch->over.target == stk || stk == NULL) &&
-              (sketch->over.start != -1 || sketch->over.end != -1);
-}
-
-static void sk_updateOverdraw(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
-{
-       if (sketch->over.target == NULL) {
-               SK_Stroke *target;
-               int closest_index = -1;
-               float dist_px = SNAP_MIN_DISTANCE * 2;
-
-               for (target = sketch->strokes.first; target; target = target->next) {
-                       if (target != stk) {
-                               int index;
-
-                               SK_Point *spt = sk_snapPointStroke(C, target, dd->mval, &dist_px, &index, 1);
-
-                               if (spt != NULL) {
-                                       sketch->over.target = target;
-                                       closest_index = index;
-                               }
-                       }
-               }
-
-               if (sketch->over.target != NULL) {
-                       if (closest_index > -1) {
-                               if (sk_lastStrokePoint(stk)->type == PT_EXACT) {
-                                       sketch->over.count = SK_OVERDRAW_LIMIT;
-                               }
-                               else {
-                                       sketch->over.count++;
-                               }
-                       }
-
-                       if (stk->nb_points == 1) {
-                               sketch->over.start = closest_index;
-                       }
-                       else {
-                               sketch->over.end = closest_index;
-                       }
-               }
-       }
-       else if (sketch->over.target != NULL) {
-               SK_Point *closest_pt = NULL;
-               float dist_px = SNAP_MIN_DISTANCE * 2;
-               int index;
-
-               closest_pt = sk_snapPointStroke(C, sketch->over.target, dd->mval, &dist_px, &index, 1);
-
-               if (closest_pt != NULL) {
-                       if (sk_lastStrokePoint(stk)->type == PT_EXACT) {
-                               sketch->over.count = SK_OVERDRAW_LIMIT;
-                       }
-                       else {
-                               sketch->over.count++;
-                       }
-
-                       sketch->over.end = index;
-               }
-               else {
-                       sketch->over.end = -1;
-               }
-       }
-}
-
-/* return 1 on reverse needed */
-static int sk_adjustIndexes(SK_Sketch *sketch, int *start, int *end)
-{
-       int retval = 0;
-
-       *start = sketch->over.start;
-       *end = sketch->over.end;
-
-       if (*start == -1) {
-               *start = 0;
-       }
-
-       if (*end == -1) {
-               *end = sketch->over.target->nb_points - 1;
-       }
-
-       if (*end < *start) {
-               int tmp = *start;
-               *start = *end;
-               *end = tmp;
-               retval = 1;
-       }
-
-       return retval;
-}
-
-static void sk_endOverdraw(SK_Sketch *sketch)
-{
-       SK_Stroke *stk = sketch->active_stroke;
-
-       if (sk_hasOverdraw(sketch, NULL)) {
-               int start;
-               int end;
-
-               if (sk_adjustIndexes(sketch, &start, &end)) {
-                       sk_reverseStroke(stk);
-               }
-
-               if (stk->nb_points > 1) {
-                       stk->points->type = sketch->over.target->points[start].type;
-                       sk_lastStrokePoint(stk)->type = sketch->over.target->points[end].type;
-               }
-
-               sk_insertStrokePoints(sketch->over.target, stk->points, stk->nb_points, start, end);
-
-               sk_removeStroke(sketch, stk);
-
-               sk_resetOverdraw(sketch);
-       }
-}
-
-
-static void sk_startStroke(SK_Sketch *sketch)
-{
-       SK_Stroke *stk = sk_createStroke();
-
-       BLI_addtail(&sketch->strokes, stk);
-       sketch->active_stroke = stk;
-
-       sk_resetOverdraw(sketch);
-}
-
-static void sk_endStroke(bContext *C, SK_Sketch *sketch)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       sk_shrinkStrokeBuffer(sketch->active_stroke);
-
-       if (ts->bone_sketching & BONE_SKETCHING_ADJUST) {
-               sk_endOverdraw(sketch);
-       }
-
-       sketch->active_stroke = NULL;
-}
-
-static void sk_updateDrawData(SK_DrawData *dd)
-{
-       dd->type = PT_CONTINUOUS;
-
-       dd->previous_mval[0] = dd->mval[0];
-       dd->previous_mval[1] = dd->mval[1];
-}
-
-static float sk_distanceDepth(bContext *C, float p1[3], float p2[3])
-{
-       ARegion *ar = CTX_wm_region(C);
-       RegionView3D *rv3d = ar->regiondata;
-       float vec[3];
-       float distance;
-
-       sub_v3_v3v3(vec, p1, p2);
-
-       project_v3_v3v3(vec, vec, rv3d->viewinv[2]);
-
-       distance = len_v3(vec);
-
-       if (dot_v3v3(rv3d->viewinv[2], vec) > 0) {
-               distance *= -1;
-       }
-
-       return distance;
-}
-
-static void sk_interpolateDepth(bContext *C, SK_Stroke *stk, int start, int end, float length, float distance)
-{
-       ARegion *ar = CTX_wm_region(C);
-       ScrArea *sa = CTX_wm_area(C);
-       View3D *v3d = sa->spacedata.first;
-
-       float progress = 0;
-       int i;
-
-       progress = len_v3v3(stk->points[start].p, stk->points[start - 1].p);
-
-       for (i = start; i <= end; i++) {
-               float ray_start[3], ray_normal[3];
-               float delta = len_v3v3(stk->points[i].p, stk->points[i + 1].p);
-               float pval[2] = {0, 0};
-
-               ED_view3d_project_float_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP);
-               ED_view3d_win_to_ray(CTX_data_depsgraph(C), ar, v3d, pval, ray_start, ray_normal, false);
-
-               mul_v3_fl(ray_normal, distance * progress / length);
-               add_v3_v3(stk->points[i].p, ray_normal);
-
-               progress += delta;
-       }
-}
-
-static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_DrawData *dd)
-{
-       ARegion *ar = CTX_wm_region(C);
-       /* copied from grease pencil, need fixing */
-       SK_Point *last = sk_lastStrokePoint(stk);
-       short cval[2];
-       float fp[3] = {0, 0, 0};
-       float dvec[3];
-       float mval_f[2];
-       float zfac;
-
-       if (last != NULL) {
-               copy_v3_v3(fp, last->p);
-       }
-
-       zfac = ED_view3d_calc_zfac(ar->regiondata, fp, NULL);
-
-       if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
-               VECSUB2D(mval_f, cval, dd->mval);
-               ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
-               sub_v3_v3v3(vec, fp, dvec);
-       }
-       else {
-               zero_v3(vec);
-       }
-}
-
-static int sk_getStrokeDrawPoint(bContext *C, SK_Point *pt, SK_Sketch *UNUSED(sketch), SK_Stroke *stk, SK_DrawData *dd)
-{
-       pt->type = dd->type;
-       pt->mode = PT_PROJECT;
-       sk_projectDrawPoint(C, pt->p, stk, dd);
-
-       return 1;
-}
-
-static int sk_addStrokeDrawPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
-{
-       ARegion *ar = CTX_wm_region(C);
-       RegionView3D *rv3d = ar->regiondata;
-       SK_Point pt;
-
-       sk_initPoint(&pt, dd, rv3d->viewinv[2]);
-
-       sk_getStrokeDrawPoint(C, &pt, sketch, stk, dd);
-
-       sk_appendStrokePoint(stk, &pt);
-
-       return 1;
-}
-
-static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       int point_added = 0;
-
-       /* TODO: Since the function `ED_transform_snap_object_context_create_view3d` creates a cache,
-        * the ideal would be to call this function only at the beginning of the snap operation,
-        * or at the beginning of the operator itself */
-       struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
-               CTX_data_main(C), CTX_data_scene(C), CTX_data_depsgraph(C), 0,
-               CTX_wm_region(C), CTX_wm_view3d(C));
-
-       float mvalf[2] = {UNPACK2(dd->mval)};
-       float loc[3], dummy_no[3];
-
-       if (ts->snap_mode == SCE_SNAP_MODE_VOLUME) {
-               float size;
-               if (peelObjectsSnapContext(
-                       snap_context, mvalf,
-                       &(const struct SnapObjectParams){
-                           .snap_select = SNAP_NOT_SELECTED,
-                           .use_object_edit_cage = false,
-                       },
-                       (ts->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0,
-                       loc, dummy_no, &size))
-               {
-                       pt->type = dd->type;
-                       pt->mode = PT_SNAP;
-                       pt->size = size / 2;
-                       copy_v3_v3(pt->p, loc);
-
-                       point_added = 1;
-               }
-       }
-       else {
-               SK_Stroke *snap_stk;
-               float dist_px = SNAP_MIN_DISTANCE; // Use a user defined value here
-
-               /* snap to strokes */
-               // if (ts->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
-               for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next) {
-                       SK_Point *spt = NULL;
-                       if (snap_stk == stk) {
-                               spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist_px, NULL, 0);
-                       }
-                       else {
-                               spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist_px, NULL, 1);
-                       }
-
-                       if (spt != NULL) {
-                               copy_v3_v3(pt->p, spt->p);
-                               point_added = 1;
-                       }
-               }
-
-               /* try to snap to closer object */
-               {
-                       if (ED_transform_snap_object_project_view3d(
-                               snap_context,
-                               ts->snap_mode,
-                               &(const struct SnapObjectParams){
-                                   .snap_select = SNAP_NOT_SELECTED,
-                                   .use_object_edit_cage = false,
-                               },
-                               mvalf, &dist_px, NULL,
-                               loc, dummy_no))
-                       {
-                               pt->type = dd->type;
-                               pt->mode = PT_SNAP;
-                               copy_v3_v3(pt->p, loc);
-
-                               point_added = 1;
-                       }
-               }
-       }
-
-       /* TODO: The ideal would be to call this function only once.
-        * At the end of the operator */
-       ED_transform_snap_object_context_destroy(snap_context);
-       return point_added;
-}
-
-static int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
-{
-       int point_added;
-       ARegion *ar = CTX_wm_region(C);
-       RegionView3D *rv3d = ar->regiondata;
-       SK_Point pt;
-
-       sk_initPoint(&pt, dd, rv3d->viewinv[2]);
-
-       point_added = sk_getStrokeSnapPoint(C, &pt, sketch, stk, dd);
-
-       if (point_added) {
-               float final_p[3];
-               float length, distance;
-               int total;
-               int i;
-
-               copy_v3_v3(final_p, pt.p);
-
-               sk_projectDrawPoint(C, pt.p, stk, dd);
-               sk_appendStrokePoint(stk, &pt);
-
-               /* update all previous point to give smooth Z progresion */
-               total = 0;
-               length = 0;
-               for (i = stk->nb_points - 2; i > 0; i--) {
-                       length += len_v3v3(stk->points[i].p, stk->points[i + 1].p);
-                       total++;
-                       if (stk->points[i].mode == PT_SNAP || stk->points[i].type == PT_EXACT) {
-                               break;
-                       }
-               }
-
-               if (total > 1) {
-                       distance = sk_distanceDepth(C, final_p, stk->points[i].p);
-
-                       sk_interpolateDepth(C, stk, i + 1, stk->nb_points - 2, length, distance);
-               }
-
-               copy_v3_v3(stk->points[stk->nb_points - 1].p, final_p);
-
-               point_added = 1;
-       }
-
-       return point_added;
-}
-
-static void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, const bool snap)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       int point_added = 0;
-
-       if (snap) {
-               point_added = sk_addStrokeSnapPoint(C, sketch, stk, dd);
-       }
-
-       if (point_added == 0) {
-               point_added = sk_addStrokeDrawPoint(C, sketch, stk, dd);
-       }
-
-       if (stk == sketch->active_stroke && ts->bone_sketching & BONE_SKETCHING_ADJUST) {
-               sk_updateOverdraw(C, sketch, stk, dd);
-       }
-}
-
-static void sk_getStrokePoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, const bool snap)
-{
-       int point_added = 0;
-
-       if (snap) {
-               point_added = sk_getStrokeSnapPoint(C, pt, sketch, stk, dd);
-               LAST_SNAP_POINT_VALID = 1;
-               copy_v3_v3(LAST_SNAP_POINT, pt->p);
-       }
-       else {
-               LAST_SNAP_POINT_VALID = 0;
-       }
-
-       if (point_added == 0) {
-               point_added = sk_getStrokeDrawPoint(C, pt, sketch, stk, dd);
-       }
-}
-
-/********************************************/
-
-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;
-}
-
-static SK_Point *setIteratorValues(SK_StrokeIterator *iter, int index)
-{
-       SK_Point *pt = NULL;
-
-       if (index >= 0 && index < iter->length) {
-               pt = &(iter->stroke->points[iter->start + (iter->stride * index)]);
-               iter->p = pt->p;
-               iter->no = pt->no;
-               iter->size = pt->size;
-       }
-       else {
-               iter->p = NULL;
-               iter->no = NULL;
-               iter->size = 0;
-       }
-
-       return pt;
-}
-
-void initStrokeIterator(BArcIterator *arg, SK_Stroke *stk, int start, int end)
-{
-       SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
-
-       initIteratorFct(iter);
-       iter->stroke = stk;
-
-       if (start < end) {
-               iter->start = start + 1;
-               iter->end = end - 1;
-               iter->stride = 1;
-       }
-       else {
-               iter->start = start - 1;
-               iter->end = end + 1;
-               iter->stride = -1;
-       }
-
-       iter->length = iter->stride * (iter->end - iter->start + 1);
-
-       iter->index = -1;
-}
-
-
-static void *headPoint(void *arg)
-{
-       SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
-       SK_Point *result = NULL;
-
-       result = &(iter->stroke->points[iter->start - iter->stride]);
-       iter->p = result->p;
-       iter->no = result->no;
-       iter->size = result->size;
-
-       return result;
-}
-
-static void *tailPoint(void *arg)
-{
-       SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
-       SK_Point *result = NULL;
-
-       result = &(iter->stroke->points[iter->end + iter->stride]);
-       iter->p = result->p;
-       iter->no = result->no;
-       iter->size = result->size;
-
-       return result;
-}
-
-static void *nextPoint(void *arg)
-{
-       SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
-       SK_Point *result = NULL;
-
-       iter->index++;
-       if (iter->index < iter->length) {
-               result = setIteratorValues(iter, iter->index);
-       }
-
-       return result;
-}
-
-static void *nextNPoint(void *arg, int n)
-{
-       SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
-       SK_Point *result = NULL;
-
-       iter->index += n;
-
-       /* check if passed end */
-       if (iter->index < iter->length) {
-               result = setIteratorValues(iter, iter->index);
-       }
-
-       return result;
-}
-
-static void *peekPoint(void *arg, int n)
-{
-       SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
-       SK_Point *result = NULL;
-       int index = iter->index + n;
-
-       /* 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;
-
-       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;
-       }
-}
-
-static void sk_convertStroke(bContext *C, SK_Stroke *stk)
-{
-       Object *obedit = CTX_data_edit_object(C);
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       bArmature *arm = obedit->data;
-       SK_Point *head;
-       EditBone *parent = NULL;
-       float invmat[4][4]; /* move in caller function */
-       float tmat[3][3];
-       int head_index = 0;
-       int i;
-
-       head = NULL;
-
-       invert_m4_m4(invmat, obedit->obmat);
-       transpose_m3_m4(tmat, obedit->obmat);
-
-       for (i = 0; i < stk->nb_points; i++) {
-               SK_Point *pt = stk->points + i;
-
-               if (pt->type == PT_EXACT) {
-                       if (head == NULL) {
-                               head_index = i;
-                               head = pt;
-                       }
-                       else {
-                               EditBone *bone = NULL;
-                               EditBone *new_parent;
-
-                               if (i - head_index > 1) {
-                                       SK_StrokeIterator sk_iter;
-                                       BArcIterator *iter = (BArcIterator *)&sk_iter;
-
-                                       initStrokeIterator(iter, stk, head_index, i);
-
-                                       if (ts->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE) {
-                                               bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
-                                       }
-                                       else if (ts->bone_sketching_convert == SK_CONVERT_CUT_LENGTH) {
-                                               bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
-                                       }
-                                       else if (ts->bone_sketching_convert == SK_CONVERT_CUT_FIXED) {
-                                               bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
-                                       }
-                               }
-
-                               if (bone == NULL) {
-                                       bone = ED_armature_ebone_add(arm, "Bone");
-
-                                       copy_v3_v3(bone->head, head->p);
-                                       copy_v3_v3(bone->tail, pt->p);
-
-                                       mul_m4_v3(invmat, bone->head);
-                                       mul_m4_v3(invmat, bone->tail);
-                                       setBoneRollFromNormal(bone, head->no, invmat, tmat);
-                               }
-
-                               new_parent = bone;
-                               bone->flag |= BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
-
-                               /* move to end of chain */
-                               while (bone->parent != NULL) {
-                                       bone = bone->parent;
-                                       bone->flag |= BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
-                               }
-
-                               if (parent != NULL) {
-                                       bone->parent = parent;
-                                       bone->flag |= BONE_CONNECTED;
-                               }
-
-                               parent = new_parent;
-                               head_index = i;
-                               head = pt;
-                       }
-               }
-       }
-}
-
-static void sk_convert(bContext *C, SK_Sketch *sketch)
-{
-       ToolSettings *ts = CTX_data_tool_settings(C);
-       SK_Stroke *stk;
-
-       for (stk = sketch->strokes.first; stk; stk = stk->next) {
-               if (stk->selected == 1) {
-                       if (ts->bone_sketching_convert == SK_CONVERT_RETARGET) {
-                               sk_retargetStroke(C, stk);
-                       }
-                       else {
-                               sk_convertStroke(C, stk);
-                       }
-//                     XXX
-//                     allqueue(REDRAWBUTSEDIT, 0);
-               }
-       }
-}
-/******************* GESTURE *************************/
-
-
-/* returns the number of self intersections */
-static int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gesture)
-{
-       ARegion *ar = CTX_wm_region(C);
-       int added = 0;
-       int s_i;
-
-       for (s_i = 0; s_i < gesture->nb_points - 1; s_i++) {
-               float s_p1[3] = {0, 0, 0};
-               float s_p2[3] = {0, 0, 0};
-               int g_i;
-
-               ED_view3d_project_float_global(ar, gesture->points[s_i].p, s_p1, V3D_PROJ_TEST_NOP);
-               ED_view3d_project_float_global(ar, gesture->points[s_i + 1].p, s_p2, V3D_PROJ_TEST_NOP);
-
-               /* start checking from second next, because two consecutive cannot intersect */
-               for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++) {
-                       float g_p1[3] = {0, 0, 0};
-                       float g_p2[3] = {0, 0, 0};
-                       float vi[3];
-                       float lambda;
-
-                       ED_view3d_project_float_global(ar, gesture->points[g_i].p, g_p1, V3D_PROJ_TEST_NOP);
-                       ED_view3d_project_float_global(ar, gesture->points[g_i + 1].p, g_p2, V3D_PROJ_TEST_NOP);
-
-                       if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) {
-                               SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
-
-                               isect->gesture_index = g_i;
-                               isect->before = s_i;
-                               isect->after = s_i + 1;
-                               isect->stroke = gesture;
-
-                               sub_v3_v3v3(isect->p, gesture->points[s_i + 1].p, gesture->points[s_i].p);
-                               mul_v3_fl(isect->p, lambda);
-                               add_v3_v3(isect->p, gesture->points[s_i].p);
-
-                               BLI_addtail(list, isect);
-
-                               added++;
-                       }
-               }
-       }
-
-       return added;
-}
-
-static int cmpIntersections(const void *i1, const void *i2)
-{
-       const SK_Intersection *isect1 = i1, *isect2 = i2;
-
-       if (isect1->stroke == isect2->stroke) {
-               if (isect1->before < isect2->before) {
-                       return -1;
-               }
-               else if (isect1->before > isect2->before) {
-                       return 1;
-               }
-               else {
-                       if (isect1->lambda < isect2->lambda) {
-                               return -1;
-                       }
-                       else if (isect1->lambda > isect2->lambda) {
-                               return 1;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-
-/* returns the maximum number of intersections per stroke */
-static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
-{
-       Depsgraph *depsgraph = CTX_data_depsgraph(C);
-       ARegion *ar = CTX_wm_region(C);
-       ScrArea *sa = CTX_wm_area(C);
-       View3D *v3d = sa->spacedata.first;
-       SK_Stroke *stk;
-       int added = 0;
-
-       for (stk = sketch->strokes.first; stk; stk = stk->next) {
-               int s_added = 0;
-               int s_i;
-
-               for (s_i = 0; s_i < stk->nb_points - 1; s_i++) {
-                       float s_p1[3] = {0, 0, 0};
-                       float s_p2[3] = {0, 0, 0};
-                       int g_i;
-
-                       ED_view3d_project_float_global(ar, stk->points[s_i].p, s_p1, V3D_PROJ_TEST_NOP);
-                       ED_view3d_project_float_global(ar, stk->points[s_i + 1].p, s_p2, V3D_PROJ_TEST_NOP);
-
-                       for (g_i = 0; g_i < gesture->nb_points - 1; g_i++) {
-                               float g_p1[3] = {0, 0, 0};
-                               float g_p2[3] = {0, 0, 0};
-                               float vi[3];
-                               float lambda;
-
-                               ED_view3d_project_float_global(ar, gesture->points[g_i].p, g_p1, V3D_PROJ_TEST_NOP);
-                               ED_view3d_project_float_global(ar, gesture->points[g_i + 1].p, g_p2, V3D_PROJ_TEST_NOP);
-
-                               if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) {
-                                       SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
-                                       float ray_start[3], ray_end[3];
-                                       float mval[2];
-
-                                       isect->gesture_index = g_i;
-                                       isect->before = s_i;
-                                       isect->after = s_i + 1;
-                                       isect->stroke = stk;
-                                       isect->lambda = lambda;
-
-                                       mval[0] = vi[0];
-                                       mval[1] = vi[1];
-                                       ED_view3d_win_to_segment(depsgraph, ar, v3d, mval, ray_start, ray_end, true);
-
-                                       isect_line_line_v3(stk->points[s_i].p,
-                                                          stk->points[s_i + 1].p,
-                                                          ray_start,
-                                                          ray_end,
-                                                          isect->p,
-                                                          vi);
-
-                                       BLI_addtail(list, isect);
-
-                                       s_added++;
-                               }
-                       }
-               }
-
-               added = MAX2(s_added, added);
-       }
-
-       BLI_listbase_sort(list, cmpIntersections);
-
-       return added;
-}
-
-static 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;
-
-       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];
-
-               /* Calculate normal */
-               sub_v3_v3v3(n, gesture->points[i].p, vec);
-
-               if (calcArcCorrelation(iter, j, i, vec, n) < CORRELATION_THRESHOLD) {
-                       j = i - 1;
-                       sk_appendStrokePoint(segments, &gesture->points[j]);
-                       vec = segments->points[segments->nb_points - 1].p;
-                       segments->points[segments->nb_points - 1].type = PT_EXACT;
-               }
-       }
-
-       sk_appendStrokePoint(segments, &gesture->points[gesture->nb_points - 1]);
-
-       return segments->nb_points - 1;
-}
-
-int sk_detectCutGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       if (gest->nb_segments == 1 && gest->nb_intersections == 1) {
-               return 1;
-       }
-
-       return 0;
-}
-
-void sk_applyCutGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       SK_Intersection *isect;
-
-       for (isect = gest->intersections.first; isect; isect = isect->next) {
-               SK_Point pt;
-
-               pt.type = PT_EXACT;
-               pt.mode = PT_PROJECT; /* take mode from neighboring points */
-               copy_v3_v3(pt.p, isect->p);
-               copy_v3_v3(pt.no, isect->stroke->points[isect->before].no);
-
-               sk_insertStrokePoint(isect->stroke, &pt, isect->after);
-       }
-}
-
-int sk_detectTrimGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       if (gest->nb_segments == 2 && gest->nb_intersections == 1 && gest->nb_self_intersections == 0) {
-               float s1[3], s2[3];
-               float angle;
-
-               sub_v3_v3v3(s1, gest->segments->points[1].p, gest->segments->points[0].p);
-               sub_v3_v3v3(s2, gest->segments->points[2].p, gest->segments->points[1].p);
-
-               angle = RAD2DEGF(angle_v2v2(s1, s2));
-
-               if (angle > 60 && angle < 120) {
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-void sk_applyTrimGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       SK_Intersection *isect;
-       float trim_dir[3];
-
-       sub_v3_v3v3(trim_dir, gest->segments->points[2].p, gest->segments->points[1].p);
-
-       for (isect = gest->intersections.first; isect; isect = isect->next) {
-               SK_Point pt;
-               float stroke_dir[3];
-
-               pt.type = PT_EXACT;
-               pt.mode = PT_PROJECT; /* take mode from neighboring points */
-               copy_v3_v3(pt.p, isect->p);
-               copy_v3_v3(pt.no, isect->stroke->points[isect->before].no);
-
-               sub_v3_v3v3(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p);
-
-               /* same direction, trim end */
-               if (dot_v3v3(stroke_dir, trim_dir) > 0) {
-                       sk_replaceStrokePoint(isect->stroke, &pt, isect->after);
-                       sk_trimStroke(isect->stroke, 0, isect->after);
-               }
-               /* else, trim start */
-               else {
-                       sk_replaceStrokePoint(isect->stroke, &pt, isect->before);
-                       sk_trimStroke(isect->stroke, isect->before, isect->stroke->nb_points - 1);
-               }
-
-       }
-}
-
-int sk_detectCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1) {
-               SK_Intersection *isect, *self_isect;
-
-               /* get the last intersection of the first pair */
-               for (isect = gest->intersections.first; isect; isect = isect->next) {
-                       if (isect->stroke == isect->next->stroke) {
-                               isect = isect->next;
-                               break;
-                       }
-               }
-
-               self_isect = gest->self_intersections.first;
-
-               if (isect && isect->gesture_index < self_isect->gesture_index) {
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-void sk_applyCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       SK_Intersection *isect;
-       int command = 1;
-
-/*     XXX */
-/*     command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3"); */
-       if (command < 1) return;
-
-       for (isect = gest->intersections.first; isect; isect = isect->next) {
-               SK_Intersection *i2;
-
-               i2 = isect->next;
-
-               if (i2 && i2->stroke == isect->stroke) {
-                       switch (command) {
-                               case 1:
-                                       sk_flattenStroke(isect->stroke, isect->before, i2->after);
-                                       break;
-                               case 2:
-                                       sk_straightenStroke(isect->stroke, isect->before, i2->after, isect->p, i2->p);
-                                       break;
-                               case 3:
-                                       sk_polygonizeStroke(isect->stroke, isect->before, i2->after);
-                                       break;
-                       }
-
-                       isect = i2;
-               }
-       }
-}
-
-int sk_detectDeleteGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       if (gest->nb_segments == 2 && gest->nb_intersections == 2) {
-               float s1[3], s2[3];
-               float angle;
-
-               sub_v3_v3v3(s1, gest->segments->points[1].p, gest->segments->points[0].p);
-               sub_v3_v3v3(s2, gest->segments->points[2].p, gest->segments->points[1].p);
-
-               angle = RAD2DEGF(angle_v2v2(s1, s2));
-
-               if (angle > 120) {
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-void sk_applyDeleteGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *sketch)
-{
-       SK_Intersection *isect;
-
-       for (isect = gest->intersections.first; isect; isect = isect->next) {
-               /* only delete strokes that are crossed twice */
-               if (isect->next && isect->next->stroke == isect->stroke) {
-                       isect = isect->next;
-
-                       sk_removeStroke(sketch, isect->stroke);
-               }
-       }
-}
-
-int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       ARegion *ar = CTX_wm_region(C);
-       if (gest->nb_segments > 2 && gest->nb_intersections == 2) {
-               int start_val[2], end_val[2];
-               int dist;
-
-               if ((ED_view3d_project_int_global(ar, gest->stk->points[0].p,           start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
-                   (ED_view3d_project_int_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val,   V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
-               {
-                       dist = len_manhattan_v2v2_int(start_val, end_val);
-
-                       /* if gesture is a circle */
-                       if (dist <= 20) {
-                               SK_Intersection *isect;
-
-                               /* check if it circled around an exact point */
-                               for (isect = gest->intersections.first; isect; isect = isect->next) {
-                                       /* only delete strokes that are crossed twice */
-                                       if (isect->next && isect->next->stroke == isect->stroke) {
-                                               int start_index, end_index;
-                                               int i;
-
-                                               start_index = MIN2(isect->after, isect->next->after);
-                                               end_index = MAX2(isect->before, isect->next->before);
-
-                                               for (i = start_index; i <= end_index; i++) {
-                                                       if (isect->stroke->points[i].type == PT_EXACT) {
-                                                               return 1; /* at least one exact point found, stop detect here */
-                                                       }
-                                               }
-
-                                               /* skip next */
-                                               isect = isect->next;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       return 0;
-}
-
-void sk_applyMergeGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       SK_Intersection *isect;
-
-       /* check if it circled around an exact point */
-       for (isect = gest->intersections.first; isect; isect = isect->next) {
-               /* only merge strokes that are crossed twice */
-               if (isect->next && isect->next->stroke == isect->stroke) {
-                       int start_index, end_index;
-                       int i;
-
-                       start_index = MIN2(isect->after, isect->next->after);
-                       end_index = MAX2(isect->before, isect->next->before);
-
-                       for (i = start_index; i <= end_index; i++) {
-                               /* if exact, switch to continuous */
-                               if (isect->stroke->points[i].type == PT_EXACT) {
-                                       isect->stroke->points[i].type = PT_CONTINUOUS;
-                               }
-                       }
-
-                       /* skip next */
-                       isect = isect->next;
-               }
-       }
-}
-
-int sk_detectReverseGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 0) {
-               SK_Intersection *isect;
-
-               /* check if it circled around an exact point */
-               for (isect = gest->intersections.first; isect; isect = isect->next) {
-                       /* only delete strokes that are crossed twice */
-                       if (isect->next && isect->next->stroke == isect->stroke) {
-                               float start_v[3], end_v[3];
-                               float angle;
-
-                               if (isect->gesture_index < isect->next->gesture_index) {
-                                       sub_v3_v3v3(start_v, isect->p, gest->stk->points[0].p);
-                                       sub_v3_v3v3(end_v, sk_lastStrokePoint(gest->stk)->p, isect->next->p);
-                               }
-                               else {
-                                       sub_v3_v3v3(start_v, isect->next->p, gest->stk->points[0].p);
-                                       sub_v3_v3v3(end_v, sk_lastStrokePoint(gest->stk)->p, isect->p);
-                               }
-
-                               angle = RAD2DEGF(angle_v2v2(start_v, end_v));
-
-                               if (angle > 120) {
-                                       return 1;
-                               }
-
-                               /* skip next */
-                               isect = isect->next;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-void sk_applyReverseGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       SK_Intersection *isect;
-
-       for (isect = gest->intersections.first; isect; isect = isect->next) {
-               /* only reverse strokes that are crossed twice */
-               if (isect->next && isect->next->stroke == isect->stroke) {
-                       sk_reverseStroke(isect->stroke);
-
-                       /* skip next */
-                       isect = isect->next;
-               }
-       }
-}
-
-int sk_detectConvertGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
-{
-       if (gest->nb_segments == 3 && gest->nb_self_intersections == 1) {
-               return 1;
-       }
-       return 0;
-}
-
-void sk_applyConvertGesture(bContext *C, SK_Gesture *UNUSED(gest), SK_Sketch *sketch)
-{
-       sk_convert(C, sketch);
-}
-
-static void sk_initGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
-{
-       BLI_listbase_clear(&gest->intersections);
-       BLI_listbase_clear(&gest->self_intersections);
-
-       gest->segments = sk_createStroke();
-       gest->stk = sketch->gesture;
-
-       gest->nb_self_intersections = sk_getSelfIntersections(C, &gest->self_intersections, gest->stk);
-       gest->nb_intersections = sk_getIntersections(C, &gest->intersections, sketch, gest->stk);
-       gest->nb_segments = sk_getSegments(gest->segments, gest->stk);
-}
-
-static void sk_freeGesture(SK_Gesture *gest)
-{
-       sk_freeStroke(gest->segments);
-       BLI_freelistN(&gest->intersections);
-       BLI_freelistN(&gest->self_intersections);
-}
-
-static void sk_applyGesture(bContext *C, SK_Sketch *sketch)
-{
-       SK_Gesture gest;
-       SK_GestureAction *act;
-
-       sk_initGesture(C, &gest, sketch);
-
-       /* detect and apply */
-       for (act = GESTURE_ACTIONS; act->apply != NULL; act++) {
-               if (act->detect(C, &gest, sketch)) {
-                       act->apply(C, &gest, sketch);
-                       break;
-               }
-       }
-
-       sk_freeGesture(&gest);
-}
-
-/********************************************/
-
-
-static bool sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], const bool extend)
-{
-       ViewContext vc;
-       rcti rect;
-       unsigned int buffer[MAXPICKBUF];
-       short hits;
-
-       ED_view3d_viewcontext_init(C, &vc);
-
-       BLI_rcti_init_pt_radius(&rect, mval, 5);
-
-       hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
-
-       if (hits > 0) {
-               int besthitresult = -1;
-
-               if (hits == 1) {
-                       besthitresult = buffer[3];
-               }
-               else {
-                       besthitresult = buffer[3];
-                       /* loop and get best hit */
-               }
-
-               if (besthitresult > 0) {
-                       SK_Stroke *selected_stk = BLI_findlink(&sketch->strokes, besthitresult - 1);
-
-                       if (extend == 0) {
-                               sk_selectAllSketch(sketch, -1);
-
-                               selected_stk->selected = 1;
-                       }
-                       else {
-                               selected_stk->selected ^= 1;
-                       }
-
-
-               }
-               return 1;
-       }
-
-       return 0;
-}
-
-#if 0 /* UNUSED 2.5 */
-static void sk_queueRedrawSketch(SK_Sketch *sketch)
-{
-       if (sketch->active_stroke != NULL)
-       {
-               SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
-
-               if (last != NULL)
-               {
-//                     XXX
-//                     allqueue(REDRAWVIEW3D, 0);
-               }
-       }
-}
-#endif
-
-static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch, int with_names)
-{
-       ToolSettings *ts = scene->toolsettings;
-       SK_Stroke *stk;
-
-       glClear(GL_DEPTH_BUFFER_BIT);
-       glEnable(GL_DEPTH_TEST);
-
-       if (with_names) {
-               int id;
-               for (id = 1, stk = sketch->strokes.first; stk; id++, stk = stk->next) {
-                       sk_drawStroke(stk, id, NULL, -1, -1);
-               }
-
-               GPU_select_load_id(-1);
-       }
-       else {
-               float selected_rgb[3] = { 1, 0, 0 };
-               float unselected_rgb[3] = { 1, 0.5, 0 };
-               float tmp_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
-               for (stk = sketch->strokes.first; stk; stk = stk->next) {
-                       int start = -1;
-                       int end = -1;
-
-                       if (sk_hasOverdraw(sketch, stk)) {
-                               sk_adjustIndexes(sketch, &start, &end);
-                       }
-
-                       sk_drawStroke(stk, -1, (stk->selected == 1 ? selected_rgb : unselected_rgb), start, end);
-
-                       if (stk->selected == 1) {
-                               sk_drawStrokeSubdivision(ts, stk);
-                       }
-               }
-
-               if (sketch->active_stroke != NULL) {
-                       SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
-
-                       if (ts->bone_sketching & BONE_SKETCHING_QUICK) {
-                               sk_drawStrokeSubdivision(ts, sketch->active_stroke);
-                       }
-
-                       if (last != NULL) {
-                               gpuPushMatrix();
-
-                               glEnable(GL_BLEND);
-                               glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
-                               switch (sketch->next_point.mode) {
-                                       case PT_SNAP:
-                                               copy_v4_fl4(tmp_color, 0.0f, 1.0f, 0.0f, 1.0f);
-                                               break;
-                                       case PT_PROJECT:
-                                               copy_v4_fl4(tmp_color, 0.0f, 0.0f, 0.0f, 1.0f);
-                                               break;
-                               }
-
-                               sk_drawPoint(&sketch->next_point, 0.1, tmp_color);
-
-                               copy_v4_fl4(tmp_color, selected_rgb[0], selected_rgb[1], selected_rgb[2], 0.3);
-                               sk_drawEdge(last, &sketch->next_point, 0.1f, tmp_color);
-
-                               glD