[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