diff options
Diffstat (limited to 'source/blender/src/editarmature_sketch.c')
-rw-r--r-- | source/blender/src/editarmature_sketch.c | 3090 |
1 files changed, 0 insertions, 3090 deletions
diff --git a/source/blender/src/editarmature_sketch.c b/source/blender/src/editarmature_sketch.c deleted file mode 100644 index dbf53bedbf9..00000000000 --- a/source/blender/src/editarmature_sketch.c +++ /dev/null @@ -1,3090 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include <string.h> -#include <math.h> - -#include "MEM_guardedalloc.h" - -#include "DNA_listBase.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_armature_types.h" -#include "DNA_userdef_types.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_graph.h" -#include "BLI_ghash.h" - -#include "BKE_utildefines.h" -#include "BKE_global.h" -#include "BKE_DerivedMesh.h" -#include "BKE_object.h" -#include "BKE_anim.h" - -#include "BSE_view.h" - -#include "BIF_gl.h" -#include "BIF_resources.h" -#include "BIF_screen.h" -#include "BIF_space.h" -#include "BIF_mywindow.h" -#include "BIF_editarmature.h" -#include "BIF_sketch.h" -#include "BIF_retarget.h" -#include "BIF_generate.h" -#include "BIF_interface.h" - -#include "BIF_transform.h" - -#include "blendef.h" -#include "mydevice.h" -#include "reeb.h" - -typedef enum SK_PType -{ - PT_CONTINUOUS, - PT_EXACT, -} SK_PType; - -typedef enum SK_PMode -{ - PT_SNAP, - PT_PROJECT, -} SK_PMode; - -typedef struct SK_Point -{ - float p[3]; - float no[3]; - SK_PType type; - SK_PMode mode; -} SK_Point; - -typedef struct SK_Stroke -{ - struct SK_Stroke *next, *prev; - - SK_Point *points; - int nb_points; - int buf_size; - int selected; -} SK_Stroke; - -#define SK_OVERDRAW_LIMIT 5 - -typedef struct SK_Overdraw -{ - SK_Stroke *target; - int start, end; - int count; -} SK_Overdraw; - -#define SK_Stroke_BUFFER_INIT_SIZE 20 - -typedef struct SK_DrawData -{ - short mval[2]; - short previous_mval[2]; - SK_PType type; -} SK_DrawData; - -typedef struct SK_Intersection -{ - struct SK_Intersection *next, *prev; - SK_Stroke *stroke; - int before; - int after; - int gesture_index; - float p[3]; - float lambda; /* used for sorting intersection points */ -} SK_Intersection; - -typedef struct SK_Sketch -{ - ListBase strokes; - SK_Stroke *active_stroke; - SK_Stroke *gesture; - SK_Point next_point; - SK_Overdraw over; -} SK_Sketch; - -typedef struct SK_StrokeIterator { - HeadFct head; - TailFct tail; - PeekFct peek; - NextFct next; - NextNFct nextN; - PreviousFct previous; - StoppedFct stopped; - - float *p, *no; - - int length; - int index; - /*********************************/ - SK_Stroke *stroke; - int start; - int end; - int stride; -} SK_StrokeIterator; - -typedef struct SK_Gesture { - SK_Stroke *stk; - SK_Stroke *segments; - - ListBase intersections; - ListBase self_intersections; - - int nb_self_intersections; - int nb_intersections; - int nb_segments; -} SK_Gesture; - -typedef int (*GestureDetectFct)(SK_Gesture*, SK_Sketch *); -typedef void (*GestureApplyFct)(SK_Gesture*, SK_Sketch *); - -typedef struct SK_GestureAction { - char name[64]; - GestureDetectFct detect; - GestureApplyFct apply; -} SK_GestureAction; - -SK_Sketch *GLOBAL_sketch = NULL; -SK_Point boneSnap; -int LAST_SNAP_POINT_VALID = 0; -float LAST_SNAP_POINT[3]; - -/******************** PROTOTYPES ******************************/ - -void initStrokeIterator(BArcIterator *iter, SK_Stroke *stk, int start, int end); - -void sk_deleteSelectedStrokes(SK_Sketch *sketch); - -void sk_freeStroke(SK_Stroke *stk); -void sk_freeSketch(SK_Sketch *sketch); - -SK_Point *sk_lastStrokePoint(SK_Stroke *stk); - -int sk_detectCutGesture(SK_Gesture *gest, SK_Sketch *sketch); -void sk_applyCutGesture(SK_Gesture *gest, SK_Sketch *sketch); -int sk_detectTrimGesture(SK_Gesture *gest, SK_Sketch *sketch); -void sk_applyTrimGesture(SK_Gesture *gest, SK_Sketch *sketch); -int sk_detectCommandGesture(SK_Gesture *gest, SK_Sketch *sketch); -void sk_applyCommandGesture(SK_Gesture *gest, SK_Sketch *sketch); -int sk_detectDeleteGesture(SK_Gesture *gest, SK_Sketch *sketch); -void sk_applyDeleteGesture(SK_Gesture *gest, SK_Sketch *sketch); -int sk_detectMergeGesture(SK_Gesture *gest, SK_Sketch *sketch); -void sk_applyMergeGesture(SK_Gesture *gest, SK_Sketch *sketch); -int sk_detectReverseGesture(SK_Gesture *gest, SK_Sketch *sketch); -void sk_applyReverseGesture(SK_Gesture *gest, SK_Sketch *sketch); -int sk_detectConvertGesture(SK_Gesture *gest, SK_Sketch *sketch); -void sk_applyConvertGesture(SK_Gesture *gest, SK_Sketch *sketch); - - -void sk_resetOverdraw(SK_Sketch *sketch); -int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk); - -/******************** GESTURE ACTIONS ******************************/ - -SK_GestureAction GESTURE_ACTIONS[] = - { - {"Cut", sk_detectCutGesture, sk_applyCutGesture}, - {"Trim", sk_detectTrimGesture, sk_applyTrimGesture}, - {"Command", sk_detectCommandGesture, sk_applyCommandGesture}, - {"Delete", sk_detectDeleteGesture, sk_applyDeleteGesture}, - {"Merge", sk_detectMergeGesture, sk_applyMergeGesture}, - {"Reverse", sk_detectReverseGesture, sk_applyReverseGesture}, - {"Convert", sk_detectConvertGesture, sk_applyConvertGesture}, - {"", NULL, NULL} - }; - -/******************** TEMPLATES UTILS *************************/ - -char *TEMPLATES_MENU = NULL; -int TEMPLATES_CURRENT = 0; -GHash *TEMPLATES_HASH = NULL; -RigGraph *TEMPLATE_RIGG = NULL; - -void BIF_makeListTemplates() -{ - Base *base; - int index = 0; - - if (TEMPLATES_HASH != NULL) - { - BLI_ghash_free(TEMPLATES_HASH, NULL, NULL); - } - - TEMPLATES_HASH = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp); - TEMPLATES_CURRENT = 0; - - for ( base = FIRSTBASE; base; base = base->next ) - { - Object *ob = base->object; - - if (ob != G.obedit && ob->type == OB_ARMATURE) - { - index++; - BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob); - - if (ob == G.scene->toolsettings->skgen_template) - { - TEMPLATES_CURRENT = index; - } - } - } -} - -char *BIF_listTemplates() -{ - GHashIterator ghi; - char menu_header[] = "Template%t|None%x0|"; - char *p; - - if (TEMPLATES_MENU != NULL) - { - MEM_freeN(TEMPLATES_MENU); - } - - TEMPLATES_MENU = MEM_callocN(sizeof(char) * (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30), "skeleton template menu"); - - p = TEMPLATES_MENU; - - p += sprintf(TEMPLATES_MENU, "%s", menu_header); - - BLI_ghashIterator_init(&ghi, TEMPLATES_HASH); - - while (!BLI_ghashIterator_isDone(&ghi)) - { - Object *ob = BLI_ghashIterator_getValue(&ghi); - int key = (int)BLI_ghashIterator_getKey(&ghi); - - p += sprintf(p, "|%s%%x%i", ob->id.name+2, key); - - BLI_ghashIterator_step(&ghi); - } - - return TEMPLATES_MENU; -} - -int BIF_currentTemplate() -{ - if (TEMPLATES_CURRENT == 0 && G.scene->toolsettings->skgen_template != NULL) - { - GHashIterator ghi; - BLI_ghashIterator_init(&ghi, TEMPLATES_HASH); - - while (!BLI_ghashIterator_isDone(&ghi)) - { - Object *ob = BLI_ghashIterator_getValue(&ghi); - int key = (int)BLI_ghashIterator_getKey(&ghi); - - if (ob == G.scene->toolsettings->skgen_template) - { - TEMPLATES_CURRENT = key; - break; - } - - BLI_ghashIterator_step(&ghi); - } - } - - return TEMPLATES_CURRENT; -} - -RigGraph* sk_makeTemplateGraph(Object *ob) -{ - if (ob == G.obedit) - { - return NULL; - } - - if (ob != NULL) - { - if (TEMPLATE_RIGG && TEMPLATE_RIGG->ob != ob) - { - RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG); - TEMPLATE_RIGG = NULL; - } - - if (TEMPLATE_RIGG == NULL) - { - bArmature *arm; - - arm = ob->data; - - TEMPLATE_RIGG = RIG_graphFromArmature(ob, arm); - } - } - - return TEMPLATE_RIGG; -} - -int BIF_nbJointsTemplate() -{ - RigGraph *rg = sk_makeTemplateGraph(G.scene->toolsettings->skgen_template); - - if (rg) - { - return RIG_nbJoints(rg); - } - else - { - return -1; - } -} - -char * BIF_nameBoneTemplate() -{ - SK_Sketch *stk = GLOBAL_sketch; - RigGraph *rg; - int index = 0; - - if (stk && stk->active_stroke != NULL) - { - index = stk->active_stroke->nb_points; - } - - rg = sk_makeTemplateGraph(G.scene->toolsettings->skgen_template); - - if (rg == NULL) - { - return ""; - } - - return RIG_nameBone(rg, 0, index); -} - -void BIF_freeTemplates() -{ - if (TEMPLATES_MENU != NULL) - { - MEM_freeN(TEMPLATES_MENU); - TEMPLATES_MENU = NULL; - } - - if (TEMPLATES_HASH != NULL) - { - BLI_ghash_free(TEMPLATES_HASH, NULL, NULL); - TEMPLATES_HASH = NULL; - } - - if (TEMPLATE_RIGG != NULL) - { - RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG); - TEMPLATE_RIGG = NULL; - } -} - -void BIF_setTemplate(int index) -{ - if (index > 0) - { - G.scene->toolsettings->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index)); - } - else - { - G.scene->toolsettings->skgen_template = NULL; - - if (TEMPLATE_RIGG != NULL) - { - RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG); - } - TEMPLATE_RIGG = NULL; - } -} - -/*********************** CONVERSION ***************************/ - -void sk_autoname(ReebArc *arc) -{ - if (G.scene->toolsettings->skgen_retarget_options & SK_RETARGET_AUTONAME) - { - if (arc == NULL) - { - char *num = G.scene->toolsettings->skgen_num_string; - int i = atoi(num); - i++; - BLI_snprintf(num, 8, "%i", i); - } - else - { - char *side = G.scene->toolsettings->skgen_side_string; - int valid = 0; - int caps = 0; - - if (BLI_streq(side, "")) - { - valid = 1; - } - else if (BLI_streq(side, "R") || BLI_streq(side, "L")) - { - valid = 1; - caps = 1; - } - else if (BLI_streq(side, "r") || BLI_streq(side, "l")) - { - valid = 1; - caps = 0; - } - - if (valid) - { - if (arc->head->p[0] < 0) - { - BLI_snprintf(side, 8, caps?"R":"r"); - } - else - { - BLI_snprintf(side, 8, caps?"L":"l"); - } - } - } - } -} - -ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3]) -{ - ReebNode *node; - - node = MEM_callocN(sizeof(ReebNode), "reeb node"); - VECCOPY(node->p, pt->p); - Mat4MulVecfl(imat, node->p); - - VECCOPY(node->no, pt->no); - Mat3MulVecfl(tmat, node->no); - - return node; -} - -ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3]) -{ - ReebArc *arc; - int i; - - arc = MEM_callocN(sizeof(ReebArc), "reeb arc"); - arc->head = sk_pointToNode(stk->points, imat, tmat); - arc->tail = sk_pointToNode(sk_lastStrokePoint(stk), imat, tmat); - - arc->bcount = stk->nb_points - 2; /* first and last are nodes, don't count */ - arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "Buckets"); - - for (i = 0; i < arc->bcount; i++) - { - VECCOPY(arc->buckets[i].p, stk->points[i + 1].p); - Mat4MulVecfl(imat, arc->buckets[i].p); - - VECCOPY(arc->buckets[i].no, stk->points[i + 1].no); - Mat3MulVecfl(tmat, arc->buckets[i].no); - } - - return arc; -} - -void sk_retargetStroke(SK_Stroke *stk) -{ - float imat[4][4]; - float tmat[3][3]; - ReebArc *arc; - RigGraph *rg; - - Mat4Invert(imat, G.obedit->obmat); - - Mat3CpyMat4(tmat, G.obedit->obmat); - Mat3Transp(tmat); - - arc = sk_strokeToArc(stk, imat, tmat); - - sk_autoname(arc); - - rg = sk_makeTemplateGraph(G.scene->toolsettings->skgen_template); - - BIF_retargetArc(arc, rg); - - sk_autoname(NULL); - - MEM_freeN(arc->head); - MEM_freeN(arc->tail); - REEB_freeArc((BArc*)arc); -} - -/**************************************************************/ - -void sk_freeSketch(SK_Sketch *sketch) -{ - SK_Stroke *stk, *next; - - for (stk = sketch->strokes.first; stk; stk = next) - { - next = stk->next; - - sk_freeStroke(stk); - } - - MEM_freeN(sketch); -} - -SK_Sketch* sk_createSketch() -{ - SK_Sketch *sketch; - - sketch = MEM_callocN(sizeof(SK_Sketch), "SK_Sketch"); - - sketch->active_stroke = NULL; - sketch->gesture = NULL; - - sketch->strokes.first = NULL; - sketch->strokes.last = NULL; - - return sketch; -} - -void sk_initPoint(SK_Point *pt) -{ - VECCOPY(pt->no, G.vd->viewinv[2]); - Normalize(pt->no); - /* more init code here */ -} - -void sk_copyPoint(SK_Point *dst, SK_Point *src) -{ - memcpy(dst, src, sizeof(SK_Point)); -} - -void sk_allocStrokeBuffer(SK_Stroke *stk) -{ - stk->points = MEM_callocN(sizeof(SK_Point) * stk->buf_size, "SK_Point buffer"); -} - -void sk_freeStroke(SK_Stroke *stk) -{ - MEM_freeN(stk->points); - MEM_freeN(stk); -} - -SK_Stroke* sk_createStroke() -{ - SK_Stroke *stk; - - stk = MEM_callocN(sizeof(SK_Stroke), "SK_Stroke"); - - stk->selected = 0; - stk->nb_points = 0; - stk->buf_size = SK_Stroke_BUFFER_INIT_SIZE; - - sk_allocStrokeBuffer(stk); - - return stk; -} - -void sk_shrinkStrokeBuffer(SK_Stroke *stk) -{ - if (stk->nb_points < stk->buf_size) - { - SK_Point *old_points = stk->points; - - stk->buf_size = stk->nb_points; - - sk_allocStrokeBuffer(stk); - - memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points); - - MEM_freeN(old_points); - } -} - -void sk_growStrokeBuffer(SK_Stroke *stk) -{ - if (stk->nb_points == stk->buf_size) - { - SK_Point *old_points = stk->points; - - stk->buf_size *= 2; - - sk_allocStrokeBuffer(stk); - - memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points); - - MEM_freeN(old_points); - } -} - -void sk_growStrokeBufferN(SK_Stroke *stk, int n) -{ - if (stk->nb_points + n > stk->buf_size) - { - SK_Point *old_points = stk->points; - - while (stk->nb_points + n > stk->buf_size) - { - stk->buf_size *= 2; - } - - sk_allocStrokeBuffer(stk); - - memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points); - - MEM_freeN(old_points); - } -} - - -void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n) -{ - memcpy(stk->points + n, pt, sizeof(SK_Point)); -} - -void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n) -{ - int size = stk->nb_points - n; - - sk_growStrokeBuffer(stk); - - memmove(stk->points + n + 1, stk->points + n, size * sizeof(SK_Point)); - - memcpy(stk->points + n, pt, sizeof(SK_Point)); - - stk->nb_points++; -} - -void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt) -{ - sk_growStrokeBuffer(stk); - - memcpy(stk->points + stk->nb_points, pt, sizeof(SK_Point)); - - stk->nb_points++; -} - -void sk_insertStrokePoints(SK_Stroke *stk, SK_Point *pts, int len, int start, int end) -{ - int size = end - start + 1; - - sk_growStrokeBufferN(stk, len - size); - - if (len != size) - { - int tail_size = stk->nb_points - end + 1; - - memmove(stk->points + start + len, stk->points + end + 1, tail_size * sizeof(SK_Point)); - } - - memcpy(stk->points + start, pts, len * sizeof(SK_Point)); - - stk->nb_points += len - size; -} - -void sk_trimStroke(SK_Stroke *stk, int start, int end) -{ - int size = end - start + 1; - - if (start > 0) - { - memmove(stk->points, stk->points + start, size * sizeof(SK_Point)); - } - - stk->nb_points = size; -} - -void sk_straightenStroke(SK_Stroke *stk, int start, int end, float p_start[3], float p_end[3]) -{ - SK_Point pt1, pt2; - SK_Point *prev, *next; - float delta_p[3]; - int i, total; - - total = end - start; - - VecSubf(delta_p, p_end, p_start); - - prev = stk->points + start; - next = stk->points + end; - - VECCOPY(pt1.p, p_start); - VECCOPY(pt1.no, prev->no); - pt1.mode = prev->mode; - pt1.type = prev->type; - - VECCOPY(pt2.p, p_end); - VECCOPY(pt2.no, next->no); - pt2.mode = next->mode; - pt2.type = next->type; - - sk_insertStrokePoint(stk, &pt1, start + 1); /* insert after start */ - sk_insertStrokePoint(stk, &pt2, end + 1); /* insert before end (since end was pushed back already) */ - - for (i = 1; i < total; i++) - { - float delta = (float)i / (float)total; - float *p = stk->points[start + 1 + i].p; - - VECCOPY(p, delta_p); - VecMulf(p, delta); - VecAddf(p, p, p_start); - } -} - -void sk_polygonizeStroke(SK_Stroke *stk, int start, int end) -{ - int offset; - int i; - - /* find first exact points outside of range */ - for (;start > 0; start--) - { - if (stk->points[start].type == PT_EXACT) - { - break; - } - } - - for (;end < stk->nb_points - 1; end++) - { - if (stk->points[end].type == PT_EXACT) - { - break; - } - } - - offset = start + 1; - - for (i = start + 1; i < end; i++) - { - if (stk->points[i].type == PT_EXACT) - { - if (offset != i) - { - memcpy(stk->points + offset, stk->points + i, sizeof(SK_Point)); - } - - offset++; - } - } - - /* some points were removes, move end of array */ - if (offset < end) - { - int size = stk->nb_points - end; - memmove(stk->points + offset, stk->points + end, size * sizeof(SK_Point)); - stk->nb_points = offset + size; - } -} - -void sk_flattenStroke(SK_Stroke *stk, int start, int end) -{ - float normal[3], distance[3]; - float limit; - int i, total; - - total = end - start + 1; - - VECCOPY(normal, stk->points[start].no); - - VecSubf(distance, stk->points[end].p, stk->points[start].p); - Projf(normal, distance, normal); - limit = Normalize(normal); - - for (i = 1; i < total - 1; i++) - { - float d = limit * i / total; - float offset[3]; - float *p = stk->points[start + i].p; - - VecSubf(distance, p, stk->points[start].p); - Projf(distance, distance, normal); - - VECCOPY(offset, normal); - VecMulf(offset, d); - - VecSubf(p, p, distance); - VecAddf(p, p, offset); - } -} - -void sk_removeStroke(SK_Sketch *sketch, SK_Stroke *stk) -{ - if (sketch->active_stroke == stk) - { - sketch->active_stroke = NULL; - } - - BLI_remlink(&sketch->strokes, stk); - sk_freeStroke(stk); -} - -void sk_reverseStroke(SK_Stroke *stk) -{ - SK_Point *old_points = stk->points; - int i = 0; - - sk_allocStrokeBuffer(stk); - - for (i = 0; i < stk->nb_points; i++) - { - sk_copyPoint(stk->points + i, old_points + stk->nb_points - 1 - i); - } - - MEM_freeN(old_points); -} - - -void sk_cancelStroke(SK_Sketch *sketch) -{ - if (sketch->active_stroke != NULL) - { - sk_resetOverdraw(sketch); - sk_removeStroke(sketch, sketch->active_stroke); - } -} - -/* Apply reverse Chaikin filter to simplify the polyline - * */ -void sk_filterStroke(SK_Stroke *stk, int start, int end) -{ - SK_Point *old_points = stk->points; - int nb_points = stk->nb_points; - int i, j; - - return; - - if (start == -1) - { - start = 0; - end = stk->nb_points - 1; - } - - sk_allocStrokeBuffer(stk); - stk->nb_points = 0; - - /* adding points before range */ - for (i = 0; i < start; i++) - { - sk_appendStrokePoint(stk, old_points + i); - } - - for (i = start, j = start; i <= end; i++) - { - if (i - j == 3) - { - SK_Point pt; - float vec[3]; - - sk_copyPoint(&pt, &old_points[j+1]); - - pt.p[0] = 0; - pt.p[1] = 0; - pt.p[2] = 0; - - VECCOPY(vec, old_points[j].p); - VecMulf(vec, -0.25); - VecAddf(pt.p, pt.p, vec); - - VECCOPY(vec, old_points[j+1].p); - VecMulf(vec, 0.75); - VecAddf(pt.p, pt.p, vec); - - VECCOPY(vec, old_points[j+2].p); - VecMulf(vec, 0.75); - VecAddf(pt.p, pt.p, vec); - - VECCOPY(vec, old_points[j+3].p); - VecMulf(vec, -0.25); - VecAddf(pt.p, pt.p, vec); - - sk_appendStrokePoint(stk, &pt); - - j += 2; - } - - /* this might be uneeded when filtering last continuous stroke */ - if (old_points[i].type == PT_EXACT) - { - sk_appendStrokePoint(stk, old_points + i); - j = i; - } - } - - /* adding points after range */ - for (i = end + 1; i < nb_points; i++) - { - sk_appendStrokePoint(stk, old_points + i); - } - - MEM_freeN(old_points); - - sk_shrinkStrokeBuffer(stk); -} - -void sk_filterLastContinuousStroke(SK_Stroke *stk) -{ - int start, end; - - end = stk->nb_points -1; - - for (start = end - 1; start > 0 && stk->points[start].type == PT_CONTINUOUS; start--) - { - /* nothing to do here*/ - } - - if (end - start > 1) - { - sk_filterStroke(stk, start, end); - } -} - -SK_Point *sk_lastStrokePoint(SK_Stroke *stk) -{ - SK_Point *pt = NULL; - - if (stk->nb_points > 0) - { - pt = stk->points + (stk->nb_points - 1); - } - - return pt; -} - -void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int end) -{ - float rgb[3]; - int i; - - if (id != -1) - { - glLoadName(id); - - glBegin(GL_LINE_STRIP); - - for (i = 0; i < stk->nb_points; i++) - { - glVertex3fv(stk->points[i].p); - } - - glEnd(); - - } - else - { - float d_rgb[3] = {1, 1, 1}; - - VECCOPY(rgb, color); - VecSubf(d_rgb, d_rgb, rgb); - VecMulf(d_rgb, 1.0f / (float)stk->nb_points); - - glBegin(GL_LINE_STRIP); - - for (i = 0; i < stk->nb_points; i++) - { - if (i >= start && i <= end) - { - glColor3f(0.3, 0.3, 0.3); - } - else - { - glColor3fv(rgb); - } - glVertex3fv(stk->points[i].p); - VecAddf(rgb, rgb, d_rgb); - } - - glEnd(); - -#if 0 - glColor3f(0, 0, 1); - glBegin(GL_LINES); - - for (i = 0; i < stk->nb_points; i++) - { - float *p = stk->points[i].p; - float *no = stk->points[i].no; - glVertex3fv(p); - glVertex3f(p[0] + no[0], p[1] + no[1], p[2] + no[2]); - } - - glEnd(); -#endif - - glColor3f(0, 0, 0); - glBegin(GL_POINTS); - - for (i = 0; i < stk->nb_points; i++) - { - if (stk->points[i].type == PT_EXACT) - { - glVertex3fv(stk->points[i].p); - } - } - - glEnd(); - } - -// glColor3f(1, 1, 1); -// glBegin(GL_POINTS); -// -// for (i = 0; i < stk->nb_points; i++) -// { -// if (stk->points[i].type == PT_CONTINUOUS) -// { -// glVertex3fv(stk->points[i].p); -// } -// } -// -// glEnd(); -} - -void drawSubdividedStrokeBy(BArcIterator *iter, NextSubdivisionFunc next_subdividion) -{ - float head[3], tail[3]; - int bone_start = 0; - int end = iter->length; - int index; - - iter->head(iter); - VECCOPY(head, iter->p); - - glColor3f(0, 1, 0); - glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE) * 2); - glBegin(GL_POINTS); - - index = next_subdividion(iter, bone_start, end, head, tail); - while (index != -1) - { - glVertex3fv(tail); - - VECCOPY(head, tail); - bone_start = index; // start next bone from current index - - index = next_subdividion(iter, bone_start, end, head, tail); - } - - glEnd(); - glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE)); -} - -void sk_drawStrokeSubdivision(SK_Stroke *stk) -{ - int head_index = -1; - int i; - - if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET) - { - return; - } - - - for (i = 0; i < stk->nb_points; i++) - { - SK_Point *pt = stk->points + i; - - if (pt->type == PT_EXACT || i == stk->nb_points - 1) /* stop on exact or on last point */ - { - if (head_index == -1) - { - head_index = i; - } - else - { - if (i - head_index > 1) - { - SK_StrokeIterator sk_iter; - BArcIterator *iter = (BArcIterator*)&sk_iter; - - initStrokeIterator(iter, stk, head_index, i); - - if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE) - { - drawSubdividedStrokeBy(iter, nextAdaptativeSubdivision); - } - else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH) - { - drawSubdividedStrokeBy(iter, nextLengthSubdivision); - } - else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED) - { - drawSubdividedStrokeBy(iter, nextFixedSubdivision); - } - - } - - head_index = i; - } - } - } -} - -SK_Point *sk_snapPointStroke(SK_Stroke *stk, short mval[2], int *dist, int *index, int all_pts) -{ - SK_Point *pt = NULL; - int i; - - for (i = 0; i < stk->nb_points; i++) - { - if (all_pts || stk->points[i].type == PT_EXACT) - { - short pval[2]; - int pdist; - - project_short_noclip(stk->points[i].p, pval); - - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - - if (pdist < *dist) - { - *dist = pdist; - pt = stk->points + i; - - if (index != NULL) - { - *index = i; - } - } - } - } - - return pt; -} - -SK_Point *sk_snapPointArmature(Object *ob, ListBase *ebones, short mval[2], int *dist) -{ - SK_Point *pt = NULL; - EditBone *bone; - - for (bone = ebones->first; bone; bone = bone->next) - { - float vec[3]; - short pval[2]; - int pdist; - - if ((bone->flag & BONE_CONNECTED) == 0) - { - VECCOPY(vec, bone->head); - Mat4MulVecfl(ob->obmat, vec); - project_short_noclip(vec, pval); - - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - - if (pdist < *dist) - { - *dist = pdist; - pt = &boneSnap; - VECCOPY(pt->p, vec); - pt->type = PT_EXACT; - } - } - - - VECCOPY(vec, bone->tail); - Mat4MulVecfl(ob->obmat, vec); - project_short_noclip(vec, pval); - - pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); - - if (pdist < *dist) - { - *dist = pdist; - pt = &boneSnap; - VECCOPY(pt->p, vec); - pt->type = PT_EXACT; - } - } - - return pt; -} - -void sk_resetOverdraw(SK_Sketch *sketch) -{ - sketch->over.target = NULL; - sketch->over.start = -1; - sketch->over.end = -1; - sketch->over.count = 0; -} - -int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk) -{ - return sketch->over.target && - sketch->over.count >= SK_OVERDRAW_LIMIT && - (sketch->over.target == stk || stk == NULL) && - (sketch->over.start != -1 || sketch->over.end != -1); -} - -void sk_updateOverdraw(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd) -{ - if (sketch->over.target == NULL) - { - SK_Stroke *target; - int closest_index = -1; - int dist = SNAP_MIN_DISTANCE * 2; - - /* If snapping, don't start overdraw */ - if (sk_lastStrokePoint(stk)->mode == PT_SNAP) - { - return; - } - - for (target = sketch->strokes.first; target; target = target->next) - { - if (target != stk) - { - int index; - - SK_Point *spt = sk_snapPointStroke(target, dd->mval, &dist, &index, 1); - - if (spt != NULL) - { - sketch->over.target = target; - closest_index = index; - } - } - } - - if (sketch->over.target != NULL) - { - if (closest_index > -1) - { - if (sk_lastStrokePoint(stk)->type == PT_EXACT) - { - sketch->over.count = SK_OVERDRAW_LIMIT; - } - else - { - sketch->over.count++; - } - } - - if (stk->nb_points == 1) - { - sketch->over.start = closest_index; - } - else - { - sketch->over.end = closest_index; - } - } - } - else if (sketch->over.target != NULL) - { - SK_Point *closest_pt = NULL; - int dist = SNAP_MIN_DISTANCE * 2; - int index; - - closest_pt = sk_snapPointStroke(sketch->over.target, dd->mval, &dist, &index, 1); - - if (closest_pt != NULL) - { - if (sk_lastStrokePoint(stk)->type == PT_EXACT) - { - sketch->over.count = SK_OVERDRAW_LIMIT; - } - else - { - sketch->over.count++; - } - - sketch->over.end = index; - } - else - { - sketch->over.end = -1; - } - } -} - -/* return 1 on reverse needed */ -int sk_adjustIndexes(SK_Sketch *sketch, int *start, int *end) -{ - int retval = 0; - - *start = sketch->over.start; - *end = sketch->over.end; - - if (*start == -1) - { - *start = 0; - } - - if (*end == -1) - { - *end = sketch->over.target->nb_points - 1; - } - - if (*end < *start) - { - int tmp = *start; - *start = *end; - *end = tmp; - retval = 1; - } - - return retval; -} - -void sk_endOverdraw(SK_Sketch *sketch) -{ - SK_Stroke *stk = sketch->active_stroke; - - if (sk_hasOverdraw(sketch, NULL)) - { - int start; - int end; - - if (sk_adjustIndexes(sketch, &start, &end)) - { - sk_reverseStroke(stk); - } - - if (stk->nb_points > 1) - { - stk->points->type = sketch->over.target->points[start].type; - sk_lastStrokePoint(stk)->type = sketch->over.target->points[end].type; - } - - sk_insertStrokePoints(sketch->over.target, stk->points, stk->nb_points, start, end); - - sk_removeStroke(sketch, stk); - - sk_resetOverdraw(sketch); - } -} - - -void sk_startStroke(SK_Sketch *sketch) -{ - SK_Stroke *stk = sk_createStroke(); - - BLI_addtail(&sketch->strokes, stk); - sketch->active_stroke = stk; - - sk_resetOverdraw(sketch); -} - -void sk_endStroke(SK_Sketch *sketch) -{ - sk_shrinkStrokeBuffer(sketch->active_stroke); - - if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST) - { - sk_endOverdraw(sketch); - } - - sketch->active_stroke = NULL; -} - -void sk_updateDrawData(SK_DrawData *dd) -{ - dd->type = PT_CONTINUOUS; - - dd->previous_mval[0] = dd->mval[0]; - dd->previous_mval[1] = dd->mval[1]; -} - -float sk_distanceDepth(float p1[3], float p2[3]) -{ - float vec[3]; - float distance; - - VecSubf(vec, p1, p2); - - Projf(vec, vec, G.vd->viewinv[2]); - - distance = VecLength(vec); - - if (Inpf(G.vd->viewinv[2], vec) > 0) - { - distance *= -1; - } - - return distance; -} - -void sk_interpolateDepth(SK_Stroke *stk, int start, int end, float length, float distance) -{ - float progress = 0; - int i; - - progress = VecLenf(stk->points[start].p, stk->points[start - 1].p); - - for (i = start; i <= end; i++) - { - float ray_start[3], ray_normal[3]; - float delta = VecLenf(stk->points[i].p, stk->points[i + 1].p); - short pval[2]; - - project_short_noclip(stk->points[i].p, pval); - viewray(pval, ray_start, ray_normal); - - VecMulf(ray_normal, distance * progress / length); - VecAddf(stk->points[i].p, stk->points[i].p, ray_normal); - - progress += delta ; - } -} - -void sk_projectDrawPoint(float vec[3], SK_Stroke *stk, SK_DrawData *dd) -{ - /* copied from grease pencil, need fixing */ - SK_Point *last = sk_lastStrokePoint(stk); - short cval[2]; - //float *fp = give_cursor(); - float fp[3] = {0, 0, 0}; - float dvec[3]; - - if (last != NULL) - { - VECCOPY(fp, last->p); - } - - initgrabz(fp[0], fp[1], fp[2]); - - /* method taken from editview.c - mouse_cursor() */ - project_short_noclip(fp, cval); - window_to_3d(dvec, cval[0] - dd->mval[0], cval[1] - dd->mval[1]); - VecSubf(vec, fp, dvec); -} - -int sk_getStrokeDrawPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd) -{ - pt->type = dd->type; - pt->mode = PT_PROJECT; - sk_projectDrawPoint(pt->p, stk, dd); - - return 1; -} - -int sk_addStrokeDrawPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd) -{ - SK_Point pt; - - sk_initPoint(&pt); - - sk_getStrokeDrawPoint(&pt, sketch, stk, dd); - - sk_appendStrokePoint(stk, &pt); - - return 1; -} - -int sk_getStrokeSnapPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd) -{ - int point_added = 0; - - if (G.scene->snap_mode == SCE_SNAP_MODE_VOLUME) - { - ListBase depth_peels; - DepthPeel *p1, *p2; - float *last_p = NULL; - float dist = FLT_MAX; - float p[3]; - - depth_peels.first = depth_peels.last = NULL; - - peelObjects(&depth_peels, dd->mval); - - if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS) - { - last_p = stk->points[stk->nb_points - 1].p; - } - else if (LAST_SNAP_POINT_VALID) - { - last_p = LAST_SNAP_POINT; - } - - - for (p1 = depth_peels.first; p1; p1 = p1->next) - { - if (p1->flag == 0) - { - float vec[3]; - float new_dist; - - p2 = NULL; - p1->flag = 1; - - /* if peeling objects, take the first and last from each object */ - if (G.scene->snap_flag & SCE_SNAP_PEEL_OBJECT) - { - DepthPeel *peel; - for (peel = p1->next; peel; peel = peel->next) - { - if (peel->ob == p1->ob) - { - peel->flag = 1; - p2 = peel; - } - } - } - /* otherwise, pair first with second and so on */ - else - { - for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next) - { - /* nothing to do here */ - } - } - - if (p2) - { - p2->flag = 1; - - VecAddf(vec, p1->p, p2->p); - VecMulf(vec, 0.5f); - } - else - { - VECCOPY(vec, p1->p); - } - - if (last_p == NULL) - { - VECCOPY(p, vec); - dist = 0; - break; - } - - new_dist = VecLenf(last_p, vec); - - if (new_dist < dist) - { - VECCOPY(p, vec); - dist = new_dist; - } - } - } - - if (dist != FLT_MAX) - { - pt->type = dd->type; - pt->mode = PT_SNAP; - VECCOPY(pt->p, p); - - point_added = 1; - } - - BLI_freelistN(&depth_peels); - } - else - { - SK_Stroke *snap_stk; - float vec[3]; - float no[3]; - int found = 0; - int dist = SNAP_MIN_DISTANCE; // Use a user defined value here - - /* snap to strokes */ - // if (G.scene->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */ - for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next) - { - SK_Point *spt = NULL; - if (snap_stk == stk) - { - spt = sk_snapPointStroke(snap_stk, dd->mval, &dist, NULL, 0); - } - else - { - spt = sk_snapPointStroke(snap_stk, dd->mval, &dist, NULL, 1); - } - - if (spt != NULL) - { - VECCOPY(pt->p, spt->p); - point_added = 1; - } - } - - /* try to snap to closer object */ - found = snapObjects(&dist, vec, no, NOT_SELECTED); - if (found == 1) - { - pt->type = dd->type; - pt->mode = PT_SNAP; - VECCOPY(pt->p, vec); - - point_added = 1; - } - } - - return point_added; -} - -int sk_addStrokeSnapPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd) -{ - int point_added; - SK_Point pt; - - sk_initPoint(&pt); - - point_added = sk_getStrokeSnapPoint(&pt, sketch, stk, dd); - - if (point_added) - { - float final_p[3]; - float length, distance; - int total; - int i; - - VECCOPY(final_p, pt.p); - - sk_projectDrawPoint(pt.p, stk, dd); - sk_appendStrokePoint(stk, &pt); - - /* update all previous point to give smooth Z progresion */ - total = 0; - length = 0; - for (i = stk->nb_points - 2; i > 0; i--) - { - length += VecLenf(stk->points[i].p, stk->points[i + 1].p); - total++; - if (stk->points[i].mode == PT_SNAP || stk->points[i].type == PT_EXACT) - { - break; - } - } - - if (total > 1) - { - distance = sk_distanceDepth(final_p, stk->points[i].p); - - sk_interpolateDepth(stk, i + 1, stk->nb_points - 2, length, distance); - } - - VECCOPY(stk->points[stk->nb_points - 1].p, final_p); - - point_added = 1; - } - - return point_added; -} - -void sk_addStrokePoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short qual) -{ - int point_added = 0; - - if (qual & LR_CTRLKEY) - { - point_added = sk_addStrokeSnapPoint(sketch, stk, dd); - } - - if (point_added == 0) - { - point_added = sk_addStrokeDrawPoint(sketch, stk, dd); - } - - if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST) - { - sk_updateOverdraw(sketch, stk, dd); - } -} - -void sk_getStrokePoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short qual) -{ - int point_added = 0; - - if (qual & LR_CTRLKEY) - { - point_added = sk_getStrokeSnapPoint(pt, sketch, stk, dd); - LAST_SNAP_POINT_VALID = 1; - VECCOPY(LAST_SNAP_POINT, pt->p); - } - else - { - LAST_SNAP_POINT_VALID = 0; - } - - if (point_added == 0) - { - point_added = sk_getStrokeDrawPoint(pt, sketch, stk, dd); - } -} - -void sk_endContinuousStroke(SK_Stroke *stk) -{ - stk->points[stk->nb_points - 1].type = PT_EXACT; -} - -void sk_updateNextPoint(SK_Sketch *sketch) -{ - if (sketch->active_stroke) - { - SK_Stroke *stk = sketch->active_stroke; - memcpy(&sketch->next_point, stk->points[stk->nb_points - 1].p, sizeof(SK_Point)); - } -} - -int sk_stroke_filtermval(SK_DrawData *dd) -{ - int retval = 0; - if (ABS(dd->mval[0] - dd->previous_mval[0]) + ABS(dd->mval[1] - dd->previous_mval[1]) > U.gp_manhattendist) - { - retval = 1; - } - - return retval; -} - -void sk_initDrawData(SK_DrawData *dd) -{ - getmouseco_areawin(dd->mval); - dd->previous_mval[0] = -1; - dd->previous_mval[1] = -1; - dd->type = PT_EXACT; -} -/********************************************/ - -static void* headPoint(void *arg); -static void* tailPoint(void *arg); -static void* nextPoint(void *arg); -static void* nextNPoint(void *arg, int n); -static void* peekPoint(void *arg, int n); -static void* previousPoint(void *arg); -static int iteratorStopped(void *arg); - -static void initIteratorFct(SK_StrokeIterator *iter) -{ - iter->head = headPoint; - iter->tail = tailPoint; - iter->peek = peekPoint; - iter->next = nextPoint; - iter->nextN = nextNPoint; - iter->previous = previousPoint; - iter->stopped = iteratorStopped; -} - -static SK_Point* setIteratorValues(SK_StrokeIterator *iter, int index) -{ - SK_Point *pt = NULL; - - if (index >= 0 && index < iter->length) - { - pt = &(iter->stroke->points[iter->start + (iter->stride * index)]); - iter->p = pt->p; - iter->no = pt->no; - } - else - { - iter->p = NULL; - iter->no = NULL; - } - - return pt; -} - -void initStrokeIterator(BArcIterator *arg, SK_Stroke *stk, int start, int end) -{ - SK_StrokeIterator *iter = (SK_StrokeIterator*)arg; - - initIteratorFct(iter); - iter->stroke = stk; - - if (start < end) - { - iter->start = start + 1; - iter->end = end - 1; - iter->stride = 1; - } - else - { - iter->start = start - 1; - iter->end = end + 1; - iter->stride = -1; - } - - iter->length = iter->stride * (iter->end - iter->start + 1); - - iter->index = -1; -} - - -static void* headPoint(void *arg) -{ - SK_StrokeIterator *iter = (SK_StrokeIterator*)arg; - SK_Point *result = NULL; - - result = &(iter->stroke->points[iter->start - iter->stride]); - iter->p = result->p; - iter->no = result->no; - - return result; -} - -static void* tailPoint(void *arg) -{ - SK_StrokeIterator *iter = (SK_StrokeIterator*)arg; - SK_Point *result = NULL; - - result = &(iter->stroke->points[iter->end + iter->stride]); - iter->p = result->p; - iter->no = result->no; - - return result; -} - -static void* nextPoint(void *arg) -{ - SK_StrokeIterator *iter = (SK_StrokeIterator*)arg; - SK_Point *result = NULL; - - iter->index++; - if (iter->index < iter->length) - { - result = setIteratorValues(iter, iter->index); - } - - return result; -} - -static void* nextNPoint(void *arg, int n) -{ - SK_StrokeIterator *iter = (SK_StrokeIterator*)arg; - SK_Point *result = NULL; - - iter->index += n; - - /* check if passed end */ - if (iter->index < iter->length) - { - result = setIteratorValues(iter, iter->index); - } - - return result; -} - -static void* peekPoint(void *arg, int n) -{ - SK_StrokeIterator *iter = (SK_StrokeIterator*)arg; - SK_Point *result = NULL; - int index = iter->index + n; - - /* check if passed end */ - if (index < iter->length) - { - result = setIteratorValues(iter, index); - } - - return result; -} - -static void* previousPoint(void *arg) -{ - SK_StrokeIterator *iter = (SK_StrokeIterator*)arg; - SK_Point *result = NULL; - - if (iter->index > 0) - { - iter->index--; - result = setIteratorValues(iter, iter->index); - } - - return result; -} - -static int iteratorStopped(void *arg) -{ - SK_StrokeIterator *iter = (SK_StrokeIterator*)arg; - - if (iter->index >= iter->length) - { - return 1; - } - else - { - return 0; - } -} - -void sk_convertStroke(SK_Stroke *stk) -{ - bArmature *arm = G.obedit->data; - SK_Point *head; - EditBone *parent = NULL; - float invmat[4][4]; /* move in caller function */ - float tmat[3][3]; - int head_index = 0; - int i; - - head = NULL; - - Mat4Invert(invmat, G.obedit->obmat); - - Mat3CpyMat4(tmat, G.obedit->obmat); - Mat3Transp(tmat); - - for (i = 0; i < stk->nb_points; i++) - { - SK_Point *pt = stk->points + i; - - if (pt->type == PT_EXACT) - { - if (head == NULL) - { - head_index = i; - head = pt; - } - else - { - EditBone *bone = NULL; - EditBone *new_parent; - - if (i - head_index > 1) - { - SK_StrokeIterator sk_iter; - BArcIterator *iter = (BArcIterator*)&sk_iter; - - initStrokeIterator(iter, stk, head_index, i); - - if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE) - { - bone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextAdaptativeSubdivision); - } - else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH) - { - bone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextLengthSubdivision); - } - else if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED) - { - bone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextFixedSubdivision); - } - } - - if (bone == NULL) - { - bone = addEditBone("Bone", &G.edbo, arm); - - VECCOPY(bone->head, head->p); - VECCOPY(bone->tail, pt->p); - - Mat4MulVecfl(invmat, bone->head); - Mat4MulVecfl(invmat, bone->tail); - setBoneRollFromNormal(bone, head->no, invmat, tmat); - } - - new_parent = bone; - bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; - - /* move to end of chain */ - while (bone->parent != NULL) - { - bone = bone->parent; - bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; - } - - if (parent != NULL) - { - bone->parent = parent; - bone->flag |= BONE_CONNECTED; - } - - parent = new_parent; - head_index = i; - head = pt; - } - } - } -} - -void sk_convert(SK_Sketch *sketch) -{ - SK_Stroke *stk; - - for (stk = sketch->strokes.first; stk; stk = stk->next) - { - if (stk->selected == 1) - { - if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET) - { - sk_retargetStroke(stk); - } - else - { - sk_convertStroke(stk); - } - allqueue(REDRAWBUTSEDIT, 0); - } - } -} -/******************* GESTURE *************************/ - - -/* returns the number of self intersections */ -int sk_getSelfIntersections(ListBase *list, SK_Stroke *gesture) -{ - int added = 0; - int s_i; - - for (s_i = 0; s_i < gesture->nb_points - 1; s_i++) - { - float s_p1[3] = {0, 0, 0}; - float s_p2[3] = {0, 0, 0}; - int g_i; - - project_float(gesture->points[s_i].p, s_p1); - project_float(gesture->points[s_i + 1].p, s_p2); - - /* start checking from second next, because two consecutive cannot intersect */ - for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++) - { - float g_p1[3] = {0, 0, 0}; - float g_p2[3] = {0, 0, 0}; - float vi[3]; - float lambda; - - project_float(gesture->points[g_i].p, g_p1); - project_float(gesture->points[g_i + 1].p, g_p2); - - if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) - { - SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection"); - - isect->gesture_index = g_i; - isect->before = s_i; - isect->after = s_i + 1; - isect->stroke = gesture; - - VecSubf(isect->p, gesture->points[s_i + 1].p, gesture->points[s_i].p); - VecMulf(isect->p, lambda); - VecAddf(isect->p, isect->p, gesture->points[s_i].p); - - BLI_addtail(list, isect); - - added++; - } - } - } - - return added; -} - -int cmpIntersections(void *i1, void *i2) -{ - SK_Intersection *isect1 = i1, *isect2 = i2; - - if (isect1->stroke == isect2->stroke) - { - if (isect1->before < isect2->before) - { - return -1; - } - else if (isect1->before > isect2->before) - { - return 1; - } - else - { - if (isect1->lambda < isect2->lambda) - { - return -1; - } - else if (isect1->lambda > isect2->lambda) - { - return 1; - } - } - } - - return 0; -} - - -/* returns the maximum number of intersections per stroke */ -int sk_getIntersections(ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture) -{ - SK_Stroke *stk; - int added = 0; - - for (stk = sketch->strokes.first; stk; stk = stk->next) - { - int s_added = 0; - int s_i; - - for (s_i = 0; s_i < stk->nb_points - 1; s_i++) - { - float s_p1[3] = {0, 0, 0}; - float s_p2[3] = {0, 0, 0}; - int g_i; - - project_float(stk->points[s_i].p, s_p1); - project_float(stk->points[s_i + 1].p, s_p2); - - for (g_i = 0; g_i < gesture->nb_points - 1; g_i++) - { - float g_p1[3] = {0, 0, 0}; - float g_p2[3] = {0, 0, 0}; - float vi[3]; - float lambda; - - project_float(gesture->points[g_i].p, g_p1); - project_float(gesture->points[g_i + 1].p, g_p2); - - if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda)) - { - SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection"); - float ray_start[3], ray_end[3]; - short mval[2]; - - isect->gesture_index = g_i; - isect->before = s_i; - isect->after = s_i + 1; - isect->stroke = stk; - isect->lambda = lambda; - - mval[0] = (short)(vi[0]); - mval[1] = (short)(vi[1]); - viewline(mval, ray_start, ray_end); - - LineIntersectLine( stk->points[s_i].p, - stk->points[s_i + 1].p, - ray_start, - ray_end, - isect->p, - vi); - - BLI_addtail(list, isect); - - s_added++; - } - } - } - - added = MAX2(s_added, added); - } - - BLI_sortlist(list, cmpIntersections); - - return added; -} - -int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture) -{ - SK_StrokeIterator sk_iter; - BArcIterator *iter = (BArcIterator*)&sk_iter; - - float CORRELATION_THRESHOLD = 0.99f; - float *vec; - int i, j; - - sk_appendStrokePoint(segments, &gesture->points[0]); - vec = segments->points[segments->nb_points - 1].p; - - initStrokeIterator(iter, gesture, 0, gesture->nb_points - 1); - - for (i = 1, j = 0; i < gesture->nb_points; i++) - { - float n[3]; - - /* Calculate normal */ - VecSubf(n, gesture->points[i].p, vec); - - if (calcArcCorrelation(iter, j, i, vec, n) < CORRELATION_THRESHOLD) - { - j = i - 1; - sk_appendStrokePoint(segments, &gesture->points[j]); - vec = segments->points[segments->nb_points - 1].p; - segments->points[segments->nb_points - 1].type = PT_EXACT; - } - } - - sk_appendStrokePoint(segments, &gesture->points[gesture->nb_points - 1]); - - return segments->nb_points - 1; -} - -int sk_detectCutGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - if (gest->nb_segments == 1 && gest->nb_intersections == 1) - { - return 1; - } - - return 0; -} - -void sk_applyCutGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - SK_Intersection *isect; - - for (isect = gest->intersections.first; isect; isect = isect->next) - { - SK_Point pt; - - pt.type = PT_EXACT; - pt.mode = PT_PROJECT; /* take mode from neighbouring points */ - VECCOPY(pt.p, isect->p); - VECCOPY(pt.no, isect->stroke->points[isect->before].no); - - sk_insertStrokePoint(isect->stroke, &pt, isect->after); - } -} - -int sk_detectTrimGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - if (gest->nb_segments == 2 && gest->nb_intersections == 1 && gest->nb_self_intersections == 0) - { - float s1[3], s2[3]; - float angle; - - VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p); - VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p); - - angle = VecAngle2(s1, s2); - - if (angle > 60 && angle < 120) - { - return 1; - } - } - - return 0; -} - -void sk_applyTrimGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - SK_Intersection *isect; - float trim_dir[3]; - - VecSubf(trim_dir, gest->segments->points[2].p, gest->segments->points[1].p); - - for (isect = gest->intersections.first; isect; isect = isect->next) - { - SK_Point pt; - float stroke_dir[3]; - - pt.type = PT_EXACT; - pt.mode = PT_PROJECT; /* take mode from neighbouring points */ - VECCOPY(pt.p, isect->p); - VECCOPY(pt.no, isect->stroke->points[isect->before].no); - - VecSubf(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p); - - /* same direction, trim end */ - if (Inpf(stroke_dir, trim_dir) > 0) - { - sk_replaceStrokePoint(isect->stroke, &pt, isect->after); - sk_trimStroke(isect->stroke, 0, isect->after); - } - /* else, trim start */ - else - { - sk_replaceStrokePoint(isect->stroke, &pt, isect->before); - sk_trimStroke(isect->stroke, isect->before, isect->stroke->nb_points - 1); - } - - } -} - -int sk_detectCommandGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1) - { - SK_Intersection *isect, *self_isect; - - /* get the the last intersection of the first pair */ - for( isect = gest->intersections.first; isect; isect = isect->next ) - { - if (isect->stroke == isect->next->stroke) - { - isect = isect->next; - break; - } - } - - self_isect = gest->self_intersections.first; - - if (isect && isect->gesture_index < self_isect->gesture_index) - { - return 1; - } - } - - return 0; -} - -void sk_applyCommandGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - SK_Intersection *isect; - int command; - - command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3"); - if(command < 1) return; - - for (isect = gest->intersections.first; isect; isect = isect->next) - { - SK_Intersection *i2; - - i2 = isect->next; - - if (i2 && i2->stroke == isect->stroke) - { - switch (command) - { - case 1: - sk_flattenStroke(isect->stroke, isect->before, i2->after); - break; - case 2: - sk_straightenStroke(isect->stroke, isect->before, i2->after, isect->p, i2->p); - break; - case 3: - sk_polygonizeStroke(isect->stroke, isect->before, i2->after); - break; - } - - isect = i2; - } - } -} - -int sk_detectDeleteGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - if (gest->nb_segments == 2 && gest->nb_intersections == 2) - { - float s1[3], s2[3]; - float angle; - - VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p); - VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p); - - angle = VecAngle2(s1, s2); - - if (angle > 120) - { - return 1; - } - } - - return 0; -} - -void sk_applyDeleteGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - SK_Intersection *isect; - - for (isect = gest->intersections.first; isect; isect = isect->next) - { - /* only delete strokes that are crossed twice */ - if (isect->next && isect->next->stroke == isect->stroke) - { - isect = isect->next; - - sk_removeStroke(sketch, isect->stroke); - } - } -} - -int sk_detectMergeGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - if (gest->nb_segments > 2 && gest->nb_intersections == 2) - { - short start_val[2], end_val[2]; - short dist; - - project_short_noclip(gest->stk->points[0].p, start_val); - project_short_noclip(sk_lastStrokePoint(gest->stk)->p, end_val); - - dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); - - /* if gesture is a circle */ - if ( dist <= 20 ) - { - SK_Intersection *isect; - - /* check if it circled around an exact point */ - for (isect = gest->intersections.first; isect; isect = isect->next) - { - /* only delete strokes that are crossed twice */ - if (isect->next && isect->next->stroke == isect->stroke) - { - int start_index, end_index; - int i; - - start_index = MIN2(isect->after, isect->next->after); - end_index = MAX2(isect->before, isect->next->before); - - for (i = start_index; i <= end_index; i++) - { - if (isect->stroke->points[i].type == PT_EXACT) - { - return 1; /* at least one exact point found, stop detect here */ - } - } - - /* skip next */ - isect = isect->next; - } - } - } - } - - return 0; -} - -void sk_applyMergeGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - SK_Intersection *isect; - - /* check if it circled around an exact point */ - for (isect = gest->intersections.first; isect; isect = isect->next) - { - /* only merge strokes that are crossed twice */ - if (isect->next && isect->next->stroke == isect->stroke) - { - int start_index, end_index; - int i; - - start_index = MIN2(isect->after, isect->next->after); - end_index = MAX2(isect->before, isect->next->before); - - for (i = start_index; i <= end_index; i++) - { - /* if exact, switch to continuous */ - if (isect->stroke->points[i].type == PT_EXACT) - { - isect->stroke->points[i].type = PT_CONTINUOUS; - } - } - - /* skip next */ - isect = isect->next; - } - } -} - -int sk_detectReverseGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 0) - { - SK_Intersection *isect; - - /* check if it circled around an exact point */ - for (isect = gest->intersections.first; isect; isect = isect->next) - { - /* only delete strokes that are crossed twice */ - if (isect->next && isect->next->stroke == isect->stroke) - { - float start_v[3], end_v[3]; - float angle; - - if (isect->gesture_index < isect->next->gesture_index) - { - VecSubf(start_v, isect->p, gest->stk->points[0].p); - VecSubf(end_v, sk_lastStrokePoint(gest->stk)->p, isect->next->p); - } - else - { - VecSubf(start_v, isect->next->p, gest->stk->points[0].p); - VecSubf(end_v, sk_lastStrokePoint(gest->stk)->p, isect->p); - } - - angle = VecAngle2(start_v, end_v); - - if (angle > 120) - { - return 1; - } - - /* skip next */ - isect = isect->next; - } - } - } - - return 0; -} - -void sk_applyReverseGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - SK_Intersection *isect; - - for (isect = gest->intersections.first; isect; isect = isect->next) - { - /* only reverse strokes that are crossed twice */ - if (isect->next && isect->next->stroke == isect->stroke) - { - sk_reverseStroke(isect->stroke); - - /* skip next */ - isect = isect->next; - } - } -} - -int sk_detectConvertGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - if (gest->nb_segments == 3 && gest->nb_self_intersections == 1) - { - return 1; - } - return 0; -} - -void sk_applyConvertGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - sk_convert(sketch); -} - -static void sk_initGesture(SK_Gesture *gest, SK_Sketch *sketch) -{ - gest->intersections.first = gest->intersections.last = NULL; - gest->self_intersections.first = gest->self_intersections.last = NULL; - - gest->segments = sk_createStroke(); - gest->stk = sketch->gesture; - - gest->nb_self_intersections = sk_getSelfIntersections(&gest->self_intersections, gest->stk); - gest->nb_intersections = sk_getIntersections(&gest->intersections, sketch, gest->stk); - gest->nb_segments = sk_getSegments(gest->segments, gest->stk); -} - -static void sk_freeGesture(SK_Gesture *gest) -{ - sk_freeStroke(gest->segments); - BLI_freelistN(&gest->intersections); - BLI_freelistN(&gest->self_intersections); -} - -void sk_applyGesture(SK_Sketch *sketch) -{ - SK_Gesture gest; - SK_GestureAction *act; - - sk_initGesture(&gest, sketch); - - /* detect and apply */ - for (act = GESTURE_ACTIONS; act->apply != NULL; act++) - { - if (act->detect(&gest, sketch)) - { - act->apply(&gest, sketch); - break; - } - } - - sk_freeGesture(&gest); -} - -/********************************************/ - -void sk_deleteSelectedStrokes(SK_Sketch *sketch) -{ - SK_Stroke *stk, *next; - - for (stk = sketch->strokes.first; stk; stk = next) - { - next = stk->next; - - if (stk->selected == 1) - { - sk_removeStroke(sketch, stk); - } - } -} - -void sk_selectAllSketch(SK_Sketch *sketch, int mode) -{ - SK_Stroke *stk = NULL; - - if (mode == -1) - { - for (stk = sketch->strokes.first; stk; stk = stk->next) - { - stk->selected = 0; - } - } - else if (mode == 0) - { - for (stk = sketch->strokes.first; stk; stk = stk->next) - { - stk->selected = 1; - } - } - else if (mode == 1) - { - int selected = 1; - - for (stk = sketch->strokes.first; stk; stk = stk->next) - { - selected &= stk->selected; - } - - selected ^= 1; - - for (stk = sketch->strokes.first; stk; stk = stk->next) - { - stk->selected = selected; - } - } -} - -void sk_selectStroke(SK_Sketch *sketch) -{ - unsigned int buffer[MAXPICKBUF]; - short hits, mval[2]; - - persp(PERSP_VIEW); - - getmouseco_areawin(mval); - hits = view3d_opengl_select(buffer, MAXPICKBUF, mval[0]-5, mval[1]-5, mval[0]+5, mval[1]+5); - if(hits==0) - hits = view3d_opengl_select(buffer, MAXPICKBUF, mval[0]-12, mval[1]-12, mval[0]+12, mval[1]+12); - - if (hits>0) - { - int besthitresult = -1; - - if(hits == 1) { - besthitresult = buffer[3]; - } - else { - besthitresult = buffer[3]; - /* loop and get best hit */ - } - - if (besthitresult > 0) - { - SK_Stroke *selected_stk = BLI_findlink(&sketch->strokes, besthitresult - 1); - - if ((G.qual & LR_SHIFTKEY) == 0) - { - sk_selectAllSketch(sketch, -1); - - selected_stk->selected = 1; - } - else - { - selected_stk->selected ^= 1; - } - - - } - } -} - -void sk_queueRedrawSketch(SK_Sketch *sketch) -{ - if (sketch->active_stroke != NULL) - { - SK_Point *last = sk_lastStrokePoint(sketch->active_stroke); - - if (last != NULL) - { - allqueue(REDRAWVIEW3D, 0); - } - } -} - -void sk_drawSketch(SK_Sketch *sketch, int with_names) -{ - SK_Stroke *stk; - - glDisable(GL_DEPTH_TEST); - - glLineWidth(BIF_GetThemeValuef(TH_VERTEX_SIZE)); - glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE)); - - if (with_names) - { - int id; - for (id = 1, stk = sketch->strokes.first; stk; id++, stk = stk->next) - { - sk_drawStroke(stk, id, NULL, -1, -1); - } - - glLoadName(-1); - } - else - { - float selected_rgb[3] = {1, 0, 0}; - float unselected_rgb[3] = {1, 0.5, 0}; - - for (stk = sketch->strokes.first; stk; stk = stk->next) - { - int start = -1; - int end = -1; - - if (sk_hasOverdraw(sketch, stk)) - { - sk_adjustIndexes(sketch, &start, &end); - } - - sk_drawStroke(stk, -1, (stk->selected==1?selected_rgb:unselected_rgb), start, end); - - if (stk->selected == 1) - { - sk_drawStrokeSubdivision(stk); - } - } - - /* only draw gesture in active area */ - if (sketch->gesture != NULL && area_is_active_area(G.vd->area)) - { - float gesture_rgb[3] = {0, 0.5, 1}; - sk_drawStroke(sketch->gesture, -1, gesture_rgb, -1, -1); - } - - if (sketch->active_stroke != NULL) - { - SK_Point *last = sk_lastStrokePoint(sketch->active_stroke); - - if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) - { - sk_drawStrokeSubdivision(sketch->active_stroke); - } - - if (last != NULL) - { - /* update point if in active area */ - if (area_is_active_area(G.vd->area)) - { - SK_DrawData dd; - - sk_initDrawData(&dd); - sk_getStrokePoint(&sketch->next_point, sketch, sketch->active_stroke, &dd, G.qual); - } - - glEnable(GL_LINE_STIPPLE); - glColor3fv(selected_rgb); - glBegin(GL_LINE_STRIP); - - glVertex3fv(last->p); - glVertex3fv(sketch->next_point.p); - - glEnd(); - - glDisable(GL_LINE_STIPPLE); - - switch (sketch->next_point.mode) - { - case PT_SNAP: - glColor3f(0, 1, 0); - break; - case PT_PROJECT: - glColor3f(0, 0, 0); - break; - } - - glBegin(GL_POINTS); - - glVertex3fv(sketch->next_point.p); - - glEnd(); - } - } - } - - glLineWidth(1.0); - glPointSize(1.0); - - glEnable(GL_DEPTH_TEST); -} - -int sk_paint(SK_Sketch *sketch, short mbut) -{ - int retval = 1; - - if (mbut == LEFTMOUSE) - { - SK_DrawData dd; - if (sketch->active_stroke == NULL) - { - sk_startStroke(sketch); - sk_selectAllSketch(sketch, -1); - - sketch->active_stroke->selected = 1; - } - - sk_initDrawData(&dd); - - /* paint loop */ - do { - /* get current user input */ - getmouseco_areawin(dd.mval); - - /* only add current point to buffer if mouse moved (otherwise wait until it does) */ - if (sk_stroke_filtermval(&dd)) { - - sk_addStrokePoint(sketch, sketch->active_stroke, &dd, G.qual); - sk_updateDrawData(&dd); - force_draw(0); - } - else - { - BIF_wait_for_statechange(); - } - - while( qtest() ) { - short event, val; - event = extern_qread(&val); - } - - /* do mouse checking at the end, so don't check twice, and potentially - * miss a short tap - */ - } while (get_mbut() & L_MOUSE); - - sk_endContinuousStroke(sketch->active_stroke); - sk_filterLastContinuousStroke(sketch->active_stroke); - sk_updateNextPoint(sketch); - } - else if (mbut == RIGHTMOUSE) - { - if (sketch->active_stroke != NULL) - { - SK_Stroke *stk = sketch->active_stroke; - - sk_endStroke(sketch); - - if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) - { - if (G.scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET) - { - sk_retargetStroke(stk); - } - else - { - sk_convertStroke(stk); - } - BIF_undo_push("Convert Sketch"); - sk_removeStroke(sketch, stk); - allqueue(REDRAWBUTSEDIT, 0); - } - - allqueue(REDRAWVIEW3D, 0); - } - /* no gestures in quick mode */ - else if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) - { - retval = 0; /* return zero for default click behavior */ - } - else - { - SK_DrawData dd; - sketch->gesture = sk_createStroke(); - - sk_initDrawData(&dd); - - /* paint loop */ - do { - /* get current user input */ - getmouseco_areawin(dd.mval); - - /* only add current point to buffer if mouse moved (otherwise wait until it does) */ - if (sk_stroke_filtermval(&dd)) { - - sk_addStrokeDrawPoint(sketch, sketch->gesture, &dd); - sk_updateDrawData(&dd); - - /* draw only if mouse has moved */ - if (sketch->gesture->nb_points > 1) - { - force_draw(0); - } - } - else - { - BIF_wait_for_statechange(); - } - - while( qtest() ) { - short event, val; - event = extern_qread(&val); - } - - /* do mouse checking at the end, so don't check twice, and potentially - * miss a short tap - */ - } while (get_mbut() & R_MOUSE); - - sk_endContinuousStroke(sketch->gesture); - sk_filterLastContinuousStroke(sketch->gesture); - sk_filterLastContinuousStroke(sketch->gesture); - sk_filterLastContinuousStroke(sketch->gesture); - - if (sketch->gesture->nb_points == 1) - { - sk_selectStroke(sketch); - } - else - { - /* apply gesture here */ - sk_applyGesture(sketch); - } - - sk_freeStroke(sketch->gesture); - sketch->gesture = NULL; - - allqueue(REDRAWVIEW3D, 0); - } - } - - return retval; -} - -void BDR_drawSketchNames() -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch != NULL) - { - sk_drawSketch(GLOBAL_sketch, 1); - } - } -} - -void BDR_drawSketch() -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch != NULL) - { - sk_drawSketch(GLOBAL_sketch, 0); - } - } -} - -void BIF_endStrokeSketch() -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch != NULL) - { - sk_endStroke(GLOBAL_sketch); - allqueue(REDRAWVIEW3D, 0); - } - } -} - -void BIF_cancelStrokeSketch() -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch != NULL) - { - sk_cancelStroke(GLOBAL_sketch); - allqueue(REDRAWVIEW3D, 0); - } - } -} - -void BIF_deleteSketch() -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch != NULL) - { - sk_deleteSelectedStrokes(GLOBAL_sketch); - allqueue(REDRAWVIEW3D, 0); - } - } -} - -void BIF_convertSketch() -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch != NULL) - { - sk_convert(GLOBAL_sketch); - BIF_undo_push("Convert Sketch"); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); - } - } -} - -int BIF_paintSketch(short mbut) -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch == NULL) - { - GLOBAL_sketch = sk_createSketch(); - } - - return sk_paint(GLOBAL_sketch, mbut); - } - else - { - return 0; - } -} - - -void BDR_queueDrawSketch() -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch != NULL) - { - sk_queueRedrawSketch(GLOBAL_sketch); - } - } -} - -void BIF_selectAllSketch(int mode) -{ - if (BIF_validSketchMode()) - { - if (GLOBAL_sketch != NULL) - { - sk_selectAllSketch(GLOBAL_sketch, mode); - allqueue(REDRAWVIEW3D, 0); - } - } -} - -int BIF_validSketchMode() -{ - if (G.obedit && - G.obedit->type == OB_ARMATURE && - G.scene->toolsettings->bone_sketching & BONE_SKETCHING) - { - return 1; - } - else - { - return 0; - } -} - -int BIF_fullSketchMode() -{ - if (G.obedit && - G.obedit->type == OB_ARMATURE && - G.scene->toolsettings->bone_sketching & BONE_SKETCHING && - (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) == 0) - { - return 1; - } - else - { - return 0; - } -} - -void BIF_freeSketch() -{ - if (GLOBAL_sketch != NULL) - { - sk_freeSketch(GLOBAL_sketch); - GLOBAL_sketch = NULL; - } -} |