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>2016-04-22 14:28:39 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-04-22 14:34:04 +0300
commitf4ecd24f96b158cb6b3c21686ebd048a9cca2c71 (patch)
tree123b737b33c162d4c701253c6d0b6ad0d78e8360 /source/blender/editors/curve/editcurve_paint.c
parentc12e1a09ec7e76455d81fe4114e91a1561cbdb6d (diff)
Fix curve snap to surface w/ offset & taper
Adjusting the pressure wasn't re-adjusting the offset.
Diffstat (limited to 'source/blender/editors/curve/editcurve_paint.c')
-rw-r--r--source/blender/editors/curve/editcurve_paint.c68
1 files changed, 55 insertions, 13 deletions
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 5a4cd871feb..bc54d27b171 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -170,6 +170,11 @@ struct StrokeElem {
float mval[2];
float location_world[3];
float location_local[3];
+
+ /* surface normal, may be zero'd */
+ float normal_world[3];
+ float normal_local[3];
+
float pressure;
};
@@ -225,10 +230,26 @@ struct CurveDrawData {
void *draw_handle_view;
};
-static float stroke_elem_radius(const struct CurveDrawData *cdd, const struct StrokeElem *selem)
+static float stroke_elem_radius_from_pressure(const struct CurveDrawData *cdd, const float pressure)
{
const Curve *cu = cdd->vc.obedit->data;
- return ((selem->pressure * cdd->radius.range) + cdd->radius.min) * cu->ext2;
+ return ((pressure * cdd->radius.range) + cdd->radius.min) * cu->ext2;
+}
+
+static float stroke_elem_radius(const struct CurveDrawData *cdd, const struct StrokeElem *selem)
+{
+ return stroke_elem_radius_from_pressure(cdd, selem->pressure);
+}
+
+static void stroke_elem_pressure_set(const struct CurveDrawData *cdd, struct StrokeElem *selem, float pressure)
+{
+ if ((cdd->radius.offset != 0.0f) && !is_zero_v3(selem->normal_local)) {
+ const float adjust = stroke_elem_radius_from_pressure(cdd, pressure) -
+ stroke_elem_radius_from_pressure(cdd, selem->pressure);
+ madd_v3_v3fl(selem->location_local, selem->normal_local, adjust);
+ mul_v3_m4v3(selem->location_world, cdd->vc.obedit->obmat, selem->location_local);
+ }
+ selem->pressure = pressure;
}
static void stroke_elem_interp(
@@ -249,7 +270,7 @@ static bool stroke_elem_project(
const struct CurveDrawData *cdd,
const int mval_i[2], const float mval_fl[2],
const float radius_offset, const float radius,
- float r_location_world[3])
+ float r_location_world[3], float r_normal_world[3])
{
View3D *v3d = cdd->vc.v3d;
ARegion *ar = cdd->vc.ar;
@@ -266,6 +287,9 @@ static bool stroke_elem_project(
float 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);
+ if (r_normal_world) {
+ zero_v3(r_normal_world);
+ }
is_location_world_set = true;
}
}
@@ -279,11 +303,17 @@ static bool stroke_elem_project(
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
if (depth_unproject(ar, &cdd->mats, mval_i, depth, r_location_world)) {
is_location_world_set = true;
+ if (r_normal_world) {
+ zero_v3(r_normal_world);
+ }
if (radius_offset != 0.0f) {
float normal[3];
if (depth_read_normal(&cdd->vc, &cdd->mats, mval_i, normal)) {
madd_v3_v3fl(r_location_world, normal, radius_offset * radius);
+ if (r_normal_world) {
+ copy_v3_v3(r_normal_world, normal);
+ }
}
}
}
@@ -305,17 +335,28 @@ static bool stroke_elem_project_fallback(
const int mval_i[2], const float mval_fl[2],
const float radius_offset, const float radius,
const float location_fallback_depth[3],
- float r_location_world[3], float r_location_local[3])
+ float r_location_world[3], float r_location_local[3],
+ float r_normal_world[3], float r_normal_local[3])
{
bool is_depth_found = stroke_elem_project(
cdd, mval_i, mval_fl,
radius_offset, radius,
- r_location_world);
+ r_location_world, r_normal_world);
if (is_depth_found == false) {
ED_view3d_win_to_3d(cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world);
+ zero_v3(r_normal_local);
}
mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world);
+ if (!is_zero_v3(r_normal_world)) {
+ copy_v3_v3(r_normal_local, r_normal_world);
+ mul_transposed_mat3_m4_v3(cdd->vc.obedit->obmat, r_normal_local);
+ normalize_v3(r_normal_local);
+ }
+ else {
+ zero_v3(r_normal_local);
+ }
+
return is_depth_found;
}
@@ -333,7 +374,8 @@ static bool stroke_elem_project_fallback_elem(
cdd, mval_i, selem->mval,
cdd->radius.offset, radius,
location_fallback_depth,
- selem->location_world, selem->location_local);
+ selem->location_world, selem->location_local,
+ selem->normal_world, selem->normal_local);
}
/** \} */
@@ -602,7 +644,7 @@ static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event)
if (stroke_elem_project(
cdd, event->mval, mval_fl, 0.0f, 0.0f,
- location_no_offset))
+ location_no_offset, NULL))
{
sub_v3_v3v3(cdd->project.offset, cdd->prev.location_world_valid, location_no_offset);
if (!is_zero_v3(cdd->project.offset)) {
@@ -739,19 +781,19 @@ static void curve_draw_exec_precalc(wmOperator *op)
}
if (cps->radius_taper_start != 0.0f) {
- selem_array[0]->pressure = 0.0f;
const float len_taper_max = cps->radius_taper_start * len_3d;
- for (i = 1; i < stroke_len && lengths[i] < len_taper_max; i++) {
- selem_array[i]->pressure *= lengths[i] / len_taper_max;
+ for (i = 0; i < stroke_len && lengths[i] < len_taper_max; i++) {
+ const float pressure_new = selem_array[i]->pressure * (lengths[i] / len_taper_max);
+ stroke_elem_pressure_set(cdd, selem_array[i], pressure_new);
}
}
if (cps->radius_taper_end != 0.0f) {
- selem_array[stroke_len - 1]->pressure = 0.0f;
const float len_taper_max = cps->radius_taper_end * len_3d;
const float len_taper_min = len_3d - len_taper_max;
- for (i = stroke_len - 2; i > 0 && lengths[i] > len_taper_min; i--) {
- selem_array[i]->pressure *= (len_3d - lengths[i]) / len_taper_max;
+ for (i = stroke_len - 1; i > 0 && lengths[i] > len_taper_min; i--) {
+ const float pressure_new = selem_array[i]->pressure * ((len_3d - lengths[i]) / len_taper_max);
+ stroke_elem_pressure_set(cdd, selem_array[i], pressure_new);
}
}