[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [61004] trunk/blender/source/blender/ editors/sculpt_paint/paint_mask.c: Optimization of lasso masking using scanfill.

Antony Riakiotakis kalast at gmail.com
Wed Oct 30 02:20:09 CET 2013


Revision: 61004
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=61004
Author:   psy-fi
Date:     2013-10-30 01:20:08 +0000 (Wed, 30 Oct 2013)
Log Message:
-----------
Optimization of lasso masking using scanfill.

Thanks to Campbell for the advice!

Modified Paths:
--------------
    trunk/blender/source/blender/editors/sculpt_paint/paint_mask.c

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_mask.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_mask.c	2013-10-30 00:54:41 UTC (rev 61003)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_mask.c	2013-10-30 01:20:08 UTC (rev 61004)
@@ -227,8 +227,9 @@
 typedef struct LassoMaskData {
 	struct ViewContext *vc;
 	float projviewobjmat[4][4];
-	int mcords_tot;
-	int (*mcords)[2];
+	bool *px;
+	int width;
+	rcti rect; /* bounding box for scanfilling */
 } LassoMaskData;
 
 
@@ -247,15 +248,21 @@
 	scr_co_s[1] = scr_co_f[1];
 
 	/* clip against screen, because lasso is limited to screen only */
-	if (scr_co_s[0] < 0 || scr_co_s[1] < 0 || scr_co_s[0] > data->vc->ar->winx || scr_co_s[1] > data->vc->ar->winy)
+	if (scr_co_s[0] < data->rect.xmin || scr_co_s[1] < data->rect.ymin || scr_co_s[0] >= data->rect.xmax || scr_co_s[1] >= data->rect.ymax)
 		return false;
 
-	if (BLI_lasso_is_point_inside((const int (*)[2])data->mcords, data->mcords_tot, scr_co_s[0], scr_co_s[1], IS_CLIPPED))
-		return true;
+	scr_co_s[0] -= data->rect.xmin;
+	scr_co_s[1] -= data->rect.ymin;
 
-	return false;
+	return data->px[scr_co_s[1] * data->width + scr_co_s[0]];
 }
 
+static void mask_lasso_px_cb(int x, int y, void *user_data)
+{
+	struct LassoMaskData *data = user_data;
+	data->px[(y * data->width) + x] = true;
+}
+
 static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
 {
 	int mcords_tot;
@@ -277,18 +284,27 @@
 		bool select = true; /* TODO: see how to implement deselection */
 		float value = select ? 1.0 : 0.0;
 
-		/* We have two types of calculations here, bounding box lasso inclusion calculation is done in 3D space, to
-		 * correctly account for volume, and individual vertices are done in 2D screen space to diminish the amount of
-		 * calculations done */
+		/* Calculations of individual vertices are done in 2D screen space to diminish the amount of
+		 * calculations done. Bounding box PBVH collision is not computed because it is quite expensive and
+		 * unnecessary */
 		view3d_set_viewcontext(C, &vc);
 		view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats);
 
+		/* lasso data calculations */
 		data.vc = &vc;
-		data.mcords = mcords;
-		data.mcords_tot = mcords_tot;
 		ob = vc.obact;
 		ED_view3d_ob_project_mat_get(vc.rv3d, ob, data.projviewobjmat);
 
+		BLI_lasso_boundbox(&data.rect, (const int (*)[2])mcords, mcords_tot);
+		data.width = data.rect.xmax - data.rect.xmin;
+		data.px = MEM_callocN(sizeof(*data.px) * data.width * (data.rect.ymax - data.rect.ymin), "lasso_mask_pixel_buffer");
+
+		fill_poly_v2i_n(
+		       data.rect.xmin, data.rect.ymin, data.rect.xmax, data.rect.ymax,
+		       (const int (*)[2])mcords, mcords_tot,
+		       mask_lasso_px_cb, &data);
+
+
 		mmd = sculpt_multires_active(vc.scene, ob);
 		ED_sculpt_mask_layers_ensure(ob, mmd);
 		dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH);
@@ -323,6 +339,7 @@
 
 		ED_region_tag_redraw(vc.ar);
 		MEM_freeN((void *)mcords);
+		MEM_freeN(data.px);
 
 		return OPERATOR_FINISHED;
 	}




More information about the Bf-blender-cvs mailing list