4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file blender/editors/armature/editarmature_sketch.c
32 #include "MEM_guardedalloc.h"
34 #include "DNA_object_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_armature_types.h"
38 #include "RNA_define.h"
39 #include "RNA_access.h"
41 #include "BLI_blenlib.h"
43 #include "BLI_utildefines.h"
44 #include "BLI_graph.h"
45 #include "BLI_ghash.h"
47 #include "BKE_context.h"
48 #include "BKE_sketch.h"
50 #include "ED_view3d.h"
51 #include "ED_screen.h"
54 //#include "BIF_screen.h"
55 //#include "BIF_space.h"
56 //#include "BIF_mywindow.h"
57 #include "ED_armature.h"
58 #include "armature_intern.h"
59 //#include "BIF_sketch.h"
60 #include "BIF_retarget.h"
61 #include "BIF_generate.h"
62 //#include "BIF_interface.h"
64 #include "ED_transform.h"
69 //#include "blendef.h"
70 //#include "mydevice.h"
75 typedef int (*GestureDetectFct)(bContext*, SK_Gesture*, SK_Sketch *);
76 typedef void (*GestureApplyFct)(bContext*, SK_Gesture*, SK_Sketch *);
78 typedef struct SK_GestureAction {
80 GestureDetectFct detect;
81 GestureApplyFct apply;
84 #if 0 /* UNUSED 2.5 */
85 static SK_Point boneSnap;
88 static int LAST_SNAP_POINT_VALID = 0;
89 static float LAST_SNAP_POINT[3];
92 typedef struct SK_StrokeIterator {
106 /*********************************/
113 /******************** PROTOTYPES ******************************/
115 void initStrokeIterator(BArcIterator *iter, SK_Stroke *stk, int start, int end);
117 int sk_detectCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
118 void sk_applyCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
119 int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
120 void sk_applyTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
121 int sk_detectCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
122 void sk_applyCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
123 int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
124 void sk_applyDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
125 int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
126 void sk_applyMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
127 int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
128 void sk_applyReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
129 int sk_detectConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
130 void sk_applyConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
132 SK_Sketch* contextSketch(const bContext *c, int create);
133 SK_Sketch* viewcontextSketch(ViewContext *vc, int create);
135 void sk_resetOverdraw(SK_Sketch *sketch);
136 int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk);
138 /******************** GESTURE ACTIONS ******************************/
140 static SK_GestureAction GESTURE_ACTIONS[] =
142 {"Cut", sk_detectCutGesture, sk_applyCutGesture},
143 {"Trim", sk_detectTrimGesture, sk_applyTrimGesture},
144 {"Command", sk_detectCommandGesture, sk_applyCommandGesture},
145 {"Delete", sk_detectDeleteGesture, sk_applyDeleteGesture},
146 {"Merge", sk_detectMergeGesture, sk_applyMergeGesture},
147 {"Reverse", sk_detectReverseGesture, sk_applyReverseGesture},
148 {"Convert", sk_detectConvertGesture, sk_applyConvertGesture},
152 /******************** TEMPLATES UTILS *************************/
154 static char *TEMPLATES_MENU = NULL;
155 static int TEMPLATES_CURRENT = 0;
156 static GHash *TEMPLATES_HASH = NULL;
157 static RigGraph *TEMPLATE_RIGG = NULL;
159 void BIF_makeListTemplates(const bContext *C)
161 Object *obedit = CTX_data_edit_object(C);
162 Scene *scene = CTX_data_scene(C);
163 ToolSettings *ts = CTX_data_tool_settings(C);
167 if (TEMPLATES_HASH != NULL)
169 BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
172 TEMPLATES_HASH = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "makeListTemplates gh");
173 TEMPLATES_CURRENT = 0;
175 for ( base = FIRSTBASE; base; base = base->next )
177 Object *ob = base->object;
179 if (ob != obedit && ob->type == OB_ARMATURE)
182 BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob);
184 if (ob == ts->skgen_template)
186 TEMPLATES_CURRENT = index;
192 char *BIF_listTemplates(const bContext *UNUSED(C))
195 char menu_header[] = "Template%t|None%x0|";
198 if (TEMPLATES_MENU != NULL)
200 MEM_freeN(TEMPLATES_MENU);
203 TEMPLATES_MENU = MEM_callocN(sizeof(char) * (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30), "skeleton template menu");
207 p += sprintf(TEMPLATES_MENU, "%s", menu_header);
209 BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
211 while (!BLI_ghashIterator_isDone(&ghi))
213 Object *ob = BLI_ghashIterator_getValue(&ghi);
214 int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
216 p += sprintf(p, "|%s%%x%i", ob->id.name+2, key);
218 BLI_ghashIterator_step(&ghi);
221 return TEMPLATES_MENU;
224 int BIF_currentTemplate(const bContext *C)
226 ToolSettings *ts = CTX_data_tool_settings(C);
228 if (TEMPLATES_CURRENT == 0 && ts->skgen_template != NULL)
231 BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
233 while (!BLI_ghashIterator_isDone(&ghi))
235 Object *ob = BLI_ghashIterator_getValue(&ghi);
236 int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
238 if (ob == ts->skgen_template)
240 TEMPLATES_CURRENT = key;
244 BLI_ghashIterator_step(&ghi);
248 return TEMPLATES_CURRENT;
251 static RigGraph* sk_makeTemplateGraph(const bContext *C, Object *ob)
253 Object *obedit = CTX_data_edit_object(C);
261 if (TEMPLATE_RIGG && TEMPLATE_RIGG->ob != ob)
263 RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
264 TEMPLATE_RIGG = NULL;
267 if (TEMPLATE_RIGG == NULL)
273 TEMPLATE_RIGG = RIG_graphFromArmature(C, ob, arm);
277 return TEMPLATE_RIGG;
280 int BIF_nbJointsTemplate(const bContext *C)
282 ToolSettings *ts = CTX_data_tool_settings(C);
283 RigGraph *rg = sk_makeTemplateGraph(C, ts->skgen_template);
287 return RIG_nbJoints(rg);
295 const char * BIF_nameBoneTemplate(const bContext *C)
297 ToolSettings *ts = CTX_data_tool_settings(C);
298 SK_Sketch *stk = contextSketch(C, 1);
302 if (stk && stk->active_stroke != NULL)
304 index = stk->active_stroke->nb_points;
307 rg = sk_makeTemplateGraph(C, ts->skgen_template);
314 return RIG_nameBone(rg, 0, index);
317 void BIF_freeTemplates(bContext *UNUSED(C))
319 if (TEMPLATES_MENU != NULL)
321 MEM_freeN(TEMPLATES_MENU);
322 TEMPLATES_MENU = NULL;
325 if (TEMPLATES_HASH != NULL)
327 BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
328 TEMPLATES_HASH = NULL;
331 if (TEMPLATE_RIGG != NULL)
333 RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
334 TEMPLATE_RIGG = NULL;
338 void BIF_setTemplate(bContext *C, int index)
340 ToolSettings *ts = CTX_data_tool_settings(C);
343 ts->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
347 ts->skgen_template = NULL;
349 if (TEMPLATE_RIGG != NULL)
351 RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
353 TEMPLATE_RIGG = NULL;
357 /*********************** CONVERSION ***************************/
359 static void sk_autoname(bContext *C, ReebArc *arc)
361 ToolSettings *ts = CTX_data_tool_settings(C);
362 if (ts->skgen_retarget_options & SK_RETARGET_AUTONAME)
366 char *num = ts->skgen_num_string;
369 BLI_snprintf(num, 8, "%i", i);
373 char *side = ts->skgen_side_string;
377 if (BLI_streq(side, ""))
381 else if (BLI_streq(side, "R") || BLI_streq(side, "L"))
386 else if (BLI_streq(side, "r") || BLI_streq(side, "l"))
394 if (arc->head->p[0] < 0)
396 BLI_snprintf(side, 8, caps?"R":"r");
400 BLI_snprintf(side, 8, caps?"L":"l");
407 static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3])
411 node = MEM_callocN(sizeof(ReebNode), "reeb node");
412 VECCOPY(node->p, pt->p);
413 mul_m4_v3(imat, node->p);
415 VECCOPY(node->no, pt->no);
416 mul_m3_v3(tmat, node->no);
421 static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3])
426 arc = MEM_callocN(sizeof(ReebArc), "reeb arc");
427 arc->head = sk_pointToNode(stk->points, imat, tmat);
428 arc->tail = sk_pointToNode(sk_lastStrokePoint(stk), imat, tmat);
430 arc->bcount = stk->nb_points - 2; /* first and last are nodes, don't count */
431 arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "Buckets");
433 for (i = 0; i < arc->bcount; i++)
435 VECCOPY(arc->buckets[i].p, stk->points[i + 1].p);
436 mul_m4_v3(imat, arc->buckets[i].p);
438 VECCOPY(arc->buckets[i].no, stk->points[i + 1].no);
439 mul_m3_v3(tmat, arc->buckets[i].no);
445 static void sk_retargetStroke(bContext *C, SK_Stroke *stk)
447 ToolSettings *ts = CTX_data_tool_settings(C);
448 Object *obedit = CTX_data_edit_object(C);
454 invert_m4_m4(imat, obedit->obmat);
456 copy_m3_m4(tmat, obedit->obmat);
459 arc = sk_strokeToArc(stk, imat, tmat);
463 rg = sk_makeTemplateGraph(C, ts->skgen_template);
465 BIF_retargetArc(C, arc, rg);
467 sk_autoname(C, NULL);
469 MEM_freeN(arc->head);
470 MEM_freeN(arc->tail);
471 REEB_freeArc((BArc*)arc);
474 /**************************************************************/
476 static void sk_cancelStroke(SK_Sketch *sketch)
478 if (sketch->active_stroke != NULL)
480 sk_resetOverdraw(sketch);
481 sk_removeStroke(sketch, sketch->active_stroke);
486 static float sk_clampPointSize(SK_Point *pt, float size)
488 return MAX2(size * pt->size, size / 2);
491 static void sk_drawPoint(GLUquadric *quad, SK_Point *pt, float size)
493 glTranslatef(pt->p[0], pt->p[1], pt->p[2]);
494 gluSphere(quad, sk_clampPointSize(pt, size), 8, 8);
497 static void sk_drawEdge(GLUquadric *quad, SK_Point *pt0, SK_Point *pt1, float size)
499 float vec1[3], vec2[3] = {0, 0, 1}, axis[3];
502 sub_v3_v3v3(vec1, pt1->p, pt0->p);
503 length = normalize_v3(vec1);
504 cross_v3_v3v3(axis, vec2, vec1);
506 if (is_zero_v3(axis))
511 angle = angle_normalized_v3v3(vec2, vec1);
513 glRotatef(angle * 180 / M_PI + 180, axis[0], axis[1], axis[2]);
515 gluCylinder(quad, sk_clampPointSize(pt1, size), sk_clampPointSize(pt0, size), length, 8, 8);
518 static void sk_drawNormal(GLUquadric *quad, SK_Point *pt, float size, float height)
520 float vec2[3] = {0, 0, 1}, axis[3];
525 cross_v3_v3v3(axis, vec2, pt->no);
527 if (is_zero_v3(axis))
532 angle = angle_normalized_v3v3(vec2, pt->no);
534 glRotatef(angle * 180 / M_PI, axis[0], axis[1], axis[2]);
537 gluCylinder(quad, sk_clampPointSize(pt, size), 0, sk_clampPointSize(pt, height), 10, 2);
542 static void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int end)
546 GLUquadric *quad = gluNewQuadric();
547 gluQuadricNormals(quad, GLU_SMOOTH);
553 for (i = 0; i < stk->nb_points; i++)
557 sk_drawPoint(quad, stk->points + i, 0.1);
561 sk_drawEdge(quad, stk->points + i - 1, stk->points + i, 0.1);
570 float d_rgb[3] = {1, 1, 1};
572 copy_v3_v3(rgb, color);
573 sub_v3_v3(d_rgb, rgb);
574 mul_v3_fl(d_rgb, 1.0f / (float)stk->nb_points);
576 for (i = 0; i < stk->nb_points; i++)
578 SK_Point *pt = stk->points + i;
582 if (pt->type == PT_EXACT)
585 sk_drawPoint(quad, pt, 0.15);
586 sk_drawNormal(quad, pt, 0.05, 0.9);
589 if (i >= start && i <= end)
591 glColor3f(0.3, 0.3, 0.3);
598 if (pt->type != PT_EXACT)
601 sk_drawPoint(quad, pt, 0.1);
606 sk_drawEdge(quad, pt - 1, pt, 0.1);
611 add_v3_v3(rgb, d_rgb);
615 gluDeleteQuadric(quad);
618 static void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *iter, NextSubdivisionFunc next_subdividion)
620 SK_Stroke *stk = ((SK_StrokeIterator*)iter)->stroke;
621 float head[3], tail[3];
623 int end = iter->length;
625 GLUquadric *quad = gluNewQuadric();
626 gluQuadricNormals(quad, GLU_SMOOTH);
629 VECCOPY(head, iter->p);
631 index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
634 SK_Point *pt = stk->points + index;
639 sk_drawPoint(quad, pt, 0.15);
641 sk_drawNormal(quad, pt, 0.05, 0.9);
646 bone_start = index; // start next bone from current index
648 index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
651 gluDeleteQuadric(quad);
654 static void sk_drawStrokeSubdivision(ToolSettings *toolsettings, SK_Stroke *stk)
659 if (toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
665 for (i = 0; i < stk->nb_points; i++)
667 SK_Point *pt = stk->points + i;
669 if (pt->type == PT_EXACT || i == stk->nb_points - 1) /* stop on exact or on last point */
671 if (head_index == -1)
677 if (i - head_index > 1)
679 SK_StrokeIterator sk_iter;
680 BArcIterator *iter = (BArcIterator*)&sk_iter;
682 initStrokeIterator(iter, stk, head_index, i);
684 if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
686 drawSubdividedStrokeBy(toolsettings, iter, nextAdaptativeSubdivision);
688 else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
690 drawSubdividedStrokeBy(toolsettings, iter, nextLengthSubdivision);
692 else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
694 drawSubdividedStrokeBy(toolsettings, iter, nextFixedSubdivision);
705 static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], int *dist, int *index, int all_pts)
707 ARegion *ar = CTX_wm_region(C);
711 for (i = 0; i < stk->nb_points; i++)
713 if (all_pts || stk->points[i].type == PT_EXACT)
718 project_short_noclip(ar, stk->points[i].p, pval);
720 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
725 pt = stk->points + i;
738 #if 0 /* UNUSED 2.5 */
739 static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, int mval[2], int *dist)
741 ARegion *ar = CTX_wm_region(C);
745 for (bone = ebones->first; bone; bone = bone->next)
751 if ((bone->flag & BONE_CONNECTED) == 0)
753 VECCOPY(vec, bone->head);
754 mul_m4_v3(ob->obmat, vec);
755 project_short_noclip(ar, vec, pval);
757 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
769 VECCOPY(vec, bone->tail);
770 mul_m4_v3(ob->obmat, vec);
771 project_short_noclip(ar, vec, pval);
773 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
788 void sk_resetOverdraw(SK_Sketch *sketch)
790 sketch->over.target = NULL;
791 sketch->over.start = -1;
792 sketch->over.end = -1;
793 sketch->over.count = 0;
796 int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk)
798 return sketch->over.target &&
799 sketch->over.count >= SK_OVERDRAW_LIMIT &&
800 (sketch->over.target == stk || stk == NULL) &&
801 (sketch->over.start != -1 || sketch->over.end != -1);
804 static void sk_updateOverdraw(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
806 if (sketch->over.target == NULL)
809 int closest_index = -1;
810 int dist = SNAP_MIN_DISTANCE * 2;
812 for (target = sketch->strokes.first; target; target = target->next)
818 SK_Point *spt = sk_snapPointStroke(C, target, dd->mval, &dist, &index, 1);
822 sketch->over.target = target;
823 closest_index = index;
828 if (sketch->over.target != NULL)
830 if (closest_index > -1)
832 if (sk_lastStrokePoint(stk)->type == PT_EXACT)
834 sketch->over.count = SK_OVERDRAW_LIMIT;
838 sketch->over.count++;
842 if (stk->nb_points == 1)
844 sketch->over.start = closest_index;
848 sketch->over.end = closest_index;
852 else if (sketch->over.target != NULL)
854 SK_Point *closest_pt = NULL;
855 int dist = SNAP_MIN_DISTANCE * 2;
858 closest_pt = sk_snapPointStroke(C, sketch->over.target, dd->mval, &dist, &index, 1);
860 if (closest_pt != NULL)
862 if (sk_lastStrokePoint(stk)->type == PT_EXACT)
864 sketch->over.count = SK_OVERDRAW_LIMIT;
868 sketch->over.count++;
871 sketch->over.end = index;
875 sketch->over.end = -1;
880 /* return 1 on reverse needed */
881 static int sk_adjustIndexes(SK_Sketch *sketch, int *start, int *end)
885 *start = sketch->over.start;
886 *end = sketch->over.end;
895 *end = sketch->over.target->nb_points - 1;
909 static void sk_endOverdraw(SK_Sketch *sketch)
911 SK_Stroke *stk = sketch->active_stroke;
913 if (sk_hasOverdraw(sketch, NULL))
918 if (sk_adjustIndexes(sketch, &start, &end))
920 sk_reverseStroke(stk);
923 if (stk->nb_points > 1)
925 stk->points->type = sketch->over.target->points[start].type;
926 sk_lastStrokePoint(stk)->type = sketch->over.target->points[end].type;
929 sk_insertStrokePoints(sketch->over.target, stk->points, stk->nb_points, start, end);
931 sk_removeStroke(sketch, stk);
933 sk_resetOverdraw(sketch);
938 static void sk_startStroke(SK_Sketch *sketch)
940 SK_Stroke *stk = sk_createStroke();
942 BLI_addtail(&sketch->strokes, stk);
943 sketch->active_stroke = stk;
945 sk_resetOverdraw(sketch);
948 static void sk_endStroke(bContext *C, SK_Sketch *sketch)
950 ToolSettings *ts = CTX_data_tool_settings(C);
951 sk_shrinkStrokeBuffer(sketch->active_stroke);
953 if (ts->bone_sketching & BONE_SKETCHING_ADJUST)
955 sk_endOverdraw(sketch);
958 sketch->active_stroke = NULL;
961 static void sk_updateDrawData(SK_DrawData *dd)
963 dd->type = PT_CONTINUOUS;
965 dd->previous_mval[0] = dd->mval[0];
966 dd->previous_mval[1] = dd->mval[1];
969 static float sk_distanceDepth(bContext *C, float p1[3], float p2[3])
971 ARegion *ar = CTX_wm_region(C);
972 RegionView3D *rv3d = ar->regiondata;
976 sub_v3_v3v3(vec, p1, p2);
978 project_v3_v3v3(vec, vec, rv3d->viewinv[2]);
980 distance = len_v3(vec);
982 if (dot_v3v3(rv3d->viewinv[2], vec) > 0)
990 static void sk_interpolateDepth(bContext *C, SK_Stroke *stk, int start, int end, float length, float distance)
992 ARegion *ar = CTX_wm_region(C);
993 ScrArea *sa = CTX_wm_area(C);
994 View3D *v3d = sa->spacedata.first;
999 progress = len_v3v3(stk->points[start].p, stk->points[start - 1].p);
1001 for (i = start; i <= end; i++)
1003 float ray_start[3], ray_normal[3];
1004 float delta = len_v3v3(stk->points[i].p, stk->points[i + 1].p);
1007 project_float(ar, stk->points[i].p, pval);
1008 ED_view3d_win_to_ray(ar, v3d, pval, ray_start, ray_normal);
1010 mul_v3_fl(ray_normal, distance * progress / length);
1011 add_v3_v3(stk->points[i].p, ray_normal);
1017 static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_DrawData *dd)
1019 ARegion *ar = CTX_wm_region(C);
1020 /* copied from grease pencil, need fixing */
1021 SK_Point *last = sk_lastStrokePoint(stk);
1023 float fp[3] = {0, 0, 0};
1029 VECCOPY(fp, last->p);
1032 initgrabz(ar->regiondata, fp[0], fp[1], fp[2]);
1034 /* method taken from editview.c - mouse_cursor() */
1035 project_short_noclip(ar, fp, cval);
1036 VECSUB2D(mval_f, cval, dd->mval);
1037 ED_view3d_win_to_delta(ar, mval_f, dvec);
1038 sub_v3_v3v3(vec, fp, dvec);
1041 static int sk_getStrokeDrawPoint(bContext *C, SK_Point *pt, SK_Sketch *UNUSED(sketch), SK_Stroke *stk, SK_DrawData *dd)
1043 pt->type = dd->type;
1044 pt->mode = PT_PROJECT;
1045 sk_projectDrawPoint(C, pt->p, stk, dd);
1050 static int sk_addStrokeDrawPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1052 ARegion *ar = CTX_wm_region(C);
1053 RegionView3D *rv3d = ar->regiondata;
1056 sk_initPoint(&pt, dd, rv3d->viewinv[2]);
1058 sk_getStrokeDrawPoint(C, &pt, sketch, stk, dd);
1060 sk_appendStrokePoint(stk, &pt);
1065 static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1067 ToolSettings *ts = CTX_data_tool_settings(C);
1068 int point_added = 0;
1070 if (ts->snap_mode == SCE_SNAP_MODE_VOLUME)
1073 float *last_p = NULL;
1074 float dist = FLT_MAX;
1079 BLI_freelistN(&sketch->depth_peels);
1080 sketch->depth_peels.first = sketch->depth_peels.last = NULL;
1082 mvalf[0]= dd->mval[0];
1083 mvalf[1]= dd->mval[1];
1084 peelObjectsContext(C, &sketch->depth_peels, mvalf);
1086 if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS)
1088 last_p = stk->points[stk->nb_points - 1].p;
1090 else if (LAST_SNAP_POINT_VALID)
1092 last_p = LAST_SNAP_POINT;
1096 for (p1 = sketch->depth_peels.first; p1; p1 = p1->next)
1107 /* if peeling objects, take the first and last from each object */
1108 if (ts->snap_flag & SCE_SNAP_PEEL_OBJECT)
1111 for (peel = p1->next; peel; peel = peel->next)
1113 if (peel->ob == p1->ob)
1120 /* otherwise, pair first with second and so on */
1123 for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next)
1125 /* nothing to do here */
1133 add_v3_v3v3(vec, p1->p, p2->p);
1134 mul_v3_fl(vec, 0.5f);
1135 new_size = len_v3v3(p1->p, p2->p);
1139 VECCOPY(vec, p1->p);
1150 new_dist = len_v3v3(last_p, vec);
1152 if (new_dist < dist)
1161 if (dist != FLT_MAX)
1163 pt->type = dd->type;
1165 pt->size = size / 2;
1171 //BLI_freelistN(&depth_peels);
1175 SK_Stroke *snap_stk;
1180 int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
1182 /* snap to strokes */
1183 // if (ts->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
1184 for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next)
1186 SK_Point *spt = NULL;
1187 if (snap_stk == stk)
1189 spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist, NULL, 0);
1193 spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist, NULL, 1);
1198 VECCOPY(pt->p, spt->p);
1203 mval[0] = dd->mval[0];
1204 mval[1] = dd->mval[1];
1206 /* try to snap to closer object */
1207 found = snapObjectsContext(C, mval, &dist, vec, no, SNAP_NOT_SELECTED);
1210 pt->type = dd->type;
1212 VECCOPY(pt->p, vec);
1221 static int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1224 ARegion *ar = CTX_wm_region(C);
1225 RegionView3D *rv3d = ar->regiondata;
1228 sk_initPoint(&pt, dd, rv3d->viewinv[2]);
1230 point_added = sk_getStrokeSnapPoint(C, &pt, sketch, stk, dd);
1235 float length, distance;
1239 VECCOPY(final_p, pt.p);
1241 sk_projectDrawPoint(C, pt.p, stk, dd);
1242 sk_appendStrokePoint(stk, &pt);
1244 /* update all previous point to give smooth Z progresion */
1247 for (i = stk->nb_points - 2; i > 0; i--)
1249 length += len_v3v3(stk->points[i].p, stk->points[i + 1].p);
1251 if (stk->points[i].mode == PT_SNAP || stk->points[i].type == PT_EXACT)
1259 distance = sk_distanceDepth(C, final_p, stk->points[i].p);
1261 sk_interpolateDepth(C, stk, i + 1, stk->nb_points - 2, length, distance);
1264 VECCOPY(stk->points[stk->nb_points - 1].p, final_p);
1272 static void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
1274 ToolSettings *ts = CTX_data_tool_settings(C);
1275 int point_added = 0;
1279 point_added = sk_addStrokeSnapPoint(C, sketch, stk, dd);
1282 if (point_added == 0)
1284 point_added = sk_addStrokeDrawPoint(C, sketch, stk, dd);
1287 if (stk == sketch->active_stroke && ts->bone_sketching & BONE_SKETCHING_ADJUST)
1289 sk_updateOverdraw(C, sketch, stk, dd);
1293 static void sk_getStrokePoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
1295 int point_added = 0;
1299 point_added = sk_getStrokeSnapPoint(C, pt, sketch, stk, dd);
1300 LAST_SNAP_POINT_VALID = 1;
1301 VECCOPY(LAST_SNAP_POINT, pt->p);
1305 LAST_SNAP_POINT_VALID = 0;
1308 if (point_added == 0)
1310 point_added = sk_getStrokeDrawPoint(C, pt, sketch, stk, dd);
1314 /********************************************/
1316 static void* headPoint(void *arg);
1317 static void* tailPoint(void *arg);
1318 static void* nextPoint(void *arg);
1319 static void* nextNPoint(void *arg, int n);
1320 static void* peekPoint(void *arg, int n);
1321 static void* previousPoint(void *arg);
1322 static int iteratorStopped(void *arg);
1324 static void initIteratorFct(SK_StrokeIterator *iter)
1326 iter->head = headPoint;
1327 iter->tail = tailPoint;
1328 iter->peek = peekPoint;
1329 iter->next = nextPoint;
1330 iter->nextN = nextNPoint;
1331 iter->previous = previousPoint;
1332 iter->stopped = iteratorStopped;
1335 static SK_Point* setIteratorValues(SK_StrokeIterator *iter, int index)
1337 SK_Point *pt = NULL;
1339 if (index >= 0 && index < iter->length)
1341 pt = &(iter->stroke->points[iter->start + (iter->stride * index)]);
1344 iter->size = pt->size;
1356 void initStrokeIterator(BArcIterator *arg, SK_Stroke *stk, int start, int end)
1358 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1360 initIteratorFct(iter);
1365 iter->start = start + 1;
1366 iter->end = end - 1;
1371 iter->start = start - 1;
1372 iter->end = end + 1;
1376 iter->length = iter->stride * (iter->end - iter->start + 1);
1382 static void* headPoint(void *arg)
1384 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1385 SK_Point *result = NULL;
1387 result = &(iter->stroke->points[iter->start - iter->stride]);
1388 iter->p = result->p;
1389 iter->no = result->no;
1390 iter->size = result->size;
1395 static void* tailPoint(void *arg)
1397 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1398 SK_Point *result = NULL;
1400 result = &(iter->stroke->points[iter->end + iter->stride]);
1401 iter->p = result->p;
1402 iter->no = result->no;
1403 iter->size = result->size;
1408 static void* nextPoint(void *arg)
1410 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1411 SK_Point *result = NULL;
1414 if (iter->index < iter->length)
1416 result = setIteratorValues(iter, iter->index);
1422 static void* nextNPoint(void *arg, int n)
1424 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1425 SK_Point *result = NULL;
1429 /* check if passed end */
1430 if (iter->index < iter->length)
1432 result = setIteratorValues(iter, iter->index);
1438 static void* peekPoint(void *arg, int n)
1440 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1441 SK_Point *result = NULL;
1442 int index = iter->index + n;
1444 /* check if passed end */
1445 if (index < iter->length)
1447 result = setIteratorValues(iter, index);
1453 static void* previousPoint(void *arg)
1455 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1456 SK_Point *result = NULL;
1458 if (iter->index > 0)
1461 result = setIteratorValues(iter, iter->index);
1467 static int iteratorStopped(void *arg)
1469 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1471 if (iter->index >= iter->length)
1481 static void sk_convertStroke(bContext *C, SK_Stroke *stk)
1483 Object *obedit = CTX_data_edit_object(C);
1484 ToolSettings *ts = CTX_data_tool_settings(C);
1485 bArmature *arm = obedit->data;
1487 EditBone *parent = NULL;
1488 float invmat[4][4]; /* move in caller function */
1495 invert_m4_m4(invmat, obedit->obmat);
1497 copy_m3_m4(tmat, obedit->obmat);
1500 for (i = 0; i < stk->nb_points; i++)
1502 SK_Point *pt = stk->points + i;
1504 if (pt->type == PT_EXACT)
1513 EditBone *bone = NULL;
1514 EditBone *new_parent;
1516 if (i - head_index > 1)
1518 SK_StrokeIterator sk_iter;
1519 BArcIterator *iter = (BArcIterator*)&sk_iter;
1521 initStrokeIterator(iter, stk, head_index, i);
1523 if (ts->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
1525 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
1527 else if (ts->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
1529 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
1531 else if (ts->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
1533 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
1539 bone = ED_armature_edit_bone_add(arm, "Bone");
1541 VECCOPY(bone->head, head->p);
1542 VECCOPY(bone->tail, pt->p);
1544 mul_m4_v3(invmat, bone->head);
1545 mul_m4_v3(invmat, bone->tail);
1546 setBoneRollFromNormal(bone, head->no, invmat, tmat);
1550 bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
1552 /* move to end of chain */
1553 while (bone->parent != NULL)
1555 bone = bone->parent;
1556 bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
1561 bone->parent = parent;
1562 bone->flag |= BONE_CONNECTED;
1565 parent = new_parent;
1573 static void sk_convert(bContext *C, SK_Sketch *sketch)
1575 ToolSettings *ts = CTX_data_tool_settings(C);
1578 for (stk = sketch->strokes.first; stk; stk = stk->next)
1580 if (stk->selected == 1)
1582 if (ts->bone_sketching_convert == SK_CONVERT_RETARGET)
1584 sk_retargetStroke(C, stk);
1588 sk_convertStroke(C, stk);
1591 // allqueue(REDRAWBUTSEDIT, 0);
1595 /******************* GESTURE *************************/
1598 /* returns the number of self intersections */
1599 static int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gesture)
1601 ARegion *ar = CTX_wm_region(C);
1605 for (s_i = 0; s_i < gesture->nb_points - 1; s_i++)
1607 float s_p1[3] = {0, 0, 0};
1608 float s_p2[3] = {0, 0, 0};
1611 project_float(ar, gesture->points[s_i].p, s_p1);
1612 project_float(ar, gesture->points[s_i + 1].p, s_p2);
1614 /* start checking from second next, because two consecutive cannot intersect */
1615 for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++)
1617 float g_p1[3] = {0, 0, 0};
1618 float g_p2[3] = {0, 0, 0};
1622 project_float(ar, gesture->points[g_i].p, g_p1);
1623 project_float(ar, gesture->points[g_i + 1].p, g_p2);
1625 if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
1627 SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
1629 isect->gesture_index = g_i;
1630 isect->before = s_i;
1631 isect->after = s_i + 1;
1632 isect->stroke = gesture;
1634 sub_v3_v3v3(isect->p, gesture->points[s_i + 1].p, gesture->points[s_i].p);
1635 mul_v3_fl(isect->p, lambda);
1636 add_v3_v3(isect->p, gesture->points[s_i].p);
1638 BLI_addtail(list, isect);
1648 static int cmpIntersections(void *i1, void *i2)
1650 SK_Intersection *isect1 = i1, *isect2 = i2;
1652 if (isect1->stroke == isect2->stroke)
1654 if (isect1->before < isect2->before)
1658 else if (isect1->before > isect2->before)
1664 if (isect1->lambda < isect2->lambda)
1668 else if (isect1->lambda > isect2->lambda)
1679 /* returns the maximum number of intersections per stroke */
1680 static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
1682 ARegion *ar = CTX_wm_region(C);
1683 ScrArea *sa = CTX_wm_area(C);
1684 View3D *v3d = sa->spacedata.first;
1688 for (stk = sketch->strokes.first; stk; stk = stk->next)
1693 for (s_i = 0; s_i < stk->nb_points - 1; s_i++)
1695 float s_p1[3] = {0, 0, 0};
1696 float s_p2[3] = {0, 0, 0};
1699 project_float(ar, stk->points[s_i].p, s_p1);
1700 project_float(ar, stk->points[s_i + 1].p, s_p2);
1702 for (g_i = 0; g_i < gesture->nb_points - 1; g_i++)
1704 float g_p1[3] = {0, 0, 0};
1705 float g_p2[3] = {0, 0, 0};
1709 project_float(ar, gesture->points[g_i].p, g_p1);
1710 project_float(ar, gesture->points[g_i + 1].p, g_p2);
1712 if (isect_line_line_strict_v3(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
1714 SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
1715 float ray_start[3], ray_end[3];
1718 isect->gesture_index = g_i;
1719 isect->before = s_i;
1720 isect->after = s_i + 1;
1721 isect->stroke = stk;
1722 isect->lambda = lambda;
1726 ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end);
1728 isect_line_line_v3( stk->points[s_i].p,
1729 stk->points[s_i + 1].p,
1735 BLI_addtail(list, isect);
1742 added = MAX2(s_added, added);
1745 BLI_sortlist(list, cmpIntersections);
1750 static int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
1752 SK_StrokeIterator sk_iter;
1753 BArcIterator *iter = (BArcIterator*)&sk_iter;
1755 float CORRELATION_THRESHOLD = 0.99f;
1759 sk_appendStrokePoint(segments, &gesture->points[0]);
1760 vec = segments->points[segments->nb_points - 1].p;
1762 initStrokeIterator(iter, gesture, 0, gesture->nb_points - 1);
1764 for (i = 1, j = 0; i < gesture->nb_points; i++)
1768 /* Calculate normal */
1769 sub_v3_v3v3(n, gesture->points[i].p, vec);
1771 if (calcArcCorrelation(iter, j, i, vec, n) < CORRELATION_THRESHOLD)
1774 sk_appendStrokePoint(segments, &gesture->points[j]);
1775 vec = segments->points[segments->nb_points - 1].p;
1776 segments->points[segments->nb_points - 1].type = PT_EXACT;
1780 sk_appendStrokePoint(segments, &gesture->points[gesture->nb_points - 1]);
1782 return segments->nb_points - 1;
1785 int sk_detectCutGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1787 if (gest->nb_segments == 1 && gest->nb_intersections == 1)
1795 void sk_applyCutGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1797 SK_Intersection *isect;
1799 for (isect = gest->intersections.first; isect; isect = isect->next)
1804 pt.mode = PT_PROJECT; /* take mode from neighbouring points */
1805 VECCOPY(pt.p, isect->p);
1806 VECCOPY(pt.no, isect->stroke->points[isect->before].no);
1808 sk_insertStrokePoint(isect->stroke, &pt, isect->after);
1812 int sk_detectTrimGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1814 if (gest->nb_segments == 2 && gest->nb_intersections == 1 && gest->nb_self_intersections == 0)
1819 sub_v3_v3v3(s1, gest->segments->points[1].p, gest->segments->points[0].p);
1820 sub_v3_v3v3(s2, gest->segments->points[2].p, gest->segments->points[1].p);
1822 angle = RAD2DEG(angle_v2v2(s1, s2));
1824 if (angle > 60 && angle < 120)
1833 void sk_applyTrimGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1835 SK_Intersection *isect;
1838 sub_v3_v3v3(trim_dir, gest->segments->points[2].p, gest->segments->points[1].p);
1840 for (isect = gest->intersections.first; isect; isect = isect->next)
1843 float stroke_dir[3];
1846 pt.mode = PT_PROJECT; /* take mode from neighbouring points */
1847 VECCOPY(pt.p, isect->p);
1848 VECCOPY(pt.no, isect->stroke->points[isect->before].no);
1850 sub_v3_v3v3(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p);
1852 /* same direction, trim end */
1853 if (dot_v3v3(stroke_dir, trim_dir) > 0)
1855 sk_replaceStrokePoint(isect->stroke, &pt, isect->after);
1856 sk_trimStroke(isect->stroke, 0, isect->after);
1858 /* else, trim start */
1861 sk_replaceStrokePoint(isect->stroke, &pt, isect->before);
1862 sk_trimStroke(isect->stroke, isect->before, isect->stroke->nb_points - 1);
1868 int sk_detectCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1870 if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1)
1872 SK_Intersection *isect, *self_isect;
1874 /* get the the last intersection of the first pair */
1875 for( isect = gest->intersections.first; isect; isect = isect->next )
1877 if (isect->stroke == isect->next->stroke)
1879 isect = isect->next;
1884 self_isect = gest->self_intersections.first;
1886 if (isect && isect->gesture_index < self_isect->gesture_index)
1895 void sk_applyCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1897 SK_Intersection *isect;
1901 // command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3");
1902 if(command < 1) return;
1904 for (isect = gest->intersections.first; isect; isect = isect->next)
1906 SK_Intersection *i2;
1910 if (i2 && i2->stroke == isect->stroke)
1915 sk_flattenStroke(isect->stroke, isect->before, i2->after);
1918 sk_straightenStroke(isect->stroke, isect->before, i2->after, isect->p, i2->p);
1921 sk_polygonizeStroke(isect->stroke, isect->before, i2->after);
1930 int sk_detectDeleteGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1932 if (gest->nb_segments == 2 && gest->nb_intersections == 2)
1937 sub_v3_v3v3(s1, gest->segments->points[1].p, gest->segments->points[0].p);
1938 sub_v3_v3v3(s2, gest->segments->points[2].p, gest->segments->points[1].p);
1940 angle = RAD2DEG(angle_v2v2(s1, s2));
1951 void sk_applyDeleteGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *sketch)
1953 SK_Intersection *isect;
1955 for (isect = gest->intersections.first; isect; isect = isect->next)
1957 /* only delete strokes that are crossed twice */
1958 if (isect->next && isect->next->stroke == isect->stroke)
1960 isect = isect->next;
1962 sk_removeStroke(sketch, isect->stroke);
1967 int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
1969 ARegion *ar = CTX_wm_region(C);
1970 if (gest->nb_segments > 2 && gest->nb_intersections == 2)
1972 short start_val[2], end_val[2];
1975 project_short_noclip(ar, gest->stk->points[0].p, start_val);
1976 project_short_noclip(ar, sk_lastStrokePoint(gest->stk)->p, end_val);
1978 dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1]));
1980 /* if gesture is a circle */
1983 SK_Intersection *isect;
1985 /* check if it circled around an exact point */
1986 for (isect = gest->intersections.first; isect; isect = isect->next)
1988 /* only delete strokes that are crossed twice */
1989 if (isect->next && isect->next->stroke == isect->stroke)
1991 int start_index, end_index;
1994 start_index = MIN2(isect->after, isect->next->after);
1995 end_index = MAX2(isect->before, isect->next->before);
1997 for (i = start_index; i <= end_index; i++)
1999 if (isect->stroke->points[i].type == PT_EXACT)
2001 return 1; /* at least one exact point found, stop detect here */
2006 isect = isect->next;
2015 void sk_applyMergeGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
2017 SK_Intersection *isect;
2019 /* check if it circled around an exact point */
2020 for (isect = gest->intersections.first; isect; isect = isect->next)
2022 /* only merge strokes that are crossed twice */
2023 if (isect->next && isect->next->stroke == isect->stroke)
2025 int start_index, end_index;
2028 start_index = MIN2(isect->after, isect->next->after);
2029 end_index = MAX2(isect->before, isect->next->before);
2031 for (i = start_index; i <= end_index; i++)
2033 /* if exact, switch to continuous */
2034 if (isect->stroke->points[i].type == PT_EXACT)
2036 isect->stroke->points[i].type = PT_CONTINUOUS;
2041 isect = isect->next;
2046 int sk_detectReverseGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
2048 if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 0)
2050 SK_Intersection *isect;
2052 /* check if it circled around an exact point */
2053 for (isect = gest->intersections.first; isect; isect = isect->next)
2055 /* only delete strokes that are crossed twice */
2056 if (isect->next && isect->next->stroke == isect->stroke)
2058 float start_v[3], end_v[3];
2061 if (isect->gesture_index < isect->next->gesture_index)
2063 sub_v3_v3v3(start_v, isect->p, gest->stk->points[0].p);
2064 sub_v3_v3v3(end_v, sk_lastStrokePoint(gest->stk)->p, isect->next->p);
2068 sub_v3_v3v3(start_v, isect->next->p, gest->stk->points[0].p);
2069 sub_v3_v3v3(end_v, sk_lastStrokePoint(gest->stk)->p, isect->p);
2072 angle = RAD2DEG(angle_v2v2(start_v, end_v));
2080 isect = isect->next;
2088 void sk_applyReverseGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
2090 SK_Intersection *isect;
2092 for (isect = gest->intersections.first; isect; isect = isect->next)
2094 /* only reverse strokes that are crossed twice */
2095 if (isect->next && isect->next->stroke == isect->stroke)
2097 sk_reverseStroke(isect->stroke);
2100 isect = isect->next;
2105 int sk_detectConvertGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED(sketch))
2107 if (gest->nb_segments == 3 && gest->nb_self_intersections == 1)
2114 void sk_applyConvertGesture(bContext *C, SK_Gesture *UNUSED(gest), SK_Sketch *sketch)
2116 sk_convert(C, sketch);
2119 static void sk_initGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2121 gest->intersections.first = gest->intersections.last = NULL;
2122 gest->self_intersections.first = gest->self_intersections.last = NULL;
2124 gest->segments = sk_createStroke();
2125 gest->stk = sketch->gesture;
2127 gest->nb_self_intersections = sk_getSelfIntersections(C, &gest->self_intersections, gest->stk);
2128 gest->nb_intersections = sk_getIntersections(C, &gest->intersections, sketch, gest->stk);
2129 gest->nb_segments = sk_getSegments(gest->segments, gest->stk);
2132 static void sk_freeGesture(SK_Gesture *gest)
2134 sk_freeStroke(gest->segments);
2135 BLI_freelistN(&gest->intersections);
2136 BLI_freelistN(&gest->self_intersections);
2139 static void sk_applyGesture(bContext *C, SK_Sketch *sketch)
2142 SK_GestureAction *act;
2144 sk_initGesture(C, &gest, sketch);
2146 /* detect and apply */
2147 for (act = GESTURE_ACTIONS; act->apply != NULL; act++)
2149 if (act->detect(C, &gest, sketch))
2151 act->apply(C, &gest, sketch);
2156 sk_freeGesture(&gest);
2159 /********************************************/
2162 static int sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], int extend)
2166 unsigned int buffer[MAXPICKBUF];
2169 view3d_set_viewcontext(C, &vc);
2171 rect.xmin= mval[0]-5;
2172 rect.xmax= mval[0]+5;
2173 rect.ymin= mval[1]-5;
2174 rect.ymax= mval[1]+5;
2176 hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
2180 int besthitresult = -1;
2183 besthitresult = buffer[3];
2186 besthitresult = buffer[3];
2187 /* loop and get best hit */
2190 if (besthitresult > 0)
2192 SK_Stroke *selected_stk = BLI_findlink(&sketch->strokes, besthitresult - 1);
2196 sk_selectAllSketch(sketch, -1);
2198 selected_stk->selected = 1;
2202 selected_stk->selected ^= 1;
2213 #if 0 /* UNUSED 2.5 */
2214 static void sk_queueRedrawSketch(SK_Sketch *sketch)
2216 if (sketch->active_stroke != NULL)
2218 SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
2223 // allqueue(REDRAWVIEW3D, 0);
2229 static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch, int with_names)
2231 ToolSettings *ts= scene->toolsettings;
2234 glClear(GL_DEPTH_BUFFER_BIT);
2235 glEnable(GL_DEPTH_TEST);
2240 for (id = 1, stk = sketch->strokes.first; stk; id++, stk = stk->next)
2242 sk_drawStroke(stk, id, NULL, -1, -1);
2249 float selected_rgb[3] = {1, 0, 0};
2250 float unselected_rgb[3] = {1, 0.5, 0};
2252 for (stk = sketch->strokes.first; stk; stk = stk->next)
2257 if (sk_hasOverdraw(sketch, stk))
2259 sk_adjustIndexes(sketch, &start, &end);
2262 sk_drawStroke(stk, -1, (stk->selected==1?selected_rgb:unselected_rgb), start, end);
2264 if (stk->selected == 1)
2266 sk_drawStrokeSubdivision(ts, stk);
2270 if (sketch->active_stroke != NULL)
2272 SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
2274 if (ts->bone_sketching & BONE_SKETCHING_QUICK)
2276 sk_drawStrokeSubdivision(ts, sketch->active_stroke);
2281 GLUquadric *quad = gluNewQuadric();
2282 gluQuadricNormals(quad, GLU_SMOOTH);
2287 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2289 switch (sketch->next_point.mode)
2299 sk_drawPoint(quad, &sketch->next_point, 0.1);
2301 glColor4f(selected_rgb[0], selected_rgb[1], selected_rgb[2], 0.3);
2303 sk_drawEdge(quad, last, &sketch->next_point, 0.1);
2305 glDisable(GL_BLEND);
2309 gluDeleteQuadric(quad);
2315 if (sketch->depth_peels.first != NULL)
2317 float colors[8][3] = {
2328 GLUquadric *quad = gluNewQuadric();
2329 gluQuadricNormals(quad, GLU_SMOOTH);
2331 for (p = sketch->depth_peels.first; p; p = p->next)
2333 int index = GET_INT_FROM_POINTER(p->ob);
2334 index = (index >> 5) & 7;
2336 glColor3fv(colors[index]);
2338 glTranslatef(p->p[0], p->p[1], p->p[2]);
2339 gluSphere(quad, 0.02, 8, 8);
2343 gluDeleteQuadric(quad);
2347 glDisable(GL_DEPTH_TEST);
2349 /* only draw gesture in active area */
2350 if (sketch->gesture != NULL /*&& area_is_active_area(G.vd->area)*/)
2352 float gesture_rgb[3] = {0, 0.5, 1};
2353 sk_drawStroke(sketch->gesture, -1, gesture_rgb, -1, -1);
2357 static int sk_finish_stroke(bContext *C, SK_Sketch *sketch)
2359 ToolSettings *ts = CTX_data_tool_settings(C);
2361 if (sketch->active_stroke != NULL)
2363 SK_Stroke *stk = sketch->active_stroke;
2365 sk_endStroke(C, sketch);
2367 if (ts->bone_sketching & BONE_SKETCHING_QUICK)
2369 if (ts->bone_sketching_convert == SK_CONVERT_RETARGET)
2371 sk_retargetStroke(C, stk);
2375 sk_convertStroke(C, stk);
2378 // BIF_undo_push("Convert Sketch");
2379 sk_removeStroke(sketch, stk);
2381 // allqueue(REDRAWBUTSEDIT, 0);
2385 // allqueue(REDRAWVIEW3D, 0);
2392 static void sk_start_draw_stroke(SK_Sketch *sketch)
2394 if (sketch->active_stroke == NULL)
2396 sk_startStroke(sketch);
2397 sk_selectAllSketch(sketch, -1);
2399 sketch->active_stroke->selected = 1;
2403 static void sk_start_draw_gesture(SK_Sketch *sketch)
2405 sketch->gesture = sk_createStroke();
2408 static int sk_draw_stroke(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
2410 if (sk_stroke_filtermval(dd))
2412 sk_addStrokePoint(C, sketch, stk, dd, snap);
2413 sk_updateDrawData(dd);
2414 sk_updateNextPoint(sketch, stk);
2422 static int ValidSketchViewContext(ViewContext *vc)
2424 Object *obedit = vc->obedit;
2425 Scene *scene= vc->scene;
2428 obedit->type == OB_ARMATURE &&
2429 scene->toolsettings->bone_sketching & BONE_SKETCHING)
2439 int BDR_drawSketchNames(ViewContext *vc)
2441 if (ValidSketchViewContext(vc))
2443 SK_Sketch *sketch = viewcontextSketch(vc, 0);
2446 sk_drawSketch(vc->scene, vc->v3d, sketch, 1);
2454 void BDR_drawSketch(const bContext *C)
2456 if (ED_operator_sketch_mode(C))
2458 SK_Sketch *sketch = contextSketch(C, 0);
2461 sk_drawSketch(CTX_data_scene(C), CTX_wm_view3d(C), sketch, 0);
2466 static int sketch_delete(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
2468 SK_Sketch *sketch = contextSketch(C, 0);
2471 sk_deleteSelectedStrokes(sketch);
2472 // allqueue(REDRAWVIEW3D, 0);
2474 WM_event_add_notifier(C, NC_SCREEN|ND_SKETCH|NA_REMOVED, NULL);
2475 return OPERATOR_FINISHED;
2478 void BIF_sk_selectStroke(bContext *C, const int mval[2], short extend)
2480 ToolSettings *ts = CTX_data_tool_settings(C);
2481 SK_Sketch *sketch = contextSketch(C, 0);
2483 if (sketch != NULL && ts->bone_sketching & BONE_SKETCHING)
2485 if (sk_selectStroke(C, sketch, mval, extend))
2486 ED_area_tag_redraw(CTX_wm_area(C));
2490 void BIF_convertSketch(bContext *C)
2492 if (ED_operator_sketch_full_mode(C))
2494 SK_Sketch *sketch = contextSketch(C, 0);
2497 sk_convert(C, sketch);
2498 // BIF_undo_push("Convert Sketch");
2499 // allqueue(REDRAWVIEW3D, 0);
2500 // allqueue(REDRAWBUTSEDIT, 0);
2505 void BIF_deleteSketch(bContext *C)
2507 if (ED_operator_sketch_full_mode(C))
2509 SK_Sketch *sketch = contextSketch(C, 0);
2512 sk_deleteSelectedStrokes(sketch);
2513 // BIF_undo_push("Convert Sketch");
2514 // allqueue(REDRAWVIEW3D, 0);
2520 void BIF_selectAllSketch(bContext *C, int mode)
2522 if (BIF_validSketchMode(C))
2524 SK_Sketch *sketch = contextSketch(C, 0);
2527 sk_selectAllSketch(sketch, mode);
2529 // allqueue(REDRAWVIEW3D, 0);
2535 SK_Sketch* contextSketch(const bContext *C, int create)
2537 Object *obedit = CTX_data_edit_object(C);
2538 SK_Sketch *sketch = NULL;
2540 if (obedit && obedit->type == OB_ARMATURE)
2542 bArmature *arm = obedit->data;
2544 if (arm->sketch == NULL && create)
2546 arm->sketch = createSketch();
2548 sketch = arm->sketch;
2554 SK_Sketch* viewcontextSketch(ViewContext *vc, int create)
2556 Object *obedit = vc->obedit;
2557 SK_Sketch *sketch = NULL;
2559 if (obedit && obedit->type == OB_ARMATURE)
2561 bArmature *arm = obedit->data;
2563 if (arm->sketch == NULL && create)
2565 arm->sketch = createSketch();
2567 sketch = arm->sketch;
2573 static int sketch_convert(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
2575 SK_Sketch *sketch = contextSketch(C, 0);
2578 sk_convert(C, sketch);
2579 ED_area_tag_redraw(CTX_wm_area(C));
2581 return OPERATOR_FINISHED;
2584 static int sketch_cancel(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
2586 SK_Sketch *sketch = contextSketch(C, 0);
2589 sk_cancelStroke(sketch);
2590 ED_area_tag_redraw(CTX_wm_area(C));
2591 return OPERATOR_FINISHED;
2593 return OPERATOR_PASS_THROUGH;
2596 static int sketch_finish(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
2598 SK_Sketch *sketch = contextSketch(C, 0);
2601 if (sk_finish_stroke(C, sketch))
2603 ED_area_tag_redraw(CTX_wm_area(C));
2604 return OPERATOR_FINISHED;
2607 return OPERATOR_PASS_THROUGH;
2610 static int sketch_select(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
2612 SK_Sketch *sketch = contextSketch(C, 0);
2616 if (sk_selectStroke(C, sketch, event->mval, extend))
2617 ED_area_tag_redraw(CTX_wm_area(C));
2620 return OPERATOR_FINISHED;
2623 static int sketch_draw_stroke_cancel(bContext *C, wmOperator *op)
2625 SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2626 sk_cancelStroke(sketch);
2627 MEM_freeN(op->customdata);
2628 return OPERATOR_CANCELLED;
2631 static int sketch_draw_stroke(bContext *C, wmOperator *op, wmEvent *event)
2633 short snap = RNA_boolean_get(op->ptr, "snap");
2635 SK_Sketch *sketch = contextSketch(C, 1);
2637 op->customdata = dd = MEM_callocN(sizeof("SK_DrawData"), "SketchDrawData");
2638 sk_initDrawData(dd, event->mval);
2640 sk_start_draw_stroke(sketch);
2642 sk_draw_stroke(C, sketch, sketch->active_stroke, dd, snap);
2644 WM_event_add_modal_handler(C, op);
2646 return OPERATOR_RUNNING_MODAL;
2649 static int sketch_draw_gesture_cancel(bContext *C, wmOperator *op)
2651 SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2652 sk_cancelStroke(sketch);
2653 MEM_freeN(op->customdata);
2654 return OPERATOR_CANCELLED;
2657 static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event)
2659 short snap = RNA_boolean_get(op->ptr, "snap");
2661 SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2662 sk_cancelStroke(sketch);
2664 op->customdata = dd = MEM_callocN(sizeof("SK_DrawData"), "SketchDrawData");
2665 sk_initDrawData(dd, event->mval);
2667 sk_start_draw_gesture(sketch);
2668 sk_draw_stroke(C, sketch, sketch->gesture, dd, snap);
2670 WM_event_add_modal_handler(C, op);
2672 return OPERATOR_RUNNING_MODAL;
2675 static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short gesture, SK_Stroke *stk)
2677 short snap = RNA_boolean_get(op->ptr, "snap");
2678 SK_DrawData *dd = op->customdata;
2679 SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2680 int retval = OPERATOR_RUNNING_MODAL;
2682 switch (event->type)
2687 RNA_boolean_set(op->ptr, "snap", snap);
2690 case INBETWEEN_MOUSEMOVE:
2691 dd->mval[0] = event->mval[0];
2692 dd->mval[1] = event->mval[1];
2693 sk_draw_stroke(C, sketch, stk, dd, snap);
2694 ED_area_tag_redraw(CTX_wm_area(C));
2697 op->type->cancel(C, op);
2698 ED_area_tag_redraw(CTX_wm_area(C));
2699 retval = OPERATOR_CANCELLED;
2702 if (event->val == KM_RELEASE)
2706 sk_endContinuousStroke(stk);
2707 sk_filterLastContinuousStroke(stk);
2708 sk_updateNextPoint(sketch, stk);
2709 ED_area_tag_redraw(CTX_wm_area(C));
2710 MEM_freeN(op->customdata);
2711 retval = OPERATOR_FINISHED;
2715 sk_endContinuousStroke(stk);
2716 sk_filterLastContinuousStroke(stk);
2718 if (stk->nb_points > 1)
2720 /* apply gesture here */
2721 sk_applyGesture(C, sketch);
2725 sketch->gesture = NULL;
2727 ED_area_tag_redraw(CTX_wm_area(C));
2728 MEM_freeN(op->customdata);
2729 retval = OPERATOR_FINISHED;
2738 static int sketch_draw_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
2740 SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2741 return sketch_draw_modal(C, op, event, 0, sketch->active_stroke);
2744 static int sketch_draw_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
2746 SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
2747 return sketch_draw_modal(C, op, event, 1, sketch->gesture);
2750 static int sketch_draw_preview(bContext *C, wmOperator *op, wmEvent *event)
2752 short snap = RNA_boolean_get(op->ptr, "snap");
2753 SK_Sketch *sketch = contextSketch(C, 0);
2759 sk_initDrawData(&dd, event->mval);
2760 sk_getStrokePoint(C, &sketch->next_point, sketch, sketch->active_stroke, &dd, snap);
2761 ED_area_tag_redraw(CTX_wm_area(C));
2764 return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
2767 /* ============================================== Poll Functions ============================================= */
2769 int ED_operator_sketch_mode_active_stroke(bContext *C)
2771 ToolSettings *ts = CTX_data_tool_settings(C);
2772 SK_Sketch *sketch = contextSketch(C, 0);
2774 if (ts->bone_sketching & BONE_SKETCHING &&
2776 sketch->active_stroke != NULL)
2786 static int ED_operator_sketch_mode_gesture(bContext *C)
2788 ToolSettings *ts = CTX_data_tool_settings(C);
2789 SK_Sketch *sketch = contextSketch(C, 0);
2791 if (ts->bone_sketching & BONE_SKETCHING &&
2792 (ts->bone_sketching & BONE_SKETCHING_QUICK) == 0 &&
2794 sketch->active_stroke == NULL)
2804 int ED_operator_sketch_full_mode(bContext *C)
2806 Object *obedit = CTX_data_edit_object(C);
2807 ToolSettings *ts = CTX_data_tool_settings(C);
2810 obedit->type == OB_ARMATURE &&
2811 ts->bone_sketching & BONE_SKETCHING &&
2812 (ts->bone_sketching & BONE_SKETCHING_QUICK) == 0)
2822 int ED_operator_sketch_mode(const bContext *C)
2824 Object *obedit = CTX_data_edit_object(C);
2825 ToolSettings *ts = CTX_data_tool_settings(C);
2828 obedit->type == OB_ARMATURE &&
2829 ts->bone_sketching & BONE_SKETCHING)
2839 /* ================================================ Operators ================================================ */
2841 void SKETCH_OT_delete(wmOperatorType *ot)
2845 ot->idname= "SKETCH_OT_delete";
2848 ot->invoke= sketch_delete;
2850 ot->poll= ED_operator_sketch_full_mode;
2853 // ot->flag= OPTYPE_UNDO;
2856 void SKETCH_OT_select(wmOperatorType *ot)
2860 ot->idname= "SKETCH_OT_select";
2863 ot->invoke= sketch_select;
2865 ot->poll= ED_operator_sketch_full_mode;
2868 // ot->flag= OPTYPE_UNDO;
2871 void SKETCH_OT_cancel_stroke(wmOperatorType *ot)
2874 ot->name= "cancel stroke";
2875 ot->idname= "SKETCH_OT_cancel_stroke";
2878 ot->invoke= sketch_cancel;
2880 ot->poll= ED_operator_sketch_mode_active_stroke;
2883 // ot->flag= OPTYPE_UNDO;
2886 void SKETCH_OT_convert(wmOperatorType *ot)
2889 ot->name= "convert";
2890 ot->idname= "SKETCH_OT_convert";
2893 ot->invoke= sketch_convert;
2895 ot->poll= ED_operator_sketch_full_mode;
2898 ot->flag= OPTYPE_UNDO;
2901 void SKETCH_OT_finish_stroke(wmOperatorType *ot)
2904 ot->name= "end stroke";
2905 ot->idname= "SKETCH_OT_finish_stroke";
2908 ot->invoke= sketch_finish;
2910 ot->poll= ED_operator_sketch_mode_active_stroke;
2913 // ot->flag= OPTYPE_UNDO;
2916 void SKETCH_OT_draw_preview(wmOperatorType *ot)
2919 ot->name= "draw preview";
2920 ot->idname= "SKETCH_OT_draw_preview";
2923 ot->invoke= sketch_draw_preview;
2925 ot->poll= ED_operator_sketch_mode_active_stroke;
2927 RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
2930 // ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
2933 void SKETCH_OT_draw_stroke(wmOperatorType *ot)
2936 ot->name= "draw stroke";
2937 ot->idname= "SKETCH_OT_draw_stroke";
2940 ot->invoke = sketch_draw_stroke;
2941 ot->modal = sketch_draw_stroke_modal;
2942 ot->cancel = sketch_draw_stroke_cancel;
2944 ot->poll= (int (*)(bContext *))ED_operator_sketch_mode;
2946 RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
2949 ot->flag= OPTYPE_BLOCKING; // OPTYPE_REGISTER|OPTYPE_UNDO
2952 void SKETCH_OT_gesture(wmOperatorType *ot)
2955 ot->name= "gesture";
2956 ot->idname= "SKETCH_OT_gesture";
2959 ot->invoke = sketch_draw_gesture;
2960 ot->modal = sketch_draw_gesture_modal;
2961 ot->cancel = sketch_draw_gesture_cancel;
2963 ot->poll= ED_operator_sketch_mode_gesture;
2965 RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
2968 ot->flag= OPTYPE_BLOCKING; // OPTYPE_UNDO