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