Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-10-04 19:02:05 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-10-04 19:02:05 +0400
commit5dc9db3533e720f09c9a66e9489056ae00e1c394 (patch)
tree4208adb15d99d2da372a61b9b3cd53bd32bf7cc3 /source/blender/editors/mesh/editmesh_select.c
parent6737a040614180f8ac27221e29bb35a09485fedf (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.c108
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;
}