9319ccf3b13281165224f416cfcccd0f7048d73b
[blender.git] / source / blender / editors / armature / editarmature_sketch.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/editors/armature/editarmature_sketch.c
22  *  \ingroup edarmature
23  */
24
25 #include "MEM_guardedalloc.h"
26
27 #include "DNA_object_types.h"
28 #include "DNA_scene_types.h"
29 #include "DNA_armature_types.h"
30
31 #include "BLI_blenlib.h"
32 #include "BLI_math.h"
33
34 #include "BKE_context.h"
35 #include "BKE_sketch.h"
36
37 #include "RNA_define.h"
38 #include "RNA_access.h"
39
40 #include "ED_view3d.h"
41 #include "ED_screen.h"
42
43 #include "BIF_gl.h"
44 #include "ED_armature.h"
45 #include "armature_intern.h"
46 #include "BIF_retarget.h"
47 #include "BIF_generate.h"
48
49 #include "ED_transform.h"
50
51 #include "WM_api.h"
52 #include "WM_types.h"
53
54 #include "GPU_select.h"
55
56 typedef int (*GestureDetectFct)(bContext *, SK_Gesture *, SK_Sketch *);
57 typedef void (*GestureApplyFct)(bContext *, SK_Gesture *, SK_Sketch *);
58
59 typedef struct SK_GestureAction {
60         char name[64];
61         GestureDetectFct detect;
62         GestureApplyFct apply;
63 } SK_GestureAction;
64
65 #if 0 /* UNUSED 2.5 */
66 static SK_Point boneSnap;
67 #endif
68
69 static int LAST_SNAP_POINT_VALID = 0;
70 static float LAST_SNAP_POINT[3];
71
72
73 typedef struct SK_StrokeIterator {
74         HeadFct     head;
75         TailFct     tail;
76         PeekFct     peek;
77         NextFct     next;
78         NextNFct    nextN;
79         PreviousFct previous;
80         StoppedFct  stopped;
81
82         float *p, *no;
83         float size;
84
85         int length;
86         int index;
87         /*********************************/
88         SK_Stroke *stroke;
89         int start;
90         int end;
91         int stride;
92 } SK_StrokeIterator;
93
94 /******************** PROTOTYPES ******************************/
95
96 void initStrokeIterator(BArcIterator *iter, SK_Stroke *stk, int start, int end);
97
98 int sk_detectCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
99 void sk_applyCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
100 int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
101 void sk_applyTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
102 int sk_detectCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
103 void sk_applyCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
104 int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
105 void sk_applyDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
106 int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
107 void sk_applyMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
108 int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
109 void sk_applyReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
110 int sk_detectConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
111 void sk_applyConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
112
113 SK_Sketch *contextSketch(const bContext *c, int create);
114 SK_Sketch *viewcontextSketch(ViewContext *vc, int create);
115
116 void sk_resetOverdraw(SK_Sketch *sketch);
117 int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk);
118
119 /******************** GESTURE ACTIONS ******************************/
120
121 static SK_GestureAction GESTURE_ACTIONS[] = {
122         {"Cut", sk_detectCutGesture, sk_applyCutGesture},
123         {"Trim", sk_detectTrimGesture, sk_applyTrimGesture},
124         {"Command", sk_detectCommandGesture, sk_applyCommandGesture},
125         {"Delete", sk_detectDeleteGesture, sk_applyDeleteGesture},
126         {"Merge", sk_detectMergeGesture, sk_applyMergeGesture},
127         {"Reverse", sk_detectReverseGesture, sk_applyReverseGesture},
128         {"Convert", sk_detectConvertGesture, sk_applyConvertGesture},
129         {"", NULL, NULL}
130 };
131
132 /******************** TEMPLATES UTILS *************************/
133
134 static char  *TEMPLATES_MENU = NULL;
135 static int TEMPLATES_CURRENT = 0;
136 static GHash *TEMPLATES_HASH = NULL;
137 static RigGraph *TEMPLATE_RIGG = NULL;
138
139 void BIF_makeListTemplates(const bContext *C)
140 {
141         Object *obedit = CTX_data_edit_object(C);
142         Scene *scene = CTX_data_scene(C);
143         ToolSettings *ts = CTX_data_tool_settings(C);
144         Base *base;
145         int index = 0;
146
147         if (TEMPLATES_HASH != NULL) {
148                 BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
149         }
150
151         TEMPLATES_HASH = BLI_ghash_int_new("makeListTemplates gh");
152         TEMPLATES_CURRENT = 0;
153
154         for (base = FIRSTBASE; base; base = base->next) {
155                 Object *ob = base->object;
156
157                 if (ob != obedit && ob->type == OB_ARMATURE) {
158                         index++;
159                         BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob);
160
161                         if (ob == ts->skgen_template) {
162                                 TEMPLATES_CURRENT = index;
163                         }
164                 }
165         }
166 }
167
168 #if 0  /* UNUSED */
169 const char *BIF_listTemplates(const bContext *UNUSED(C))
170 {
171         GHashIterator ghi;
172         const char *menu_header = IFACE_("Template %t|None %x0|");
173         char *p;
174         const size_t template_size = (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30);
175
176         if (TEMPLATES_MENU != NULL) {
177                 MEM_freeN(TEMPLATES_MENU);
178         }
179
180         TEMPLATES_MENU = MEM_callocN(sizeof(char) * template_size, "skeleton template menu");
181
182         p = TEMPLATES_MENU;
183         p += BLI_strncpy_rlen(p, menu_header, template_size);
184
185         BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
186
187         while (!BLI_ghashIterator_done(&ghi)) {
188                 Object *ob = BLI_ghashIterator_getValue(&ghi);
189                 int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
190
191                 p += sprintf(p, "|%s %%x%i", ob->id.name + 2, key);
192
193                 BLI_ghashIterator_step(&ghi);
194         }
195
196         return TEMPLATES_MENU;
197 }
198 #endif
199
200 int   BIF_currentTemplate(const bContext *C)
201 {
202         ToolSettings *ts = CTX_data_tool_settings(C);
203
204         if (TEMPLATES_CURRENT == 0 && ts->skgen_template != NULL) {
205                 GHashIterator ghi;
206                 BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
207
208                 while (!BLI_ghashIterator_done(&ghi)) {
209                         Object *ob = BLI_ghashIterator_getValue(&ghi);
210                         int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
211
212                         if (ob == ts->skgen_template) {
213                                 TEMPLATES_CURRENT = key;
214                                 break;
215                         }
216
217                         BLI_ghashIterator_step(&ghi);
218                 }
219         }
220
221         return TEMPLATES_CURRENT;
222 }
223
224 static RigGraph *sk_makeTemplateGraph(const bContext *C, Object *ob)
225 {
226         Object *obedit = CTX_data_edit_object(C);
227         if (ob == obedit) {
228                 return NULL;
229         }
230
231         if (ob != NULL) {
232                 if (TEMPLATE_RIGG && TEMPLATE_RIGG->ob != ob) {
233                         RIG_freeRigGraph((BGraph *)TEMPLATE_RIGG);
234                         TEMPLATE_RIGG = NULL;
235                 }
236
237                 if (TEMPLATE_RIGG == NULL) {
238                         bArmature *arm;
239
240                         arm = ob->data;
241
242                         TEMPLATE_RIGG = RIG_graphFromArmature(C, ob, arm);
243                 }
244         }
245
246         return TEMPLATE_RIGG;
247 }
248
249 int BIF_nbJointsTemplate(const bContext *C)
250 {
251         ToolSettings *ts = CTX_data_tool_settings(C);
252         RigGraph *rg = sk_makeTemplateGraph(C, ts->skgen_template);
253
254         if (rg) {
255                 return RIG_nbJoints(rg);
256         }
257         else {
258                 return -1;
259         }
260 }
261
262 const char *BIF_nameBoneTemplate(const bContext *C)
263 {
264         ToolSettings *ts = CTX_data_tool_settings(C);
265         SK_Sketch *stk = contextSketch(C, 1);
266         RigGraph *rg;
267         int index = 0;
268
269         if (stk && stk->active_stroke != NULL) {
270                 index = stk->active_stroke->nb_points;
271         }
272
273         rg = sk_makeTemplateGraph(C, ts->skgen_template);
274
275         if (rg == NULL) {
276                 return "";
277         }
278
279         return RIG_nameBone(rg, 0, index);
280 }
281
282 void  BIF_freeTemplates(bContext *UNUSED(C))
283 {
284         if (TEMPLATES_MENU != NULL) {
285                 MEM_freeN(TEMPLATES_MENU);
286                 TEMPLATES_MENU = NULL;
287         }
288
289         if (TEMPLATES_HASH != NULL) {
290                 BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
291                 TEMPLATES_HASH = NULL;
292         }
293
294         if (TEMPLATE_RIGG != NULL) {
295                 RIG_freeRigGraph((BGraph *)TEMPLATE_RIGG);
296                 TEMPLATE_RIGG = NULL;
297         }
298 }
299
300 void  BIF_setTemplate(bContext *C, int index)
301 {
302         ToolSettings *ts = CTX_data_tool_settings(C);
303         if (index > 0) {
304                 ts->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
305         }
306         else {
307                 ts->skgen_template = NULL;
308
309                 if (TEMPLATE_RIGG != NULL) {
310                         RIG_freeRigGraph((BGraph *)TEMPLATE_RIGG);
311                 }
312                 TEMPLATE_RIGG = NULL;
313         }
314 }
315
316 /*********************** CONVERSION ***************************/
317
318 static void sk_autoname(bContext *C, ReebArc *arc)
319 {
320         ToolSettings *ts = CTX_data_tool_settings(C);
321         if (ts->skgen_retarget_options & SK_RETARGET_AUTONAME) {
322                 if (arc == NULL) {
323                         char *num = ts->skgen_num_string;
324                         int i = atoi(num);
325                         i++;
326                         BLI_snprintf(num, 8, "%i", i);
327                 }
328                 else {
329                         char *side = ts->skgen_side_string;
330                         int valid = 0;
331                         int caps = 0;
332
333                         if (side[0] == '\0') {
334                                 valid = 1;
335                         }
336                         else if (STREQ(side, "R") || STREQ(side, "L")) {
337                                 valid = 1;
338                                 caps = 1;
339                         }
340                         else if (STREQ(side, "r") || STREQ(side, "l")) {
341                                 valid = 1;
342                                 caps = 0;
343                         }
344
345                         if (valid) {
346                                 if (arc->head->p[0] < 0) {
347                                         BLI_snprintf(side, 8, caps ? "R" : "r");
348                                 }
349                                 else {
350                                         BLI_snprintf(side, 8, caps ? "L" : "l");
351                                 }
352                         }
353                 }
354         }
355 }
356
357 static ReebNode *sk_pointToNode(SK_Point *pt, float imat[4][4], float tmat[3][3])
358 {
359         ReebNode *node;
360
361         node = MEM_callocN(sizeof(ReebNode), "reeb node");
362         copy_v3_v3(node->p, pt->p);
363         mul_m4_v3(imat, node->p);
364
365         copy_v3_v3(node->no, pt->no);
366         mul_m3_v3(tmat, node->no);
367
368         return node;
369 }
370
371 static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[4][4], float tmat[3][3])
372 {
373         ReebArc *arc;
374         int i;
375
376         arc = MEM_callocN(sizeof(ReebArc), "reeb arc");
377         arc->head = sk_pointToNode(stk->points, imat, tmat);
378         arc->tail = sk_pointToNode(sk_lastStrokePoint(stk), imat, tmat);
379
380         arc->bcount = stk->nb_points - 2; /* first and last are nodes, don't count */
381         arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "Buckets");
382
383         for (i = 0; i < arc->bcount; i++) {
384                 copy_v3_v3(arc->buckets[i].p, stk->points[i + 1].p);
385                 mul_m4_v3(imat, arc->buckets[i].p);
386
387                 copy_v3_v3(arc->buckets[i].no, stk->points[i + 1].no);
388                 mul_m3_v3(tmat, arc->buckets[i].no);
389         }
390
391         return arc;
392 }
393
394 static void sk_retargetStroke(bContext *C, SK_Stroke *stk)
395 {
396         ToolSettings *ts = CTX_data_tool_settings(C);
397         Object *obedit = CTX_data_edit_object(C);
398         float imat[4][4];
399         float tmat[3][3];
400         ReebArc *arc;
401         RigGraph *rg;
402
403         invert_m4_m4(imat, obedit->obmat);
404         transpose_m3_m4(tmat, obedit->obmat);
405
406         arc = sk_strokeToArc(stk, imat, tmat);
407
408         sk_autoname(C, arc);
409
410         rg = sk_makeTemplateGraph(C, ts->skgen_template);
411
412         BIF_retargetArc(C, arc, rg);
413
414         sk_autoname(C, NULL);
415
416         MEM_freeN(arc->head);
417         MEM_freeN(arc->tail);
418         REEB_freeArc((BArc *)arc);
419 }
420
421 /**************************************************************/
422
423 static void sk_cancelStroke(SK_Sketch *sketch)
424 {
425         if (sketch->active_stroke != NULL) {
426                 sk_resetOverdraw(sketch);
427                 sk_removeStroke(sketch, sketch->active_stroke);
428         }
429 }
430
431
432 static float sk_clampPointSize(SK_Point *pt, float size)
433 {
434         return max_ff(size * pt->size, size / 2);
435 }
436
437 static void sk_drawPoint(GLUquadric *quad, SK_Point *pt, float size)
438 {
439         glTranslate3fv(pt->p);
440         gluSphere(quad, sk_clampPointSize(pt, size), 8, 8);
441 }
442
443 static void sk_drawEdge(GLUquadric *quad, SK_Point *pt0, SK_Point *pt1, float size)
444 {
445         float vec1[3], vec2[3] = {0, 0, 1}, axis[3];
446         float angle, length;
447
448         sub_v3_v3v3(vec1, pt1->p, pt0->p);
449         length = normalize_v3(vec1);
450         cross_v3_v3v3(axis, vec2, vec1);
451
452         if (is_zero_v3(axis)) {
453                 axis[1] = 1;
454         }
455
456         angle = angle_normalized_v3v3(vec2, vec1);
457
458         glRotate3fv(angle * (float)(180.0 / M_PI) + 180.0f, axis);
459
460         gluCylinder(quad, sk_clampPointSize(pt1, size), sk_clampPointSize(pt0, size), length, 8, 8);
461 }
462
463 static void sk_drawNormal(GLUquadric *quad, SK_Point *pt, float size, float height)
464 {
465         float vec2[3] = {0, 0, 1}, axis[3];
466         float angle;
467         
468         glPushMatrix();
469
470         cross_v3_v3v3(axis, vec2, pt->no);
471
472         if (is_zero_v3(axis)) {
473                 axis[1] = 1;
474         }
475
476         angle = angle_normalized_v3v3(vec2, pt->no);
477
478         glRotate3fv(angle * (float)(180.0 / M_PI), axis);
479
480         glColor3f(0, 1, 1);
481         gluCylinder(quad, sk_clampPointSize(pt, size), 0, sk_clampPointSize(pt, height), 10, 2);
482
483         glPopMatrix();
484 }
485
486 static void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int end)
487 {
488         float rgb[3];
489         int i;
490         GLUquadric *quad = gluNewQuadric();
491         gluQuadricNormals(quad, GLU_SMOOTH);
492
493         if (id != -1) {
494                 GPU_select_load_id(id);
495
496                 for (i = 0; i < stk->nb_points; i++) {
497                         glPushMatrix();
498
499                         sk_drawPoint(quad, stk->points + i, 0.1);
500
501                         if (i > 0) {
502                                 sk_drawEdge(quad, stk->points + i - 1, stk->points + i, 0.1);
503                         }
504
505                         glPopMatrix();
506                 }
507
508         }
509         else {
510                 float d_rgb[3] = {1, 1, 1};
511
512                 copy_v3_v3(rgb, color);
513                 sub_v3_v3(d_rgb, rgb);
514                 mul_v3_fl(d_rgb, 1.0f / (float)stk->nb_points);
515
516                 for (i = 0; i < stk->nb_points; i++) {
517                         SK_Point *pt = stk->points + i;
518
519                         glPushMatrix();
520
521                         if (pt->type == PT_EXACT) {
522                                 glColor3f(0, 0, 0);
523                                 sk_drawPoint(quad, pt, 0.15);
524                                 sk_drawNormal(quad, pt, 0.05, 0.9);
525                         }
526
527                         if (i >= start && i <= end) {
528                                 glColor3f(0.3, 0.3, 0.3);
529                         }
530                         else {
531                                 glColor3fv(rgb);
532                         }
533
534                         if (pt->type != PT_EXACT) {
535
536                                 sk_drawPoint(quad, pt, 0.1);
537                         }
538
539                         if (i > 0) {
540                                 sk_drawEdge(quad, pt - 1, pt, 0.1);
541                         }
542
543                         glPopMatrix();
544
545                         add_v3_v3(rgb, d_rgb);
546                 }
547         }
548
549         gluDeleteQuadric(quad);
550 }
551
552 static void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *iter, NextSubdivisionFunc next_subdividion)
553 {
554         SK_Stroke *stk = ((SK_StrokeIterator *)iter)->stroke;
555         float head[3], tail[3];
556         int bone_start = 0;
557         int end = iter->length;
558         int index;
559         GLUquadric *quad = gluNewQuadric();
560         gluQuadricNormals(quad, GLU_SMOOTH);
561
562         iter->head(iter);
563         copy_v3_v3(head, iter->p);
564
565         index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
566         while (index != -1) {
567                 SK_Point *pt = stk->points + index;
568
569                 glPushMatrix();
570
571                 glColor3f(0, 1, 0);
572                 sk_drawPoint(quad, pt, 0.15);
573
574                 sk_drawNormal(quad, pt, 0.05, 0.9);
575
576                 glPopMatrix();
577
578                 copy_v3_v3(head, tail);
579                 bone_start = index; // start next bone from current index
580
581                 index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
582         }
583
584         gluDeleteQuadric(quad);
585 }
586
587 static void sk_drawStrokeSubdivision(ToolSettings *toolsettings, SK_Stroke *stk)
588 {
589         int head_index = -1;
590         int i;
591
592         if (toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET) {
593                 return;
594         }
595
596
597         for (i = 0; i < stk->nb_points; i++) {
598                 SK_Point *pt = stk->points + i;
599
600                 if (pt->type == PT_EXACT || i == stk->nb_points - 1) /* stop on exact or on last point */ {
601                         if (head_index == -1) {
602                                 head_index = i;
603                         }
604                         else {
605                                 if (i - head_index > 1) {
606                                         SK_StrokeIterator sk_iter;
607                                         BArcIterator *iter = (BArcIterator *)&sk_iter;
608
609                                         initStrokeIterator(iter, stk, head_index, i);
610
611                                         if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE) {
612                                                 drawSubdividedStrokeBy(toolsettings, iter, nextAdaptativeSubdivision);
613                                         }
614                                         else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH) {
615                                                 drawSubdividedStrokeBy(toolsettings, iter, nextLengthSubdivision);
616                                         }
617                                         else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED) {
618                                                 drawSubdividedStrokeBy(toolsettings, iter, nextFixedSubdivision);
619                                         }
620
621                                 }
622
623                                 head_index = i;
624                         }
625                 }
626         }
627 }
628
629 static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], float *r_dist_px, int *index, int all_pts)
630 {
631         ARegion *ar = CTX_wm_region(C);
632         SK_Point *pt = NULL;
633         int i;
634
635         for (i = 0; i < stk->nb_points; i++) {
636                 if (all_pts || stk->points[i].type == PT_EXACT) {
637                         short pval[2];
638                         int pdist;
639
640                         if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
641
642                                 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
643
644                                 if (pdist < *r_dist_px) {
645                                         *r_dist_px = pdist;
646                                         pt = stk->points + i;
647
648                                         if (index != NULL) {
649                                                 *index = i;
650                                         }
651                                 }
652                         }
653                 }
654         }
655
656         return pt;
657 }
658
659 #if 0 /* UNUSED 2.5 */
660 static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, int mval[2], int *dist)
661 {
662         ARegion *ar = CTX_wm_region(C);
663         SK_Point *pt = NULL;
664         EditBone *bone;
665
666         for (bone = ebones->first; bone; bone = bone->next)
667         {
668                 float vec[3];
669                 short pval[2];
670                 int pdist;
671
672                 if ((bone->flag & BONE_CONNECTED) == 0)
673                 {
674                         copy_v3_v3(vec, bone->head);
675                         mul_m4_v3(ob->obmat, vec);
676                         if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
677
678                                 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
679
680                                 if (pdist < *dist)
681                                 {
682                                         *dist = pdist;
683                                         pt = &boneSnap;
684                                         copy_v3_v3(pt->p, vec);
685                                         pt->type = PT_EXACT;
686                                 }
687                         }
688                 }
689
690
691                 copy_v3_v3(vec, bone->tail);
692                 mul_m4_v3(ob->obmat, vec);
693                 if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
694
695                         pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
696
697                         if (pdist < *dist)
698                         {
699                                 *dist = pdist;
700                                 pt = &boneSnap;
701                                 copy_v3_v3(pt->p, vec);
702                                 pt->type = PT_EXACT;
703                         }
704                 }
705         }
706
707         return pt;
708 }
709 #endif
710
711 void sk_resetOverdraw(SK_Sketch *sketch)
712 {
713         sketch->over.target = NULL;
714         sketch->over.start = -1;
715         sketch->over.end = -1;
716         sketch->over.count = 0;
717 }
718
719 int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk)
720 {
721         return sketch->over.target &&
722                sketch->over.count >= SK_OVERDRAW_LIMIT &&
723                (sketch->over.target == stk || stk == NULL) &&
724                (sketch->over.start != -1 || sketch->over.end != -1);
725 }
726
727 static void sk_updateOverdraw(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
728 {
729         if (sketch->over.target == NULL) {
730                 SK_Stroke *target;
731                 int closest_index = -1;
732                 float dist_px = SNAP_MIN_DISTANCE * 2;
733
734                 for (target = sketch->strokes.first; target; target = target->next) {
735                         if (target != stk) {
736                                 int index;
737
738                                 SK_Point *spt = sk_snapPointStroke(C, target, dd->mval, &dist_px, &index, 1);
739
740                                 if (spt != NULL) {
741                                         sketch->over.target = target;
742                                         closest_index = index;
743                                 }
744                         }
745                 }
746
747                 if (sketch->over.target != NULL) {
748                         if (closest_index > -1) {
749                                 if (sk_lastStrokePoint(stk)->type == PT_EXACT) {
750                                         sketch->over.count = SK_OVERDRAW_LIMIT;
751                                 }
752                                 else {
753                                         sketch->over.count++;
754                                 }
755                         }
756
757                         if (stk->nb_points == 1) {
758                                 sketch->over.start = closest_index;
759                         }
760                         else {
761                                 sketch->over.end = closest_index;
762                         }
763                 }
764         }
765         else if (sketch->over.target != NULL) {
766                 SK_Point *closest_pt = NULL;
767                 float dist_px = SNAP_MIN_DISTANCE * 2;
768                 int index;
769
770                 closest_pt = sk_snapPointStroke(C, sketch->over.target, dd->mval, &dist_px, &index, 1);
771
772                 if (closest_pt != NULL) {
773                         if (sk_lastStrokePoint(stk)->type == PT_EXACT) {
774                                 sketch->over.count = SK_OVERDRAW_LIMIT;
775                         }
776                         else {
777                                 sketch->over.count++;
778                         }
779
780                         sketch->over.end = index;
781                 }
782                 else {
783                         sketch->over.end = -1;
784                 }
785         }
786 }
787
788 /* return 1 on reverse needed */
789 static int sk_adjustIndexes(SK_Sketch *sketch, int *start, int *end)
790 {
791         int retval = 0;
792
793         *start = sketch->over.start;
794         *end = sketch->over.end;
795
796         if (*start == -1) {
797                 *start = 0;
798         }
799
800         if (*end == -1) {
801                 *end = sketch->over.target->nb_points - 1;
802         }
803
804         if (*end < *start) {
805                 int tmp = *start;
806                 *start = *end;
807                 *end = tmp;
808                 retval = 1;
809         }
810
811         return retval;
812 }
813
814 static void sk_endOverdraw(SK_Sketch *sketch)
815 {
816         SK_Stroke *stk = sketch->active_stroke;
817
818         if (sk_hasOverdraw(sketch, NULL)) {
819                 int start;
820                 int end;
821
822                 if (sk_adjustIndexes(sketch, &start, &end)) {
823                         sk_reverseStroke(stk);
824                 }
825
826                 if (stk->nb_points > 1) {
827                         stk->points->type = sketch->over.target->points[start].type;
828                         sk_lastStrokePoint(stk)->type = sketch->over.target->points[end].type;
829                 }
830
831                 sk_insertStrokePoints(sketch->over.target, stk->points, stk->nb_points, start, end);
832
833                 sk_removeStroke(sketch, stk);
834
835                 sk_resetOverdraw(sketch);
836         }
837 }
838
839
840 static void sk_startStroke(SK_Sketch *sketch)
841 {
842         SK_Stroke *stk = sk_createStroke();
843
844         BLI_addtail(&sketch->strokes, stk);
845         sketch->active_stroke = stk;
846
847         sk_resetOverdraw(sketch);
848 }
849
850 static void sk_endStroke(bContext *C, SK_Sketch *sketch)
851 {
852         ToolSettings *ts = CTX_data_tool_settings(C);
853         sk_shrinkStrokeBuffer(sketch->active_stroke);
854
855         if (ts->bone_sketching & BONE_SKETCHING_ADJUST) {
856                 sk_endOverdraw(sketch);
857         }
858
859         sketch->active_stroke = NULL;
860 }
861
862 static void sk_updateDrawData(SK_DrawData *dd)
863 {
864         dd->type = PT_CONTINUOUS;
865
866         dd->previous_mval[0] = dd->mval[0];
867         dd->previous_mval[1] = dd->mval[1];
868 }
869
870 static float sk_distanceDepth(bContext *C, float p1[3], float p2[3])
871 {
872         ARegion *ar = CTX_wm_region(C);
873         RegionView3D *rv3d = ar->regiondata;
874         float vec[3];
875         float distance;
876
877         sub_v3_v3v3(vec, p1, p2);
878
879         project_v3_v3v3(vec, vec, rv3d->viewinv[2]);
880
881         distance = len_v3(vec);
882
883         if (dot_v3v3(rv3d->viewinv[2], vec) > 0) {
884                 distance *= -1;
885         }
886
887         return distance;
888 }
889
890 static void sk_interpolateDepth(bContext *C, SK_Stroke *stk, int start, int end, float length, float distance)
891 {
892         ARegion *ar = CTX_wm_region(C);
893         ScrArea *sa = CTX_wm_area(C);
894         View3D *v3d = sa->spacedata.first;
895
896         float progress = 0;
897         int i;
898
899         progress = len_v3v3(stk->points[start].p, stk->points[start - 1].p);
900
901         for (i = start; i <= end; i++) {
902                 float ray_start[3], ray_normal[3];
903                 float delta = len_v3v3(stk->points[i].p, stk->points[i + 1].p);
904                 float pval[2] = {0, 0};
905
906                 ED_view3d_project_float_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP);
907                 ED_view3d_win_to_ray(ar, v3d, pval, ray_start, ray_normal, false);
908
909                 mul_v3_fl(ray_normal, distance * progress / length);
910                 add_v3_v3(stk->points[i].p, ray_normal);
911
912                 progress += delta;
913         }
914 }
915
916 static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_DrawData *dd)
917 {
918         ARegion *ar = CTX_wm_region(C);
919         /* copied from grease pencil, need fixing */
920         SK_Point *last = sk_lastStrokePoint(stk);
921         short cval[2];
922         float fp[3] = {0, 0, 0};
923         float dvec[3];
924         float mval_f[2];
925         float zfac;
926
927         if (last != NULL) {
928                 copy_v3_v3(fp, last->p);
929         }
930
931         zfac = ED_view3d_calc_zfac(ar->regiondata, fp, NULL);
932
933         if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
934                 VECSUB2D(mval_f, cval, dd->mval);
935                 ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
936                 sub_v3_v3v3(vec, fp, dvec);
937         }
938         else {
939                 zero_v3(vec);
940         }
941 }
942
943 static int sk_getStrokeDrawPoint(bContext *C, SK_Point *pt, SK_Sketch *UNUSED(sketch), SK_Stroke *stk, SK_DrawData *dd)
944 {
945         pt->type = dd->type;
946         pt->mode = PT_PROJECT;
947         sk_projectDrawPoint(C, pt->p, stk, dd);
948
949         return 1;
950 }
951
952 static int sk_addStrokeDrawPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
953 {
954         ARegion *ar = CTX_wm_region(C);
955         RegionView3D *rv3d = ar->regiondata;
956         SK_Point pt;
957
958         sk_initPoint(&pt, dd, rv3d->viewinv[2]);
959
960         sk_getStrokeDrawPoint(C, &pt, sketch, stk, dd);
961
962         sk_appendStrokePoint(stk, &pt);
963
964         return 1;
965 }
966
967 static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
968 {
969         ToolSettings *ts = CTX_data_tool_settings(C);
970         int point_added = 0;
971
972         if (ts->snap_mode == SCE_SNAP_MODE_VOLUME) {
973                 DepthPeel *p1, *p2;
974                 float *last_p = NULL;
975                 float dist = FLT_MAX;
976                 float p[3] = {0};
977                 float size = 0;
978                 float mvalf[2];
979
980                 BLI_freelistN(&sketch->depth_peels);
981                 BLI_listbase_clear(&sketch->depth_peels);
982
983                 mvalf[0] = dd->mval[0];
984                 mvalf[1] = dd->mval[1];
985                 peelObjectsContext(C, &sketch->depth_peels, mvalf, SNAP_ALL);
986
987                 if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS) {
988                         last_p = stk->points[stk->nb_points - 1].p;
989                 }
990                 else if (LAST_SNAP_POINT_VALID) {
991                         last_p = LAST_SNAP_POINT;
992                 }
993
994
995                 for (p1 = sketch->depth_peels.first; p1; p1 = p1->next) {
996                         if (p1->flag == 0) {
997                                 float vec[3];
998                                 float new_dist;
999                                 float new_size = 0;
1000
1001                                 p2 = NULL;
1002                                 p1->flag = 1;
1003
1004                                 /* if peeling objects, take the first and last from each object */
1005                                 if (ts->snap_flag & SCE_SNAP_PEEL_OBJECT) {
1006                                         DepthPeel *peel;
1007                                         for (peel = p1->next; peel; peel = peel->next) {
1008                                                 if (peel->ob == p1->ob) {
1009                                                         peel->flag = 1;
1010                                                         p2 = peel;
1011                                                 }
1012                                         }
1013                                 }
1014                                 /* otherwise, pair first with second and so on */
1015                                 else {
1016                                         for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next) {
1017                                                 /* nothing to do here */
1018                                         }
1019                                 }
1020
1021                                 if (p2) {
1022                                         p2->flag = 1;
1023
1024                                         add_v3_v3v3(vec, p1->p, p2->p);
1025                                         mul_v3_fl(vec, 0.5f);
1026                                         new_size = len_v3v3(p1->p, p2->p);
1027                                 }
1028                                 else {
1029                                         copy_v3_v3(vec, p1->p);
1030                                 }
1031
1032                                 if (last_p == NULL) {
1033                                         copy_v3_v3(p, vec);
1034                                         size = new_size;
1035                                         dist = 0;
1036                                         break;
1037                                 }
1038
1039                                 new_dist = len_v3v3(last_p, vec);
1040
1041                                 if (new_dist < dist) {
1042                                         copy_v3_v3(p, vec);
1043                                         dist = new_dist;
1044                                         size = new_size;
1045                                 }
1046                         }
1047                 }
1048
1049                 if (dist != FLT_MAX) {
1050                         pt->type = dd->type;
1051                         pt->mode = PT_SNAP;
1052                         pt->size = size / 2;
1053                         copy_v3_v3(pt->p, p);
1054
1055                         point_added = 1;
1056                 }
1057
1058                 //BLI_freelistN(&depth_peels);
1059         }
1060         else {
1061                 SK_Stroke *snap_stk;
1062                 float vec[3];
1063                 float no[3];
1064                 float mval[2];
1065                 int found = 0;
1066                 float dist_px = SNAP_MIN_DISTANCE; // Use a user defined value here
1067
1068                 /* snap to strokes */
1069                 // if (ts->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
1070                 for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next) {
1071                         SK_Point *spt = NULL;
1072                         if (snap_stk == stk) {
1073                                 spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist_px, NULL, 0);
1074                         }
1075                         else {
1076                                 spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist_px, NULL, 1);
1077                         }
1078
1079                         if (spt != NULL) {
1080                                 copy_v3_v3(pt->p, spt->p);
1081                                 point_added = 1;
1082                         }
1083                 }
1084                 
1085                 mval[0] = dd->mval[0];
1086                 mval[1] = dd->mval[1];
1087
1088                 /* try to snap to closer object */
1089                 found = snapObjectsContext(C, mval, &dist_px, vec, no, SNAP_NOT_SELECTED);
1090                 if (found == 1) {
1091                         pt->type = dd->type;
1092                         pt->mode = PT_SNAP;
1093                         copy_v3_v3(pt->p, vec);
1094
1095                         point_added = 1;
1096                 }
1097         }
1098
1099         return point_added;
1100 }
1101
1102 static int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1103 {
1104         int point_added;
1105         ARegion *ar = CTX_wm_region(C);
1106         RegionView3D *rv3d = ar->regiondata;
1107         SK_Point pt;
1108
1109         sk_initPoint(&pt, dd, rv3d->viewinv[2]);
1110
1111         point_added = sk_getStrokeSnapPoint(C, &pt, sketch, stk, dd);
1112
1113         if (point_added) {
1114                 float final_p[3];
1115                 float length, distance;
1116                 int total;
1117                 int i;
1118
1119                 copy_v3_v3(final_p, pt.p);
1120
1121                 sk_projectDrawPoint(C, pt.p, stk, dd);
1122                 sk_appendStrokePoint(stk, &pt);
1123
1124                 /* update all previous point to give smooth Z progresion */
1125                 total = 0;
1126                 length = 0;
1127                 for (i = stk->nb_points - 2; i > 0; i--) {
1128                         length += len_v3v3(stk->points[i].p, stk->points[i + 1].p);
1129                         total++;
1130                         if (stk->points[i].mode == PT_SNAP || stk->points[i].type == PT_EXACT) {
1131                                 break;
1132                         }
1133                 }
1134
1135                 if (total > 1) {
1136                         distance = sk_distanceDepth(C, final_p, stk->points[i].p);
1137
1138                         sk_interpolateDepth(C, stk, i + 1, stk->nb_points - 2, length, distance);
1139                 }
1140
1141                 copy_v3_v3(stk->points[stk->nb_points - 1].p, final_p);
1142
1143                 point_added = 1;
1144         }
1145
1146         return point_added;
1147 }
1148
1149 static void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, const bool snap)
1150 {
1151         ToolSettings *ts = CTX_data_tool_settings(C);
1152         int point_added = 0;
1153
1154         if (snap) {
1155                 point_added = sk_addStrokeSnapPoint(C, sketch, stk, dd);
1156         }
1157
1158         if (point_added == 0) {
1159                 point_added = sk_addStrokeDrawPoint(C, sketch, stk, dd);
1160         }
1161
1162         if (stk == sketch->active_stroke && ts->bone_sketching & BONE_SKETCHING_ADJUST) {
1163                 sk_updateOverdraw(C, sketch, stk, dd);
1164         }
1165 }
1166
1167 static void sk_getStrokePoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, const bool snap)
1168 {
1169         int point_added = 0;
1170
1171         if (snap) {
1172                 point_added = sk_getStrokeSnapPoint(C, pt, sketch, stk, dd);
1173                 LAST_SNAP_POINT_VALID = 1;
1174                 copy_v3_v3(LAST_SNAP_POINT, pt->p);
1175         }
1176         else {
1177                 LAST_SNAP_POINT_VALID = 0;
1178         }
1179
1180         if (point_added == 0) {
1181                 point_added = sk_getStrokeDrawPoint(C, pt, sketch, stk, dd);
1182         }
1183 }
1184
1185 /********************************************/
1186
1187 static void *headPoint(void *arg);
1188 static void *tailPoint(void *arg);
1189 static void *nextPoint(void *arg);
1190 static void *nextNPoint(void *arg, int n);
1191 static void *peekPoint(void *arg, int n);
1192 static void *previousPoint(void *arg);
1193 static int   iteratorStopped(void *arg);
1194
1195 static void initIteratorFct(SK_StrokeIterator *iter)
1196 {
1197         iter->head = headPoint;
1198         iter->tail = tailPoint;
1199         iter->peek = peekPoint;
1200         iter->next = nextPoint;
1201         iter->nextN = nextNPoint;
1202         iter->previous = previousPoint;
1203         iter->stopped = iteratorStopped;
1204 }
1205
1206 static SK_Point *setIteratorValues(SK_StrokeIterator *iter, int index)
1207 {
1208         SK_Point *pt = NULL;
1209
1210         if (index >= 0 && index < iter->length) {
1211                 pt = &(iter->stroke->points[iter->start + (iter->stride * index)]);
1212                 iter->p = pt->p;
1213                 iter->no = pt->no;
1214                 iter->size = pt->size;
1215         }
1216         else {
1217                 iter->p = NULL;
1218                 iter->no = NULL;
1219                 iter->size = 0;
1220         }
1221
1222         return pt;
1223 }
1224
1225 void initStrokeIterator(BArcIterator *arg, SK_Stroke *stk, int start, int end)
1226 {
1227         SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
1228
1229         initIteratorFct(iter);
1230         iter->stroke = stk;
1231
1232         if (start < end) {
1233                 iter->start = start + 1;
1234                 iter->end = end - 1;
1235                 iter->stride = 1;
1236         }
1237         else {
1238                 iter->start = start - 1;
1239                 iter->end = end + 1;
1240                 iter->stride = -1;
1241         }
1242
1243         iter->length = iter->stride * (iter->end - iter->start + 1);
1244
1245         iter->index = -1;
1246 }
1247
1248
1249 static void *headPoint(void *arg)
1250 {
1251         SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
1252         SK_Point *result = NULL;
1253
1254         result = &(iter->stroke->points[iter->start - iter->stride]);
1255         iter->p = result->p;
1256         iter->no = result->no;
1257         iter->size = result->size;
1258
1259         return result;
1260 }
1261
1262 static void *tailPoint(void *arg)
1263 {
1264         SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
1265         SK_Point *result = NULL;
1266
1267         result = &(iter->stroke->points[iter->end + iter->stride]);
1268         iter->p = result->p;
1269         iter->no = result->no;
1270         iter->size = result->size;
1271
1272         return result;
1273 }
1274
1275 static void *nextPoint(void *arg)
1276 {
1277         SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
1278         SK_Point *result = NULL;
1279
1280         iter->index++;
1281         if (iter->index < iter->length) {
1282                 result = setIteratorValues(iter, iter->index);
1283         }
1284
1285         return result;
1286 }
1287
1288 static void *nextNPoint(void *arg, int n)
1289 {
1290         SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
1291         SK_Point *result = NULL;
1292
1293         iter->index += n;
1294
1295         /* check if passed end */
1296         if (iter->index < iter->length) {
1297                 result = setIteratorValues(iter, iter->index);
1298         }
1299
1300         return result;
1301 }
1302
1303 static void *peekPoint(void *arg, int n)
1304 {
1305         SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
1306         SK_Point *result = NULL;
1307         int index = iter->index + n;
1308
1309         /* check if passed end */
1310         if (index < iter->length) {
1311                 result = setIteratorValues(iter, index);
1312         }
1313
1314         return result;
1315 }
1316
1317 static void *previousPoint(void *arg)
1318 {
1319         SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
1320         SK_Point *result = NULL;
1321
1322         if (iter->index > 0) {
1323                 iter->index--;
1324                 result = setIteratorValues(iter, iter->index);
1325         }
1326
1327         return result;
1328 }
1329
1330 static int iteratorStopped(void *arg)
1331 {
1332         SK_StrokeIterator *iter = (SK_StrokeIterator *)arg;
1333
1334         if (iter->index >= iter->length) {
1335                 return 1;
1336         }
1337         else {
1338                 return 0;
1339         }
1340 }
1341
1342 static void sk_convertStroke(bContext *C, SK_Stroke *stk)
1343 {
1344         Object *obedit = CTX_data_edit_object(C);
1345         ToolSettings *ts = CTX_data_tool_settings(C);
1346         bArmature *arm = obedit->data;
1347         SK_Point *head;
1348         EditBone *parent = NULL;
1349         float invmat[4][4]; /* move in caller function */
1350         float tmat[3][3];
1351         int head_index = 0;
1352         int i;
1353
1354         head = NULL;
1355
1356         invert_m4_m4(invmat, obedit->obmat);
1357         transpose_m3_m4(tmat, obedit->obmat);
1358
1359         for (i = 0; i < stk->nb_points; i++) {
1360                 SK_Point *pt = stk->points + i;
1361
1362                 if (pt->type == PT_EXACT) {
1363                         if (head == NULL) {
1364                                 head_index = i;
1365                                 head = pt;
1366                         }
1367                         else {
1368                                 EditBone *bone = NULL;
1369                                 EditBone *new_parent;
1370
1371                                 if (i - head_index > 1) {
1372                                         SK_StrokeIterator sk_iter;
1373                                         BArcIterator *iter = (BArcIterator *)&sk_iter;
1374
1375                                         initStrokeIterator(iter, stk, head_index, i);
1376
1377                                         if (ts->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE) {
1378                                                 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
1379                                         }
1380                                         else if (ts->bone_sketching_convert == SK_CONVERT_CUT_LENGTH) {
1381                                                 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
1382                                         }
1383                                         else if (ts->bone_sketching_convert == SK_CONVERT_CUT_FIXED) {
1384                                                 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
1385                                         }
1386                                 }
1387
1388                                 if (bone == NULL) {
1389                                         bone = ED_armature_edit_bone_add(arm, "Bone");
1390
1391                                         copy_v3_v3(bone->head, head->p);
1392                                         copy_v3_v3(bone->tail, pt->p);
1393
1394                                         mul_m4_v3(invmat, bone->head);
1395                                         mul_m4_v3(invmat, bone->tail);
1396                                         setBoneRollFromNormal(bone, head->no, invmat, tmat);
1397                                 }
1398
1399                                 new_parent = bone;
1400                                 bone->flag |= BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
1401
1402                                 /* move to end of chain */
1403                                 while (bone->parent != NULL) {
1404                                         bone = bone->parent;
1405                                         bone->flag |= BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
1406                                 }
1407
1408                                 if (parent != NULL) {
1409                                         bone->parent = parent;
1410                                         bone->flag |= BONE_CONNECTED;
1411                                 }
1412
1413                                 parent = new_parent;
1414                                 head_index = i;
1415                                 head = pt;
1416                         }
1417                 }
1418         }
1419 }
1420
1421 static void sk_convert(bContext *C, SK_Sketch *sketch)
1422 {
1423         ToolSettings *ts = CTX_data_tool_settings(C);
1424         SK_Stroke *stk;
1425
1426         for (stk = sketch->strokes.first; stk; stk = stk->next) {
1427                 if (stk->selected == 1) {
1428                         if (ts->bone_sketching_convert == SK_CONVERT_RETARGET) {
1429                                 sk_retargetStroke(C, stk);
1430                         }
1431                         else {
1432                                 sk_convertStroke(C, stk);
1433                         }
1434 //                      XXX
1435 //                      allqueue(REDRAWBUTSEDIT, 0);
1436                 }
1437         }
1438 }
1439 /******************* GESTURE *************************/
1440
1441
1442 /* returns the number of self intersections */
1443 static int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gesture)
1444 {
1445         ARegion *ar = CTX_wm_region(C);
1446         int added = 0;
1447         int s_i;
1448
1449         for (s_i = 0; s_i < gesture->nb_points - 1; s_i++) {
1450                 float s_p1[3] = {0, 0, 0};
1451                 float s_p2[3] = {0, 0, 0};
1452                 int g_i;
1453
1454                 ED_view3d_project_float_global(ar, gesture->points[s_i].p, s_p1, V3D_PROJ_TEST_NOP);
1455                 ED_view3d_project_float_global(ar, gesture->points[s_i + 1].p, s_p2, V3D_PROJ_TEST_NOP);
1456
1457                 /* start checking from second next, because two consecutive cannot intersect */
1458                 for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++) {
1459                         float g_p1[3] = {0, 0, 0};
1460                         float g_p2[3] = {0, 0, 0};
1461                         float vi[3];
1462                         float lambda;
1463
1464                         ED_view3d_project_float_global(ar, gesture->points[g_i].p, g_p1, V3D_PROJ_TEST_NOP);
1465                         ED_view3d_project_float_global(ar, gesture->points[g_i + 1].p, g_p2, V3D_PROJ_TEST_NOP);
1466
1467                         if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) {
1468                                 SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
1469
1470                                 isect->gesture_index = g_i;
1471                                 isect->before = s_i;
1472                                 isect->after = s_i + 1;
1473                                 isect->stroke = gesture;
1474
1475                                 sub_v3_v3v3(isect->p, gesture->points[s_i + 1].p, gesture->points[s_i].p);
1476                                 mul_v3_fl(isect->p, lambda);
1477                                 add_v3_v3(isect->p, gesture->points[s_i].p);
1478
1479                                 BLI_addtail(list, isect);
1480
1481                                 added++;
1482                         }
1483                 }
1484         }
1485
1486         return added;
1487 }
1488
1489 static int cmpIntersections(const void *i1, const void *i2)
1490 {
1491         const SK_Intersection *isect1 = i1, *isect2 = i2;
1492
1493         if (isect1->stroke == isect2->stroke) {
1494                 if (isect1->before < isect2->before) {
1495                         return -1;
1496                 }
1497                 else if (isect1->before > isect2->before) {
1498                         return 1;
1499                 }
1500                 else {
1501                         if (isect1->lambda < isect2->lambda) {
1502                                 return -1;
1503                         }
1504                         else if (isect1->lambda > isect2->lambda) {
1505                                 return 1;
1506                         }
1507                 }
1508         }
1509
1510         return 0;
1511 }
1512
1513
1514 /* returns the maximum number of intersections per stroke */
1515 static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
1516 {
1517         ARegion *ar = CTX_wm_region(C);
1518         ScrArea *sa = CTX_wm_area(C);
1519         View3D *v3d = sa->spacedata.first;
1520         SK_Stroke *stk;
1521         int added = 0;
1522
1523         for (stk = sketch->strokes.first; stk; stk = stk->next) {
1524                 int s_added = 0;
1525                 int s_i;
1526
1527                 for (s_i = 0; s_i < stk->nb_points - 1; s_i++) {
1528                         float s_p1[3] = {0, 0, 0};
1529                         float s_p2[3] = {0, 0, 0};
1530                         int g_i;
1531
1532                         ED_view3d_project_float_global(ar, stk->points[s_i].p, s_p1, V3D_PROJ_TEST_NOP);
1533                         ED_view3d_project_float_global(ar, stk->points[s_i + 1].p, s_p2, V3D_PROJ_TEST_NOP);
1534
1535                         for (g_i = 0; g_i < gesture->nb_points - 1; g_i++) {
1536                                 float g_p1[3] = {0, 0, 0};
1537                                 float g_p2[3] = {0, 0, 0};
1538                                 float vi[3];
1539                                 float lambda;
1540
1541                                 ED_view3d_project_float_global(ar, gesture->points[g_i].p, g_p1, V3D_PROJ_TEST_NOP);
1542                                 ED_view3d_project_float_global(ar, gesture->points[g_i + 1].p, g_p2, V3D_PROJ_TEST_NOP);
1543
1544                                 if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) {
1545                                         SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
1546                                         float ray_start[3], ray_end[3];
1547                                         float mval[2];
1548
1549                                         isect->gesture_index = g_i;
1550                                         isect->before = s_i;
1551                                         isect->after = s_i + 1;
1552                                         isect->stroke = stk;
1553                                         isect->lambda = lambda;
1554
1555                                         mval[0] = vi[0];
1556                                         mval[1] = vi[1];
1557                                         ED_view3d_win_to_segment(ar, v3d, mval, ray_start, ray_end, true);
1558
1559                                         isect_line_line_v3(stk->points[s_i].p,
1560                                                            stk->points[s_i + 1].p,
1561                                                            ray_start,
1562                                                            ray_end,
1563                                                            isect->p,
1564                                                            vi);
1565
1566                                         BLI_addtail(list, isect);
1567
1568                                         s_added++;
1569                                 }
1570                         }
1571                 }
1572
1573                 added = MAX2(s_added, added);
1574         }
1575
1576         BLI_listbase_sort(list, cmpIntersections);
1577
1578         return added;
1579 }
1580
1581 static int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
1582 {
1583         SK_StrokeIterator sk_iter;
1584         BArcIterator *iter = (BArcIterator *)&sk_iter;
1585
1586         float CORRELATION_THRESHOLD = 0.99f;
1587         float *vec;
1588         int i, j;
1589
1590         sk_appendStrokePoint(segments, &gesture->points[0]);
1591         vec = segments->points[segments->nb_points - 1].p;
1592
1593         initStrokeIterator(iter, gesture, 0, gesture->nb_points - 1);
1594
1595         for (i = 1, j = 0; i < gesture->nb_points; i++) {
1596                 float n[3];
1597
1598                 /* Calculate normal */
1599                 sub_v3_v3v3(n, gesture->points[i].p, vec);
1600
1601                 if (calcArcCorrelation(iter, j, i, vec, n) < CORRELATION_THRESHOLD) {
1602                         j = i - 1;
1603                         sk_appendStrokePoint(segments, &gesture->points[j]);
1604                         vec = segments->points[segments->nb_points - 1].p;
1605                         segments->points[segments->nb_points - 1].type = PT_EXACT;
1606                 }
1607         }
1608
1609         sk_appendStrokePoint(segments, &gesture->points[gesture->nb_points - 1]);
1610
1611         return segments->nb_points - 1;
1612 }
1613
1614 int sk_detectCutGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1615 {
1616         if (gest->nb_segments == 1 && gest->nb_intersections == 1) {
1617                 return 1;
1618         }
1619
1620         return 0;
1621 }
1622
1623 void sk_applyCutGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1624 {
1625         SK_Intersection *isect;
1626
1627         for (isect = gest->intersections.first; isect; isect = isect->next) {
1628                 SK_Point pt;
1629
1630                 pt.type = PT_EXACT;
1631                 pt.mode = PT_PROJECT; /* take mode from neighboring points */
1632                 copy_v3_v3(pt.p, isect->p);
1633                 copy_v3_v3(pt.no, isect->stroke->points[isect->before].no);
1634
1635                 sk_insertStrokePoint(isect->stroke, &pt, isect->after);
1636         }
1637 }
1638
1639 int sk_detectTrimGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1640 {
1641         if (gest->nb_segments == 2 && gest->nb_intersections == 1 && gest->nb_self_intersections == 0) {
1642                 float s1[3], s2[3];
1643                 float angle;
1644
1645                 sub_v3_v3v3(s1, gest->segments->points[1].p, gest->segments->points[0].p);
1646                 sub_v3_v3v3(s2, gest->segments->points[2].p, gest->segments->points[1].p);
1647
1648                 angle = RAD2DEGF(angle_v2v2(s1, s2));
1649
1650                 if (angle > 60 && angle < 120) {
1651                         return 1;
1652                 }
1653         }
1654
1655         return 0;
1656 }
1657
1658 void sk_applyTrimGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1659 {
1660         SK_Intersection *isect;
1661         float trim_dir[3];
1662
1663         sub_v3_v3v3(trim_dir, gest->segments->points[2].p, gest->segments->points[1].p);
1664
1665         for (isect = gest->intersections.first; isect; isect = isect->next) {
1666                 SK_Point pt;
1667                 float stroke_dir[3];
1668
1669                 pt.type = PT_EXACT;
1670                 pt.mode = PT_PROJECT; /* take mode from neighboring points */
1671                 copy_v3_v3(pt.p, isect->p);
1672                 copy_v3_v3(pt.no, isect->stroke->points[isect->before].no);
1673
1674                 sub_v3_v3v3(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p);
1675
1676                 /* same direction, trim end */
1677                 if (dot_v3v3(stroke_dir, trim_dir) > 0) {
1678                         sk_replaceStrokePoint(isect->stroke, &pt, isect->after);
1679                         sk_trimStroke(isect->stroke, 0, isect->after);
1680                 }
1681                 /* else, trim start */
1682                 else {
1683                         sk_replaceStrokePoint(isect->stroke, &pt, isect->before);
1684                         sk_trimStroke(isect->stroke, isect->before, isect->stroke->nb_points - 1);
1685                 }
1686
1687         }
1688 }
1689
1690 int sk_detectCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1691 {
1692         if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1) {
1693                 SK_Intersection *isect, *self_isect;
1694
1695                 /* get the last intersection of the first pair */
1696                 for (isect = gest->intersections.first; isect; isect = isect->next) {
1697                         if (isect->stroke == isect->next->stroke) {
1698                                 isect = isect->next;
1699                                 break;
1700                         }
1701                 }
1702
1703                 self_isect = gest->self_intersections.first;
1704
1705                 if (isect && isect->gesture_index < self_isect->gesture_index) {
1706                         return 1;
1707                 }
1708         }
1709
1710         return 0;
1711 }
1712
1713 void sk_applyCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1714 {
1715         SK_Intersection *isect;
1716         int command = 1;
1717
1718 /*      XXX */
1719 /*      command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3"); */
1720         if (command < 1) return;
1721
1722         for (isect = gest->intersections.first; isect; isect = isect->next) {
1723                 SK_Intersection *i2;
1724
1725                 i2 = isect->next;
1726
1727                 if (i2 && i2->stroke == isect->stroke) {
1728                         switch (command) {
1729                                 case 1:
1730                                         sk_flattenStroke(isect->stroke, isect->before, i2->after);
1731                                         break;
1732                                 case 2:
1733                                         sk_straightenStroke(isect->stroke, isect->before, i2->after, isect->p, i2->p);
1734                                         break;
1735                                 case 3:
1736                                         sk_polygonizeStroke(isect->stroke, isect->before, i2->after);
1737                                         break;
1738                         }
1739
1740                         isect = i2;
1741                 }
1742         }
1743 }
1744
1745 int sk_detectDeleteGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1746 {
1747         if (gest->nb_segments == 2 && gest->nb_intersections == 2) {
1748                 float s1[3], s2[3];
1749                 float angle;
1750
1751                 sub_v3_v3v3(s1, gest->segments->points[1].p, gest->segments->points[0].p);
1752                 sub_v3_v3v3(s2, gest->segments->points[2].p, gest->segments->points[1].p);
1753
1754                 angle = RAD2DEGF(angle_v2v2(s1, s2));
1755
1756                 if (angle > 120) {
1757                         return 1;
1758                 }
1759         }
1760
1761         return 0;
1762 }
1763
1764 void sk_applyDeleteGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *sketch)
1765 {
1766         SK_Intersection *isect;
1767
1768         for (isect = gest->intersections.first; isect; isect = isect->next) {
1769                 /* only delete strokes that are crossed twice */
1770                 if (isect->next && isect->next->stroke == isect->stroke) {
1771                         isect = isect->next;
1772
1773                         sk_removeStroke(sketch, isect->stroke);
1774                 }
1775         }
1776 }
1777
1778 int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1779 {
1780         ARegion *ar = CTX_wm_region(C);
1781         if (gest->nb_segments > 2 && gest->nb_intersections == 2) {
1782                 int start_val[2], end_val[2];
1783                 int dist;
1784
1785                 if ((ED_view3d_project_int_global(ar, gest->stk->points[0].p,           start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
1786                     (ED_view3d_project_int_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val,   V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
1787                 {
1788                         dist = len_manhattan_v2v2_int(start_val, end_val);
1789
1790                         /* if gesture is a circle */
1791                         if (dist <= 20) {
1792                                 SK_Intersection *isect;
1793
1794                                 /* check if it circled around an exact point */
1795                                 for (isect = gest->intersections.first; isect; isect = isect->next) {
1796                                         /* only delete strokes that are crossed twice */
1797                                         if (isect->next && isect->next->stroke == isect->stroke) {
1798                                                 int start_index, end_index;
1799                                                 int i;
1800
1801                                                 start_index = MIN2(isect->after, isect->next->after);
1802                                                 end_index = MAX2(isect->before, isect->next->before);
1803
1804                                                 for (i = start_index; i <= end_index; i++) {
1805                                                         if (isect->stroke->points[i].type == PT_EXACT) {
1806                                                                 return 1; /* at least one exact point found, stop detect here */
1807                                                         }
1808                                                 }
1809
1810                                                 /* skip next */
1811                                                 isect = isect->next;
1812                                         }
1813                                 }
1814                         }
1815                 }
1816         }
1817
1818         return 0;
1819 }
1820
1821 void sk_applyMergeGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1822 {
1823         SK_Intersection *isect;
1824
1825         /* check if it circled around an exact point */
1826         for (isect = gest->intersections.first; isect; isect = isect->next) {
1827                 /* only merge strokes that are crossed twice */
1828                 if (isect->next && isect->next->stroke == isect->stroke) {
1829                         int start_index, end_index;
1830                         int i;
1831
1832                         start_index = MIN2(isect->after, isect->next->after);
1833                         end_index = MAX2(isect->before, isect->next->before);
1834
1835                         for (i = start_index; i <= end_index; i++) {
1836                                 /* if exact, switch to continuous */
1837                                 if (isect->stroke->points[i].type == PT_EXACT) {
1838                                         isect->stroke->points[i].type = PT_CONTINUOUS;
1839                                 }
1840                         }
1841
1842                         /* skip next */
1843                         isect = isect->next;
1844                 }
1845         }
1846 }
1847
1848 int sk_detectReverseGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1849 {
1850         if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 0) {
1851                 SK_Intersection *isect;
1852
1853                 /* check if it circled around an exact point */
1854                 for (isect = gest->intersections.first; isect; isect = isect->next) {
1855                         /* only delete strokes that are crossed twice */
1856                         if (isect->next && isect->next->stroke == isect->stroke) {
1857                                 float start_v[3], end_v[3];
1858                                 float angle;
1859
1860                                 if (isect->gesture_index < isect->next->gesture_index) {
1861                                         sub_v3_v3v3(start_v, isect->p, gest->stk->points[0].p);
1862                                         sub_v3_v3v3(end_v, sk_lastStrokePoint(gest->stk)->p, isect->next->p);
1863                                 }
1864                                 else {
1865                                         sub_v3_v3v3(start_v, isect->next->p, gest->stk->points[0].p);
1866                                         sub_v3_v3v3(end_v, sk_lastStrokePoint(gest->stk)->p, isect->p);
1867                                 }
1868
1869                                 angle = RAD2DEGF(angle_v2v2(start_v, end_v));
1870
1871                                 if (angle > 120) {
1872                                         return 1;
1873                                 }
1874
1875                                 /* skip next */
1876                                 isect = isect->next;
1877                         }
1878                 }
1879         }
1880
1881         return 0;
1882 }
1883
1884 void sk_applyReverseGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1885 {
1886         SK_Intersection *isect;
1887
1888         for (isect = gest->intersections.first; isect; isect = isect->next) {
1889                 /* only reverse strokes that are crossed twice */
1890                 if (isect->next && isect->next->stroke == isect->stroke) {
1891                         sk_reverseStroke(isect->stroke);
1892
1893                         /* skip next */
1894                         isect = isect->next;
1895                 }
1896         }
1897 }
1898
1899 int sk_detectConvertGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1900 {
1901         if (gest->nb_segments == 3 && gest->nb_self_intersections == 1) {
1902                 return 1;
1903         }
1904         return 0;
1905 }
1906
1907 void sk_applyConvertGesture(bContext *C, SK_Gesture *UNUSED(gest), SK_Sketch *sketch)
1908 {
1909         sk_convert(C, sketch);
1910 }
1911
1912 static void sk_initGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
1913 {
1914         BLI_listbase_clear(&gest->intersections);
1915         BLI_listbase_clear(&gest->self_intersections);
1916
1917         gest->segments = sk_createStroke();
1918         gest->stk = sketch->gesture;
1919
1920         gest->nb_self_intersections = sk_getSelfIntersections(C, &gest->self_intersections, gest->stk);
1921         gest->nb_intersections = sk_getIntersections(C, &gest->intersections, sketch, gest->stk);
1922         gest->nb_segments = sk_getSegments(gest->segments, gest->stk);
1923 }
1924
1925 static void sk_freeGesture(SK_Gesture *gest)
1926 {
1927         sk_freeStroke(gest->segments);
1928         BLI_freelistN(&gest->intersections);
1929         BLI_freelistN(&gest->self_intersections);
1930 }
1931
1932 static void sk_applyGesture(bContext *C, SK_Sketch *sketch)
1933 {
1934         SK_Gesture gest;
1935         SK_GestureAction *act;
1936
1937         sk_initGesture(C, &gest, sketch);
1938
1939         /* detect and apply */
1940         for (act = GESTURE_ACTIONS; act->apply != NULL; act++) {
1941                 if (act->detect(C, &gest, sketch)) {
1942                         act->apply(C, &gest, sketch);
1943                         break;
1944                 }
1945         }
1946
1947         sk_freeGesture(&gest);
1948 }
1949
1950 /********************************************/
1951
1952
1953 static bool sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], const bool extend)
1954 {
1955         ViewContext vc;
1956         rcti rect;
1957         unsigned int buffer[MAXPICKBUF];
1958         short hits;
1959
1960         view3d_set_viewcontext(C, &vc);
1961
1962         rect.xmin = mval[0] - 5;
1963         rect.xmax = mval[0] + 5;
1964         rect.ymin = mval[1] - 5;
1965         rect.ymax = mval[1] + 5;
1966
1967         hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
1968
1969         if (hits > 0) {
1970                 int besthitresult = -1;
1971
1972                 if (hits == 1) {
1973                         besthitresult = buffer[3];
1974                 }
1975                 else {
1976                         besthitresult = buffer[3];
1977                         /* loop and get best hit */
1978                 }
1979
1980                 if (besthitresult > 0) {
1981                         SK_Stroke *selected_stk = BLI_findlink(&sketch->strokes, besthitresult - 1);
1982
1983                         if (extend == 0) {
1984                                 sk_selectAllSketch(sketch, -1);
1985
1986                                 selected_stk->selected = 1;
1987                         }
1988                         else {
1989                                 selected_stk->selected ^= 1;
1990                         }
1991
1992
1993                 }
1994                 return 1;
1995         }
1996
1997         return 0;
1998 }
1999
2000 #if 0 /* UNUSED 2.5 */
2001 static void sk_queueRedrawSketch(SK_Sketch *sketch)
2002 {
2003         if (sketch->active_stroke != NULL)
2004         {
2005                 SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
2006
2007                 if (last != NULL)
2008                 {
2009 //                      XXX
2010 //                      allqueue(REDRAWVIEW3D, 0);
2011                 }
2012         }
2013 }
2014 #endif
2015
2016 static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch, int with_names)
2017 {
2018         ToolSettings *ts = scene->toolsettings;
2019         SK_Stroke *stk;
2020
2021         glClear(GL_DEPTH_BUFFER_BIT);
2022         glEnable(GL_DEPTH_TEST);
2023
2024         if (with_names) {
2025                 int id;
2026                 for (id = 1, stk = sketch->strokes.first; stk; id++, stk = stk->next) {
2027                         sk_drawStroke(stk, id, NULL, -1, -1);
2028                 }
2029
2030                 GPU_select_load_id(-1);
2031         }
2032         else {
2033                 float selected_rgb[3] = {1, 0, 0};
2034                 float unselected_rgb[3] = {1, 0.5, 0};
2035
2036                 for (stk = sketch->strokes.first; stk; stk = stk->next) {
2037                         int start = -1;
2038                         int end = -1;
2039
2040                         if (sk_hasOverdraw(sketch, stk)) {
2041                                 sk_adjustIndexes(sketch, &start, &end);
2042                         }
2043
2044                         sk_drawStroke(stk, -1, (stk->selected == 1 ? selected_rgb : unselected_rgb), start, end);
2045
2046                         if (stk->selected == 1) {
2047                                 sk_drawStrokeSubdivision(ts, stk);
2048                         }
2049                 }
2050
2051                 if (sketch->active_stroke != NULL) {
2052                         SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
2053
2054                         if (ts->bone_sketching & BONE_SKETCHING_QUICK) {
2055                                 sk_drawStrokeSubdivision(ts, sketch->active_stroke);
2056                         }
2057
2058                         if (last != NULL) {
2059                                 GLUquadric *quad = gluNewQuadric();
2060                                 gluQuadricNormals(quad, GLU_SMOOTH);
2061
2062                                 glPushMatrix();
2063
2064                                 glEnable(GL_BLEND);
2065                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2066
2067                                 switch (sketch->next_point.mode) {
2068                                         case PT_SNAP:
2069                                                 glColor3f(0, 1, 0);
2070                                                 break;
2071                                         case PT_PROJECT:
2072                                                 glColor3f(0, 0, 0);
2073                                                 break;
2074                                 }
2075
2076                                 sk_drawPoint(quad, &sketch->next_point, 0.1);
2077
2078                                 glColor4f(selected_rgb[0], selected_rgb[1], selected_rgb[2], 0.3);
2079
2080                                 sk_drawEdge(quad, last, &sketch->next_point, 0.1);
2081
2082                                 glDisable(GL_BLEND);
2083
2084                                 glPopMatrix();
2085
2086                                 gluDeleteQuadric(quad);
2087                         }
2088                 }
2089         }
2090
2091 #if 0
2092         if (BLI_listbase_is_empty(&sketch->depth_peels) == false) {
2093                 float colors[8][3] = {
2094                         {1, 0, 0},
2095                         {0, 1, 0},
2096                         {0, 0, 1},
2097                         {1, 1, 0},
2098                         {1, 0, 1},
2099                         {0, 1, 1},
2100                         {1, 1, 1},
2101                         {0, 0, 0}
2102                 };
2103                 DepthPeel *p;
2104                 GLUquadric *quad = gluNewQuadric();
2105                 gluQuadricNormals(quad, GLU_SMOOTH);
2106
2107                 for (p = sketch->depth_peels.first; p; p = p->next)
2108                 {
2109                         int index = GET_INT_FROM_POINTER(p->ob);
2110                         index = (index >> 5) & 7;
2111
2112                         glColor3fv(colors[index]);
2113                         glPushMatrix();
2114                         glTranslate3fv(p->p);
2115                         gluSphere(quad, 0.02, 8, 8);
2116                         glPopMatrix();
2117                 }
2118
2119                 gluDeleteQuadric(quad);
2120         }
2121 #endif
2122
2123         glDisable(GL_DEPTH_TEST);
2124
2125         /* only draw gesture in active area */
2126         if (sketch->gesture != NULL /* && area_is_active_area(G.vd->area) */) {
2127                 float gesture_rgb[3] = {0, 0.5, 1};
2128                 sk_drawStroke(sketch->gesture, -1, gesture_rgb, -1, -1);
2129         }
2130 }
2131
2132 static int sk_finish_stroke(bContext *C, SK_Sketch *sketch)
2133 {
2134         ToolSettings *ts = CTX_data_tool_settings(C);
2135
2136         if (sketch->active_stroke != NULL) {
2137                 SK_Stroke *stk = sketch->active_stroke;
2138
2139                 sk_endStroke(C, sketch);
2140
2141                 if (ts->bone_sketching & BONE_SKETCHING_QUICK) {
2142                         if (ts->bone_sketching_convert == SK_CONVERT_RETARGET) {
2143                                 sk_retargetStroke(C, stk);
2144                         }
2145                         else {
2146                                 sk_convertStroke(C, stk);
2147                         }
2148 //                      XXX
2149 //                      BIF_undo_push("Convert Sketch");
2150                         sk_removeStroke(sketch, stk);
2151 //                      XXX
2152 //                      allqueue(REDRAWBUTSEDIT, 0);
2153                 }
2154
2155 //              XXX
2156 //              allqueue(REDRAWVIEW3D, 0);
2157                 return 1;
2158         }
2159
2160         return 0;
2161 }
2162
2163 static void sk_start_draw_stroke(SK_Sketch *sketch)
2164 {
2165         if (sketch->active_stroke == NULL) {
2166                 sk_startStroke(sketch);
2167                 sk_selectAllSketch(sketch, -1);
2168
2169                 sketch->active_stroke->selected = 1;
2170         }
2171 }
2172
2173 static void sk_start_draw_gesture(SK_Sketch *sketch)
2174 {
2175         sketch->gesture = sk_createStroke();
2176 }
2177
2178 static int sk_draw_stroke(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, bool snap)
2179 {
2180         if (sk_stroke_filtermval(dd)) {
2181                 sk_addStrokePoint(C, sketch, stk, dd, snap);
2182                 sk_updateDrawData(dd);
2183                 sk_updateNextPoint(sketch, stk);
2184                 
2185                 return 1;
2186         }
2187
2188         return 0;
2189 }
2190
2191 static int ValidSketchViewContext(ViewContext *vc)
2192 {
2193         Object *obedit = vc->obedit;
2194         Scene *scene = vc->scene;
2195
2196         if (obedit &&
2197             obedit->type == OB_ARMATURE &&
2198             scene->toolsettings->bone_sketching & BONE_SKETCHING)
2199         {
2200                 return 1;
2201         }
2202         else {
2203                 return 0;
2204         }
2205 }
2206
2207 int BDR_drawSketchNames(ViewContext *vc)
2208 {
2209         if (ValidSketchViewContext(vc)) {
2210                 SK_Sketch *sketch = viewcontextSketch(vc, 0);
2211                 if (sketch) {
2212                         sk_drawSketch(vc->scene, vc->v3d, sketch, 1);
2213                         return 1;
2214                 }
2215         }
2216
2217         return 0;
2218 }
2219
2220 void BDR_drawSketch(const bContext *C)
2221 {
2222         if (ED_operator_sketch_mode(C)) {
2223                 SK_Sketch *sketch = contextSketch(C, 0);
2224                 if (sketch) {
2225                         sk_drawSketch(CTX_data_scene(C), CTX_wm_view3d(C), sketch, 0);
2226                 }
2227         }
2228 }
2229
2230 static int sketch_delete(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
2231 {
2232         SK_Sketch *sketch = contextSketch(C, 0);
2233         if (sketch) {
2234                 sk_deleteSelectedStrokes(sketch);
2235 //                      allqueue(REDRAWVIEW3D, 0);
2236         }
2237         WM_event_add_notifier(C, NC_SCREEN | ND_SKETCH | NA_REMOVED, NULL);
2238         return OPERATOR_FINISHED;
2239 }
2240
2241 bool BIF_sk_selectStroke(bContext *C, const int mval[2], const bool extend)
2242 {
2243         ToolSettings *ts = CTX_data_tool_settings(C);
2244         SK_Sketch *sketch = contextSketch(C, 0);
2245
2246         if (sketch != NULL && ts->bone_sketching & BONE_SKETCHING) {
2247                 if (sk_selectStroke(C, sketch, mval, extend)) {
2248                         ED_area_tag_redraw(CTX_wm_area(C));
2249                         return true;
2250                 }
2251         }
2252
2253         return false;
2254 }
2255
2256 void BIF_convertSketch(bContext *C)
2257 {
2258         if (ED_operator_sketch_full_mode(C)) {
2259                 SK_Sketch *sketch = contextSketch(C, 0);
2260                 if (sketch) {
2261                         sk_convert(C, sketch);
2262 //                      BIF_undo_push("Convert Sketch");
2263 //                      allqueue(REDRAWVIEW3D, 0);
2264 //                      allqueue(REDRAWBUTSEDIT, 0);
2265                 }
2266         }
2267 }
2268
2269 void BIF_deleteSketch(bContext *C)
2270 {
2271         if (ED_operator_sketch_full_mode(C)) {
2272                 SK_Sketch *sketch = contextSketch(C, 0);
2273                 if (sketch) {
2274                         sk_deleteSelectedStrokes(sketch);
2275 //                      BIF_undo_push("Convert Sketch");
2276 //                      allqueue(REDRAWVIEW3D, 0);
2277                 }
2278         }
2279 }
2280
2281 #if 0
2282 void BIF_selectAllSketch(bContext *C, int mode)
2283 {
2284         if (BIF_validSketchMode(C))
2285         {
2286                 SK_Sketch *sketch = contextSketch(C, 0);
2287                 if (sketch)
2288                 {
2289                         sk_selectAllSketch(sketch, mode);
2290 //                      XXX
2291 //                      allqueue(REDRAWVIEW3D, 0);
2292                 }
2293         }
2294 }
2295 #endif
2296
2297 SK_Sketch *contextSketch(const bContext *C, int create)
2298 {
2299         Object *obedit = CTX_data_edit_object(C);
2300         SK_Sketch *sketch = NULL;
2301
2302         if (obedit && obedit->type == OB_ARMATURE) {
2303                 bArmature *arm = obedit->data;
2304         
2305                 if (arm->sketch == NULL && create) {
2306                         arm->sketch = createSketch();
2307                 }
2308                 sketch = arm->sketch;
2309         }
2310
2311         return sketch;
2312 }
2313
2314 SK_Sketch *viewcontextSketch(ViewContext *vc, int create)
2315 {
2316         Object *obedit = vc->obedit;
2317         SK_Sketch *sketch = NULL;
2318
2319         if (obedit && obedit->type == OB_ARMATURE) {
2320                 bArmature *arm = obedit->data;
2321         
2322                 if (arm->sketch == NULL && create) {
2323                         arm->sketch = createSketch();
2324                 }
2325                 sketch = arm->sketch;
2326         }
2327
2328         return sketch;
2329 }
2330
2331 static int sketch_convert(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
2332 {
2333         SK_Sketch *sketch = contextSketch(C, 0);
2334         if (sketch != NULL) {
2335                 sk_convert(C, sketch);
2336                 ED_area_tag_redraw(CTX_wm_area(C));
2337         }
2338         return OPERATOR_FINISHED;
2339 }
2340
2341 static int sketch_cancel_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
2342 {
2343         SK_Sketch *sketch = contextSketch(C, 0);
2344         if (sketch != NULL) {
2345                 sk_cancelStroke(sketch);
2346                 ED_area_tag_redraw(CTX_wm_area(C));
2347                 return OPERATOR_FINISHED;
2348         }
2349         return OPERATOR_PASS_THROUGH;
2350 }
2351
2352 static int sketch_finish(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
2353 {
2354         SK_Sketch *sketch = contextSketch(C, 0);
2355         if (sketch != NULL) {
2356                 if (sk_finish_stroke(C, sketch)) {
2357                         ED_area_tag_redraw(CTX_wm_area(C));
2358                         return OPERATOR_FINISHED;
2359                 }
2360         }
2361         return OPERATOR_PASS_THROUGH;
2362 }
2363
2364 static int sketch_select(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
2365 {
2366         SK_Sketch *sketch = contextSketch(C, 0);
2367         if (sketch) {
2368                 short extend = 0;
2369                 if (sk_selectStroke(C, sketch, event->mval, extend))
2370                         ED_area_tag_redraw(CTX_wm_area(C));
2371         }
2372
2373         return OPERATOR_FINISHED;
2374 }
2375
2376 static void sketch_draw_stroke_cancel(bContext *C, wmOperator *op)
2377 {
2378         SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2379         sk_cancelStroke(sketch);
2380         MEM_freeN(op->customdata);
2381 }
2382
2383 static int sketch_draw_stroke(bContext *C, wmOperator *op, const wmEvent *event)
2384 {
2385         const bool snap = RNA_boolean_get(op->ptr, "snap");
2386         SK_DrawData *dd;
2387         SK_Sketch *sketch = contextSketch(C, 1);
2388
2389         op->customdata = dd = MEM_callocN(sizeof(SK_DrawData), "SketchDrawData");
2390         sk_initDrawData(dd, event->mval);
2391
2392         sk_start_draw_stroke(sketch);
2393
2394         sk_draw_stroke(C, sketch, sketch->active_stroke, dd, snap);
2395
2396         WM_event_add_modal_handler(C, op);
2397
2398         return OPERATOR_RUNNING_MODAL;
2399 }
2400
2401 static void sketch_draw_gesture_cancel(bContext *C, wmOperator *op)
2402 {
2403         SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2404         sk_cancelStroke(sketch);
2405         MEM_freeN(op->customdata);
2406 }
2407
2408 static int sketch_draw_gesture(bContext *C, wmOperator *op, const wmEvent *event)
2409 {
2410         const bool snap = RNA_boolean_get(op->ptr, "snap");
2411         SK_DrawData *dd;
2412         SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2413         sk_cancelStroke(sketch);
2414
2415         op->customdata = dd = MEM_callocN(sizeof(SK_DrawData), "SketchDrawData");
2416         sk_initDrawData(dd, event->mval);
2417
2418         sk_start_draw_gesture(sketch);
2419         sk_draw_stroke(C, sketch, sketch->gesture, dd, snap);
2420
2421         WM_event_add_modal_handler(C, op);
2422
2423         return OPERATOR_RUNNING_MODAL;
2424 }
2425
2426 static int sketch_draw_modal(bContext *C, wmOperator *op, const wmEvent *event, short gesture, SK_Stroke *stk)
2427 {
2428         bool snap = RNA_boolean_get(op->ptr, "snap");
2429         SK_DrawData *dd = op->customdata;
2430         SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2431         int retval = OPERATOR_RUNNING_MODAL;
2432
2433         switch (event->type) {
2434                 case LEFTCTRLKEY:
2435                 case RIGHTCTRLKEY:
2436                         snap = event->ctrl != 0;
2437                         RNA_boolean_set(op->ptr, "snap", snap);
2438                         break;
2439                 case MOUSEMOVE:
2440                 case INBETWEEN_MOUSEMOVE:
2441                         dd->mval[0] = event->mval[0];
2442                         dd->mval[1] = event->mval[1];
2443                         sk_draw_stroke(C, sketch, stk, dd, snap);
2444                         ED_area_tag_redraw(CTX_wm_area(C));
2445                         break;
2446                 case ESCKEY:
2447                         op->type->cancel(C, op);
2448                         ED_area_tag_redraw(CTX_wm_area(C));
2449                         retval = OPERATOR_CANCELLED;
2450                         break;
2451                 case LEFTMOUSE:
2452                         if (event->val == KM_RELEASE) {
2453                                 if (gesture == 0) {
2454                                         sk_endContinuousStroke(stk);
2455                                         sk_filterLastContinuousStroke(stk);
2456                                         sk_updateNextPoint(sketch, stk);
2457                                         ED_area_tag_redraw(CTX_wm_area(C));
2458                                         MEM_freeN(op->customdata);
2459                                         retval = OPERATOR_FINISHED;
2460                                 }
2461                                 else {
2462                                         sk_endContinuousStroke(stk);
2463                                         sk_filterLastContinuousStroke(stk);
2464
2465                                         if (stk->nb_points > 1) {
2466                                                 /* apply gesture here */
2467                                                 sk_applyGesture(C, sketch);
2468                                         }
2469
2470                                         sk_freeStroke(stk);
2471                                         sketch->gesture = NULL;
2472
2473                                         ED_area_tag_redraw(CTX_wm_area(C));
2474                                         MEM_freeN(op->customdata);
2475                                         retval = OPERATOR_FINISHED;
2476                                 }
2477                         }
2478                         break;
2479         }
2480
2481         return retval;
2482 }
2483
2484 static int sketch_draw_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
2485 {
2486         SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2487         return sketch_draw_modal(C, op, event, 0, sketch->active_stroke);
2488 }
2489
2490 static int sketch_draw_gesture_modal(bContext *C, wmOperator *op, const wmEvent *event)
2491 {
2492         SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2493         return sketch_draw_modal(C, op, event, 1, sketch->gesture);
2494 }
2495
2496 static int sketch_draw_preview(bContext *C, wmOperator *op, const wmEvent *event)
2497 {
2498         const bool snap = RNA_boolean_get(op->ptr, "snap");
2499         SK_Sketch *sketch = contextSketch(C, 0);
2500
2501         if (sketch) {
2502                 SK_DrawData dd;
2503
2504                 sk_initDrawData(&dd, event->mval);
2505                 sk_getStrokePoint(C, &sketch->next_point, sketch, sketch->active_stroke, &dd, snap);
2506                 ED_area_tag_redraw(CTX_wm_area(C));
2507         }
2508
2509         return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
2510 }
2511
2512 /* ============================================== Poll Functions ============================================= */
2513
2514 int ED_operator_sketch_mode_active_stroke(bContext *C)
2515 {
2516         ToolSettings *ts = CTX_data_tool_settings(C);
2517         SK_Sketch *sketch = contextSketch(C, 0);
2518
2519         if (ts->bone_sketching & BONE_SKETCHING &&
2520             sketch != NULL &&
2521             sketch->active_stroke != NULL)
2522         {
2523                 return 1;
2524         }
2525         else {
2526                 return 0;
2527         }
2528 }
2529
2530 static int ED_operator_sketch_mode_gesture(bContext *C)
2531 {
2532         ToolSettings *ts = CTX_data_tool_settings(C);
2533         SK_Sketch *sketch = contextSketch(C, 0);
2534
2535         if (ts->bone_sketching & BONE_SKETCHING &&
2536             (ts->bone_sketching & BONE_SKETCHING_QUICK) == 0 &&
2537             sketch != NULL &&
2538             sketch->active_stroke == NULL)
2539         {
2540                 return 1;
2541         }
2542         else {
2543                 return 0;
2544         }
2545 }
2546
2547 int ED_operator_sketch_full_mode(bContext *C)
2548 {
2549         Object *obedit = CTX_data_edit_object(C);
2550         ToolSettings *ts = CTX_data_tool_settings(C);
2551
2552         if (obedit &&
2553             obedit->type == OB_ARMATURE &&
2554             ts->bone_sketching & BONE_SKETCHING &&
2555             (ts->bone_sketching & BONE_SKETCHING_QUICK) == 0)
2556         {
2557                 return 1;
2558         }
2559         else {
2560                 return 0;
2561         }
2562 }
2563
2564 int ED_operator_sketch_mode(const bContext *C)
2565 {
2566         Object *obedit = CTX_data_edit_object(C);
2567         ToolSettings *ts = CTX_data_tool_settings(C);
2568
2569         if (obedit &&
2570             obedit->type == OB_ARMATURE &&
2571             ts->bone_sketching & BONE_SKETCHING)
2572         {
2573                 return 1;
2574         }
2575         else {
2576                 return 0;
2577         }
2578 }
2579
2580 /* ================================================ Operators ================================================ */
2581
2582 void SKETCH_OT_delete(wmOperatorType *ot)
2583 {
2584         /* identifiers */
2585         ot->name = "Delete";
2586         ot->idname = "SKETCH_OT_delete";
2587         ot->description = "Delete a sketch stroke";
2588
2589         /* api callbacks */
2590         ot->invoke = sketch_delete;
2591
2592         ot->poll = ED_operator_sketch_full_mode;
2593
2594         /* flags */
2595 //      ot->flag = OPTYPE_UNDO;
2596 }
2597
2598 void SKETCH_OT_select(wmOperatorType *ot)
2599 {
2600         /* identifiers */
2601         ot->name = "Select";
2602         ot->idname = "SKETCH_OT_select";
2603         ot->description = "Select a sketch stroke";
2604
2605         /* api callbacks */
2606         ot->invoke = sketch_select;
2607
2608         ot->poll = ED_operator_sketch_full_mode;
2609
2610         /* flags */
2611 //      ot->flag = OPTYPE_UNDO;
2612 }
2613
2614 void SKETCH_OT_cancel_stroke(wmOperatorType *ot)
2615 {
2616         /* identifiers */
2617         ot->name = "Cancel Stroke";
2618         ot->idname = "SKETCH_OT_cancel_stroke";
2619         ot->description = "Cancel the current sketch stroke";
2620
2621         /* api callbacks */
2622         ot->invoke = sketch_cancel_invoke;
2623
2624         ot->poll = ED_operator_sketch_mode_active_stroke;
2625
2626         /* flags */
2627 //      ot->flag = OPTYPE_UNDO;
2628 }
2629
2630 void SKETCH_OT_convert(wmOperatorType *ot)
2631 {
2632         /* identifiers */
2633         ot->name = "Convert";
2634         ot->idname = "SKETCH_OT_convert";
2635         ot->description = "Convert the selected sketch strokes to bone chains";
2636
2637         /* api callbacks */
2638         ot->invoke = sketch_convert;
2639
2640         ot->poll = ED_operator_sketch_full_mode;
2641
2642         /* flags */
2643         ot->flag = OPTYPE_UNDO;
2644 }
2645
2646 void SKETCH_OT_finish_stroke(wmOperatorType *ot)
2647 {
2648         /* identifiers */
2649         ot->name = "End Stroke";
2650         ot->idname = "SKETCH_OT_finish_stroke";
2651         ot->description = "End and keep the current sketch stroke";
2652
2653         /* api callbacks */
2654         ot->invoke = sketch_finish;
2655
2656         ot->poll = ED_operator_sketch_mode_active_stroke;
2657
2658         /* flags */
2659 //      ot->flag = OPTYPE_UNDO;
2660 }
2661
2662 void SKETCH_OT_draw_preview(wmOperatorType *ot)
2663 {
2664         /* identifiers */
2665         ot->name = "Draw Preview";
2666         ot->idname = "SKETCH_OT_draw_preview";
2667         ot->description = "Draw preview of current sketch stroke (internal use)";
2668
2669         /* api callbacks */
2670         ot->invoke = sketch_draw_preview;
2671
2672         ot->poll = ED_operator_sketch_mode_active_stroke;
2673
2674         RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
2675
2676         /* flags */
2677 //      ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
2678 }
2679
2680 void SKETCH_OT_draw_stroke(wmOperatorType *ot)
2681 {
2682         /* identifiers */
2683         ot->name = "Draw Stroke";
2684         ot->idname = "SKETCH_OT_draw_stroke";
2685         ot->description = "Start to draw a sketch stroke";
2686
2687         /* api callbacks */
2688         ot->invoke = sketch_draw_stroke;
2689         ot->modal  = sketch_draw_stroke_modal;
2690         ot->cancel = sketch_draw_stroke_cancel;
2691
2692         ot->poll = (int (*)(bContext *))ED_operator_sketch_mode;
2693
2694         RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
2695
2696         /* flags */
2697         ot->flag = OPTYPE_BLOCKING; // OPTYPE_REGISTER|OPTYPE_UNDO
2698 }
2699
2700 void SKETCH_OT_gesture(wmOperatorType *ot)
2701 {
2702         /* identifiers */
2703         ot->name = "Gesture";
2704         ot->idname = "SKETCH_OT_gesture";
2705         ot->description = "Start to draw a gesture stroke";
2706
2707         /* api callbacks */
2708         ot->invoke = sketch_draw_gesture;
2709         ot->modal  = sketch_draw_gesture_modal;
2710         ot->cancel = sketch_draw_gesture_cancel;
2711
2712         ot->poll = ED_operator_sketch_mode_gesture;
2713
2714         RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
2715
2716         /* flags */
2717         ot->flag = OPTYPE_BLOCKING; // OPTYPE_UNDO
2718 }
2719