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