diff --git a/source/blender/blenkernel/BKE_sketch.h b/source/blender/blenkernel/BKE_sketch.h new file mode 100644 index 00000000000..424dd5c9f80 --- /dev/null +++ b/source/blender/blenkernel/BKE_sketch.h @@ -0,0 +1,157 @@ +/** + * + * $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. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef BKE_SKETCH_H +#define BKE_SKETCH_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]; + short p2d[2]; + float no[3]; + float size; + 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; + ListBase depth_peels; + SK_Stroke *active_stroke; + SK_Stroke *gesture; + SK_Point next_point; + SK_Overdraw over; +} SK_Sketch; + + +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; + + +/************************************************/ + +void freeSketch(SK_Sketch *sketch); +SK_Sketch* createSketch(); + +void sk_removeStroke(SK_Sketch *sketch, SK_Stroke *stk); + +void sk_freeStroke(SK_Stroke *stk); +SK_Stroke* sk_createStroke(); + +SK_Point *sk_lastStrokePoint(SK_Stroke *stk); + +void sk_allocStrokeBuffer(SK_Stroke *stk); +void sk_shrinkStrokeBuffer(SK_Stroke *stk); +void sk_growStrokeBuffer(SK_Stroke *stk); +void sk_growStrokeBufferN(SK_Stroke *stk, int n); + +void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n); +void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n); +void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt); +void sk_insertStrokePoints(SK_Stroke *stk, SK_Point *pts, int len, int start, int end); + +void sk_trimStroke(SK_Stroke *stk, int start, int end); +void sk_straightenStroke(SK_Stroke *stk, int start, int end, float p_start[3], float p_end[3]); +void sk_polygonizeStroke(SK_Stroke *stk, int start, int end); +void sk_flattenStroke(SK_Stroke *stk, int start, int end); +void sk_reverseStroke(SK_Stroke *stk); + +void sk_filterLastContinuousStroke(SK_Stroke *stk); +void sk_filterStroke(SK_Stroke *stk, int start, int end); + +void sk_initPoint(SK_Point *pt, SK_DrawData *dd, float *no); +void sk_copyPoint(SK_Point *dst, SK_Point *src); + +int sk_stroke_filtermval(SK_DrawData *dd); +void sk_endContinuousStroke(SK_Stroke *stk); + +void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk); + +void sk_initDrawData(SK_DrawData *dd, short mval[2]); + +void sk_deleteSelectedStrokes(SK_Sketch *sketch); +void sk_selectAllSketch(SK_Sketch *sketch, int mode); + +#endif diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 37130a0e3a0..eb8a894e800 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -66,8 +66,7 @@ #include "BKE_object.h" #include "BKE_object.h" #include "BKE_utildefines.h" - -//XXX #include "BIF_editdeform.h" +#include "BKE_sketch.h" #include "IK_solver.h" @@ -144,7 +143,7 @@ void free_armature(bArmature *arm) /* free sketch */ if (arm->sketch) { - ED_freeSketch(arm->sketch); + freeSketch(arm->sketch); arm->sketch = NULL; } } diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c new file mode 100644 index 00000000000..8deae7e8e10 --- /dev/null +++ b/source/blender/blenkernel/intern/sketch.c @@ -0,0 +1,600 @@ +/** + * + * $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. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "BKE_sketch.h" +#include "BKE_utildefines.h" + +#include "DNA_userdef_types.h" + +void freeSketch(SK_Sketch *sketch) +{ + SK_Stroke *stk, *next; + + for (stk = sketch->strokes.first; stk; stk = next) + { + next = stk->next; + + sk_freeStroke(stk); + } + + BLI_freelistN(&sketch->depth_peels); + + MEM_freeN(sketch); +} + +SK_Sketch* 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, SK_DrawData *dd, float *no) +{ + if (no) + { + VECCOPY(pt->no, no); + Normalize(pt->no); + } + else + { + pt->no[0] = 0; + pt->no[1] = 0; + pt->no[2] = 1; + } + pt->p2d[0] = dd->mval[0]; + pt->p2d[1] = dd->mval[1]; + /* 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); +} + + +/* Ramer-Douglas-Peucker algorithm for line simplification */ +void sk_filterStroke(SK_Stroke *stk, int start, int end) +{ + SK_Point *old_points = stk->points; + int nb_points = stk->nb_points; + char *marked = NULL; + char work; + int i; + + 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); + } + + marked = MEM_callocN(nb_points, "marked array"); + marked[start] = 1; + marked[end] = 1; + + work = 1; + + /* while still reducing */ + while (work) + { + int ls, le; + work = 0; + + ls = start; + le = start+1; + + /* while not over interval */ + while (ls < end) + { + int max_i = 0; + short v1[2]; + float max_dist = 16; /* more than 4 pixels */ + + /* find the next marked point */ + while(marked[le] == 0) + { + le++; + } + + /* perpendicular vector to ls-le */ + v1[1] = old_points[le].p2d[0] - old_points[ls].p2d[0]; + v1[0] = old_points[ls].p2d[1] - old_points[le].p2d[1]; + + + for( i = ls + 1; i < le; i++ ) + { + float mul; + float dist; + short v2[2]; + + v2[0] = old_points[i].p2d[0] - old_points[ls].p2d[0]; + v2[1] = old_points[i].p2d[1] - old_points[ls].p2d[1]; + + if (v2[0] == 0 && v2[1] == 0) + { + continue; + } + + mul = (float)(v1[0]*v2[0] + v1[1]*v2[1]) / (float)(v2[0]*v2[0] + v2[1]*v2[1]); + + dist = mul * mul * (v2[0]*v2[0] + v2[1]*v2[1]); + + if (dist > max_dist) + { + max_dist = dist; + max_i = i; + } + } + + if (max_i != 0) + { + work = 1; + marked[max_i] = 1; + } + + ls = le; + le = ls + 1; + } + } + + + /* adding points after range */ + for (i = start; i <= end; i++) + { + if (marked[i]) + { + sk_appendStrokePoint(stk, old_points + i); + } + } + + MEM_freeN(marked); + + /* 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_endContinuousStroke(SK_Stroke *stk) +{ + stk->points[stk->nb_points - 1].type = PT_EXACT; +} + +void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk) +{ + if (stk) + { + 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, short mval[2]) +{ + dd->mval[0] = mval[0]; + dd->mval[1] = mval[1]; + dd->previous_mval[0] = -1; + dd->previous_mval[1] = -1; + dd->type = PT_EXACT; +} + + +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; + } + } +} diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 16c5971a930..f3f7bccde04 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -49,6 +49,7 @@ #include "BKE_object.h" #include "BKE_anim.h" #include "BKE_context.h" +#include "BKE_sketch.h" #include "ED_view3d.h" #include "ED_screen.h" @@ -74,76 +75,21 @@ //#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]; - short p2d[2]; - float no[3]; - float size; - SK_PType type; - SK_PMode mode; -} SK_Point; +typedef int (*GestureDetectFct)(bContext*, SK_Gesture*, SK_Sketch *); +typedef void (*GestureApplyFct)(bContext*, SK_Gesture*, SK_Sketch *); -typedef struct SK_Stroke -{ - struct SK_Stroke *next, *prev; +typedef struct SK_GestureAction { + char name[64]; + GestureDetectFct detect; + GestureApplyFct apply; +} SK_GestureAction; - SK_Point *points; - int nb_points; - int buf_size; - int selected; -} SK_Stroke; +SK_Point boneSnap; +int LAST_SNAP_POINT_VALID = 0; +float LAST_SNAP_POINT[3]; -#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; - ListBase depth_peels; - SK_Stroke *active_stroke; - SK_Stroke *gesture; - SK_Point next_point; - SK_Overdraw over; -} SK_Sketch; typedef struct SK_StrokeIterator { HeadFct head; @@ -166,40 +112,12 @@ typedef struct SK_StrokeIterator { 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)(bContext*, SK_Gesture*, SK_Sketch *); -typedef void (*GestureApplyFct)(bContext*, SK_Gesture*, SK_Sketch *); - -typedef struct SK_GestureAction { - char name[64]; - GestureDetectFct detect; - GestureApplyFct apply; -} SK_GestureAction; - -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(bContext *C, SK_Gesture *gest, SK_Sketch *sketch); @@ -561,331 +479,6 @@ void sk_retargetStroke(bContext *C, SK_Stroke *stk) /**************************************************************/ -void sk_freeSketch(SK_Sketch *sketch) -{ - SK_Stroke *stk, *next; - - for (stk = sketch->strokes.first; stk; stk = next) - { - next = stk->next; - - sk_freeStroke(stk); - } - - BLI_freelistN(&sketch->depth_peels); - - 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(bContext *C, SK_Point *pt, SK_DrawData *dd) -{ - ARegion *ar = CTX_wm_region(C); - RegionView3D *rv3d = ar->regiondata; - - VECCOPY(pt->no, rv3d->viewinv[2]); - pt->p2d[0] = dd->mval[0]; - pt->p2d[1] = dd->mval[1]; - 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) @@ -895,201 +488,6 @@ void sk_cancelStroke(SK_Sketch *sketch) } } -void sk_filterStroke(SK_Stroke *stk, int start, int end) -{ - SK_Point *old_points = stk->points; - int nb_points = stk->nb_points; - char *marked = NULL; - char work; - int i, j; - - 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); - } - -#if 0 - - /* Apply reverse Chaikin filter to simplify the polyline - * */ - 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); - - 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; - - 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; - } - } -#else - /* Ramer-Douglas-Peucker */ - marked = MEM_callocN(nb_points, "marked array"); - marked[start] = 1; - marked[end] = 1; - - work = 1; - - /* while still reducing */ - while (work) - { - int ls, le; - work = 0; - - ls = start; - le = start+1; - - /* while not over interval */ - while (ls < end) - { - int i; - int max_i = 0; - short v1[2]; - float max_dist = 16; /* more than 4 pixels */ - - /* find the next marked point */ - while(marked[le] == 0) - { - le++; - } - - /* perpendicular vector to ls-le */ - v1[1] = old_points[le].p2d[0] - old_points[ls].p2d[0]; - v1[0] = old_points[ls].p2d[1] - old_points[le].p2d[1]; - - - for( i = ls + 1; i < le; i++ ) - { - float mul; - float dist; - short v2[2]; - - v2[0] = old_points[i].p2d[0] - old_points[ls].p2d[0]; - v2[1] = old_points[i].p2d[1] - old_points[ls].p2d[1]; - - if (v2[0] == 0 && v2[1] == 0) - { - continue; - } - - mul = (float)(v1[0]*v2[0] + v1[1]*v2[1]) / (float)(v2[0]*v2[0] + v2[1]*v2[1]); - - dist = mul * mul * (v2[0]*v2[0] + v2[1]*v2[1]); - - if (dist > max_dist) - { - max_dist = dist; - max_i = i; - } - } - - if (max_i != 0) - { - work = 1; - marked[max_i] = 1; - } - - ls = le; - le = ls + 1; - } - } - - - /* adding points after range */ - for (i = start; i <= end; i++) - { - if (marked[i]) - { - sk_appendStrokePoint(stk, old_points + i); - } - } - - MEM_freeN(marked); -#endif - - - /* 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; -} float sk_clampPointSize(SK_Point *pt, float size) { @@ -1127,7 +525,7 @@ void sk_drawNormal(GLUquadric *quad, SK_Point *pt, float size, float height) { float vec2[3] = {0, 0, 1}, axis[3]; float angle; - + glPushMatrix(); Crossf(axis, vec2, pt->no); @@ -1415,12 +813,6 @@ void sk_updateOverdraw(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawDa int closest_index = -1; int dist = SNAP_MIN_DISTANCE * 2; -// /* If snapping, don't start overdraw */ Can't do that, snap is embed too now -// if (sk_lastStrokePoint(stk)->mode == PT_SNAP) -// { -// return; -// } - for (target = sketch->strokes.first; target; target = target->next) { if (target != stk) @@ -1659,9 +1051,11 @@ int sk_getStrokeDrawPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok int sk_addStrokeDrawPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd) { + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; SK_Point pt; - sk_initPoint(C, &pt, dd); + sk_initPoint(&pt, dd, rv3d->viewinv[2]); sk_getStrokeDrawPoint(C, &pt, sketch, stk, dd); @@ -1822,9 +1216,11 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd) { int point_added; + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; SK_Point pt; - sk_initPoint(C, &pt, dd); + sk_initPoint(&pt, dd, rv3d->viewinv[2]); point_added = sk_getStrokeSnapPoint(C, &pt, sketch, stk, dd); @@ -1910,38 +1306,6 @@ void sk_getStrokePoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke * } } -void sk_endContinuousStroke(SK_Stroke *stk) -{ - stk->points[stk->nb_points - 1].type = PT_EXACT; -} - -void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk) -{ - if (stk) - { - 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, short mval[2]) -{ - dd->mval[0] = mval[0]; - dd->mval[1] = mval[1]; - dd->previous_mval[0] = -1; - dd->previous_mval[1] = -1; - dd->type = PT_EXACT; -} /********************************************/ static void* headPoint(void *arg); @@ -2789,56 +2153,6 @@ void sk_applyGesture(bContext *C, SK_Sketch *sketch) /********************************************/ -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(bContext *C, SK_Sketch *sketch, short mval[2], int extend) { @@ -2987,7 +2301,7 @@ void sk_drawSketch(Scene *scene, View3D *v3d, SK_Sketch *sketch, int with_names) } } -#if 0 +#if 1 if (sketch->depth_peels.first != NULL) { float colors[8][3] = { @@ -3204,16 +2518,6 @@ void BIF_selectAllSketch(bContext *C, int mode) } #endif -void ED_freeSketch(SK_Sketch *sketch) -{ - sk_freeSketch(sketch); -} - -SK_Sketch* ED_createSketch() -{ - return sk_createSketch(); -} - SK_Sketch* contextSketch(const bContext *C, int create) { Object *obedit = CTX_data_edit_object(C); @@ -3225,7 +2529,7 @@ SK_Sketch* contextSketch(const bContext *C, int create) if (arm->sketch == NULL && create) { - arm->sketch = sk_createSketch(); + arm->sketch = createSketch(); } sketch = arm->sketch; } @@ -3244,7 +2548,7 @@ SK_Sketch* viewcontextSketch(ViewContext *vc, int create) if (arm->sketch == NULL && create) { - arm->sketch = sk_createSketch(); + arm->sketch = createSketch(); } sketch = arm->sketch; } diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 31b0f712b97..738cbf094cb 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -141,9 +141,6 @@ int ED_operator_sketch_mode_active_stroke(struct bContext *C); int ED_operator_sketch_full_mode(struct bContext *C); int ED_operator_sketch_mode(const struct bContext *C); -void ED_freeSketch(struct SK_Sketch *sketch); -struct SK_Sketch* ED_createSketch(); - void BIF_convertSketch(struct bContext *C); void BIF_deleteSketch(struct bContext *C); void BIF_selectAllSketch(struct bContext *C, int mode); /* -1: deselect, 0: select, 1: toggle */