Sketch Retargetting:
[blender-staging.git] / source / blender / src / 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
26 #include "MEM_guardedalloc.h"
27
28 #include "DNA_listBase.h"
29 #include "DNA_scene_types.h"
30 #include "DNA_view3d_types.h"
31 #include "DNA_meshdata_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_armature_types.h"
34
35 #include "BLI_blenlib.h"
36 #include "BLI_arithb.h"
37 #include "BLI_graph.h"
38
39 #include "BKE_utildefines.h"
40 #include "BKE_global.h"
41 #include "BKE_DerivedMesh.h"
42 #include "BKE_object.h"
43 #include "BKE_anim.h"
44
45 #include "BSE_view.h"
46
47 #include "BIF_gl.h"
48 #include "BIF_resources.h"
49 #include "BIF_screen.h"
50 #include "BIF_space.h"
51 #include "BIF_mywindow.h"
52 #include "BIF_editarmature.h"
53 #include "BIF_sketch.h"
54 #include "BIF_retarget.h"
55
56 #include "blendef.h"
57 #include "mydevice.h"
58 #include "reeb.h"
59
60 typedef enum SK_PType
61 {
62         PT_CONTINUOUS,
63         PT_EXACT,
64 } SK_PType;
65
66 typedef enum SK_PMode
67 {
68         PT_EMBED,
69         PT_SNAP,
70         PT_PROJECT,
71 } SK_PMode;
72
73 typedef struct SK_Point
74 {
75         float p[3];
76         float no[3];
77         SK_PType type;
78         SK_PMode mode;
79 } SK_Point;
80
81 typedef struct SK_Stroke
82 {
83         struct SK_Stroke *next, *prev;
84
85         SK_Point *points;
86         int nb_points;
87         int buf_size;
88         int selected;
89 } SK_Stroke;
90
91 #define SK_Stroke_BUFFER_INIT_SIZE 20
92
93 typedef struct SK_DrawData
94 {
95         short mval[2];
96         short previous_mval[2];
97         SK_PType type;
98 } SK_DrawData;
99
100 typedef struct SK_Intersection
101 {
102         struct SK_Intersection *next, *prev;
103         SK_Stroke *stroke;
104         int                     before;
105         int                     after;
106         int                     gesture_index;
107         float           p[3];
108 } SK_Intersection;
109
110 typedef struct SK_Sketch
111 {
112         ListBase        strokes;
113         SK_Stroke       *active_stroke;
114         SK_Stroke       *gesture;
115         SK_Point        next_point;
116 } SK_Sketch;
117
118 SK_Sketch *GLOBAL_sketch = NULL;
119 SK_Point boneSnap;
120
121 #define SNAP_MIN_DISTANCE 12
122
123 /******************** PROTOTYPES ******************************/
124
125 typedef int(NextSubdivisionFunc)(SK_Stroke*, int, int, float[3], float[3]);
126
127 void sk_deleteSelectedStrokes(SK_Sketch *sketch);
128
129 void sk_freeStroke(SK_Stroke *stk);
130 void sk_freeSketch(SK_Sketch *sketch);
131
132 SK_Point *sk_lastStrokePoint(SK_Stroke *stk);
133
134 int nextFixedSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3]);
135 int nextLengthSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3]);
136 int nextCorrelationSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3]);
137
138 /******************** PEELING *********************************/
139
140 typedef struct SK_DepthPeel
141 {
142         struct SK_DepthPeel *next, *prev;
143         
144         float depth;
145         float p[3];
146         float no[3];
147         Object *ob;
148         int flag;
149 } SK_DepthPeel;
150
151 int cmpPeel(void *arg1, void *arg2)
152 {
153         SK_DepthPeel *p1 = arg1;
154         SK_DepthPeel *p2 = arg2;
155         int val = 0;
156         
157         if (p1->depth < p2->depth)
158         {
159                 val = -1;
160         }
161         else if (p1->depth > p2->depth)
162         {
163                 val = 1;
164         }
165         
166         return val;
167 }
168
169 void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], Object *ob)
170 {
171         SK_DepthPeel *peel = MEM_callocN(sizeof(SK_DepthPeel), "DepthPeel");
172         
173         peel->depth = depth;
174         peel->ob = ob;
175         VECCOPY(peel->p, p);
176         VECCOPY(peel->no, no);
177         
178         BLI_addtail(depth_peels, peel);
179         
180         peel->flag = 0;
181 }
182
183 int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], ListBase *depth_peels)
184 {
185         int retval = 0;
186         int totvert = dm->getNumVerts(dm);
187         int totface = dm->getNumFaces(dm);
188         
189         if (totvert > 0) {
190                 float imat[4][4];
191                 float timat[3][3]; /* transpose inverse matrix for normals */
192                 float ray_start_local[3], ray_normal_local[3];
193                 int test = 1;
194
195                 Mat4Invert(imat, obmat);
196
197                 Mat3CpyMat4(timat, imat);
198                 Mat3Transp(timat);
199                 
200                 VECCOPY(ray_start_local, ray_start);
201                 VECCOPY(ray_normal_local, ray_normal);
202                 
203                 Mat4MulVecfl(imat, ray_start_local);
204                 Mat4Mul3Vecfl(imat, ray_normal_local);
205                 
206                 
207                 /* If number of vert is more than an arbitrary limit, 
208                  * test against boundbox first
209                  * */
210                 if (totface > 16) {
211                         struct BoundBox *bb = object_get_boundbox(ob);
212                         test = ray_hit_boundbox(bb, ray_start_local, ray_normal_local);
213                 }
214                 
215                 if (test == 1) {
216                         MVert *verts = dm->getVertArray(dm);
217                         MFace *faces = dm->getFaceArray(dm);
218                         int i;
219                         
220                         for( i = 0; i < totface; i++) {
221                                 MFace *f = faces + i;
222                                 float lambda;
223                                 int result;
224                                 
225                                 
226                                 result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL);
227                                 
228                                 if (result) {
229                                         float location[3], normal[3];
230                                         float intersect[3];
231                                         float new_depth;
232                                         
233                                         VECCOPY(intersect, ray_normal_local);
234                                         VecMulf(intersect, lambda);
235                                         VecAddf(intersect, intersect, ray_start_local);
236                                         
237                                         VECCOPY(location, intersect);
238                                         
239                                         if (f->v4)
240                                                 CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
241                                         else
242                                                 CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
243
244                                         Mat4MulVecfl(obmat, location);
245                                         
246                                         new_depth = VecLenf(location, ray_start);                                       
247                                         
248                                         Mat3MulVecfl(timat, normal);
249                                         Normalize(normal);
250
251                                         addDepthPeel(depth_peels, new_depth, location, normal, ob);
252                                 }
253                 
254                                 if (f->v4 && result == 0)
255                                 {
256                                         result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL);
257                                         
258                                         if (result) {
259                                                 float location[3], normal[3];
260                                                 float intersect[3];
261                                                 float new_depth;
262                                                 
263                                                 VECCOPY(intersect, ray_normal_local);
264                                                 VecMulf(intersect, lambda);
265                                                 VecAddf(intersect, intersect, ray_start_local);
266                                                 
267                                                 VECCOPY(location, intersect);
268                                                 
269                                                 if (f->v4)
270                                                         CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
271                                                 else
272                                                         CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
273
274                                                 Mat4MulVecfl(obmat, location);
275                                                 
276                                                 new_depth = VecLenf(location, ray_start);                                       
277                                                 
278                                                 Mat3MulVecfl(timat, normal);
279                                                 Normalize(normal);
280         
281                                                 addDepthPeel(depth_peels, new_depth, location, normal, ob);
282                                         } 
283                                 }
284                         }
285                 }
286         }
287
288         return retval;
289
290
291 int peelObjects(ListBase *depth_peels, short mval[2])
292 {
293         Base *base;
294         int retval = 0;
295         float ray_start[3], ray_normal[3];
296         
297         viewray(mval, ray_start, ray_normal);
298
299         base= FIRSTBASE;
300         for ( base = FIRSTBASE; base != NULL; base = base->next ) {
301                 if ( BASE_SELECTABLE(base) ) {
302                         Object *ob = base->object;
303                         
304                         if (ob->transflag & OB_DUPLI)
305                         {
306                                 DupliObject *dupli_ob;
307                                 ListBase *lb = object_duplilist(G.scene, ob);
308                                 
309                                 for(dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next)
310                                 {
311                                         Object *ob = dupli_ob->ob;
312                                         
313                                         if (ob->type == OB_MESH) {
314                                                 DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
315                                                 int val;
316                                                 
317                                                 val = peelDerivedMesh(ob, dm, dupli_ob->mat, ray_start, ray_normal, mval, depth_peels);
318         
319                                                 retval = retval || val;
320         
321                                                 dm->release(dm);
322                                         }
323                                 }
324                                 
325                                 free_object_duplilist(lb);
326                         }
327                         
328                         if (ob->type == OB_MESH) {
329                                 DerivedMesh *dm = NULL;
330                                 int val;
331
332                                 if (ob != G.obedit)
333                                 {
334                                         dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
335                                         
336                                         val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
337                                 }
338                                 else
339                                 {
340                                         dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
341                                         
342                                         val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
343                                 }
344                                         
345                                 retval = retval || val;
346                                 
347                                 dm->release(dm);
348                         }
349                 }
350         }
351         
352         BLI_sortlist(depth_peels, cmpPeel);
353         
354         return retval;
355 }
356 /*********************** CONVERSION ***************************/
357
358 ReebNode *pointToNode(SK_Point *pt)
359 {
360         ReebNode *node;
361         
362         node = MEM_callocN(sizeof(ReebNode), "reeb node");
363         VECCOPY(node->p, pt->p);
364         
365         return node;
366 }
367
368 ReebArc *strokeToArc(SK_Stroke *stk)
369 {
370         ReebArc *arc;
371         int i;
372         
373         arc = MEM_callocN(sizeof(ReebArc), "reeb arc");
374         arc->head = pointToNode(stk->points);
375         arc->tail = pointToNode(sk_lastStrokePoint(stk));
376         
377         arc->bcount = stk->nb_points - 2; /* first and last are nodes, don't count */
378         arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "Buckets");
379         
380         for (i = 0; i < arc->bcount; i++)
381         {
382                 VECCOPY(arc->buckets[i].p, stk->points[i + 1].p);
383                 arc->buckets[i].no = stk->points[i + 1].no;
384         }
385         
386         return arc;
387 }
388
389 void retargetStroke(SK_Stroke *stk)
390 {
391         ReebArc *arc = strokeToArc(stk);
392         
393         BIF_retargetArc(arc);
394         
395         MEM_freeN(arc->head);
396         MEM_freeN(arc->tail);
397         REEB_freeArc((BArc*)arc);
398 }
399
400 /**************************************************************/
401
402 void sk_freeSketch(SK_Sketch *sketch)
403 {
404         SK_Stroke *stk, *next;
405         
406         for (stk = sketch->strokes.first; stk; stk = next)
407         {
408                 next = stk->next;
409                 
410                 sk_freeStroke(stk);
411         }
412         
413         MEM_freeN(sketch);
414 }
415
416 SK_Sketch* sk_createSketch()
417 {
418         SK_Sketch *sketch;
419         
420         sketch = MEM_callocN(sizeof(SK_Sketch), "SK_Sketch");
421         
422         sketch->active_stroke = NULL;
423         sketch->gesture = NULL;
424
425         sketch->strokes.first = NULL;
426         sketch->strokes.last = NULL;
427         
428         return sketch;
429 }
430
431 void sk_initPoint(SK_Point *pt)
432 {
433         VECCOPY(pt->no, G.vd->viewinv[2]);
434         Normalize(pt->no);
435         /* more init code here */
436 }
437
438 void sk_copyPoint(SK_Point *dst, SK_Point *src)
439 {
440         memcpy(dst, src, sizeof(SK_Point));
441 }
442
443 void sk_allocStrokeBuffer(SK_Stroke *stk)
444 {
445         stk->points = MEM_callocN(sizeof(SK_Point) * stk->buf_size, "SK_Point buffer");
446 }
447
448 void sk_freeStroke(SK_Stroke *stk)
449 {
450         MEM_freeN(stk->points);
451         MEM_freeN(stk);
452 }
453
454 SK_Stroke* sk_createStroke()
455 {
456         SK_Stroke *stk;
457         
458         stk = MEM_callocN(sizeof(SK_Stroke), "SK_Stroke");
459         
460         stk->selected = 0;
461         stk->nb_points = 0;
462         stk->buf_size = SK_Stroke_BUFFER_INIT_SIZE;
463         
464         sk_allocStrokeBuffer(stk);
465         
466         return stk;
467 }
468
469 void sk_shrinkStrokeBuffer(SK_Stroke *stk)
470 {
471         if (stk->nb_points < stk->buf_size)
472         {
473                 SK_Point *old_points = stk->points;
474                 
475                 stk->buf_size = stk->nb_points;
476
477                 sk_allocStrokeBuffer(stk);              
478                 
479                 memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
480                 
481                 MEM_freeN(old_points);
482         }
483 }
484
485 void sk_growStrokeBuffer(SK_Stroke *stk)
486 {
487         if (stk->nb_points == stk->buf_size)
488         {
489                 SK_Point *old_points = stk->points;
490                 
491                 stk->buf_size *= 2;
492                 
493                 sk_allocStrokeBuffer(stk);
494                 
495                 memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
496                 
497                 MEM_freeN(old_points);
498         }
499 }
500
501 void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
502 {
503         memcpy(stk->points + n, pt, sizeof(SK_Point));
504 }
505
506 void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
507 {
508         int size = stk->nb_points - n;
509         
510         sk_growStrokeBuffer(stk);
511         
512         memmove(stk->points + n + 1, stk->points + n, size * sizeof(SK_Point));
513         
514         memcpy(stk->points + n, pt, sizeof(SK_Point));
515         
516         stk->nb_points++;
517 }
518
519 void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt)
520 {
521         sk_growStrokeBuffer(stk);
522         
523         memcpy(stk->points + stk->nb_points, pt, sizeof(SK_Point));
524         
525         stk->nb_points++;
526 }
527
528 void sk_trimStroke(SK_Stroke *stk, int start, int end)
529 {
530         int size = end - start + 1;
531         
532         if (start > 0)
533         {
534                 memmove(stk->points, stk->points + start, size * sizeof(SK_Point));
535         }
536         
537         stk->nb_points = size;
538 }
539
540 void sk_removeStroke(SK_Sketch *sketch, SK_Stroke *stk)
541 {
542         if (sketch->active_stroke == stk)
543         {
544                 sketch->active_stroke = NULL;
545         }
546         
547         BLI_remlink(&sketch->strokes, stk);
548         sk_freeStroke(stk);
549 }
550
551 void sk_reverseStroke(SK_Stroke *stk)
552 {
553         SK_Point *old_points = stk->points;
554         int i = 0;
555         
556         sk_allocStrokeBuffer(stk);
557         
558         for (i = 0; i < stk->nb_points; i++)
559         {
560                 sk_copyPoint(stk->points + i, old_points + stk->nb_points - 1 - i);
561         }
562         
563         MEM_freeN(old_points);
564 }
565
566
567 void sk_cancelStroke(SK_Sketch *sketch)
568 {
569         if (sketch->active_stroke != NULL)
570         {
571                 sk_removeStroke(sketch, sketch->active_stroke);
572         }
573 }
574
575 /* Apply reverse Chaikin filter to simplify the polyline
576  * */
577 void sk_filterStroke(SK_Stroke *stk, int start, int end)
578 {
579         SK_Point *old_points = stk->points;
580         int nb_points = stk->nb_points;
581         int i, j;
582         
583         if (start == -1)
584         {
585                 start = 0;
586                 end = stk->nb_points - 1;
587         }
588
589         sk_allocStrokeBuffer(stk);
590         stk->nb_points = 0;
591         
592         /* adding points before range */
593         for (i = 0; i < start; i++)
594         {
595                 sk_appendStrokePoint(stk, old_points + i);
596         }
597         
598         for (i = start, j = start; i <= end; i++)
599         {
600                 if (i - j == 3)
601                 {
602                         SK_Point pt;
603                         float vec[3];
604                         
605                         sk_copyPoint(&pt, &old_points[j+1]);
606
607                         pt.p[0] = 0;
608                         pt.p[1] = 0;
609                         pt.p[2] = 0;
610                         
611                         VECCOPY(vec, old_points[j].p);
612                         VecMulf(vec, -0.25);
613                         VecAddf(pt.p, pt.p, vec);
614                         
615                         VECCOPY(vec, old_points[j+1].p);
616                         VecMulf(vec,  0.75);
617                         VecAddf(pt.p, pt.p, vec);
618
619                         VECCOPY(vec, old_points[j+2].p);
620                         VecMulf(vec,  0.75);
621                         VecAddf(pt.p, pt.p, vec);
622
623                         VECCOPY(vec, old_points[j+3].p);
624                         VecMulf(vec, -0.25);
625                         VecAddf(pt.p, pt.p, vec);
626                         
627                         sk_appendStrokePoint(stk, &pt);
628
629                         j += 2;
630                 }
631                 
632                 /* this might be uneeded when filtering last continuous stroke */
633                 if (old_points[i].type == PT_EXACT)
634                 {
635                         sk_appendStrokePoint(stk, old_points + i);
636                         j = i;
637                 }
638         } 
639         
640         /* adding points after range */
641         for (i = end + 1; i < nb_points; i++)
642         {
643                 sk_appendStrokePoint(stk, old_points + i);
644         }
645
646         MEM_freeN(old_points);
647
648         sk_shrinkStrokeBuffer(stk);
649 }
650
651 void sk_filterLastContinuousStroke(SK_Stroke *stk)
652 {
653         int start, end;
654         
655         end = stk->nb_points -1;
656         
657         for (start = end - 1; start > 0 && stk->points[start].type == PT_CONTINUOUS; start--)
658         {
659                 /* nothing to do here*/
660         }
661         
662         if (end - start > 1)
663         {
664                 sk_filterStroke(stk, start, end);
665         }
666 }
667
668 SK_Point *sk_lastStrokePoint(SK_Stroke *stk)
669 {
670         SK_Point *pt = NULL;
671         
672         if (stk->nb_points > 0)
673         {
674                 pt = stk->points + (stk->nb_points - 1);
675         }
676         
677         return pt;
678 }
679
680 void sk_drawStroke(SK_Stroke *stk, int id, float color[3])
681 {
682         float rgb[3];
683         int i;
684         
685         if (id != -1)
686         {
687                 glLoadName(id);
688                 
689                 glBegin(GL_LINE_STRIP);
690                 
691                 for (i = 0; i < stk->nb_points; i++)
692                 {
693                         glVertex3fv(stk->points[i].p);
694                 }
695                 
696                 glEnd();
697                 
698         }
699         else
700         {
701                 float d_rgb[3] = {1, 1, 1};
702                 
703                 VECCOPY(rgb, color);
704                 VecSubf(d_rgb, d_rgb, rgb);
705                 VecMulf(d_rgb, 1.0f / (float)stk->nb_points);
706                 
707                 glBegin(GL_LINE_STRIP);
708
709                 for (i = 0; i < stk->nb_points; i++)
710                 {
711                         glColor3fv(rgb);
712                         glVertex3fv(stk->points[i].p);
713                         VecAddf(rgb, rgb, d_rgb);
714                 }
715                 
716                 glEnd();
717         
718                 glColor3f(0, 0, 0);
719                 glBegin(GL_POINTS);
720         
721                 for (i = 0; i < stk->nb_points; i++)
722                 {
723                         if (stk->points[i].type == PT_EXACT)
724                         {
725                                 glVertex3fv(stk->points[i].p);
726                         }
727                 }
728                 
729                 glEnd();
730         }
731
732 //      glColor3f(1, 1, 1);
733 //      glBegin(GL_POINTS);
734 //
735 //      for (i = 0; i < stk->nb_points; i++)
736 //      {
737 //              if (stk->points[i].type == PT_CONTINUOUS)
738 //              {
739 //                      glVertex3fv(stk->points[i].p);
740 //              }
741 //      }
742 //
743 //      glEnd();
744 }
745
746 void drawSubdividedStrokeBy(SK_Stroke *stk, int start, int end, NextSubdivisionFunc next_subdividion)
747 {
748         float head[3], tail[3];
749         int bone_start = start;
750         int index;
751
752         VECCOPY(head, stk->points[start].p);
753         
754         glColor3f(0, 1, 1);
755         glBegin(GL_POINTS);
756         
757         index = next_subdividion(stk, bone_start, end, head, tail);
758         while (index != -1)
759         {
760                 glVertex3fv(tail);
761                 
762                 VECCOPY(head, tail);
763                 bone_start = index; // start next bone from current index
764
765                 index = next_subdividion(stk, bone_start, end, head, tail);
766         }
767         
768         glEnd();
769 }
770
771 void sk_drawStrokeSubdivision(SK_Stroke *stk)
772 {
773         int head_index = -1;
774         int i;
775         
776         if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
777         {
778                 return;
779         }
780
781         
782         for (i = 0; i < stk->nb_points; i++)
783         {
784                 SK_Point *pt = stk->points + i;
785                 
786                 if (pt->type == PT_EXACT || i == stk->nb_points - 1) /* stop on exact or on last point */
787                 {
788                         if (head_index == -1)
789                         {
790                                 head_index = i;
791                         }
792                         else
793                         {
794                                 if (i - head_index > 1)
795                                 {
796                                         if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_CORRELATION)
797                                         {
798                                                 drawSubdividedStrokeBy(stk, head_index, i, nextCorrelationSubdivision);
799                                         }
800                                         else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
801                                         {
802                                                 drawSubdividedStrokeBy(stk, head_index, i, nextLengthSubdivision);
803                                         }
804                                         else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
805                                         {
806                                                 drawSubdividedStrokeBy(stk, head_index, i, nextFixedSubdivision);
807                                         }
808                                         
809                                 }
810
811                                 head_index = i;
812                         }
813                 }
814         }       
815 }
816
817 SK_Point *sk_snapPointStroke(SK_Stroke *stk, short mval[2], int *dist)
818 {
819         SK_Point *pt = NULL;
820         int i;
821         
822         for (i = 0; i < stk->nb_points; i++)
823         {
824                 if (stk->points[i].type == PT_EXACT)
825                 {
826                         short pval[2];
827                         int pdist;
828                         
829                         project_short_noclip(stk->points[i].p, pval);
830                         
831                         pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
832                         
833                         if (pdist < *dist)
834                         {
835                                 *dist = pdist;
836                                 pt = stk->points + i;
837                         }
838                 }
839         }
840         
841         return pt;
842 }
843
844 SK_Point *sk_snapPointArmature(Object *ob, ListBase *ebones, short mval[2], int *dist)
845 {
846         SK_Point *pt = NULL;
847         EditBone *bone;
848         
849         for (bone = ebones->first; bone; bone = bone->next)
850         {
851                 float vec[3];
852                 short pval[2];
853                 int pdist;
854                 
855                 if ((bone->flag & BONE_CONNECTED) == 0)
856                 {
857                         VECCOPY(vec, bone->head);
858                         Mat4MulVecfl(ob->obmat, vec);
859                         project_short_noclip(vec, pval);
860                         
861                         pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
862                         
863                         if (pdist < *dist)
864                         {
865                                 *dist = pdist;
866                                 pt = &boneSnap;
867                                 VECCOPY(pt->p, vec);
868                                 pt->type = PT_EXACT;
869                         }
870                 }
871                 
872                 
873                 VECCOPY(vec, bone->tail);
874                 Mat4MulVecfl(ob->obmat, vec);
875                 project_short_noclip(vec, pval);
876                 
877                 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
878                 
879                 if (pdist < *dist)
880                 {
881                         *dist = pdist;
882                         pt = &boneSnap;
883                         VECCOPY(pt->p, vec);
884                         pt->type = PT_EXACT;
885                 }
886         }
887         
888         return pt;
889 }
890
891 void sk_startStroke(SK_Sketch *sketch)
892 {
893         SK_Stroke *stk = sk_createStroke();
894         
895         BLI_addtail(&sketch->strokes, stk);
896         sketch->active_stroke = stk;
897 }
898
899 void sk_endStroke(SK_Sketch *sketch)
900 {
901         sk_shrinkStrokeBuffer(sketch->active_stroke);
902         sketch->active_stroke = NULL;
903 }
904
905 void sk_updateDrawData(SK_DrawData *dd)
906 {
907         dd->type = PT_CONTINUOUS;
908         
909         dd->previous_mval[0] = dd->mval[0];
910         dd->previous_mval[1] = dd->mval[1];
911 }
912
913 float sk_distanceDepth(float p1[3], float p2[3])
914 {
915         float vec[3];
916         float distance;
917         
918         VecSubf(vec, p1, p2);
919         
920         Projf(vec, vec, G.vd->viewinv[2]);
921         
922         distance = VecLength(vec);
923         
924         if (Inpf(G.vd->viewinv[2], vec) > 0)
925         {
926                 distance *= -1;
927         }
928         
929         return distance; 
930 }
931
932 void sk_interpolateDepth(SK_Stroke *stk, int start, int end, float length, float distance)
933 {
934         float progress = 0;
935         int i;
936         
937         progress = VecLenf(stk->points[start].p, stk->points[start - 1].p);
938         
939         for (i = start; i <= end; i++)
940         {
941                 float ray_start[3], ray_normal[3];
942                 float delta = VecLenf(stk->points[i].p, stk->points[i + 1].p);
943                 short pval[2];
944                 
945                 project_short_noclip(stk->points[i].p, pval);
946                 viewray(pval, ray_start, ray_normal);
947                 
948                 VecMulf(ray_normal, distance * progress / length);
949                 VecAddf(stk->points[i].p, stk->points[i].p, ray_normal);
950
951                 progress += delta ;
952         }
953 }
954
955 void sk_projectDrawPoint(float vec[3], SK_Stroke *stk, SK_DrawData *dd)
956 {
957         /* copied from grease pencil, need fixing */    
958         SK_Point *last = sk_lastStrokePoint(stk);
959         short cval[2];
960         //float *fp = give_cursor();
961         float fp[3] = {0, 0, 0};
962         float dvec[3];
963         
964         if (last != NULL)
965         {
966                 VECCOPY(fp, last->p);
967         }
968         
969         initgrabz(fp[0], fp[1], fp[2]);
970         
971         /* method taken from editview.c - mouse_cursor() */
972         project_short_noclip(fp, cval);
973         window_to_3d(dvec, cval[0] - dd->mval[0], cval[1] - dd->mval[1]);
974         VecSubf(vec, fp, dvec);
975 }
976
977 int sk_getStrokeDrawPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
978 {
979         pt->type = dd->type;
980         pt->mode = PT_PROJECT;
981         sk_projectDrawPoint(pt->p, stk, dd);
982         
983         return 1;
984 }
985
986 int sk_addStrokeDrawPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
987 {
988         SK_Point pt;
989         
990         sk_initPoint(&pt);
991         
992         sk_getStrokeDrawPoint(&pt, sketch, stk, dd);
993
994         sk_appendStrokePoint(stk, &pt);
995         
996         return 1;
997 }
998
999
1000 int sk_getStrokeSnapPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *source_stk, SK_DrawData *dd)
1001 {
1002         SK_Stroke *stk;
1003         int dist = SNAP_MIN_DISTANCE;
1004         int point_added = 0;
1005         
1006         for (stk = sketch->strokes.first; stk; stk = stk->next)
1007         {
1008                 SK_Point *spt = sk_snapPointStroke(stk, dd->mval, &dist);
1009                 
1010                 if (spt != NULL)
1011                 {
1012                         VECCOPY(pt->p, spt->p);
1013                         point_added = 1;
1014                 }
1015         }
1016         
1017         /* check on bones */
1018         {
1019                 SK_Point *spt = sk_snapPointArmature(G.obedit, &G.edbo, dd->mval, &dist);
1020                 
1021                 if (spt != NULL)
1022                 {
1023                         VECCOPY(pt->p, spt->p);
1024                         point_added = 1;
1025                 }
1026         }
1027         
1028         if (point_added)
1029         {
1030                 pt->type = PT_EXACT;
1031                 pt->mode = PT_SNAP;
1032         }
1033         
1034         return point_added;
1035 }
1036
1037 int sk_addStrokeSnapPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1038 {
1039         int point_added = 0;
1040         SK_Point pt;
1041         
1042         sk_initPoint(&pt);
1043         
1044         point_added = sk_getStrokeSnapPoint(&pt, sketch, stk, dd);
1045
1046         if (point_added)
1047         {
1048                 float final_p[3];
1049                 float distance;
1050                 float length;
1051                 int i, total;
1052                 
1053                 VECCOPY(final_p, pt.p);
1054
1055                 sk_projectDrawPoint(pt.p, stk, dd);
1056                 sk_appendStrokePoint(stk, &pt);
1057                 
1058                 /* update all previous point to give smooth Z progresion */
1059                 total = 0;
1060                 length = 0;
1061                 for (i = stk->nb_points - 2; i > 0; i--)
1062                 {
1063                         length += VecLenf(stk->points[i].p, stk->points[i + 1].p);
1064                         total++;
1065                         if (stk->points[i].type == PT_EXACT)
1066                         {
1067                                 break;
1068                         }
1069                 }
1070                 
1071                 if (total > 1)
1072                 {
1073                         distance = sk_distanceDepth(final_p, stk->points[i].p);
1074                         
1075                         sk_interpolateDepth(stk, i + 1, stk->nb_points - 2, length, distance);
1076                 }
1077         
1078                 VECCOPY(stk->points[stk->nb_points - 1].p, final_p);
1079         }
1080         
1081         return point_added;
1082 }
1083
1084 int sk_getStrokeEmbedPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1085 {
1086         ListBase depth_peels;
1087         SK_DepthPeel *p1, *p2;
1088         SK_Point *last_pt = NULL;
1089         float dist = FLT_MAX;
1090         float p[3];
1091         int point_added = 0;
1092         
1093         depth_peels.first = depth_peels.last = NULL;
1094         
1095         peelObjects(&depth_peels, dd->mval);
1096         
1097         if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS)
1098         {
1099                 last_pt = stk->points + (stk->nb_points - 1);
1100         }
1101         
1102         
1103         for (p1 = depth_peels.first; p1; p1 = p1->next)
1104         {
1105                 if (p1->flag == 0)
1106                 {
1107                         float vec[3];
1108                         float new_dist;
1109                         
1110                         p1->flag = 0;
1111                         
1112                         for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next)
1113                         {
1114                                 /* nothing to do here */
1115                         }
1116                         
1117                         
1118                         if (p2)
1119                         {
1120                                 p2->flag = 1;
1121                                 
1122                                 VecAddf(vec, p1->p, p2->p);
1123                                 VecMulf(vec, 0.5f);
1124                         }
1125                         else
1126                         {
1127                                 VECCOPY(vec, p1->p);
1128                         }
1129                         
1130                         if (last_pt == NULL)
1131                         {
1132                                 VECCOPY(p, vec);
1133                                 dist = 0;
1134                                 break;
1135                         }
1136                         
1137                         new_dist = VecLenf(last_pt->p, vec);
1138                         
1139                         if (new_dist < dist)
1140                         {
1141                                 VECCOPY(p, vec);
1142                                 dist = new_dist;
1143                         }
1144                 }
1145         }
1146         
1147         if (dist != FLT_MAX)
1148         {
1149                 pt->type = dd->type;
1150                 pt->mode = PT_EMBED;
1151                 VECCOPY(pt->p, p);
1152                 
1153                 point_added = 1;
1154         }
1155         
1156         BLI_freelistN(&depth_peels);
1157         
1158         return point_added;
1159 }
1160
1161 int sk_addStrokeEmbedPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1162 {
1163         int point_added;
1164         SK_Point pt;
1165         
1166         sk_initPoint(&pt);
1167
1168         point_added = sk_getStrokeEmbedPoint(&pt, sketch, stk, dd);
1169         
1170         if (point_added)
1171         {
1172                 float final_p[3];
1173                 float length, distance;
1174                 int total;
1175                 int i;
1176                 
1177                 VECCOPY(final_p, pt.p);
1178                 
1179                 sk_projectDrawPoint(pt.p, stk, dd);
1180                 sk_appendStrokePoint(stk, &pt);
1181                 
1182                 /* update all previous point to give smooth Z progresion */
1183                 total = 0;
1184                 length = 0;
1185                 for (i = stk->nb_points - 2; i > 0; i--)
1186                 {
1187                         length += VecLenf(stk->points[i].p, stk->points[i + 1].p);
1188                         total++;
1189                         if (stk->points[i].mode == PT_EMBED || stk->points[i].type == PT_EXACT)
1190                         {
1191                                 break;
1192                         }
1193                 }
1194                 
1195                 if (total > 1)
1196                 {
1197                         distance = sk_distanceDepth(final_p, stk->points[i].p);
1198                         
1199                         sk_interpolateDepth(stk, i + 1, stk->nb_points - 2, length, distance);
1200                 }
1201                 
1202                 VECCOPY(stk->points[stk->nb_points - 1].p, final_p);
1203                 
1204                 point_added = 1;
1205         }
1206         
1207         return point_added;
1208 }
1209
1210 void sk_addStrokePoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short qual)
1211 {
1212         int point_added = 0;
1213         
1214         if (qual & LR_CTRLKEY)
1215         {
1216                 point_added = sk_addStrokeSnapPoint(sketch, stk, dd);
1217         }
1218         
1219         if (point_added == 0 && qual & LR_SHIFTKEY)
1220         {
1221                 point_added = sk_addStrokeEmbedPoint(sketch, stk, dd);
1222         }
1223         
1224         if (point_added == 0)
1225         {
1226                 point_added = sk_addStrokeDrawPoint(sketch, stk, dd);
1227         }       
1228 }
1229
1230 void sk_getStrokePoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short qual)
1231 {
1232         int point_added = 0;
1233         
1234         if (qual & LR_CTRLKEY)
1235         {
1236                 point_added = sk_getStrokeSnapPoint(pt, sketch, stk, dd);
1237         }
1238         
1239         if (point_added == 0 && qual & LR_SHIFTKEY)
1240         {
1241                 point_added = sk_getStrokeEmbedPoint(pt, sketch, stk, dd);
1242         }
1243         
1244         if (point_added == 0)
1245         {
1246                 point_added = sk_getStrokeDrawPoint(pt, sketch, stk, dd);
1247         }       
1248 }
1249
1250 void sk_endContinuousStroke(SK_Stroke *stk)
1251 {
1252         stk->points[stk->nb_points - 1].type = PT_EXACT;
1253 }
1254
1255 void sk_updateNextPoint(SK_Sketch *sketch)
1256 {
1257         if (sketch->active_stroke)
1258         {
1259                 SK_Stroke *stk = sketch->active_stroke;
1260                 memcpy(&sketch->next_point, stk->points[stk->nb_points - 1].p, sizeof(SK_Point));
1261         }
1262 }
1263
1264 int sk_stroke_filtermval(SK_DrawData *dd)
1265 {
1266         int retval = 0;
1267         if (dd->mval[0] != dd->previous_mval[0] || dd->mval[1] != dd->previous_mval[1])
1268         {
1269                 retval = 1;
1270         }
1271         
1272         return retval;
1273 }
1274
1275 void sk_initDrawData(SK_DrawData *dd)
1276 {
1277         getmouseco_areawin(dd->mval);
1278         dd->previous_mval[0] = -1;
1279         dd->previous_mval[1] = -1;
1280         dd->type = PT_EXACT;
1281 }
1282 /********************************************/
1283
1284 /* bone is assumed to be in GLOBAL space */
1285 void setBoneRollFromPoint(EditBone *bone, SK_Point *pt, float invmat[][4], float tmat[][3])
1286 {
1287         float tangent[3], cotangent[3], normal[3];
1288         
1289         VecSubf(tangent, bone->tail, bone->head);
1290         Crossf(cotangent, tangent, pt->no);
1291         Crossf(normal, cotangent, tangent);
1292         
1293         Mat3MulVecfl(tmat, normal);
1294         Normalize(normal);
1295         
1296         bone->roll = rollBoneToVector(bone, normal);
1297
1298 }
1299
1300 float calcStrokeCorrelation(SK_Stroke *stk, int start, int end, float v0[3], float n[3])
1301 {
1302         int len = 2 + abs(end - start);
1303         
1304         if (len > 2)
1305         {
1306                 float avg_t = 0.0f;
1307                 float s_t = 0.0f;
1308                 float s_xyz = 0.0f;
1309                 int i;
1310                 
1311                 /* First pass, calculate average */
1312                 for (i = start; i <= end; i++)
1313                 {
1314                         float v[3];
1315                         
1316                         VecSubf(v, stk->points[i].p, v0);
1317                         avg_t += Inpf(v, n);
1318                 }
1319                 
1320                 avg_t /= Inpf(n, n);
1321                 avg_t += 1.0f; /* adding start (0) and end (1) values */
1322                 avg_t /= len;
1323                 
1324                 /* Second pass, calculate s_xyz and s_t */
1325                 for (i = start; i <= end; i++)
1326                 {
1327                         float v[3], d[3];
1328                         float dt;
1329                         
1330                         VecSubf(v, stk->points[i].p, v0);
1331                         Projf(d, v, n);
1332                         VecSubf(v, v, d);
1333                         
1334                         dt = VecLength(d) - avg_t;
1335                         
1336                         s_t += dt * dt;
1337                         s_xyz += Inpf(v, v);
1338                 }
1339                 
1340                 /* adding start(0) and end(1) values to s_t */
1341                 s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
1342                 
1343                 return 1.0f - s_xyz / s_t; 
1344         }
1345         else
1346         {
1347                 return 1.0f;
1348         }
1349 }
1350
1351 int nextFixedSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3])
1352 {
1353         static float stroke_length = 0;
1354         static float current_length;
1355         static char n;
1356         float length_threshold;
1357         int i;
1358         
1359         if (stroke_length == 0)
1360         {
1361                 current_length = 0;
1362                 for (i = start + 1; i <= end; i++)
1363                 {
1364                         stroke_length += VecLenf(stk->points[i].p, stk->points[i - 1].p);
1365                 }
1366                 
1367                 n = 0;
1368                 current_length = 0;
1369         }
1370         
1371         n++;
1372         
1373         length_threshold = n * stroke_length / G.scene->toolsettings->skgen_subdivision_number;
1374         
1375         /* < and not <= because we don't care about end, it is P_EXACT anyway */
1376         for (i = start + 1; i < end; i++)
1377         {
1378                 current_length += VecLenf(stk->points[i].p, stk->points[i - 1].p);
1379
1380                 if (current_length >= length_threshold)
1381                 {
1382                         VECCOPY(p, stk->points[i].p);
1383                         return i;
1384                 }
1385         }
1386         
1387         stroke_length = 0;
1388         
1389         return -1;
1390 }
1391 int nextCorrelationSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3])
1392 {
1393         float correlation_threshold = G.scene->toolsettings->skgen_correlation_limit;
1394         float n[3];
1395         int i;
1396         
1397         for (i = start + 2; i <= end; i++)
1398         {
1399                 /* Calculate normal */
1400                 VecSubf(n, stk->points[i].p, head);
1401
1402                 if (calcStrokeCorrelation(stk, start, i, stk->points[start].p, n) < correlation_threshold)
1403                 {
1404                         VECCOPY(p, stk->points[i - 1].p);
1405                         return i - 1;
1406                 }
1407         }
1408         
1409         return -1;
1410 }
1411
1412 int nextLengthSubdivision(SK_Stroke *stk, int start, int end, float head[3], float p[3])
1413 {
1414         float lengthLimit = G.scene->toolsettings->skgen_length_limit;
1415         int same = 1;
1416         int i;
1417         
1418         i = start + 1;
1419         while (i <= end)
1420         {
1421                 float *vec0 = stk->points[i - 1].p;
1422                 float *vec1 = stk->points[i].p;
1423
1424                 /* If lengthLimit hits the current segment */
1425                 if (VecLenf(vec1, head) > lengthLimit)
1426                 {
1427                         if (same == 0)
1428                         {
1429                                 float dv[3], off[3];
1430                                 float a, b, c, f;
1431                                 
1432                                 /* Solve quadratic distance equation */
1433                                 VecSubf(dv, vec1, vec0);
1434                                 a = Inpf(dv, dv);
1435                                 
1436                                 VecSubf(off, vec0, head);
1437                                 b = 2 * Inpf(dv, off);
1438                                 
1439                                 c = Inpf(off, off) - (lengthLimit * lengthLimit);
1440                                 
1441                                 f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
1442                                 
1443                                 //printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
1444                                 
1445                                 if (isnan(f) == 0 && f < 1.0f)
1446                                 {
1447                                         VECCOPY(p, dv);
1448                                         VecMulf(p, f);
1449                                         VecAddf(p, p, vec0);
1450                                 }
1451                                 else
1452                                 {
1453                                         VECCOPY(p, vec1);
1454                                 }
1455                         }
1456                         else
1457                         {
1458                                 float dv[3];
1459                                 
1460                                 VecSubf(dv, vec1, vec0);
1461                                 Normalize(dv);
1462                                  
1463                                 VECCOPY(p, dv);
1464                                 VecMulf(p, lengthLimit);
1465                                 VecAddf(p, p, head);
1466                         }
1467                         
1468                         return i - 1; /* restart at lower bound */
1469                 }
1470                 else
1471                 {
1472                         i++;
1473                         same = 0; // Reset same
1474                 }
1475         }
1476         
1477         return -1;
1478 }
1479
1480 EditBone * subdivideStrokeBy(SK_Stroke *stk, int start, int end, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion)
1481 {
1482         bArmature *arm = G.obedit->data;
1483         EditBone *lastBone = NULL;
1484         EditBone *child = NULL;
1485         EditBone *parent = NULL;
1486         int bone_start = start;
1487         int index;
1488         
1489         parent = addEditBone("Bone", &G.edbo, arm);
1490         VECCOPY(parent->head, stk->points[start].p);
1491         
1492         index = next_subdividion(stk, bone_start, end, parent->head, parent->tail);
1493         while (index != -1)
1494         {
1495                 setBoneRollFromPoint(parent, &stk->points[index], invmat, tmat);
1496                 Mat4MulVecfl(invmat, parent->head); /* going to next bone, fix previous head */
1497
1498                 child = addEditBone("Bone", &G.edbo, arm);
1499                 VECCOPY(child->head, parent->tail);
1500                 child->parent = parent;
1501                 child->flag |= BONE_CONNECTED;
1502                 
1503                 parent = child; // new child is next parent
1504                 bone_start = index; // start next bone from current index
1505
1506                 index = next_subdividion(stk, bone_start, end, parent->head, parent->tail);
1507         }
1508
1509         VECCOPY(parent->tail, stk->points[end].p);
1510
1511         setBoneRollFromPoint(parent, &stk->points[end], invmat, tmat);
1512
1513         Mat4MulVecfl(invmat, parent->head);
1514         Mat4MulVecfl(invmat, parent->tail);
1515         lastBone = parent;
1516         
1517         return lastBone;
1518 }
1519
1520
1521 void sk_convertStroke(SK_Stroke *stk)
1522 {
1523         bArmature *arm= G.obedit->data;
1524         SK_Point *head;
1525         EditBone *parent = NULL;
1526         float invmat[4][4]; /* move in caller function */
1527         float tmat[3][3];
1528         int head_index = 0;
1529         int i;
1530         
1531         head = NULL;
1532         
1533         Mat4Invert(invmat, G.obedit->obmat);
1534         
1535         Mat3CpyMat4(tmat, G.obedit->obmat);
1536         Mat3Transp(tmat);
1537         
1538         for (i = 0; i < stk->nb_points; i++)
1539         {
1540                 SK_Point *pt = stk->points + i;
1541                 
1542                 if (pt->type == PT_EXACT)
1543                 {
1544                         if (head == NULL)
1545                         {
1546                                 head_index = i;
1547                                 head = pt;
1548                         }
1549                         else
1550                         {
1551                                 EditBone *bone = NULL;
1552                                 EditBone *new_parent;
1553                                 
1554                                 if (i - head_index > 1)
1555                                 {
1556                                         if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_CORRELATION)
1557                                         {
1558                                                 bone = subdivideStrokeBy(stk, head_index, i, invmat, tmat, nextCorrelationSubdivision);
1559                                         }
1560                                         else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
1561                                         {
1562                                                 bone = subdivideStrokeBy(stk, head_index, i, invmat, tmat, nextLengthSubdivision);
1563                                         }
1564                                         else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
1565                                         {
1566                                                 bone = subdivideStrokeBy(stk, head_index, i, invmat, tmat, nextFixedSubdivision);
1567                                         }
1568                                 }
1569                                 
1570                                 if (bone == NULL)
1571                                 {
1572                                         bone = addEditBone("Bone", &G.edbo, arm);
1573                                         
1574                                         VECCOPY(bone->head, head->p);
1575                                         VECCOPY(bone->tail, pt->p);
1576                                         setBoneRollFromPoint(bone, pt, invmat, tmat);
1577                                         
1578                                         Mat4MulVecfl(invmat, bone->head);
1579                                         Mat4MulVecfl(invmat, bone->tail);
1580                                 }
1581                                 
1582                                 new_parent = bone;
1583                                 bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
1584                                 
1585                                 /* move to end of chain */
1586                                 while (bone->parent != NULL)
1587                                 {
1588                                         bone = bone->parent;
1589                                         bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
1590                                 }
1591
1592                                 if (parent != NULL)
1593                                 {
1594                                         bone->parent = parent;
1595                                         bone->flag |= BONE_CONNECTED;                                   
1596                                 }
1597                                 
1598                                 parent = new_parent;
1599                                 head_index = i;
1600                                 head = pt;
1601                         }
1602                 }
1603         }
1604 }
1605
1606 void sk_convert(SK_Sketch *sketch)
1607 {
1608         SK_Stroke *stk;
1609         
1610         for (stk = sketch->strokes.first; stk; stk = stk->next)
1611         {
1612                 if (stk->selected == 1)
1613                 {
1614                         sk_convertStroke(stk);
1615                 }
1616         }
1617 }
1618 /******************* GESTURE *************************/
1619
1620
1621 /* returns the number of self intersections */
1622 int sk_getSelfIntersections(ListBase *list, SK_Stroke *gesture)
1623 {
1624         int added = 0;
1625         int s_i;
1626
1627         for (s_i = 0; s_i < gesture->nb_points - 1; s_i++)
1628         {
1629                 float s_p1[3] = {0, 0, 0};
1630                 float s_p2[3] = {0, 0, 0};
1631                 int g_i;
1632                 
1633                 project_float(gesture->points[s_i].p, s_p1);
1634                 project_float(gesture->points[s_i + 1].p, s_p2);
1635
1636                 /* start checking from second next, because two consecutive cannot intersect */
1637                 for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++)
1638                 {
1639                         float g_p1[3] = {0, 0, 0};
1640                         float g_p2[3] = {0, 0, 0};
1641                         float vi[3];
1642                         float lambda;
1643                         
1644                         project_float(gesture->points[g_i].p, g_p1);
1645                         project_float(gesture->points[g_i + 1].p, g_p2);
1646                         
1647                         if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
1648                         {
1649                                 SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
1650                                 
1651                                 isect->gesture_index = g_i;
1652                                 isect->before = s_i;
1653                                 isect->after = s_i + 1;
1654                                 isect->stroke = gesture;
1655                                 
1656                                 VecSubf(isect->p, gesture->points[s_i + 1].p, gesture->points[s_i].p);
1657                                 VecMulf(isect->p, lambda);
1658                                 VecAddf(isect->p, isect->p, gesture->points[s_i].p);
1659                                 
1660                                 BLI_addtail(list, isect);
1661
1662                                 added++;
1663                         }
1664                 }
1665         }
1666         
1667         return added;
1668 }
1669
1670
1671 /* returns the maximum number of intersections per stroke */
1672 int sk_getIntersections(ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
1673 {
1674         SK_Stroke *stk;
1675         int added = 0;
1676
1677         for (stk = sketch->strokes.first; stk; stk = stk->next)
1678         {
1679                 int s_added = 0;
1680                 int s_i;
1681                 
1682                 for (s_i = 0; s_i < stk->nb_points - 1; s_i++)
1683                 {
1684                         float s_p1[3] = {0, 0, 0};
1685                         float s_p2[3] = {0, 0, 0};
1686                         int g_i;
1687                         
1688                         project_float(stk->points[s_i].p, s_p1);
1689                         project_float(stk->points[s_i + 1].p, s_p2);
1690
1691                         for (g_i = 0; g_i < gesture->nb_points - 1; g_i++)
1692                         {
1693                                 float g_p1[3] = {0, 0, 0};
1694                                 float g_p2[3] = {0, 0, 0};
1695                                 float vi[3];
1696                                 float lambda;
1697                                 
1698                                 project_float(gesture->points[g_i].p, g_p1);
1699                                 project_float(gesture->points[g_i + 1].p, g_p2);
1700                                 
1701                                 if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
1702                                 {
1703                                         SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
1704                                         float ray_start[3], ray_end[3];
1705                                         short mval[2];
1706                                         
1707                                         isect->gesture_index = g_i;
1708                                         isect->before = s_i;
1709                                         isect->after = s_i + 1;
1710                                         isect->stroke = stk;
1711                                         
1712                                         mval[0] = (short)(vi[0]);
1713                                         mval[1] = (short)(vi[1]);
1714                                         viewline(mval, ray_start, ray_end);
1715                                         
1716                                         LineIntersectLine(      stk->points[s_i].p,
1717                                                                                 stk->points[s_i + 1].p,
1718                                                                                 ray_start,
1719                                                                                 ray_end,
1720                                                                                 isect->p,
1721                                                                                 vi);
1722                                         
1723                                         BLI_addtail(list, isect);
1724
1725                                         s_added++;
1726                                 }
1727                         }
1728                 }
1729                 
1730                 added = MAX2(s_added, added);
1731         }
1732         
1733         
1734         return added;
1735 }
1736
1737 int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
1738 {
1739         float CORRELATION_THRESHOLD = 0.99f;
1740         float *vec;
1741         int i, j;
1742         
1743         sk_appendStrokePoint(segments, &gesture->points[0]);
1744         vec = segments->points[segments->nb_points - 1].p;
1745
1746         for (i = 1, j = 0; i < gesture->nb_points; i++)
1747         { 
1748                 float n[3];
1749                 
1750                 /* Calculate normal */
1751                 VecSubf(n, gesture->points[i].p, vec);
1752                 
1753                 if (calcStrokeCorrelation(gesture, j, i, vec, n) < CORRELATION_THRESHOLD)
1754                 {
1755                         j = i - 1;
1756                         sk_appendStrokePoint(segments, &gesture->points[j]);
1757                         vec = segments->points[segments->nb_points - 1].p;
1758                         segments->points[segments->nb_points - 1].type = PT_EXACT;
1759                 }
1760         }
1761
1762         sk_appendStrokePoint(segments, &gesture->points[gesture->nb_points - 1]);
1763         
1764         return segments->nb_points - 1;
1765 }
1766
1767 void sk_applyCutGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1768 {
1769         SK_Intersection *isect;
1770         
1771         for (isect = list->first; isect; isect = isect->next)
1772         {
1773                 SK_Point pt;
1774                 
1775                 pt.type = PT_EXACT;
1776                 pt.mode = PT_PROJECT; /* take mode from neighbouring points */
1777                 VECCOPY(pt.p, isect->p);
1778                 
1779                 sk_insertStrokePoint(isect->stroke, &pt, isect->after);
1780         }
1781 }
1782
1783 int sk_detectTrimGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1784 {
1785         float s1[3], s2[3];
1786         float angle;
1787         
1788         VecSubf(s1, segments->points[1].p, segments->points[0].p);
1789         VecSubf(s2, segments->points[2].p, segments->points[1].p);
1790         
1791         angle = VecAngle2(s1, s2);
1792         
1793         if (angle > 60 && angle < 120)
1794         {
1795                 return 1;
1796         }
1797         else
1798         {
1799                 return 0;
1800         }
1801 }
1802
1803 void sk_applyTrimGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1804 {
1805         SK_Intersection *isect;
1806         float trim_dir[3];
1807         
1808         VecSubf(trim_dir, segments->points[2].p, segments->points[1].p);
1809         
1810         for (isect = list->first; isect; isect = isect->next)
1811         {
1812                 SK_Point pt;
1813                 float stroke_dir[3];
1814                 
1815                 pt.type = PT_EXACT;
1816                 pt.mode = PT_PROJECT; /* take mode from neighbouring points */
1817                 VECCOPY(pt.p, isect->p);
1818                 
1819                 VecSubf(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p);
1820                 
1821                 /* same direction, trim end */
1822                 if (Inpf(stroke_dir, trim_dir) > 0)
1823                 {
1824                         sk_replaceStrokePoint(isect->stroke, &pt, isect->after);
1825                         sk_trimStroke(isect->stroke, 0, isect->after);
1826                 }
1827                 /* else, trim start */
1828                 else
1829                 {
1830                         sk_replaceStrokePoint(isect->stroke, &pt, isect->before);
1831                         sk_trimStroke(isect->stroke, isect->before, isect->stroke->nb_points - 1);
1832                 }
1833         
1834         }
1835 }
1836
1837 int sk_detectDeleteGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1838 {
1839         float s1[3], s2[3];
1840         float angle;
1841         
1842         VecSubf(s1, segments->points[1].p, segments->points[0].p);
1843         VecSubf(s2, segments->points[2].p, segments->points[1].p);
1844         
1845         angle = VecAngle2(s1, s2);
1846         
1847         if (angle > 120)
1848         {
1849                 return 1;
1850         }
1851         else
1852         {
1853                 return 0;
1854         }
1855 }
1856
1857 void sk_applyDeleteGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1858 {
1859         SK_Intersection *isect;
1860         
1861         for (isect = list->first; isect; isect = isect->next)
1862         {
1863                 /* only delete strokes that are crossed twice */
1864                 if (isect->next && isect->next->stroke == isect->stroke)
1865                 {
1866                         isect = isect->next;
1867                         
1868                         sk_removeStroke(sketch, isect->stroke);
1869                 }
1870         }
1871 }
1872
1873 int sk_detectMergeGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1874 {
1875         short start_val[2], end_val[2];
1876         short dist;
1877         
1878         project_short_noclip(gesture->points[0].p, start_val);
1879         project_short_noclip(gesture->points[gesture->nb_points - 1].p, end_val);
1880         
1881         dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1]));
1882         
1883         /* if gesture is a circle */
1884         if ( dist <= 20 )
1885         {
1886                 SK_Intersection *isect;
1887                 
1888                 /* check if it circled around an exact point */
1889                 for (isect = list->first; isect; isect = isect->next)
1890                 {
1891                         /* only delete strokes that are crossed twice */
1892                         if (isect->next && isect->next->stroke == isect->stroke)
1893                         {
1894                                 int start_index, end_index;
1895                                 int i;
1896                                 
1897                                 start_index = MIN2(isect->after, isect->next->after);
1898                                 end_index = MAX2(isect->before, isect->next->before);
1899
1900                                 for (i = start_index; i <= end_index; i++)
1901                                 {
1902                                         if (isect->stroke->points[i].type == PT_EXACT)
1903                                         {
1904                                                 return 1; /* at least one exact point found, stop detect here */
1905                                         }
1906                                 }
1907
1908                                 /* skip next */                         
1909                                 isect = isect->next;
1910                         }
1911                 }
1912                         
1913                 return 0;
1914         }
1915         else
1916         {
1917                 return 0;
1918         }
1919 }
1920
1921 void sk_applyMergeGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1922 {
1923         SK_Intersection *isect;
1924         
1925         /* check if it circled around an exact point */
1926         for (isect = list->first; isect; isect = isect->next)
1927         {
1928                 /* only merge strokes that are crossed twice */
1929                 if (isect->next && isect->next->stroke == isect->stroke)
1930                 {
1931                         int start_index, end_index;
1932                         int i;
1933                         
1934                         start_index = MIN2(isect->after, isect->next->after);
1935                         end_index = MAX2(isect->before, isect->next->before);
1936
1937                         for (i = start_index; i <= end_index; i++)
1938                         {
1939                                 /* if exact, switch to continuous */
1940                                 if (isect->stroke->points[i].type == PT_EXACT)
1941                                 {
1942                                         isect->stroke->points[i].type = PT_CONTINUOUS;
1943                                 }
1944                         }
1945
1946                         /* skip next */                         
1947                         isect = isect->next;
1948                 }
1949         }
1950 }
1951
1952 int sk_detectReverseGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1953 {
1954         SK_Intersection *isect;
1955         
1956         /* check if it circled around an exact point */
1957         for (isect = list->first; isect; isect = isect->next)
1958         {
1959                 /* only delete strokes that are crossed twice */
1960                 if (isect->next && isect->next->stroke == isect->stroke)
1961                 {
1962                         float start_v[3], end_v[3];
1963                         float angle;
1964                         
1965                         if (isect->gesture_index < isect->next->gesture_index)
1966                         {
1967                                 VecSubf(start_v, isect->p, gesture->points[0].p);
1968                                 VecSubf(end_v, sk_lastStrokePoint(gesture)->p, isect->next->p);
1969                         }
1970                         else
1971                         {
1972                                 VecSubf(start_v, isect->next->p, gesture->points[0].p);
1973                                 VecSubf(end_v, sk_lastStrokePoint(gesture)->p, isect->p);
1974                         }
1975                         
1976                         angle = VecAngle2(start_v, end_v);
1977                         
1978                         if (angle > 120)
1979                         {
1980                                 return 1;
1981                         }
1982
1983                         /* skip next */                         
1984                         isect = isect->next;
1985                 }
1986         }
1987                 
1988         return 0;
1989 }
1990
1991 void sk_applyReverseGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
1992 {
1993         SK_Intersection *isect;
1994         
1995         for (isect = list->first; isect; isect = isect->next)
1996         {
1997                 /* only reverse strokes that are crossed twice */
1998                 if (isect->next && isect->next->stroke == isect->stroke)
1999                 {
2000                         sk_reverseStroke(isect->stroke);
2001
2002                         /* skip next */                         
2003                         isect = isect->next;
2004                 }
2005         }
2006 }
2007
2008 void sk_applyGesture(SK_Sketch *sketch)
2009 {
2010         ListBase intersections;
2011         ListBase self_intersections;
2012         SK_Stroke *segments = sk_createStroke();
2013         int nb_self_intersections, nb_intersections, nb_segments;
2014         
2015         intersections.first = intersections.last = NULL;
2016         self_intersections.first = self_intersections.last = NULL;
2017         
2018         nb_self_intersections = sk_getSelfIntersections(&self_intersections, sketch->gesture);
2019         nb_intersections = sk_getIntersections(&intersections, sketch, sketch->gesture);
2020         nb_segments = sk_getSegments(segments, sketch->gesture);
2021         
2022         /* detect and apply */
2023         if (nb_segments == 1 && nb_intersections == 1)
2024         {
2025                 sk_applyCutGesture(sketch, sketch->gesture, &intersections, segments);
2026         }
2027         else if (nb_segments == 2 && nb_intersections == 1 && sk_detectTrimGesture(sketch, sketch->gesture, &intersections, segments))
2028         {
2029                 sk_applyTrimGesture(sketch, sketch->gesture, &intersections, segments);
2030         }
2031         else if (nb_segments == 2 && nb_intersections == 2 && sk_detectDeleteGesture(sketch, sketch->gesture, &intersections, segments))
2032         {
2033                 sk_applyDeleteGesture(sketch, sketch->gesture, &intersections, segments);
2034         }
2035         else if (nb_segments > 2 && nb_intersections == 2 && sk_detectMergeGesture(sketch, sketch->gesture, &intersections, segments))
2036         {
2037                 sk_applyMergeGesture(sketch, sketch->gesture, &intersections, segments);
2038         }
2039         else if (nb_segments > 2 && nb_intersections == 2 && sk_detectReverseGesture(sketch, sketch->gesture, &intersections, segments))
2040         {
2041                 sk_applyReverseGesture(sketch, sketch->gesture, &intersections, segments);
2042         }
2043         else if (nb_segments > 2 && nb_self_intersections == 1)
2044         {
2045                 sk_convert(sketch);
2046                 BIF_undo_push("Convert Sketch");
2047                 allqueue(REDRAWBUTSEDIT, 0);
2048         }
2049         else if (nb_segments > 2 && nb_self_intersections == 2)
2050         {
2051                 sk_deleteSelectedStrokes(sketch);
2052         }
2053         
2054         sk_freeStroke(segments);
2055         BLI_freelistN(&intersections);
2056         BLI_freelistN(&self_intersections);
2057 }
2058
2059 /********************************************/
2060
2061 void sk_deleteSelectedStrokes(SK_Sketch *sketch)
2062 {
2063         SK_Stroke *stk, *next;
2064         
2065         for (stk = sketch->strokes.first; stk; stk = next)
2066         {
2067                 next = stk->next;
2068                 
2069                 if (stk->selected == 1)
2070                 {
2071                         sk_removeStroke(sketch, stk);
2072                 }
2073         }
2074 }
2075
2076 void sk_selectAllSketch(SK_Sketch *sketch, int mode)
2077 {
2078         SK_Stroke *stk = NULL;
2079         
2080         if (mode == -1)
2081         {
2082                 for (stk = sketch->strokes.first; stk; stk = stk->next)
2083                 {
2084                         stk->selected = 0;
2085                 }
2086         }
2087         else if (mode == 0)
2088         {
2089                 for (stk = sketch->strokes.first; stk; stk = stk->next)
2090                 {
2091                         stk->selected = 1;
2092                 }
2093         }
2094         else if (mode == 1)
2095         {
2096                 int selected = 1;
2097                 
2098                 for (stk = sketch->strokes.first; stk; stk = stk->next)
2099                 {
2100                         selected &= stk->selected;
2101                 }
2102                 
2103                 selected ^= 1;
2104
2105                 for (stk = sketch->strokes.first; stk; stk = stk->next)
2106                 {
2107                         stk->selected = selected;
2108                 }
2109         }
2110 }
2111
2112 void sk_selectStroke(SK_Sketch *sketch)
2113 {
2114         unsigned int buffer[MAXPICKBUF];
2115         short hits, mval[2];
2116
2117         persp(PERSP_VIEW);
2118
2119         getmouseco_areawin(mval);
2120         hits = view3d_opengl_select(buffer, MAXPICKBUF, mval[0]-5, mval[1]-5, mval[0]+5, mval[1]+5);
2121         if(hits==0)
2122                 hits = view3d_opengl_select(buffer, MAXPICKBUF, mval[0]-12, mval[1]-12, mval[0]+12, mval[1]+12);
2123                 
2124         if (hits>0)
2125         {
2126                 int besthitresult = -1;
2127                         
2128                 if(hits == 1) {
2129                         besthitresult = buffer[3];
2130                 }
2131                 else {
2132                         besthitresult = buffer[3];
2133                         /* loop and get best hit */
2134                 }
2135                 
2136                 if (besthitresult > 0)
2137                 {
2138                         SK_Stroke *selected_stk = BLI_findlink(&sketch->strokes, besthitresult - 1);
2139                         
2140                         if ((G.qual & LR_SHIFTKEY) == 0)
2141                         {
2142                                 sk_selectAllSketch(sketch, -1);
2143                                 
2144                                 selected_stk->selected = 1;
2145                         }
2146                         else
2147                         {
2148                                 selected_stk->selected ^= 1;
2149                         }
2150                         
2151                         
2152                 }
2153         }
2154 }
2155
2156 void sk_queueRedrawSketch(SK_Sketch *sketch)
2157 {
2158         if (sketch->active_stroke != NULL)
2159         {
2160                 SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
2161                 
2162                 if (last != NULL)
2163                 {
2164                         allqueue(REDRAWVIEW3D, 0);
2165                 }
2166         }
2167 }
2168
2169 void sk_drawSketch(SK_Sketch *sketch, int with_names)
2170 {
2171         SK_Stroke *stk;
2172         
2173         glDisable(GL_DEPTH_TEST);
2174
2175         glLineWidth(BIF_GetThemeValuef(TH_VERTEX_SIZE));
2176         glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
2177         
2178         if (with_names)
2179         {
2180                 int id;
2181                 for (id = 1, stk = sketch->strokes.first; stk; id++, stk = stk->next)
2182                 {
2183                         sk_drawStroke(stk, id, NULL);
2184                 }
2185                 
2186                 glLoadName(-1);
2187         }
2188         else
2189         {
2190                 float selected_rgb[3] = {1, 0, 0};
2191                 float unselected_rgb[3] = {1, 0.5, 0};
2192                 
2193                 for (stk = sketch->strokes.first; stk; stk = stk->next)
2194                 {
2195                         sk_drawStroke(stk, -1, (stk->selected==1?selected_rgb:unselected_rgb));
2196                 
2197                         if (stk->selected == 1)
2198                         {
2199                                 sk_drawStrokeSubdivision(stk);
2200                         }
2201                 }
2202         
2203                 /* only draw gesture in active area */
2204                 if (sketch->gesture != NULL && area_is_active_area(G.vd->area))
2205                 {
2206                         float gesture_rgb[3] = {0, 0.5, 1};
2207                         sk_drawStroke(sketch->gesture, -1, gesture_rgb);
2208                 }
2209                 
2210                 if (sketch->active_stroke != NULL)
2211                 {
2212                         SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
2213                         
2214                         if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
2215                         {
2216                                 sk_drawStrokeSubdivision(sketch->active_stroke);
2217                         }
2218                         
2219                         if (last != NULL)
2220                         {
2221                                 /* update point if in active area */
2222                                 if (area_is_active_area(G.vd->area))
2223                                 {
2224                                         SK_DrawData dd;
2225                                         
2226                                         sk_initDrawData(&dd);
2227                                         sk_getStrokePoint(&sketch->next_point, sketch, sketch->active_stroke, &dd, G.qual);
2228                                 }
2229                                 
2230                                 glEnable(GL_LINE_STIPPLE);
2231                                 glColor3f(1, 0.5, 0);
2232                                 glBegin(GL_LINE_STRIP);
2233                                 
2234                                         glVertex3fv(last->p);
2235                                         glVertex3fv(sketch->next_point.p);
2236                                 
2237                                 glEnd();
2238                                 
2239                                 glDisable(GL_LINE_STIPPLE);
2240         
2241                                 switch (sketch->next_point.mode)
2242                                 {
2243                                         case PT_SNAP:
2244                                                 glColor3f(0, 0.5, 1);
2245                                                 break;
2246                                         case PT_EMBED:
2247                                                 glColor3f(0, 1, 0);
2248                                                 break;
2249                                         case PT_PROJECT:
2250                                                 glColor3f(0, 0, 0);
2251                                                 break;
2252                                 }
2253                                 
2254                                 glBegin(GL_POINTS);
2255                                 
2256                                         glVertex3fv(sketch->next_point.p);
2257                                 
2258                                 glEnd();
2259                         }
2260                 }
2261         }
2262         
2263         glLineWidth(1.0);
2264         glPointSize(1.0);
2265
2266         glEnable(GL_DEPTH_TEST);
2267 }
2268
2269 int sk_paint(SK_Sketch *sketch, short mbut)
2270 {
2271         int retval = 1;
2272         
2273         if (mbut == LEFTMOUSE)
2274         {
2275                 SK_DrawData dd;
2276                 if (sketch->active_stroke == NULL)
2277                 {
2278                         sk_startStroke(sketch);
2279                 }
2280
2281                 sk_initDrawData(&dd);
2282                 
2283                 /* paint loop */
2284                 do {
2285                         /* get current user input */
2286                         getmouseco_areawin(dd.mval);
2287                         
2288                         /* only add current point to buffer if mouse moved (otherwise wait until it does) */
2289                         if (sk_stroke_filtermval(&dd)) {
2290
2291                                 sk_addStrokePoint(sketch, sketch->active_stroke, &dd, G.qual);
2292                                 sk_updateDrawData(&dd);
2293                                 force_draw(0);
2294                         }
2295                         else
2296                         {
2297                                 BIF_wait_for_statechange();
2298                         }
2299                         
2300                         while( qtest() ) {
2301                                 short event, val;
2302                                 event = extern_qread(&val);
2303                         }
2304                         
2305                         /* do mouse checking at the end, so don't check twice, and potentially
2306                          * miss a short tap 
2307                          */
2308                 } while (get_mbut() & L_MOUSE);
2309                 
2310                 sk_endContinuousStroke(sketch->active_stroke);
2311                 sk_filterLastContinuousStroke(sketch->active_stroke);
2312                 sk_updateNextPoint(sketch);
2313         }
2314         else if (mbut == RIGHTMOUSE)
2315         {
2316                 if (sketch->active_stroke != NULL)
2317                 {
2318                         SK_Stroke *stk = sketch->active_stroke;
2319                         
2320                         sk_endStroke(sketch);
2321                         
2322                         if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
2323                         {
2324                                 if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
2325                                 {
2326                                         retargetStroke(stk);
2327                                 }
2328                                 else
2329                                 {
2330                                         sk_convertStroke(stk);
2331                                 }
2332                                 sk_removeStroke(sketch, stk);
2333                                 BIF_undo_push("Convert Sketch");
2334                                 allqueue(REDRAWBUTSEDIT, 0);
2335                         }
2336                         
2337                         allqueue(REDRAWVIEW3D, 0);
2338                 }
2339                 /* no gestures in quick mode */
2340                 else if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
2341                 {
2342                         retval = 0; /* return zero for default click behavior */
2343                 }
2344                 else
2345                 {
2346                         SK_DrawData dd;
2347                         sketch->gesture = sk_createStroke();
2348         
2349                         sk_initDrawData(&dd);
2350                         
2351                         /* paint loop */
2352                         do {
2353                                 /* get current user input */
2354                                 getmouseco_areawin(dd.mval);
2355                                 
2356                                 /* only add current point to buffer if mouse moved (otherwise wait until it does) */
2357                                 if (sk_stroke_filtermval(&dd)) {
2358
2359                                         sk_addStrokeDrawPoint(sketch, sketch->gesture, &dd);
2360                                         sk_updateDrawData(&dd);
2361                                         
2362                                         /* draw only if mouse has moved */
2363                                         if (sketch->gesture->nb_points > 1)
2364                                         {
2365                                                 force_draw(0);
2366                                         }
2367                                 }
2368                                 else
2369                                 {
2370                                         BIF_wait_for_statechange();
2371                                 }
2372                                 
2373                                 while( qtest() ) {
2374                                         short event, val;
2375                                         event = extern_qread(&val);
2376                                 }
2377                                 
2378                                 /* do mouse checking at the end, so don't check twice, and potentially
2379                                  * miss a short tap 
2380                                  */
2381                         } while (get_mbut() & R_MOUSE);
2382                         
2383                         sk_endContinuousStroke(sketch->gesture);
2384                         sk_filterLastContinuousStroke(sketch->gesture);
2385                         sk_filterLastContinuousStroke(sketch->gesture);
2386                         sk_filterLastContinuousStroke(sketch->gesture);
2387         
2388                         if (sketch->gesture->nb_points == 1)            
2389                         {
2390                                 sk_selectStroke(sketch);
2391                         }
2392                         else
2393                         {
2394                                 /* apply gesture here */
2395                                 sk_applyGesture(sketch);
2396                         }
2397         
2398                         sk_freeStroke(sketch->gesture);
2399                         sketch->gesture = NULL;
2400                         
2401                         allqueue(REDRAWVIEW3D, 0);
2402                 }
2403         }
2404         
2405         return retval;
2406 }
2407
2408 void BDR_drawSketchNames()
2409 {
2410         if (BIF_validSketchMode())
2411         {
2412                 if (GLOBAL_sketch != NULL)
2413                 {
2414                         sk_drawSketch(GLOBAL_sketch, 1);
2415                 }
2416         }
2417 }
2418
2419 void BDR_drawSketch()
2420 {
2421         if (BIF_validSketchMode())
2422         {
2423                 if (GLOBAL_sketch != NULL)
2424                 {
2425                         sk_drawSketch(GLOBAL_sketch, 0);
2426                 }
2427         }
2428 }
2429
2430 void BIF_endStrokeSketch()
2431 {
2432         if (BIF_validSketchMode())
2433         {
2434                 if (GLOBAL_sketch != NULL)
2435                 {
2436                         sk_endStroke(GLOBAL_sketch);
2437                         allqueue(REDRAWVIEW3D, 0);
2438                 }
2439         }
2440 }
2441
2442 void BIF_cancelStrokeSketch()
2443 {
2444         if (BIF_validSketchMode())
2445         {
2446                 if (GLOBAL_sketch != NULL)
2447                 {
2448                         sk_cancelStroke(GLOBAL_sketch);
2449                         allqueue(REDRAWVIEW3D, 0);
2450                 }
2451         }
2452 }
2453
2454 void BIF_deleteSketch()
2455 {
2456         if (BIF_validSketchMode())
2457         {
2458                 if (GLOBAL_sketch != NULL)
2459                 {
2460                         sk_deleteSelectedStrokes(GLOBAL_sketch);
2461                         allqueue(REDRAWVIEW3D, 0);
2462                 }
2463         }
2464 }
2465
2466 void BIF_convertSketch()
2467 {
2468         if (BIF_validSketchMode())
2469         {
2470                 if (GLOBAL_sketch != NULL)
2471                 {
2472                         sk_convert(GLOBAL_sketch);
2473                         BIF_undo_push("Convert Sketch");
2474                         allqueue(REDRAWVIEW3D, 0);
2475                         allqueue(REDRAWBUTSEDIT, 0);
2476                 }
2477         }
2478 }
2479
2480 int BIF_paintSketch(short mbut)
2481 {
2482         if (BIF_validSketchMode())
2483         {
2484                 if (GLOBAL_sketch == NULL)
2485                 {
2486                         GLOBAL_sketch = sk_createSketch();
2487                 }
2488                 
2489                 return sk_paint(GLOBAL_sketch, mbut);
2490         }
2491         else
2492         {
2493                 return 0;
2494         }
2495 }
2496         
2497
2498 void BDR_queueDrawSketch()
2499 {
2500         if (BIF_validSketchMode())
2501         {
2502                 if (GLOBAL_sketch != NULL)
2503                 {
2504                         sk_queueRedrawSketch(GLOBAL_sketch);
2505                 }
2506         }
2507 }
2508
2509 void BIF_selectAllSketch(int mode)
2510 {
2511         if (BIF_validSketchMode())
2512         {
2513                 if (GLOBAL_sketch != NULL)
2514                 {
2515                         sk_selectAllSketch(GLOBAL_sketch, mode);
2516                         allqueue(REDRAWVIEW3D, 0);
2517                 }
2518         }
2519 }
2520
2521 int BIF_validSketchMode()
2522 {
2523         if (G.obedit && 
2524                 G.obedit->type == OB_ARMATURE && 
2525                 G.scene->toolsettings->bone_sketching & BONE_SKETCHING)
2526         {
2527                 return 1;
2528         }
2529         else
2530         {
2531                 return 0;
2532         }
2533 }
2534
2535 int BIF_fullSketchMode()
2536 {
2537         if (G.obedit && 
2538                 G.obedit->type == OB_ARMATURE && 
2539                 G.scene->toolsettings->bone_sketching & BONE_SKETCHING && 
2540                 (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) == 0)
2541         {
2542                 return 1;
2543         }
2544         else
2545         {
2546                 return 0;
2547         }
2548 }