diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-10-04 19:02:05 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-10-04 19:02:05 +0400 |
commit | 5dc9db3533e720f09c9a66e9489056ae00e1c394 (patch) | |
tree | 4208adb15d99d2da372a61b9b3cd53bd32bf7cc3 /source/blender/windowmanager | |
parent | 6737a040614180f8ac27221e29bb35a09485fedf (diff) |
fix for lasso failing/glitches on overlapping lines, replace scanfill with 2d pixel filling for drawing and selection.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/intern/wm_gesture.c | 96 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_subwindow.c | 9 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_subwindow.h | 1 |
3 files changed, 67 insertions, 39 deletions
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index adf159bcfee..05ee23e2361 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -40,6 +40,7 @@ #include "BLI_math.h" #include "BLI_scanfill.h" /* lasso tessellation */ #include "BLI_utildefines.h" +#include "BLI_lasso.h" #include "BKE_context.h" @@ -231,56 +232,73 @@ static void wm_gesture_draw_circle(wmGesture *gt) } -static void draw_filled_lasso(wmGesture *gt) +struct LassoFillData { + unsigned int *px; + int width; +}; + +static void draw_filled_lasso_px_cb(int x, int y, void *user_data) +{ + struct LassoFillData *data = user_data; + unsigned char *col = (unsigned char *)&(data->px[(y * data->width) + x]); + col[0] = col[1] = col[2] = 0xff; + col[3] = 0x10; +} + +static void draw_filled_lasso(wmWindow *win, wmGesture *gt) { - ScanFillContext sf_ctx; - ScanFillVert *sf_vert = NULL, *sf_vert_last = NULL, *sf_vert_first = NULL; - ScanFillFace *sf_tri; short *lasso = (short *)gt->customdata; + const int tot = gt->points; + int (*moves)[2] = MEM_mallocN(sizeof(*moves) * (tot + 1), __func__); int i; - - BLI_scanfill_begin(&sf_ctx); - for (i = 0; i < gt->points; i++, lasso += 2) { - float co[3]; - - co[0] = (float)lasso[0]; - co[1] = (float)lasso[1]; - co[2] = 0.0f; - - sf_vert = BLI_scanfill_vert_add(&sf_ctx, co); - if (sf_vert_last) - /* e = */ /* UNUSED */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert); - sf_vert_last = sf_vert; - if (sf_vert_first == NULL) sf_vert_first = sf_vert; + rcti rect; + rcti rect_win; + + for (i = 0; i < tot; i++, lasso += 2) { + moves[i][0] = lasso[0]; + moves[i][1] = lasso[1]; } - - /* highly unlikely this will fail, but could crash if (gt->points == 0) */ - if (sf_vert_first) { - const float zvec[3] = {0.0f, 0.0f, 1.0f}; - BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert); - BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES | BLI_SCANFILL_CALC_HOLES, zvec); - + + BLI_lasso_boundbox(&rect, (const int (*)[2])moves, tot); + + wm_subwindow_getrect(win, gt->swinid, &rect_win); + BLI_rcti_translate(&rect, rect_win.xmin, rect_win.ymin); + BLI_rcti_isect(&rect_win, &rect, &rect); + BLI_rcti_translate(&rect, -rect_win.xmin, -rect_win.ymin); + + /* highly unlikely this will fail, but could crash if (tot == 0) */ + if (BLI_rcti_is_empty(&rect) == false) { + const int w = BLI_rcti_size_x(&rect); + const int h = BLI_rcti_size_y(&rect); + unsigned int *pixel_buf = MEM_callocN(sizeof(*pixel_buf) * w * h, __func__); + struct LassoFillData lasso_fill_data = {pixel_buf, w}; + + fill_poly_v2i_n( + rect.xmin, rect.ymin, rect.xmax, rect.ymax, + (const int (*)[2])moves, tot, + draw_filled_lasso_px_cb, &lasso_fill_data); + glEnable(GL_BLEND); - glColor4f(1.0, 1.0, 1.0, 0.05); - glBegin(GL_TRIANGLES); - for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { - glVertex2fv(sf_tri->v1->co); - glVertex2fv(sf_tri->v2->co); - glVertex2fv(sf_tri->v3->co); - } - glEnd(); + // glColor4f(1.0, 1.0, 1.0, 0.05); + + glRasterPos2f(rect.xmin, rect.ymin); + + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixel_buf); + glDisable(GL_BLEND); - - BLI_scanfill_end(&sf_ctx); + MEM_freeN(pixel_buf); } + + MEM_freeN(moves); } -static void wm_gesture_draw_lasso(wmGesture *gt) + +static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt) { short *lasso = (short *)gt->customdata; int i; - draw_filled_lasso(gt); + draw_filled_lasso(win, gt); glEnable(GL_LINE_STIPPLE); glColor3ub(96, 96, 96); @@ -347,9 +365,9 @@ void wm_gesture_draw(wmWindow *win) wm_gesture_draw_cross(win, gt); } else if (gt->type == WM_GESTURE_LINES) - wm_gesture_draw_lasso(gt); + wm_gesture_draw_lasso(win, gt); else if (gt->type == WM_GESTURE_LASSO) - wm_gesture_draw_lasso(gt); + wm_gesture_draw_lasso(win, gt); else if (gt->type == WM_GESTURE_STRAIGHTLINE) wm_gesture_draw_line(gt); } diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 4ad4286b657..ae535ed45e8 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -148,6 +148,15 @@ void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]) } } +void wm_subwindow_getrect(wmWindow *win, int swinid, rcti *r_rect) +{ + wmSubWindow *swin = swin_from_swinid(win, swinid); + + if (swin) { + *r_rect = swin->winrct; + } +} + /* always sets pixel-precise 2D window/view matrices */ /* coords is in whole pixels. xmin = 15, xmax = 16: means window is 2 pix big */ int wm_subwindow_open(wmWindow *win, rcti *winrct) diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h index 064d00b0723..a70e7765ecf 100644 --- a/source/blender/windowmanager/wm_subwindow.h +++ b/source/blender/windowmanager/wm_subwindow.h @@ -45,6 +45,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct); void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y); void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y); void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]); +void wm_subwindow_getrect(wmWindow *win, int swinid, struct rcti *r_rect); unsigned int index_to_framebuffer(int index); |