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/editors/mesh/editmesh_select.c | |
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/editors/mesh/editmesh_select.c')
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 108 |
1 files changed, 25 insertions, 83 deletions
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 85b0cbbc318..4d512fab1c0 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -186,53 +186,6 @@ unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0; /* set in dr /* facilities for border select and circle select */ static char *selbuf = NULL; -/* opengl doesn't support concave... */ -static void draw_triangulated(const int mcords[][2], const short tot) -{ - ListBase lb = {NULL, NULL}; - DispList *dl; - float *fp; - int a; - const float z_up[3] = {0.0f, 0.0f, 1.0f}; - - /* make displist */ - dl = MEM_callocN(sizeof(DispList), "poly disp"); - dl->type = DL_POLY; - dl->parts = 1; - dl->nr = tot; - dl->verts = fp = MEM_callocN(tot * 3 * sizeof(float), "poly verts"); - BLI_addtail(&lb, dl); - - for (a = 0; a < tot; a++, fp += 3) { - fp[0] = (float)mcords[a][0]; - fp[1] = (float)mcords[a][1]; - } - - /* do the fill */ - BKE_displist_fill(&lb, &lb, z_up, false); - - /* do the draw */ - dl = lb.first; /* filldisplist adds in head of list */ - if (dl->type == DL_INDEX3) { - int *index; - - a = dl->parts; - fp = dl->verts; - index = dl->index; - glBegin(GL_TRIANGLES); - while (a--) { - glVertex3fv(fp + 3 * index[0]); - glVertex3fv(fp + 3 * index[1]); - glVertex3fv(fp + 3 * index[2]); - index += 3; - } - glEnd(); - } - - BKE_displist_free(&lb); -} - - /* reads rect, and builds selection array for quick lookup */ /* returns if all is OK */ bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xmax, short ymax) @@ -282,6 +235,18 @@ void EDBM_backbuf_free(void) selbuf = NULL; } +struct LassoMaskData { + unsigned int *px; + int width; +}; + +static void edbm_mask_lasso_px_cb(int x, int y, void *user_data) +{ + struct LassoMaskData *data = user_data; + data->px[(y * data->width) + x] = true; +} + + /* mcords is a polygon mask * - grab backbuffer, * - draw with black in backbuffer, @@ -290,9 +255,10 @@ void EDBM_backbuf_free(void) */ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) { - unsigned int *dr, *drm; - struct ImBuf *buf, *bufmask; + unsigned int *dr, *dr_mask, *dr_mask_arr; + struct ImBuf *buf; int a; + struct LassoMaskData lasso_mask_data; /* method in use for face selecting too */ if (vc->obedit == NULL) { @@ -310,49 +276,25 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short dr = buf->rect; - if (vc->rv3d->gpuoffscreen) - GPU_offscreen_bind(vc->rv3d->gpuoffscreen); - - /* draw the mask */ - glDisable(GL_DEPTH_TEST); - - glColor3ub(0, 0, 0); - - /* yah, opengl doesn't do concave... tsk! */ - ED_region_pixelspace(vc->ar); - draw_triangulated(mcords, tot); - - glBegin(GL_LINE_LOOP); /* for zero sized masks, lines */ - for (a = 0; a < tot; a++) { - glVertex2iv(mcords[a]); - } - glEnd(); - - glFinish(); /* to be sure readpixels sees mask */ - - if (vc->rv3d->gpuoffscreen) - GPU_offscreen_unbind(vc->rv3d->gpuoffscreen); - - /* grab mask */ - bufmask = view3d_read_backbuf(vc, xmin, ymin, xmax, ymax); + dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf->x * buf->y, __func__); + lasso_mask_data.px = dr_mask; + lasso_mask_data.width = (xmax - xmin) + 1; - if (bufmask == NULL) { - return false; /* only when mem alloc fails, go crash somewhere else! */ - } - else { - drm = bufmask->rect; - } + fill_poly_v2i_n( + xmin, ymin, xmax + 1, ymax + 1, + mcords, tot, + edbm_mask_lasso_px_cb, &lasso_mask_data); /* build selection lookup */ selbuf = MEM_callocN(bm_vertoffs + 1, "selbuf"); a = (xmax - xmin + 1) * (ymax - ymin + 1); while (a--) { - if (*dr > 0 && *dr <= bm_vertoffs && *drm == 0) selbuf[*dr] = 1; - dr++; drm++; + if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) selbuf[*dr] = 1; + dr++; dr_mask++; } IMB_freeImBuf(buf); - IMB_freeImBuf(bufmask); + MEM_freeN(dr_mask_arr); return true; } |