[Bf-blender-cvs] [1194e88] temp-curve-draw: Add substeps, used when projecting onto surface to get accurate depth

Campbell Barton noreply at git.blender.org
Thu Apr 14 21:21:12 CEST 2016


Commit: 1194e8825f8df104dfb212990aadbbefb8f32b15
Author: Campbell Barton
Date:   Fri Apr 15 04:05:34 2016 +1000
Branches: temp-curve-draw
https://developer.blender.org/rB1194e8825f8df104dfb212990aadbbefb8f32b15

Add substeps, used when projecting onto surface to get accurate depth

===================================================================

M	source/blender/editors/curve/editcurve_paint.c

===================================================================

diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index d3f3696..83d0aa1 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -83,7 +83,8 @@
 #endif
 
 /* Distance between input samples */
-#define STROKE_SAMPLE_DIST_PX 3
+#define STROKE_SAMPLE_DIST_MIN_PX 3
+#define STROKE_SAMPLE_DIST_MAX_PX 6
 
 /* -------------------------------------------------------------------- */
 
@@ -91,7 +92,7 @@
  * \{ */
 
 struct StrokeElem {
-	float mouse[2];
+	float mval[2];
 	float location_world[3];
 	float location_local[3];
 	float pressure;
@@ -101,12 +102,22 @@ struct CurveDrawData {
 	short init_event_type;
 	short nurbs_type;
 
-	/* use a plane or project to the surface */
-	bool use_project_plane;
-	float    project_plane[4];
+	/* projecting 2D into 3D space */
+	struct {
+		/* use a plane or project to the surface */
+		bool use_plane;
+		float    plane[4];
+
+		/* use 'rv3d->depths', note that this will become 'damaged' while drawing, but thats OK. */
+		bool use_depth;
+	} project;
+
+	/* cursor sampling */
+	struct {
+		/* use substeps, needed for nicely interpolating depth */
+		bool use_substeps;
+	} sample;
 
-	/* use 'rv3d->depths', note that this will become 'damaged' while drawing, but thats OK. */
-	bool use_project_depth;
 
 	struct {
 		float mouse[2];
@@ -115,6 +126,7 @@ struct CurveDrawData {
 
 		float location_world_valid[3];
 
+		const struct StrokeElem *selem;
 	} prev;
 
 	ViewContext vc;
@@ -126,13 +138,23 @@ struct CurveDrawData {
 	void *draw_handle_view;
 };
 
+static void stroke_elem_interp(
+        struct StrokeElem *selem_out,
+        const struct StrokeElem *selem_a,  const struct StrokeElem *selem_b, float t)
+{
+	interp_v2_v2v2(selem_out->mval, selem_a->mval, selem_b->mval, t);
+	interp_v3_v3v3(selem_out->location_world, selem_a->location_world, selem_b->location_world, t);
+	interp_v3_v3v3(selem_out->location_local, selem_a->location_local, selem_b->location_local, t);
+	selem_out->pressure = interpf(selem_a->pressure, selem_b->pressure, t);
+}
+
 static void curve_draw_stroke_to_operator_elem(
         wmOperator *op, const struct StrokeElem *selem)
 {
 	PointerRNA itemptr;
 	RNA_collection_add(op->ptr, "stroke", &itemptr);
 
-	RNA_float_set_array(&itemptr, "mouse", selem->mouse);
+	RNA_float_set_array(&itemptr, "mouse", selem->mval);
 	RNA_float_set_array(&itemptr, "location", selem->location_world);
 	RNA_float_set(&itemptr, "pressure", selem->pressure);
 }
@@ -144,7 +166,7 @@ static void curve_draw_stroke_from_operator_elem(
 
 	struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool);
 
-	RNA_float_get_array(itemptr, "mouse", selem->mouse);
+	RNA_float_get_array(itemptr, "mouse", selem->mval);
 	RNA_float_get_array(itemptr, "location", selem->location_world);
 	mul_v3_m4v3(selem->location_local, cdd->vc.obedit->imat, selem->location_world);
 	selem->pressure = RNA_float_get(itemptr, "pressure");
@@ -273,7 +295,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
 	}
 }
 
-static float depth_read(const ViewContext *vc, int x, int y)
+static float depth_read_zbuf(const ViewContext *vc, int x, int y)
 {
 	ViewDepths *vd = vc->rv3d->depths;
 
@@ -283,6 +305,24 @@ static float depth_read(const ViewContext *vc, int x, int y)
 		return -1.0f;
 }
 
+static bool depth_unproject(
+        const ARegion *ar, const bglMats *mats,
+        const int mval[2], const float depth,
+        float r_location_world[3])
+{
+	double p[3];
+	if (gluUnProject(
+	        (double)ar->winrct.xmin + mval[0] + 0.5,
+	        (double)ar->winrct.ymin + mval[1] + 0.5,
+	        depth, mats->modelview, mats->projection, (const GLint *)mats->viewport,
+	        &p[0], &p[1], &p[2]))
+	{
+		copy_v3fl_v3db(r_location_world, p);
+		return true;
+	}
+	return false;
+}
+
 static bool depth_read_normal(
         const ViewContext *vc, const bglMats *mats, const int mval[2],
         float r_normal[3])
@@ -291,24 +331,18 @@ static bool depth_read_normal(
 	bool  depths_valid[9] = {false};
 	float coords[9][3] = {{0}};
 
+	ARegion *ar = vc->ar;
 	const ViewDepths *depths = vc->rv3d->depths;
 
 	for (int x = 0, i = 0; x < 2; x++) {
 		for (int y = 0; y < 2; y++) {
 			const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};
-			float depth = depth_read(vc, mval_ofs[0], mval_ofs[1]);
+
+			float depth = depth_read_zbuf(vc, mval_ofs[0], mval_ofs[1]);
 			if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
-				double p[3];
-				if (gluUnProject(
-				        (double)vc->ar->winrct.xmin + mval_ofs[0] + 0.5,
-				        (double)vc->ar->winrct.ymin + mval_ofs[1] + 0.5,
-				        depth, mats->modelview, mats->projection, (const GLint *)mats->viewport,
-				        &p[0], &p[1], &p[2]))
-				{
-					copy_v3fl_v3db(coords[i], p);
+				if (depth_unproject(ar, mats, mval_ofs, depth, coords[i])) {
 					depths_valid[i] = true;
 				}
-
 			}
 			i++;
 		}
@@ -347,66 +381,98 @@ static bool depth_read_normal(
 	}
 }
 
-static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
+/**
+ * Sets the depth from #StrokeElem.mval
+ */
+static bool stroke_elem_project(
+        const struct CurveDrawData *cdd,
+        const int mval_i[2], const float mval_fl[2],
+        float r_location_world[3])
 {
-	struct CurveDrawData *cdd = op->customdata;
-	Object *obedit = cdd->vc.obedit;
-	const float mval_fl[2] = {event->mval[0], event->mval[1]};
 	View3D *v3d = cdd->vc.v3d;
-
-	invert_m4_m4(obedit->imat, obedit->obmat);
-
-	struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool);
+	ARegion *ar = cdd->vc.ar;
+	RegionView3D *rv3d = cdd->vc.rv3d;
 
 	bool is_location_world_set = false;
 
 	/* project to 'location_world' */
-	if (cdd->use_project_plane) {
+	if (cdd->project.use_plane) {
 		/* get the view vector to 'location' */
 		float ray_origin[3], ray_direction[3];
 		ED_view3d_win_to_ray(cdd->vc.ar, v3d, mval_fl, ray_origin, ray_direction, false);
 
 		float lambda;
-		if (isect_ray_plane_v3(ray_origin, ray_direction, cdd->project_plane, &lambda, true)) {
-			madd_v3_v3v3fl(selem->location_world, ray_origin, ray_direction, lambda);
+		if (isect_ray_plane_v3(ray_origin, ray_direction, cdd->project.plane, &lambda, true)) {
+			madd_v3_v3v3fl(r_location_world, ray_origin, ray_direction, lambda);
 			is_location_world_set = true;
 		}
 	}
 	else {
-		const ViewDepths *depths = cdd->vc.rv3d->depths;
+		const ViewDepths *depths = rv3d->depths;
 		if (depths &&
-		    ((unsigned int)event->mval[0] < depths->w) &&
-		    ((unsigned int)event->mval[1] < depths->h))
+		    ((unsigned int)mval_i[0] < depths->w) &&
+		    ((unsigned int)mval_i[1] < depths->h))
 		{
-			float depth = depth_read(&cdd->vc, event->mval[0], event->mval[1]);
+			float depth = depth_read_zbuf(&cdd->vc, mval_i[0], mval_i[1]);
 			if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
-				is_location_world_set = true;
-				double p[3];
-				if (gluUnProject(
-				        (double)event->x + 0.5, event->y + 0.5, depth,
-				        cdd->mats.modelview, cdd->mats.projection, (GLint *)cdd->mats.viewport,
-				        &p[0], &p[1], &p[2]))
-				{
-					copy_v3fl_v3db(selem->location_world, p);
+				if (depth_unproject(ar, &cdd->mats, mval_i, depth, r_location_world)) {
 					is_location_world_set = true;
 				}
 			}
 		}
 	}
 
-	/* fallback to previous depth */
-	if (!is_location_world_set) {
-		ED_view3d_win_to_3d(cdd->vc.ar, cdd->prev.location_world_valid, mval_fl, selem->location_world);
+	return is_location_world_set;
+}
+
+static bool stroke_elem_project_fallback(
+        const struct CurveDrawData *cdd,
+        const int mval_i[2], const float mval_fl[2],
+        const float location_fallback_depth[3],
+        float r_location_world[3], float r_location_local[3])
+{
+	bool is_depth_found = stroke_elem_project(cdd, mval_i, mval_fl, r_location_world);
+	if (is_depth_found == false) {
+		ED_view3d_win_to_3d(cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world);
 	}
-	else {
+	mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world);
+
+	return is_depth_found;
+}
+
+static bool stroke_elem_project_fallback_elem(
+        const struct CurveDrawData *cdd,
+        const float location_fallback_depth[3],
+        struct StrokeElem *selem)
+{
+	const int mval_i[2] = {UNPACK2(selem->mval)};
+	return stroke_elem_project_fallback(
+	        cdd, mval_i, selem->mval, location_fallback_depth,
+	        selem->location_world, selem->location_local);
+}
+
+
+static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
+{
+	struct CurveDrawData *cdd = op->customdata;
+	Object *obedit = cdd->vc.obedit;
+
+	invert_m4_m4(obedit->imat, obedit->obmat);
+
+	struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool);
+
+	ARRAY_SET_ITEMS(selem->mval, event->mval[0], event->mval[1]);
+
+	bool is_depth_found = stroke_elem_project_fallback_elem(
+	        cdd, cdd->prev.location_world_valid, selem);
+
+	if (is_depth_found) {
+		/* use the depth if a fallback wasn't used */
 		copy_v3_v3(cdd->prev.location_world_valid, selem->location_world);
 	}
 	copy_v3_v3(cdd->prev.location_world, selem->location_world);
 
 
-	copy_v2_v2(selem->mouse, mval_fl);
-	mul_v3_m4v3(selem->location_local, obedit->imat, selem->location_world);
-
 	/* handle pressure sensitivity (which is supplied by tablets) */
 	if (event->tablet_data) {
 		const wmTabletData *wmtab = event->tablet_data;
@@ -416,8 +482,35 @@ static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
 		selem->pressure = 1.0f;
 	}
 
-	copy_v2_v2(cdd->prev.mouse, mval_fl);
-	copy_v3_v3(cdd->prev.mouse, selem->location_world);
+	float len_sq = len_squared_v2v2(cdd->prev.mouse, selem->mval);
+	copy_v2_v2(cdd->prev.mouse, selem->mval);
+
+	if (cdd->sample.use_substeps && cdd->prev.selem) {
+		const struct StrokeElem selem_target = *selem;
+		struct StrokeElem *selem_new_last = selem;
+		if (len_sq >= SQUARE(STROKE_SAMPLE_DIST_MAX_PX)) {
+			int n = (int)ceil(sqrt((double)len_sq)) / STROKE_SAMPLE_DIST_MAX_PX ;
+
+			for (int i = 1; i < n; i++) {
+				struct StrokeElem *selem_new = selem_new_last;
+				s

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list