[Bf-blender-cvs] [d48737a] temp-curve-draw: Option to use the surface as starting point for the stroke

Campbell Barton noreply at git.blender.org
Thu Apr 14 08:10:38 CEST 2016


Commit: d48737afe99928ac3c68f220e21f2516b5bb8ee1
Author: Campbell Barton
Date:   Thu Apr 14 16:05:06 2016 +1000
Branches: temp-curve-draw
https://developer.blender.org/rBd48737afe99928ac3c68f220e21f2516b5bb8ee1

Option to use the surface as starting point for the stroke

Similar to grease pencil end-points, however this only works for the first point.

Uses a plane calculated from the surface normal (so lines can be drawn perpendicular to the surface).

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/editors/curve/editcurve_paint.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index f2188ee..124ebbd 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -587,6 +587,10 @@ class VIEW3D_PT_tools_curveedit_options(View3DPanel, Panel):
         row = layout.row(align=True)
         row.prop(cps, "depth_mode", expand=True)
 
+        col = layout.column()
+        if cps.depth_mode == 'SURFACE':
+            col.prop(cps, "use_stroke_endpoints")
+
 
 # ********** default tools for editmode_surface ****************
 
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index dc19de1..20150ff 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -273,6 +273,79 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
 	}
 }
 
+static float depth_read(const ViewContext *vc, int x, int y)
+{
+	ViewDepths *vd = vc->rv3d->depths;
+
+	if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h)
+		return vd->depths[y * vd->w + x];
+	else
+		return -1.0f;
+}
+
+static bool depth_read_normal(
+        const ViewContext *vc, const bglMats *mats, const int mval[2],
+        float r_normal[3])
+{
+	/* pixels surrounding */
+	bool  depths_valid[9] = {false};
+	float coords[9][3] = {{0}};
+
+	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]);
+			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);
+					depths_valid[i] = true;
+				}
+
+			}
+			i++;
+		}
+	}
+
+	const int edges[2][6][2] = {
+	    /* x edges */
+	    {{0, 1}, {1, 2},
+	     {3, 4}, {4, 5},
+	     {6, 7}, {7, 8}},
+	    /* y edges */
+	    {{0, 3}, {3, 6},
+	     {1, 4}, {4, 7},
+	     {2, 5}, {5, 8}},
+	};
+
+	float cross[2][3] = {{0.0f}};
+
+	for (int i = 0; i < 6; i++) {
+		for (int axis = 0; axis < 2; axis++) {
+			if (depths_valid[edges[axis][i][0]] && depths_valid[edges[axis][i][1]]) {
+				float delta[3];
+				sub_v3_v3v3(delta, coords[edges[axis][i][0]], coords[edges[axis][i][1]]);
+				add_v3_v3(cross[axis], delta);
+			}
+		}
+	}
+
+	cross_v3_v3v3(r_normal, cross[0], cross[1]);
+
+	if (normalize_v3(r_normal) != 0.0f) {
+		return true;
+	}
+	else {
+		return false;
+	}
+}
 
 static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
 {
@@ -305,15 +378,14 @@ static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
 		    ((unsigned int)event->mval[0] < depths->w) &&
 		    ((unsigned int)event->mval[1] < depths->h))
 		{
-			float depth = ED_view3d_depth_read_cached(&cdd->vc, event->x, event->y);
-			ED_view3d_autodist_simple(cdd->vc.ar, event->mval, selem->location_world, 0, &depth);
-
-			if ((depth > depths->depth_range[0]) &&
-			    (depth < depths->depth_range[1]))
-			{
+			float depth = depth_read(&cdd->vc, event->mval[0], event->mval[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]))
+				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);
 					is_location_world_set = true;
@@ -627,6 +699,8 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 
 	view3d_set_viewcontext(C, &cdd->vc);
 
+	const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
+
 	/* fallback (incase we can't find the depth on first test) */
 	{
 		const float mval_fl[2] = {UNPACK2(event->mval)};
@@ -644,7 +718,6 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 
 
 	{
-		const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings;
 		View3D *v3d = cdd->vc.v3d;
 		RegionView3D *rv3d = cdd->vc.rv3d;
 		Object *obedit = cdd->vc.obedit;
@@ -692,6 +765,31 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 	/* add first point */
 	curve_draw_event_add(op, event);
 
+	if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) && cdd->use_project_depth &&
+	    (cps->flag & CURVE_PAINT_FLAG_DEPTH_STROKE_ENDPOINTS))
+	{
+		RegionView3D *rv3d = cdd->vc.rv3d;
+
+		cdd->use_project_depth = false;
+		cdd->use_project_plane = true;
+
+		/* calculate the plane from the surface normal */
+		float normal[3];
+		if (depth_read_normal(&cdd->vc, &cdd->mats, event->mval, normal)) {
+			float cross_a[3], cross_b[3];
+			cross_v3_v3v3(cross_a, rv3d->viewinv[2], normal);
+			cross_v3_v3v3(cross_b, normal, cross_a);
+			copy_v3_v3(normal, cross_b);
+		}
+		else {
+			copy_v3_v3(normal, rv3d->viewinv[2]);
+		}
+
+		normalize_v3_v3(cdd->project_plane, normal);
+		cdd->project_plane[3] = -dot_v3v3(cdd->project_plane, cdd->prev.location_world_valid);
+
+	}
+
 	return OPERATOR_RUNNING_MODAL;
 }
 
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 2ee22e4..957e44a 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1279,6 +1279,7 @@ typedef struct CurvePaintSettings {
 enum {
 	CURVE_PAINT_FLAG_CORNERS_DETECT			= (1 << 0),
 	CURVE_PAINT_FLAG_PRESSURE_RADIUS		= (1 << 1),
+	CURVE_PAINT_FLAG_DEPTH_STROKE_ENDPOINTS	= (1 << 2),
 };
 
 enum {
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 65a1b3b..0f3e5d4 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2625,6 +2625,11 @@ static void rna_def_curve_paint_settings(BlenderRNA  *brna)
 	RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
 	RNA_def_property_ui_text(prop, "Use Pressure", "Map tablet pressure to curve radius");
 
+	prop = RNA_def_property(srna, "use_stroke_endpoints", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", CURVE_PAINT_FLAG_DEPTH_STROKE_ENDPOINTS);
+	RNA_def_property_ui_text(prop, "Only First", "Only use the first part of the stroke for snapping");
+
+
 	prop = RNA_def_property(srna, "error_threshold", PROP_INT, PROP_PIXEL);
 	RNA_def_property_range(prop, 1, 100);
 	RNA_def_property_ui_text(prop, "Tolerance", "Allow deviation for a smoother, less preceise line");




More information about the Bf-blender-cvs mailing list