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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * ***** END GPL LICENSE BLOCK *****
27 #include "MEM_guardedalloc.h"
29 #include "DNA_listBase.h"
30 #include "DNA_scene_types.h"
31 #include "DNA_screen_types.h"
32 #include "DNA_view3d_types.h"
33 #include "DNA_meshdata_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_armature_types.h"
36 #include "DNA_userdef_types.h"
38 #include "RNA_define.h"
39 #include "RNA_access.h"
41 #include "BLI_blenlib.h"
42 #include "BLI_arithb.h"
43 #include "BLI_graph.h"
44 #include "BLI_ghash.h"
46 #include "BKE_utildefines.h"
47 #include "BKE_global.h"
48 #include "BKE_DerivedMesh.h"
49 #include "BKE_object.h"
51 #include "BKE_context.h"
53 #include "ED_view3d.h"
54 #include "ED_screen.h"
57 #include "UI_resources.h"
58 //#include "BIF_screen.h"
59 //#include "BIF_space.h"
60 //#include "BIF_mywindow.h"
61 #include "ED_armature.h"
62 #include "armature_intern.h"
63 //#include "BIF_sketch.h"
64 #include "BIF_retarget.h"
65 #include "BIF_generate.h"
66 //#include "BIF_interface.h"
68 #include "ED_transform.h"
73 //#include "blendef.h"
74 //#include "mydevice.h"
89 typedef struct SK_Point
98 typedef struct SK_Stroke
100 struct SK_Stroke *next, *prev;
108 #define SK_OVERDRAW_LIMIT 5
110 typedef struct SK_Overdraw
117 #define SK_Stroke_BUFFER_INIT_SIZE 20
119 typedef struct SK_DrawData
122 short previous_mval[2];
126 typedef struct SK_Intersection
128 struct SK_Intersection *next, *prev;
134 float lambda; /* used for sorting intersection points */
137 typedef struct SK_Sketch
140 ListBase depth_peels;
141 SK_Stroke *active_stroke;
147 typedef struct SK_StrokeIterator {
153 PreviousFct previous;
161 /*********************************/
168 typedef struct SK_Gesture {
172 ListBase intersections;
173 ListBase self_intersections;
175 int nb_self_intersections;
176 int nb_intersections;
180 typedef int (*GestureDetectFct)(bContext*, SK_Gesture*, SK_Sketch *);
181 typedef void (*GestureApplyFct)(bContext*, SK_Gesture*, SK_Sketch *);
183 typedef struct SK_GestureAction {
185 GestureDetectFct detect;
186 GestureApplyFct apply;
190 int LAST_SNAP_POINT_VALID = 0;
191 float LAST_SNAP_POINT[3];
193 /******************** PROTOTYPES ******************************/
195 void initStrokeIterator(BArcIterator *iter, SK_Stroke *stk, int start, int end);
197 void sk_deleteSelectedStrokes(SK_Sketch *sketch);
199 void sk_freeStroke(SK_Stroke *stk);
200 void sk_freeSketch(SK_Sketch *sketch);
202 SK_Point *sk_lastStrokePoint(SK_Stroke *stk);
204 int sk_detectCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
205 void sk_applyCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
206 int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
207 void sk_applyTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
208 int sk_detectCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
209 void sk_applyCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
210 int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
211 void sk_applyDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
212 int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
213 void sk_applyMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
214 int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
215 void sk_applyReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
216 int sk_detectConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
217 void sk_applyConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
219 SK_Sketch* contextSketch(const bContext *c, int create);
220 SK_Sketch* viewcontextSketch(ViewContext *vc, int create);
222 void sk_resetOverdraw(SK_Sketch *sketch);
223 int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk);
225 /******************** GESTURE ACTIONS ******************************/
227 SK_GestureAction GESTURE_ACTIONS[] =
229 {"Cut", sk_detectCutGesture, sk_applyCutGesture},
230 {"Trim", sk_detectTrimGesture, sk_applyTrimGesture},
231 {"Command", sk_detectCommandGesture, sk_applyCommandGesture},
232 {"Delete", sk_detectDeleteGesture, sk_applyDeleteGesture},
233 {"Merge", sk_detectMergeGesture, sk_applyMergeGesture},
234 {"Reverse", sk_detectReverseGesture, sk_applyReverseGesture},
235 {"Convert", sk_detectConvertGesture, sk_applyConvertGesture},
239 /******************** TEMPLATES UTILS *************************/
241 char *TEMPLATES_MENU = NULL;
242 int TEMPLATES_CURRENT = 0;
243 GHash *TEMPLATES_HASH = NULL;
244 RigGraph *TEMPLATE_RIGG = NULL;
246 void BIF_makeListTemplates(const bContext *C)
248 Object *obedit = CTX_data_edit_object(C);
249 Scene *scene = CTX_data_scene(C);
250 ToolSettings *ts = CTX_data_tool_settings(C);
254 if (TEMPLATES_HASH != NULL)
256 BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
259 TEMPLATES_HASH = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
260 TEMPLATES_CURRENT = 0;
262 for ( base = FIRSTBASE; base; base = base->next )
264 Object *ob = base->object;
266 if (ob != obedit && ob->type == OB_ARMATURE)
269 BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob);
271 if (ob == ts->skgen_template)
273 TEMPLATES_CURRENT = index;
279 char *BIF_listTemplates(const bContext *C)
282 char menu_header[] = "Template%t|None%x0|";
285 if (TEMPLATES_MENU != NULL)
287 MEM_freeN(TEMPLATES_MENU);
290 TEMPLATES_MENU = MEM_callocN(sizeof(char) * (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30), "skeleton template menu");
294 p += sprintf(TEMPLATES_MENU, "%s", menu_header);
296 BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
298 while (!BLI_ghashIterator_isDone(&ghi))
300 Object *ob = BLI_ghashIterator_getValue(&ghi);
301 int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
303 p += sprintf(p, "|%s%%x%i", ob->id.name+2, key);
305 BLI_ghashIterator_step(&ghi);
308 return TEMPLATES_MENU;
311 int BIF_currentTemplate(const bContext *C)
313 ToolSettings *ts = CTX_data_tool_settings(C);
315 if (TEMPLATES_CURRENT == 0 && ts->skgen_template != NULL)
318 BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
320 while (!BLI_ghashIterator_isDone(&ghi))
322 Object *ob = BLI_ghashIterator_getValue(&ghi);
323 int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
325 if (ob == ts->skgen_template)
327 TEMPLATES_CURRENT = key;
331 BLI_ghashIterator_step(&ghi);
335 return TEMPLATES_CURRENT;
338 RigGraph* sk_makeTemplateGraph(const bContext *C, Object *ob)
340 Object *obedit = CTX_data_edit_object(C);
348 if (TEMPLATE_RIGG && TEMPLATE_RIGG->ob != ob)
350 RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
351 TEMPLATE_RIGG = NULL;
354 if (TEMPLATE_RIGG == NULL)
360 TEMPLATE_RIGG = RIG_graphFromArmature(C, ob, arm);
364 return TEMPLATE_RIGG;
367 int BIF_nbJointsTemplate(const bContext *C)
369 ToolSettings *ts = CTX_data_tool_settings(C);
370 RigGraph *rg = sk_makeTemplateGraph(C, ts->skgen_template);
374 return RIG_nbJoints(rg);
382 char * BIF_nameBoneTemplate(const bContext *C)
384 ToolSettings *ts = CTX_data_tool_settings(C);
385 SK_Sketch *stk = contextSketch(C, 1);
389 if (stk && stk->active_stroke != NULL)
391 index = stk->active_stroke->nb_points;
394 rg = sk_makeTemplateGraph(C, ts->skgen_template);
401 return RIG_nameBone(rg, 0, index);
404 void BIF_freeTemplates(bContext *C)
406 if (TEMPLATES_MENU != NULL)
408 MEM_freeN(TEMPLATES_MENU);
409 TEMPLATES_MENU = NULL;
412 if (TEMPLATES_HASH != NULL)
414 BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
415 TEMPLATES_HASH = NULL;
418 if (TEMPLATE_RIGG != NULL)
420 RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
421 TEMPLATE_RIGG = NULL;
425 void BIF_setTemplate(bContext *C, int index)
427 ToolSettings *ts = CTX_data_tool_settings(C);
430 ts->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
434 ts->skgen_template = NULL;
436 if (TEMPLATE_RIGG != NULL)
438 RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
440 TEMPLATE_RIGG = NULL;
444 /*********************** CONVERSION ***************************/
446 void sk_autoname(bContext *C, ReebArc *arc)
448 ToolSettings *ts = CTX_data_tool_settings(C);
449 if (ts->skgen_retarget_options & SK_RETARGET_AUTONAME)
453 char *num = ts->skgen_num_string;
456 BLI_snprintf(num, 8, "%i", i);
460 char *side = ts->skgen_side_string;
464 if (BLI_streq(side, ""))
468 else if (BLI_streq(side, "R") || BLI_streq(side, "L"))
473 else if (BLI_streq(side, "r") || BLI_streq(side, "l"))
481 if (arc->head->p[0] < 0)
483 BLI_snprintf(side, 8, caps?"R":"r");
487 BLI_snprintf(side, 8, caps?"L":"l");
494 ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3])
498 node = MEM_callocN(sizeof(ReebNode), "reeb node");
499 VECCOPY(node->p, pt->p);
500 Mat4MulVecfl(imat, node->p);
502 VECCOPY(node->no, pt->no);
503 Mat3MulVecfl(tmat, node->no);
508 ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3])
513 arc = MEM_callocN(sizeof(ReebArc), "reeb arc");
514 arc->head = sk_pointToNode(stk->points, imat, tmat);
515 arc->tail = sk_pointToNode(sk_lastStrokePoint(stk), imat, tmat);
517 arc->bcount = stk->nb_points - 2; /* first and last are nodes, don't count */
518 arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "Buckets");
520 for (i = 0; i < arc->bcount; i++)
522 VECCOPY(arc->buckets[i].p, stk->points[i + 1].p);
523 Mat4MulVecfl(imat, arc->buckets[i].p);
525 VECCOPY(arc->buckets[i].no, stk->points[i + 1].no);
526 Mat3MulVecfl(tmat, arc->buckets[i].no);
532 void sk_retargetStroke(bContext *C, SK_Stroke *stk)
534 ToolSettings *ts = CTX_data_tool_settings(C);
535 Object *obedit = CTX_data_edit_object(C);
541 Mat4Invert(imat, obedit->obmat);
543 Mat3CpyMat4(tmat, obedit->obmat);
546 arc = sk_strokeToArc(stk, imat, tmat);
550 rg = sk_makeTemplateGraph(C, ts->skgen_template);
552 BIF_retargetArc(C, arc, rg);
554 sk_autoname(C, NULL);
556 MEM_freeN(arc->head);
557 MEM_freeN(arc->tail);
558 REEB_freeArc((BArc*)arc);
561 /**************************************************************/
563 void sk_freeSketch(SK_Sketch *sketch)
565 SK_Stroke *stk, *next;
567 for (stk = sketch->strokes.first; stk; stk = next)
574 BLI_freelistN(&sketch->depth_peels);
579 SK_Sketch* sk_createSketch()
583 sketch = MEM_callocN(sizeof(SK_Sketch), "SK_Sketch");
585 sketch->active_stroke = NULL;
586 sketch->gesture = NULL;
588 sketch->strokes.first = NULL;
589 sketch->strokes.last = NULL;
594 void sk_initPoint(bContext *C, SK_Point *pt)
596 ARegion *ar = CTX_wm_region(C);
597 RegionView3D *rv3d = ar->regiondata;
599 VECCOPY(pt->no, rv3d->viewinv[2]);
601 /* more init code here */
604 void sk_copyPoint(SK_Point *dst, SK_Point *src)
606 memcpy(dst, src, sizeof(SK_Point));
609 void sk_allocStrokeBuffer(SK_Stroke *stk)
611 stk->points = MEM_callocN(sizeof(SK_Point) * stk->buf_size, "SK_Point buffer");
614 void sk_freeStroke(SK_Stroke *stk)
616 MEM_freeN(stk->points);
620 SK_Stroke* sk_createStroke()
624 stk = MEM_callocN(sizeof(SK_Stroke), "SK_Stroke");
628 stk->buf_size = SK_Stroke_BUFFER_INIT_SIZE;
630 sk_allocStrokeBuffer(stk);
635 void sk_shrinkStrokeBuffer(SK_Stroke *stk)
637 if (stk->nb_points < stk->buf_size)
639 SK_Point *old_points = stk->points;
641 stk->buf_size = stk->nb_points;
643 sk_allocStrokeBuffer(stk);
645 memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
647 MEM_freeN(old_points);
651 void sk_growStrokeBuffer(SK_Stroke *stk)
653 if (stk->nb_points == stk->buf_size)
655 SK_Point *old_points = stk->points;
659 sk_allocStrokeBuffer(stk);
661 memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
663 MEM_freeN(old_points);
667 void sk_growStrokeBufferN(SK_Stroke *stk, int n)
669 if (stk->nb_points + n > stk->buf_size)
671 SK_Point *old_points = stk->points;
673 while (stk->nb_points + n > stk->buf_size)
678 sk_allocStrokeBuffer(stk);
680 memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
682 MEM_freeN(old_points);
687 void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
689 memcpy(stk->points + n, pt, sizeof(SK_Point));
692 void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
694 int size = stk->nb_points - n;
696 sk_growStrokeBuffer(stk);
698 memmove(stk->points + n + 1, stk->points + n, size * sizeof(SK_Point));
700 memcpy(stk->points + n, pt, sizeof(SK_Point));
705 void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt)
707 sk_growStrokeBuffer(stk);
709 memcpy(stk->points + stk->nb_points, pt, sizeof(SK_Point));
714 void sk_insertStrokePoints(SK_Stroke *stk, SK_Point *pts, int len, int start, int end)
716 int size = end - start + 1;
718 sk_growStrokeBufferN(stk, len - size);
722 int tail_size = stk->nb_points - end + 1;
724 memmove(stk->points + start + len, stk->points + end + 1, tail_size * sizeof(SK_Point));
727 memcpy(stk->points + start, pts, len * sizeof(SK_Point));
729 stk->nb_points += len - size;
732 void sk_trimStroke(SK_Stroke *stk, int start, int end)
734 int size = end - start + 1;
738 memmove(stk->points, stk->points + start, size * sizeof(SK_Point));
741 stk->nb_points = size;
744 void sk_straightenStroke(SK_Stroke *stk, int start, int end, float p_start[3], float p_end[3])
747 SK_Point *prev, *next;
753 VecSubf(delta_p, p_end, p_start);
755 prev = stk->points + start;
756 next = stk->points + end;
758 VECCOPY(pt1.p, p_start);
759 VECCOPY(pt1.no, prev->no);
760 pt1.mode = prev->mode;
761 pt1.type = prev->type;
763 VECCOPY(pt2.p, p_end);
764 VECCOPY(pt2.no, next->no);
765 pt2.mode = next->mode;
766 pt2.type = next->type;
768 sk_insertStrokePoint(stk, &pt1, start + 1); /* insert after start */
769 sk_insertStrokePoint(stk, &pt2, end + 1); /* insert before end (since end was pushed back already) */
771 for (i = 1; i < total; i++)
773 float delta = (float)i / (float)total;
774 float *p = stk->points[start + 1 + i].p;
778 VecAddf(p, p, p_start);
782 void sk_polygonizeStroke(SK_Stroke *stk, int start, int end)
787 /* find first exact points outside of range */
788 for (;start > 0; start--)
790 if (stk->points[start].type == PT_EXACT)
796 for (;end < stk->nb_points - 1; end++)
798 if (stk->points[end].type == PT_EXACT)
806 for (i = start + 1; i < end; i++)
808 if (stk->points[i].type == PT_EXACT)
812 memcpy(stk->points + offset, stk->points + i, sizeof(SK_Point));
819 /* some points were removes, move end of array */
822 int size = stk->nb_points - end;
823 memmove(stk->points + offset, stk->points + end, size * sizeof(SK_Point));
824 stk->nb_points = offset + size;
828 void sk_flattenStroke(SK_Stroke *stk, int start, int end)
830 float normal[3], distance[3];
834 total = end - start + 1;
836 VECCOPY(normal, stk->points[start].no);
838 VecSubf(distance, stk->points[end].p, stk->points[start].p);
839 Projf(normal, distance, normal);
840 limit = Normalize(normal);
842 for (i = 1; i < total - 1; i++)
844 float d = limit * i / total;
846 float *p = stk->points[start + i].p;
848 VecSubf(distance, p, stk->points[start].p);
849 Projf(distance, distance, normal);
851 VECCOPY(offset, normal);
854 VecSubf(p, p, distance);
855 VecAddf(p, p, offset);
859 void sk_removeStroke(SK_Sketch *sketch, SK_Stroke *stk)
861 if (sketch->active_stroke == stk)
863 sketch->active_stroke = NULL;
866 BLI_remlink(&sketch->strokes, stk);
870 void sk_reverseStroke(SK_Stroke *stk)
872 SK_Point *old_points = stk->points;
875 sk_allocStrokeBuffer(stk);
877 for (i = 0; i < stk->nb_points; i++)
879 sk_copyPoint(stk->points + i, old_points + stk->nb_points - 1 - i);
882 MEM_freeN(old_points);
886 void sk_cancelStroke(SK_Sketch *sketch)
888 if (sketch->active_stroke != NULL)
890 sk_resetOverdraw(sketch);
891 sk_removeStroke(sketch, sketch->active_stroke);
895 /* Apply reverse Chaikin filter to simplify the polyline
897 void sk_filterStroke(SK_Stroke *stk, int start, int end)
899 SK_Point *old_points = stk->points;
900 int nb_points = stk->nb_points;
908 end = stk->nb_points - 1;
911 sk_allocStrokeBuffer(stk);
914 /* adding points before range */
915 for (i = 0; i < start; i++)
917 sk_appendStrokePoint(stk, old_points + i);
920 for (i = start, j = start; i <= end; i++)
927 sk_copyPoint(&pt, &old_points[j+1]);
933 VECCOPY(vec, old_points[j].p);
935 VecAddf(pt.p, pt.p, vec);
937 VECCOPY(vec, old_points[j+1].p);
939 VecAddf(pt.p, pt.p, vec);
941 VECCOPY(vec, old_points[j+2].p);
943 VecAddf(pt.p, pt.p, vec);
945 VECCOPY(vec, old_points[j+3].p);
947 VecAddf(pt.p, pt.p, vec);
949 pt.size = -0.25 * old_points[j].size + 0.75 * old_points[j+1].size + 0.75 * old_points[j+2].size - 0.25 * old_points[j+3].size;
951 sk_appendStrokePoint(stk, &pt);
956 /* this might be uneeded when filtering last continuous stroke */
957 if (old_points[i].type == PT_EXACT)
959 sk_appendStrokePoint(stk, old_points + i);
964 /* adding points after range */
965 for (i = end + 1; i < nb_points; i++)
967 sk_appendStrokePoint(stk, old_points + i);
970 MEM_freeN(old_points);
972 sk_shrinkStrokeBuffer(stk);
975 void sk_filterLastContinuousStroke(SK_Stroke *stk)
979 end = stk->nb_points -1;
981 for (start = end - 1; start > 0 && stk->points[start].type == PT_CONTINUOUS; start--)
983 /* nothing to do here*/
988 sk_filterStroke(stk, start, end);
992 SK_Point *sk_lastStrokePoint(SK_Stroke *stk)
996 if (stk->nb_points > 0)
998 pt = stk->points + (stk->nb_points - 1);
1004 float sk_clampPointSize(SK_Point *pt, float size)
1006 return MAX2(size * pt->size, size / 2);
1009 void sk_drawPoint(GLUquadric *quad, SK_Point *pt, float size)
1011 glTranslatef(pt->p[0], pt->p[1], pt->p[2]);
1012 gluSphere(quad, sk_clampPointSize(pt, size), 8, 8);
1015 void sk_drawEdge(GLUquadric *quad, SK_Point *pt0, SK_Point *pt1, float size)
1017 float vec1[3], vec2[3] = {0, 0, 1}, axis[3];
1018 float angle, length;
1020 VecSubf(vec1, pt1->p, pt0->p);
1021 length = Normalize(vec1);
1022 Crossf(axis, vec2, vec1);
1024 if (VecIsNull(axis))
1029 angle = NormalizedVecAngle2(vec2, vec1);
1031 glRotatef(angle * 180 / M_PI + 180, axis[0], axis[1], axis[2]);
1033 gluCylinder(quad, sk_clampPointSize(pt1, size), sk_clampPointSize(pt0, size), length, 8, 8);
1036 void sk_drawNormal(GLUquadric *quad, SK_Point *pt, float size, float height)
1038 float vec2[3] = {0, 0, 1}, axis[3];
1043 Crossf(axis, vec2, pt->no);
1045 if (VecIsNull(axis))
1050 angle = NormalizedVecAngle2(vec2, pt->no);
1052 glRotatef(angle * 180 / M_PI, axis[0], axis[1], axis[2]);
1055 gluCylinder(quad, sk_clampPointSize(pt, size), 0, sk_clampPointSize(pt, height), 10, 2);
1060 void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int end)
1064 GLUquadric *quad = gluNewQuadric();
1065 gluQuadricNormals(quad, GLU_SMOOTH);
1071 for (i = 0; i < stk->nb_points; i++)
1075 sk_drawPoint(quad, stk->points + i, 0.1);
1079 sk_drawEdge(quad, stk->points + i - 1, stk->points + i, 0.1);
1088 float d_rgb[3] = {1, 1, 1};
1090 VECCOPY(rgb, color);
1091 VecSubf(d_rgb, d_rgb, rgb);
1092 VecMulf(d_rgb, 1.0f / (float)stk->nb_points);
1094 for (i = 0; i < stk->nb_points; i++)
1096 SK_Point *pt = stk->points + i;
1100 if (pt->type == PT_EXACT)
1103 sk_drawPoint(quad, pt, 0.15);
1104 sk_drawNormal(quad, pt, 0.05, 0.9);
1107 if (i >= start && i <= end)
1109 glColor3f(0.3, 0.3, 0.3);
1116 if (pt->type != PT_EXACT)
1119 sk_drawPoint(quad, pt, 0.1);
1124 sk_drawEdge(quad, pt - 1, pt, 0.1);
1129 VecAddf(rgb, rgb, d_rgb);
1133 gluDeleteQuadric(quad);
1136 void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *iter, NextSubdivisionFunc next_subdividion)
1138 SK_Stroke *stk = ((SK_StrokeIterator*)iter)->stroke;
1139 float head[3], tail[3];
1141 int end = iter->length;
1143 GLUquadric *quad = gluNewQuadric();
1144 gluQuadricNormals(quad, GLU_SMOOTH);
1147 VECCOPY(head, iter->p);
1149 index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
1152 SK_Point *pt = stk->points + index;
1157 sk_drawPoint(quad, pt, 0.15);
1159 sk_drawNormal(quad, pt, 0.05, 0.9);
1163 VECCOPY(head, tail);
1164 bone_start = index; // start next bone from current index
1166 index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
1169 gluDeleteQuadric(quad);
1172 void sk_drawStrokeSubdivision(ToolSettings *toolsettings, SK_Stroke *stk)
1174 int head_index = -1;
1177 if (toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
1183 for (i = 0; i < stk->nb_points; i++)
1185 SK_Point *pt = stk->points + i;
1187 if (pt->type == PT_EXACT || i == stk->nb_points - 1) /* stop on exact or on last point */
1189 if (head_index == -1)
1195 if (i - head_index > 1)
1197 SK_StrokeIterator sk_iter;
1198 BArcIterator *iter = (BArcIterator*)&sk_iter;
1200 initStrokeIterator(iter, stk, head_index, i);
1202 if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
1204 drawSubdividedStrokeBy(toolsettings, iter, nextAdaptativeSubdivision);
1206 else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
1208 drawSubdividedStrokeBy(toolsettings, iter, nextLengthSubdivision);
1210 else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
1212 drawSubdividedStrokeBy(toolsettings, iter, nextFixedSubdivision);
1223 SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, short mval[2], int *dist, int *index, int all_pts)
1225 ARegion *ar = CTX_wm_region(C);
1226 SK_Point *pt = NULL;
1229 for (i = 0; i < stk->nb_points; i++)
1231 if (all_pts || stk->points[i].type == PT_EXACT)
1236 project_short_noclip(ar, stk->points[i].p, pval);
1238 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
1243 pt = stk->points + i;
1256 SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, short mval[2], int *dist)
1258 ARegion *ar = CTX_wm_region(C);
1259 SK_Point *pt = NULL;
1262 for (bone = ebones->first; bone; bone = bone->next)
1268 if ((bone->flag & BONE_CONNECTED) == 0)
1270 VECCOPY(vec, bone->head);
1271 Mat4MulVecfl(ob->obmat, vec);
1272 project_short_noclip(ar, vec, pval);
1274 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
1280 VECCOPY(pt->p, vec);
1281 pt->type = PT_EXACT;
1286 VECCOPY(vec, bone->tail);
1287 Mat4MulVecfl(ob->obmat, vec);
1288 project_short_noclip(ar, vec, pval);
1290 pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
1296 VECCOPY(pt->p, vec);
1297 pt->type = PT_EXACT;
1304 void sk_resetOverdraw(SK_Sketch *sketch)
1306 sketch->over.target = NULL;
1307 sketch->over.start = -1;
1308 sketch->over.end = -1;
1309 sketch->over.count = 0;
1312 int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk)
1314 return sketch->over.target &&
1315 sketch->over.count >= SK_OVERDRAW_LIMIT &&
1316 (sketch->over.target == stk || stk == NULL) &&
1317 (sketch->over.start != -1 || sketch->over.end != -1);
1320 void sk_updateOverdraw(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1322 if (sketch->over.target == NULL)
1325 int closest_index = -1;
1326 int dist = SNAP_MIN_DISTANCE * 2;
1328 // /* If snapping, don't start overdraw */ Can't do that, snap is embed too now
1329 // if (sk_lastStrokePoint(stk)->mode == PT_SNAP)
1334 for (target = sketch->strokes.first; target; target = target->next)
1340 SK_Point *spt = sk_snapPointStroke(C, target, dd->mval, &dist, &index, 1);
1344 sketch->over.target = target;
1345 closest_index = index;
1350 if (sketch->over.target != NULL)
1352 if (closest_index > -1)
1354 if (sk_lastStrokePoint(stk)->type == PT_EXACT)
1356 sketch->over.count = SK_OVERDRAW_LIMIT;
1360 sketch->over.count++;
1364 if (stk->nb_points == 1)
1366 sketch->over.start = closest_index;
1370 sketch->over.end = closest_index;
1374 else if (sketch->over.target != NULL)
1376 SK_Point *closest_pt = NULL;
1377 int dist = SNAP_MIN_DISTANCE * 2;
1380 closest_pt = sk_snapPointStroke(C, sketch->over.target, dd->mval, &dist, &index, 1);
1382 if (closest_pt != NULL)
1384 if (sk_lastStrokePoint(stk)->type == PT_EXACT)
1386 sketch->over.count = SK_OVERDRAW_LIMIT;
1390 sketch->over.count++;
1393 sketch->over.end = index;
1397 sketch->over.end = -1;
1402 /* return 1 on reverse needed */
1403 int sk_adjustIndexes(SK_Sketch *sketch, int *start, int *end)
1407 *start = sketch->over.start;
1408 *end = sketch->over.end;
1417 *end = sketch->over.target->nb_points - 1;
1431 void sk_endOverdraw(SK_Sketch *sketch)
1433 SK_Stroke *stk = sketch->active_stroke;
1435 if (sk_hasOverdraw(sketch, NULL))
1440 if (sk_adjustIndexes(sketch, &start, &end))
1442 sk_reverseStroke(stk);
1445 if (stk->nb_points > 1)
1447 stk->points->type = sketch->over.target->points[start].type;
1448 sk_lastStrokePoint(stk)->type = sketch->over.target->points[end].type;
1451 sk_insertStrokePoints(sketch->over.target, stk->points, stk->nb_points, start, end);
1453 sk_removeStroke(sketch, stk);
1455 sk_resetOverdraw(sketch);
1460 void sk_startStroke(SK_Sketch *sketch)
1462 SK_Stroke *stk = sk_createStroke();
1464 BLI_addtail(&sketch->strokes, stk);
1465 sketch->active_stroke = stk;
1467 sk_resetOverdraw(sketch);
1470 void sk_endStroke(bContext *C, SK_Sketch *sketch)
1472 ToolSettings *ts = CTX_data_tool_settings(C);
1473 sk_shrinkStrokeBuffer(sketch->active_stroke);
1475 if (ts->bone_sketching & BONE_SKETCHING_ADJUST)
1477 sk_endOverdraw(sketch);
1480 sketch->active_stroke = NULL;
1483 void sk_updateDrawData(SK_DrawData *dd)
1485 dd->type = PT_CONTINUOUS;
1487 dd->previous_mval[0] = dd->mval[0];
1488 dd->previous_mval[1] = dd->mval[1];
1491 float sk_distanceDepth(bContext *C, float p1[3], float p2[3])
1493 ARegion *ar = CTX_wm_region(C);
1494 RegionView3D *rv3d = ar->regiondata;
1498 VecSubf(vec, p1, p2);
1500 Projf(vec, vec, rv3d->viewinv[2]);
1502 distance = VecLength(vec);
1504 if (Inpf(rv3d->viewinv[2], vec) > 0)
1512 void sk_interpolateDepth(bContext *C, SK_Stroke *stk, int start, int end, float length, float distance)
1514 ARegion *ar = CTX_wm_region(C);
1515 ScrArea *sa = CTX_wm_area(C);
1516 View3D *v3d = sa->spacedata.first;
1521 progress = VecLenf(stk->points[start].p, stk->points[start - 1].p);
1523 for (i = start; i <= end; i++)
1525 float ray_start[3], ray_normal[3];
1526 float delta = VecLenf(stk->points[i].p, stk->points[i + 1].p);
1529 project_short_noclip(ar, stk->points[i].p, pval);
1530 viewray(ar, v3d, pval, ray_start, ray_normal);
1532 VecMulf(ray_normal, distance * progress / length);
1533 VecAddf(stk->points[i].p, stk->points[i].p, ray_normal);
1539 void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_DrawData *dd)
1541 ARegion *ar = CTX_wm_region(C);
1542 /* copied from grease pencil, need fixing */
1543 SK_Point *last = sk_lastStrokePoint(stk);
1545 float fp[3] = {0, 0, 0};
1550 VECCOPY(fp, last->p);
1553 initgrabz(ar->regiondata, fp[0], fp[1], fp[2]);
1555 /* method taken from editview.c - mouse_cursor() */
1556 project_short_noclip(ar, fp, cval);
1557 window_to_3d_delta(ar, dvec, cval[0] - dd->mval[0], cval[1] - dd->mval[1]);
1558 VecSubf(vec, fp, dvec);
1561 int sk_getStrokeDrawPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1563 pt->type = dd->type;
1564 pt->mode = PT_PROJECT;
1565 sk_projectDrawPoint(C, pt->p, stk, dd);
1570 int sk_addStrokeDrawPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1574 sk_initPoint(C, &pt);
1576 sk_getStrokeDrawPoint(C, &pt, sketch, stk, dd);
1578 sk_appendStrokePoint(stk, &pt);
1583 int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1585 ToolSettings *ts = CTX_data_tool_settings(C);
1586 int point_added = 0;
1588 if (ts->snap_mode == SCE_SNAP_MODE_VOLUME)
1591 float *last_p = NULL;
1592 float dist = FLT_MAX;
1596 BLI_freelistN(&sketch->depth_peels);
1597 sketch->depth_peels.first = sketch->depth_peels.last = NULL;
1599 peelObjectsContext(C, &sketch->depth_peels, dd->mval);
1601 if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS)
1603 last_p = stk->points[stk->nb_points - 1].p;
1605 else if (LAST_SNAP_POINT_VALID)
1607 last_p = LAST_SNAP_POINT;
1611 for (p1 = sketch->depth_peels.first; p1; p1 = p1->next)
1622 /* if peeling objects, take the first and last from each object */
1623 if (ts->snap_flag & SCE_SNAP_PEEL_OBJECT)
1626 for (peel = p1->next; peel; peel = peel->next)
1628 if (peel->ob == p1->ob)
1635 /* otherwise, pair first with second and so on */
1638 for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next)
1640 /* nothing to do here */
1648 VecAddf(vec, p1->p, p2->p);
1650 new_size = VecLenf(p1->p, p2->p);
1654 VECCOPY(vec, p1->p);
1665 new_dist = VecLenf(last_p, vec);
1667 if (new_dist < dist)
1676 if (dist != FLT_MAX)
1678 pt->type = dd->type;
1680 pt->size = size / 2;
1686 //BLI_freelistN(&depth_peels);
1690 SK_Stroke *snap_stk;
1694 int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
1696 /* snap to strokes */
1697 // if (ts->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
1698 for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next)
1700 SK_Point *spt = NULL;
1701 if (snap_stk == stk)
1703 spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist, NULL, 0);
1707 spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist, NULL, 1);
1712 VECCOPY(pt->p, spt->p);
1717 /* try to snap to closer object */
1718 found = snapObjectsContext(C, dd->mval, &dist, vec, no, SNAP_NOT_SELECTED);
1721 pt->type = dd->type;
1723 VECCOPY(pt->p, vec);
1732 int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
1737 sk_initPoint(C, &pt);
1739 point_added = sk_getStrokeSnapPoint(C, &pt, sketch, stk, dd);
1744 float length, distance;
1748 VECCOPY(final_p, pt.p);
1750 sk_projectDrawPoint(C, pt.p, stk, dd);
1751 sk_appendStrokePoint(stk, &pt);
1753 /* update all previous point to give smooth Z progresion */
1756 for (i = stk->nb_points - 2; i > 0; i--)
1758 length += VecLenf(stk->points[i].p, stk->points[i + 1].p);
1760 if (stk->points[i].mode == PT_SNAP || stk->points[i].type == PT_EXACT)
1768 distance = sk_distanceDepth(C, final_p, stk->points[i].p);
1770 sk_interpolateDepth(C, stk, i + 1, stk->nb_points - 2, length, distance);
1773 VECCOPY(stk->points[stk->nb_points - 1].p, final_p);
1781 void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
1783 ToolSettings *ts = CTX_data_tool_settings(C);
1784 int point_added = 0;
1788 point_added = sk_addStrokeSnapPoint(C, sketch, stk, dd);
1791 if (point_added == 0)
1793 point_added = sk_addStrokeDrawPoint(C, sketch, stk, dd);
1796 if (stk == sketch->active_stroke && ts->bone_sketching & BONE_SKETCHING_ADJUST)
1798 sk_updateOverdraw(C, sketch, stk, dd);
1802 void sk_getStrokePoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
1804 int point_added = 0;
1808 point_added = sk_getStrokeSnapPoint(C, pt, sketch, stk, dd);
1809 LAST_SNAP_POINT_VALID = 1;
1810 VECCOPY(LAST_SNAP_POINT, pt->p);
1814 LAST_SNAP_POINT_VALID = 0;
1817 if (point_added == 0)
1819 point_added = sk_getStrokeDrawPoint(C, pt, sketch, stk, dd);
1823 void sk_endContinuousStroke(SK_Stroke *stk)
1825 stk->points[stk->nb_points - 1].type = PT_EXACT;
1828 void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk)
1832 memcpy(&sketch->next_point, stk->points[stk->nb_points - 1].p, sizeof(SK_Point));
1836 int sk_stroke_filtermval(SK_DrawData *dd)
1839 if (ABS(dd->mval[0] - dd->previous_mval[0]) + ABS(dd->mval[1] - dd->previous_mval[1]) > U.gp_manhattendist)
1847 void sk_initDrawData(SK_DrawData *dd, short mval[2])
1849 dd->mval[0] = mval[0];
1850 dd->mval[1] = mval[1];
1851 dd->previous_mval[0] = -1;
1852 dd->previous_mval[1] = -1;
1853 dd->type = PT_EXACT;
1855 /********************************************/
1857 static void* headPoint(void *arg);
1858 static void* tailPoint(void *arg);
1859 static void* nextPoint(void *arg);
1860 static void* nextNPoint(void *arg, int n);
1861 static void* peekPoint(void *arg, int n);
1862 static void* previousPoint(void *arg);
1863 static int iteratorStopped(void *arg);
1865 static void initIteratorFct(SK_StrokeIterator *iter)
1867 iter->head = headPoint;
1868 iter->tail = tailPoint;
1869 iter->peek = peekPoint;
1870 iter->next = nextPoint;
1871 iter->nextN = nextNPoint;
1872 iter->previous = previousPoint;
1873 iter->stopped = iteratorStopped;
1876 static SK_Point* setIteratorValues(SK_StrokeIterator *iter, int index)
1878 SK_Point *pt = NULL;
1880 if (index >= 0 && index < iter->length)
1882 pt = &(iter->stroke->points[iter->start + (iter->stride * index)]);
1885 iter->size = pt->size;
1897 void initStrokeIterator(BArcIterator *arg, SK_Stroke *stk, int start, int end)
1899 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1901 initIteratorFct(iter);
1906 iter->start = start + 1;
1907 iter->end = end - 1;
1912 iter->start = start - 1;
1913 iter->end = end + 1;
1917 iter->length = iter->stride * (iter->end - iter->start + 1);
1923 static void* headPoint(void *arg)
1925 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1926 SK_Point *result = NULL;
1928 result = &(iter->stroke->points[iter->start - iter->stride]);
1929 iter->p = result->p;
1930 iter->no = result->no;
1931 iter->size = result->size;
1936 static void* tailPoint(void *arg)
1938 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1939 SK_Point *result = NULL;
1941 result = &(iter->stroke->points[iter->end + iter->stride]);
1942 iter->p = result->p;
1943 iter->no = result->no;
1944 iter->size = result->size;
1949 static void* nextPoint(void *arg)
1951 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1952 SK_Point *result = NULL;
1955 if (iter->index < iter->length)
1957 result = setIteratorValues(iter, iter->index);
1963 static void* nextNPoint(void *arg, int n)
1965 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1966 SK_Point *result = NULL;
1970 /* check if passed end */
1971 if (iter->index < iter->length)
1973 result = setIteratorValues(iter, iter->index);
1979 static void* peekPoint(void *arg, int n)
1981 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1982 SK_Point *result = NULL;
1983 int index = iter->index + n;
1985 /* check if passed end */
1986 if (index < iter->length)
1988 result = setIteratorValues(iter, index);
1994 static void* previousPoint(void *arg)
1996 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
1997 SK_Point *result = NULL;
1999 if (iter->index > 0)
2002 result = setIteratorValues(iter, iter->index);
2008 static int iteratorStopped(void *arg)
2010 SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
2012 if (iter->index >= iter->length)
2022 void sk_convertStroke(bContext *C, SK_Stroke *stk)
2024 Object *obedit = CTX_data_edit_object(C);
2025 ToolSettings *ts = CTX_data_tool_settings(C);
2026 bArmature *arm = obedit->data;
2028 EditBone *parent = NULL;
2029 float invmat[4][4]; /* move in caller function */
2036 Mat4Invert(invmat, obedit->obmat);
2038 Mat3CpyMat4(tmat, obedit->obmat);
2041 for (i = 0; i < stk->nb_points; i++)
2043 SK_Point *pt = stk->points + i;
2045 if (pt->type == PT_EXACT)
2054 EditBone *bone = NULL;
2055 EditBone *new_parent;
2057 if (i - head_index > 1)
2059 SK_StrokeIterator sk_iter;
2060 BArcIterator *iter = (BArcIterator*)&sk_iter;
2062 initStrokeIterator(iter, stk, head_index, i);
2064 if (ts->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
2066 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
2068 else if (ts->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
2070 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
2072 else if (ts->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
2074 bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
2080 bone = addEditBone(arm, "Bone");
2082 VECCOPY(bone->head, head->p);
2083 VECCOPY(bone->tail, pt->p);
2085 Mat4MulVecfl(invmat, bone->head);
2086 Mat4MulVecfl(invmat, bone->tail);
2087 setBoneRollFromNormal(bone, head->no, invmat, tmat);
2091 bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
2093 /* move to end of chain */
2094 while (bone->parent != NULL)
2096 bone = bone->parent;
2097 bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
2102 bone->parent = parent;
2103 bone->flag |= BONE_CONNECTED;
2106 parent = new_parent;
2114 void sk_convert(bContext *C, SK_Sketch *sketch)
2116 ToolSettings *ts = CTX_data_tool_settings(C);
2119 for (stk = sketch->strokes.first; stk; stk = stk->next)
2121 if (stk->selected == 1)
2123 if (ts->bone_sketching_convert == SK_CONVERT_RETARGET)
2125 sk_retargetStroke(C, stk);
2129 sk_convertStroke(C, stk);
2132 // allqueue(REDRAWBUTSEDIT, 0);
2136 /******************* GESTURE *************************/
2139 /* returns the number of self intersections */
2140 int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gesture)
2142 ARegion *ar = CTX_wm_region(C);
2146 for (s_i = 0; s_i < gesture->nb_points - 1; s_i++)
2148 float s_p1[3] = {0, 0, 0};
2149 float s_p2[3] = {0, 0, 0};
2152 project_float(ar, gesture->points[s_i].p, s_p1);
2153 project_float(ar, gesture->points[s_i + 1].p, s_p2);
2155 /* start checking from second next, because two consecutive cannot intersect */
2156 for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++)
2158 float g_p1[3] = {0, 0, 0};
2159 float g_p2[3] = {0, 0, 0};
2163 project_float(ar, gesture->points[g_i].p, g_p1);
2164 project_float(ar, gesture->points[g_i + 1].p, g_p2);
2166 if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
2168 SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
2170 isect->gesture_index = g_i;
2171 isect->before = s_i;
2172 isect->after = s_i + 1;
2173 isect->stroke = gesture;
2175 VecSubf(isect->p, gesture->points[s_i + 1].p, gesture->points[s_i].p);
2176 VecMulf(isect->p, lambda);
2177 VecAddf(isect->p, isect->p, gesture->points[s_i].p);
2179 BLI_addtail(list, isect);
2189 int cmpIntersections(void *i1, void *i2)
2191 SK_Intersection *isect1 = i1, *isect2 = i2;
2193 if (isect1->stroke == isect2->stroke)
2195 if (isect1->before < isect2->before)
2199 else if (isect1->before > isect2->before)
2205 if (isect1->lambda < isect2->lambda)
2209 else if (isect1->lambda > isect2->lambda)
2220 /* returns the maximum number of intersections per stroke */
2221 int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
2223 ARegion *ar = CTX_wm_region(C);
2224 ScrArea *sa = CTX_wm_area(C);
2225 View3D *v3d = sa->spacedata.first;
2229 for (stk = sketch->strokes.first; stk; stk = stk->next)
2234 for (s_i = 0; s_i < stk->nb_points - 1; s_i++)
2236 float s_p1[3] = {0, 0, 0};
2237 float s_p2[3] = {0, 0, 0};
2240 project_float(ar, stk->points[s_i].p, s_p1);
2241 project_float(ar, stk->points[s_i + 1].p, s_p2);
2243 for (g_i = 0; g_i < gesture->nb_points - 1; g_i++)
2245 float g_p1[3] = {0, 0, 0};
2246 float g_p2[3] = {0, 0, 0};
2250 project_float(ar, gesture->points[g_i].p, g_p1);
2251 project_float(ar, gesture->points[g_i + 1].p, g_p2);
2253 if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
2255 SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
2256 float ray_start[3], ray_end[3];
2259 isect->gesture_index = g_i;
2260 isect->before = s_i;
2261 isect->after = s_i + 1;
2262 isect->stroke = stk;
2263 isect->lambda = lambda;
2265 mval[0] = (short)(vi[0]);
2266 mval[1] = (short)(vi[1]);
2267 viewline(ar, v3d, mval, ray_start, ray_end);
2269 LineIntersectLine( stk->points[s_i].p,
2270 stk->points[s_i + 1].p,
2276 BLI_addtail(list, isect);
2283 added = MAX2(s_added, added);
2286 BLI_sortlist(list, cmpIntersections);
2291 int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
2293 SK_StrokeIterator sk_iter;
2294 BArcIterator *iter = (BArcIterator*)&sk_iter;
2296 float CORRELATION_THRESHOLD = 0.99f;
2300 sk_appendStrokePoint(segments, &gesture->points[0]);
2301 vec = segments->points[segments->nb_points - 1].p;
2303 initStrokeIterator(iter, gesture, 0, gesture->nb_points - 1);
2305 for (i = 1, j = 0; i < gesture->nb_points; i++)
2309 /* Calculate normal */
2310 VecSubf(n, gesture->points[i].p, vec);
2312 if (calcArcCorrelation(iter, j, i, vec, n) < CORRELATION_THRESHOLD)
2315 sk_appendStrokePoint(segments, &gesture->points[j]);
2316 vec = segments->points[segments->nb_points - 1].p;
2317 segments->points[segments->nb_points - 1].type = PT_EXACT;
2321 sk_appendStrokePoint(segments, &gesture->points[gesture->nb_points - 1]);
2323 return segments->nb_points - 1;
2326 int sk_detectCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2328 if (gest->nb_segments == 1 && gest->nb_intersections == 1)
2336 void sk_applyCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2338 SK_Intersection *isect;
2340 for (isect = gest->intersections.first; isect; isect = isect->next)
2345 pt.mode = PT_PROJECT; /* take mode from neighbouring points */
2346 VECCOPY(pt.p, isect->p);
2347 VECCOPY(pt.no, isect->stroke->points[isect->before].no);
2349 sk_insertStrokePoint(isect->stroke, &pt, isect->after);
2353 int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2355 if (gest->nb_segments == 2 && gest->nb_intersections == 1 && gest->nb_self_intersections == 0)
2360 VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p);
2361 VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p);
2363 angle = VecAngle2(s1, s2);
2365 if (angle > 60 && angle < 120)
2374 void sk_applyTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2376 SK_Intersection *isect;
2379 VecSubf(trim_dir, gest->segments->points[2].p, gest->segments->points[1].p);
2381 for (isect = gest->intersections.first; isect; isect = isect->next)
2384 float stroke_dir[3];
2387 pt.mode = PT_PROJECT; /* take mode from neighbouring points */
2388 VECCOPY(pt.p, isect->p);
2389 VECCOPY(pt.no, isect->stroke->points[isect->before].no);
2391 VecSubf(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p);
2393 /* same direction, trim end */
2394 if (Inpf(stroke_dir, trim_dir) > 0)
2396 sk_replaceStrokePoint(isect->stroke, &pt, isect->after);
2397 sk_trimStroke(isect->stroke, 0, isect->after);
2399 /* else, trim start */
2402 sk_replaceStrokePoint(isect->stroke, &pt, isect->before);
2403 sk_trimStroke(isect->stroke, isect->before, isect->stroke->nb_points - 1);
2409 int sk_detectCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2411 if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1)
2413 SK_Intersection *isect, *self_isect;
2415 /* get the the last intersection of the first pair */
2416 for( isect = gest->intersections.first; isect; isect = isect->next )
2418 if (isect->stroke == isect->next->stroke)
2420 isect = isect->next;
2425 self_isect = gest->self_intersections.first;
2427 if (isect && isect->gesture_index < self_isect->gesture_index)
2436 void sk_applyCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2438 SK_Intersection *isect;
2442 // command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3");
2443 if(command < 1) return;
2445 for (isect = gest->intersections.first; isect; isect = isect->next)
2447 SK_Intersection *i2;
2451 if (i2 && i2->stroke == isect->stroke)
2456 sk_flattenStroke(isect->stroke, isect->before, i2->after);
2459 sk_straightenStroke(isect->stroke, isect->before, i2->after, isect->p, i2->p);
2462 sk_polygonizeStroke(isect->stroke, isect->before, i2->after);
2471 int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2473 if (gest->nb_segments == 2 && gest->nb_intersections == 2)
2478 VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p);
2479 VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p);
2481 angle = VecAngle2(s1, s2);
2492 void sk_applyDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2494 SK_Intersection *isect;
2496 for (isect = gest->intersections.first; isect; isect = isect->next)
2498 /* only delete strokes that are crossed twice */
2499 if (isect->next && isect->next->stroke == isect->stroke)
2501 isect = isect->next;
2503 sk_removeStroke(sketch, isect->stroke);
2508 int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2510 ARegion *ar = CTX_wm_region(C);
2511 if (gest->nb_segments > 2 && gest->nb_intersections == 2)
2513 short start_val[2], end_val[2];
2516 project_short_noclip(ar, gest->stk->points[0].p, start_val);
2517 project_short_noclip(ar, sk_lastStrokePoint(gest->stk)->p, end_val);
2519 dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1]));
2521 /* if gesture is a circle */
2524 SK_Intersection *isect;
2526 /* check if it circled around an exact point */
2527 for (isect = gest->intersections.first; isect; isect = isect->next)
2529 /* only delete strokes that are crossed twice */
2530 if (isect->next && isect->next->stroke == isect->stroke)
2532 int start_index, end_index;
2535 start_index = MIN2(isect->after, isect->next->after);
2536 end_index = MAX2(isect->before, isect->next->before);
2538 for (i = start_index; i <= end_index; i++)
2540 if (isect->stroke->points[i].type == PT_EXACT)
2542 return 1; /* at least one exact point found, stop detect here */
2547 isect = isect->next;
2556 void sk_applyMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2558 SK_Intersection *isect;
2560 /* check if it circled around an exact point */
2561 for (isect = gest->intersections.first; isect; isect = isect->next)
2563 /* only merge strokes that are crossed twice */
2564 if (isect->next && isect->next->stroke == isect->stroke)
2566 int start_index, end_index;
2569 start_index = MIN2(isect->after, isect->next->after);
2570 end_index = MAX2(isect->before, isect->next->before);
2572 for (i = start_index; i <= end_index; i++)
2574 /* if exact, switch to continuous */
2575 if (isect->stroke->points[i].type == PT_EXACT)
2577 isect->stroke->points[i].type = PT_CONTINUOUS;
2582 isect = isect->next;
2587 int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2589 if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 0)
2591 SK_Intersection *isect;
2593 /* check if it circled around an exact point */
2594 for (isect = gest->intersections.first; isect; isect = isect->next)
2596 /* only delete strokes that are crossed twice */
2597 if (isect->next && isect->next->stroke == isect->stroke)
2599 float start_v[3], end_v[3];
2602 if (isect->gesture_index < isect->next->gesture_index)
2604 VecSubf(start_v, isect->p, gest->stk->points[0].p);
2605 VecSubf(end_v, sk_lastStrokePoint(gest->stk)->p, isect->next->p);
2609 VecSubf(start_v, isect->next->p, gest->stk->points[0].p);
2610 VecSubf(end_v, sk_lastStrokePoint(gest->stk)->p, isect->p);
2613 angle = VecAngle2(start_v, end_v);
2621 isect = isect->next;
2629 void sk_applyReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2631 SK_Intersection *isect;
2633 for (isect = gest->intersections.first; isect; isect = isect->next)
2635 /* only reverse strokes that are crossed twice */
2636 if (isect->next && isect->next->stroke == isect->stroke)
2638 sk_reverseStroke(isect->stroke);
2641 isect = isect->next;
2646 int sk_detectConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2648 if (gest->nb_segments == 3 && gest->nb_self_intersections == 1)
2655 void sk_applyConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2657 sk_convert(C, sketch);
2660 static void sk_initGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
2662 gest->intersections.first = gest->intersections.last = NULL;
2663 gest->self_intersections.first = gest->self_intersections.last = NULL;
2665 gest->segments = sk_createStroke();
2666 gest->stk = sketch->gesture;
2668 gest->nb_self_intersections = sk_getSelfIntersections(C, &gest->self_intersections, gest->stk);
2669 gest->nb_intersections = sk_getIntersections(C, &gest->intersections, sketch, gest->stk);
2670 gest->nb_segments = sk_getSegments(gest->segments, gest->stk);
2673 static void sk_freeGesture(SK_Gesture *gest)
2675 sk_freeStroke(gest->segments);
2676 BLI_freelistN(&gest->intersections);
2677 BLI_freelistN(&gest->self_intersections);
2680 void sk_applyGesture(bContext *C, SK_Sketch *sketch)
2683 SK_GestureAction *act;
2685 sk_initGesture(C, &gest, sketch);
2687 /* detect and apply */
2688 for (act = GESTURE_ACTIONS; act->apply != NULL; act++)
2690 if (act->detect(C, &gest, sketch))
2692 act->apply(C, &gest, sketch);
2697 sk_freeGesture(&gest);
2700 /********************************************/
2702 void sk_deleteSelectedStrokes(SK_Sketch *sketch)
2704 SK_Stroke *stk, *next;
2706 for (stk = sketch->strokes.first; stk; stk = next)
2710 if (stk->selected == 1)
2712 sk_removeStroke(sketch, stk);
2717 void sk_selectAllSketch(SK_Sketch *sketch, int mode)
2719 SK_Stroke *stk = NULL;
2723 for (stk = sketch->strokes.first; stk; stk = stk->next)
2730 for (stk = sketch->strokes.first; stk; stk = stk->next)
2739 for (stk = sketch->strokes.first; stk; stk = stk->next)
2741 selected &= stk->selected;
2746 for (stk = sketch->strokes.first; stk; stk = stk->next)
2748 stk->selected = selected;
2753 void sk_selectStroke(bContext *C, SK_Sketch *sketch, short mval[2], int extend)
2757 unsigned int buffer[MAXPICKBUF];
2760 view3d_set_viewcontext(C, &vc);
2762 rect.xmin= mval[0]-5;
2763 rect.xmax= mval[0]+5;
2764 rect.ymin= mval[1]-5;
2765 rect.ymax= mval[1]+5;
2767 hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
2771 int besthitresult = -1;
2774 besthitresult = buffer[3];
2777 besthitresult = buffer[3];
2778 /* loop and get best hit */
2781 if (besthitresult > 0)
2783 SK_Stroke *selected_stk = BLI_findlink(&sketch->strokes, besthitresult - 1);
2787 sk_selectAllSketch(sketch, -1);
2789 selected_stk->selected = 1;
2793 selected_stk->selected ^= 1;
2801 void sk_queueRedrawSketch(SK_Sketch *sketch)
2803 if (sketch->active_stroke != NULL)
2805 SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
2810 // allqueue(REDRAWVIEW3D, 0);
2815 void sk_drawSketch(Scene *scene, View3D *v3d, SK_Sketch *sketch, int with_names)
2817 ToolSettings *ts= scene->toolsettings;
2820 glClear(GL_DEPTH_BUFFER_BIT);
2821 glEnable(GL_DEPTH_TEST);
2826 for (id = 1, stk = sketch->strokes.first; stk; id++, stk = stk->next)
2828 sk_drawStroke(stk, id, NULL, -1, -1);
2835 float selected_rgb[3] = {1, 0, 0};
2836 float unselected_rgb[3] = {1, 0.5, 0};
2838 for (stk = sketch->strokes.first; stk; stk = stk->next)
2843 if (sk_hasOverdraw(sketch, stk))
2845 sk_adjustIndexes(sketch, &start, &end);
2848 sk_drawStroke(stk, -1, (stk->selected==1?selected_rgb:unselected_rgb), start, end);
2850 if (stk->selected == 1)
2852 sk_drawStrokeSubdivision(ts, stk);
2856 if (sketch->active_stroke != NULL)
2858 SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
2860 if (ts->bone_sketching & BONE_SKETCHING_QUICK)
2862 sk_drawStrokeSubdivision(ts, sketch->active_stroke);
2867 GLUquadric *quad = gluNewQuadric();
2868 gluQuadricNormals(quad, GLU_SMOOTH);
2873 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2875 switch (sketch->next_point.mode)
2885 sk_drawPoint(quad, &sketch->next_point, 0.1);
2887 glColor4f(selected_rgb[0], selected_rgb[1], selected_rgb[2], 0.3);
2889 sk_drawEdge(quad, last, &sketch->next_point, 0.1);
2891 glDisable(GL_BLEND);
2895 gluDeleteQuadric(quad);
2901 if (sketch->depth_peels.first != NULL)
2903 float colors[8][3] = {
2914 GLUquadric *quad = gluNewQuadric();
2915 gluQuadricNormals(quad, GLU_SMOOTH);
2917 for (p = sketch->depth_peels.first; p; p = p->next)
2919 int index = (int)(p->ob);
2920 index = (index >> 5) & 7;
2922 glColor3fv(colors[index]);
2924 glTranslatef(p->p[0], p->p[1], p->p[2]);
2925 gluSphere(quad, 0.02, 8, 8);
2929 gluDeleteQuadric(quad);
2933 glDisable(GL_DEPTH_TEST);
2935 /* only draw gesture in active area */
2936 if (sketch->gesture != NULL /*&& area_is_active_area(G.vd->area)*/)
2938 float gesture_rgb[3] = {0, 0.5, 1};
2939 sk_drawStroke(sketch->gesture, -1, gesture_rgb, -1, -1);
2943 int sk_finish_stroke(bContext *C, SK_Sketch *sketch)
2945 ToolSettings *ts = CTX_data_tool_settings(C);
2947 if (sketch->active_stroke != NULL)
2949 SK_Stroke *stk = sketch->active_stroke;
2951 sk_endStroke(C, sketch);
2953 if (ts->bone_sketching & BONE_SKETCHING_QUICK)
2955 if (ts->bone_sketching_convert == SK_CONVERT_RETARGET)
2957 sk_retargetStroke(C, stk);
2961 sk_convertStroke(C, stk);
2964 // BIF_undo_push("Convert Sketch");
2965 sk_removeStroke(sketch, stk);
2967 // allqueue(REDRAWBUTSEDIT, 0);
2971 // allqueue(REDRAWVIEW3D, 0);
2978 void sk_start_draw_stroke(SK_Sketch *sketch)
2980 if (sketch->active_stroke == NULL)
2982 sk_startStroke(sketch);
2983 sk_selectAllSketch(sketch, -1);
2985 sketch->active_stroke->selected = 1;
2989 void sk_start_draw_gesture(SK_Sketch *sketch)
2991 sketch->gesture = sk_createStroke();
2994 int sk_draw_stroke(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
2996 if (sk_stroke_filtermval(dd))
2998 sk_addStrokePoint(C, sketch, stk, dd, snap);
2999 sk_updateDrawData(dd);
3000 sk_updateNextPoint(sketch, stk);
3007 static int ValidSketchViewContext(ViewContext *vc)
3009 Object *obedit = vc->obedit;
3010 Scene *scene= vc->scene;
3013 obedit->type == OB_ARMATURE &&
3014 scene->toolsettings->bone_sketching & BONE_SKETCHING)
3024 int BDR_drawSketchNames(ViewContext *vc)
3026 if (ValidSketchViewContext(vc))
3028 SK_Sketch *sketch = viewcontextSketch(vc, 0);
3031 sk_drawSketch(vc->scene, vc->v3d, sketch, 1);
3039 void BDR_drawSketch(const bContext *C)
3041 if (ED_operator_sketch_mode(C))
3043 SK_Sketch *sketch = contextSketch(C, 0);
3046 sk_drawSketch(CTX_data_scene(C), CTX_wm_view3d(C), sketch, 0);
3051 static int sketch_delete(bContext *C, wmOperator *op, wmEvent *event)
3053 SK_Sketch *sketch = contextSketch(C, 0);
3056 sk_deleteSelectedStrokes(sketch);
3057 // allqueue(REDRAWVIEW3D, 0);
3059 return OPERATOR_FINISHED;
3062 void BIF_sk_selectStroke(bContext *C, short mval[2], short extend)
3064 SK_Sketch *sketch = contextSketch(C, 0);
3067 sk_selectStroke(C, sketch, mval, extend);
3071 void BIF_convertSketch(bContext *C)
3073 if (ED_operator_sketch_full_mode(C))
3075 SK_Sketch *sketch = contextSketch(C, 0);
3078 sk_convert(C, sketch);
3079 // BIF_undo_push("Convert Sketch");
3080 // allqueue(REDRAWVIEW3D, 0);
3081 // allqueue(REDRAWBUTSEDIT, 0);
3086 void BIF_deleteSketch(bContext *C)
3088 if (ED_operator_sketch_full_mode(C))
3090 SK_Sketch *sketch = contextSketch(C, 0);
3093 sk_deleteSelectedStrokes(sketch);
3094 // BIF_undo_push("Convert Sketch");
3095 // allqueue(REDRAWVIEW3D, 0);
3101 void BIF_selectAllSketch(bContext *C, int mode)
3103 if (BIF_validSketchMode(C))
3105 SK_Sketch *sketch = contextSketch(C, 0);
3108 sk_selectAllSketch(sketch, mode);
3110 // allqueue(REDRAWVIEW3D, 0);
3116 void ED_freeSketch(SK_Sketch *sketch)
3118 sk_freeSketch(sketch);
3121 SK_Sketch* ED_createSketch()
3123 return sk_createSketch();
3126 SK_Sketch* contextSketch(const bContext *C, int create)
3128 Object *obedit = CTX_data_edit_object(C);
3129 SK_Sketch *sketch = NULL;
3131 if (obedit && obedit->type == OB_ARMATURE)
3133 bArmature *arm = obedit->data;
3135 if (arm->sketch == NULL && create)
3137 arm->sketch = sk_createSketch();
3139 sketch = arm->sketch;
3145 SK_Sketch* viewcontextSketch(ViewContext *vc, int create)
3147 Object *obedit = vc->obedit;
3148 SK_Sketch *sketch = NULL;
3150 if (obedit && obedit->type == OB_ARMATURE)
3152 bArmature *arm = obedit->data;
3154 if (arm->sketch == NULL && create)
3156 arm->sketch = sk_createSketch();
3158 sketch = arm->sketch;