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:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/curve.c10
-rw-r--r--source/blender/blenkernel/intern/mask.c185
2 files changed, 140 insertions, 55 deletions
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 44c9bc9ebbe..0ce2953a2e3 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -3080,7 +3080,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
madd_v3_v3v3fl(p2_h2, p2, dvec_b, 1.0f / 3.0f);
}
- if (skip_align || !ELEM(HD_ALIGN, bezt->h1, bezt->h2)) {
+ if (skip_align || (!ELEM(HD_ALIGN, bezt->h1, bezt->h2) && !ELEM(HD_ALIGN_DOUBLESIDE, bezt->h1, bezt->h2))) {
/* handles need to be updated during animation and applying stuff like hooks,
* but in such situations it's quite difficult to distinguish in which order
* align handles should be aligned so skip them for now */
@@ -3095,7 +3095,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
len_b = 1.0f;
if (bezt->f1 & SELECT) { /* order of calculation */
- if (bezt->h2 == HD_ALIGN) { /* aligned */
+ if (ELEM(bezt->h2, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) { /* aligned */
if (len_a > eps) {
len = len_b / len_a;
p2_h2[0] = p2[0] + len * (p2[0] - p2_h1[0]);
@@ -3103,7 +3103,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
p2_h2[2] = p2[2] + len * (p2[2] - p2_h1[2]);
}
}
- if (bezt->h1 == HD_ALIGN) {
+ if (ELEM(bezt->h1, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) {
if (len_b > eps) {
len = len_a / len_b;
p2_h1[0] = p2[0] + len * (p2[0] - p2_h2[0]);
@@ -3113,7 +3113,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
}
}
else {
- if (bezt->h1 == HD_ALIGN) {
+ if (ELEM(bezt->h1, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) {
if (len_b > eps) {
len = len_a / len_b;
p2_h1[0] = p2[0] + len * (p2[0] - p2_h2[0]);
@@ -3121,7 +3121,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
p2_h1[2] = p2[2] + len * (p2[2] - p2_h2[2]);
}
}
- if (bezt->h2 == HD_ALIGN) { /* aligned */
+ if (ELEM(bezt->h2, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) { /* aligned */
if (len_a > eps) {
len = len_b / len_a;
p2_h2[0] = p2[0] + len * (p2[0] - p2_h1[0]);
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index d08b7316e61..8ea035e3249 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -435,58 +435,87 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point,
/* point */
-bool BKE_mask_point_has_handle(MaskSplinePoint *point)
+eMaskhandleMode BKE_mask_point_handles_mode_get(MaskSplinePoint *point)
{
BezTriple *bezt = &point->bezt;
- return bezt->h1 == HD_ALIGN;
+ if (bezt->h1 == bezt->h2 && bezt->h1 == HD_ALIGN) {
+ return MASK_HANDLE_MODE_STICK;
+ }
+
+ return MASK_HANDLE_MODE_INDIVIDUAL_HANDLES;
}
-void BKE_mask_point_handle(MaskSplinePoint *point, float handle[2])
+void BKE_mask_point_handle(MaskSplinePoint *point, eMaskWhichHandle which_handle, float handle[2])
{
- float vec[2];
+ BezTriple *bezt = &point->bezt;
+
+ if (which_handle == MASK_WHICH_HANDLE_STICK) {
+ float vec[2];
- sub_v2_v2v2(vec, point->bezt.vec[0], point->bezt.vec[1]);
+ sub_v2_v2v2(vec, bezt->vec[0], bezt->vec[1]);
- handle[0] = (point->bezt.vec[1][0] + vec[1]);
- handle[1] = (point->bezt.vec[1][1] - vec[0]);
+ handle[0] = (bezt->vec[1][0] + vec[1]);
+ handle[1] = (bezt->vec[1][1] - vec[0]);
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ copy_v2_v2(handle, bezt->vec[0]);
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ copy_v2_v2(handle, bezt->vec[2]);
+ }
+ else {
+ BLI_assert(!"Unknown handle passed to BKE_mask_point_handle");
+ }
}
-void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], bool keep_direction,
+void BKE_mask_point_set_handle(MaskSplinePoint *point, eMaskWhichHandle which_handle,
+ float loc[2], bool keep_direction,
float orig_handle[2], float orig_vec[3][3])
{
BezTriple *bezt = &point->bezt;
- float v1[2], v2[2], vec[2];
- if (keep_direction) {
- sub_v2_v2v2(v1, loc, orig_vec[1]);
- sub_v2_v2v2(v2, orig_handle, orig_vec[1]);
+ if (which_handle == MASK_WHICH_HANDLE_STICK) {
+ float v1[2], v2[2], vec[2];
+ if (keep_direction) {
+ sub_v2_v2v2(v1, loc, orig_vec[1]);
+ sub_v2_v2v2(v2, orig_handle, orig_vec[1]);
- project_v2_v2v2(vec, v1, v2);
+ project_v2_v2v2(vec, v1, v2);
- if (dot_v2v2(v2, vec) > 0) {
- float len = len_v2(vec);
+ if (dot_v2v2(v2, vec) > 0) {
+ float len = len_v2(vec);
- sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]);
+ sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]);
- mul_v2_fl(v1, len / len_v2(v1));
+ mul_v2_fl(v1, len / len_v2(v1));
- add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1);
- sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1);
+ add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1);
+ sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1);
+ }
+ else {
+ copy_v3_v3(bezt->vec[0], bezt->vec[1]);
+ copy_v3_v3(bezt->vec[2], bezt->vec[1]);
+ }
}
else {
- copy_v3_v3(bezt->vec[0], bezt->vec[1]);
- copy_v3_v3(bezt->vec[2], bezt->vec[1]);
+ sub_v2_v2v2(v1, loc, bezt->vec[1]);
+
+ v2[0] = -v1[1];
+ v2[1] = v1[0];
+
+ add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2);
+ sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2);
}
}
+ else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ copy_v2_v2(bezt->vec[0], loc);
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ copy_v2_v2(bezt->vec[2], loc);
+ }
else {
- sub_v2_v2v2(v1, loc, bezt->vec[1]);
-
- v2[0] = -v1[1];
- v2[1] = v1[0];
-
- add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2);
- sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2);
+ BLI_assert(!"unknown handle passed to BKE_mask_point_set_handle");
}
}
@@ -514,36 +543,68 @@ void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float
interp_v2_v2v2(co, r0, r1, u);
}
+BLI_INLINE void orthogonal_direction_get(float vec[2], float result[2])
+{
+ result[0] = -vec[1];
+ result[1] = vec[0];
+ normalize_v2(result);
+}
+
+/* TODO(sergey): This function will re-calculate loads of stuff again and again
+ * when differentiating feather points. This might be easily cached
+ * in the callee function for this case.
+ */
void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float n[2])
{
- MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
- BezTriple *bezt = &point->bezt, *bezt_next;
- float q0[2], q1[2], q2[2], r0[2], r1[2], vec[2];
+ MaskSplinePoint *point_prev, *point_next;
- bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
+ /* TODO(sergey): This actually depends on a resolution. */
+ const float du = 0.05f;
- if (!bezt_next) {
- BKE_mask_point_handle(point, vec);
+ BKE_mask_get_handle_point_adjacent(spline, point, &point_prev, &point_next);
- sub_v2_v2v2(n, vec, bezt->vec[1]);
- normalize_v2(n);
- return;
+ if (u - du < 0.0f && point_prev == NULL) {
+ float co[2], dir[2];
+ BKE_mask_point_segment_co(spline, point, u + du, co);
+ sub_v2_v2v2(dir, co, point->bezt.vec[1]);
+ orthogonal_direction_get(dir, n);
+ }
+ else if (u + du > 1.0f && point_next == NULL) {
+ float co[2], dir[2];
+ BKE_mask_point_segment_co(spline, point, u - du, co);
+ sub_v2_v2v2(dir, point->bezt.vec[1], co);
+ orthogonal_direction_get(dir, n);
}
+ else {
+ float prev_co[2], next_co[2], co[2];
+ float dir1[2], dir2[2], dir[2];
- interp_v2_v2v2(q0, bezt->vec[1], bezt->vec[2], u);
- interp_v2_v2v2(q1, bezt->vec[2], bezt_next->vec[0], u);
- interp_v2_v2v2(q2, bezt_next->vec[0], bezt_next->vec[1], u);
+ if (u - du < 0.0f) {
+ BKE_mask_point_segment_co(spline, point_prev, 1.0f + (u - du), prev_co);
+ }
+ else {
+ BKE_mask_point_segment_co(spline, point, u - du, prev_co);
+ }
- interp_v2_v2v2(r0, q0, q1, u);
- interp_v2_v2v2(r1, q1, q2, u);
+ BKE_mask_point_segment_co(spline, point, u, co);
+
+ if (u + du > 1.0f) {
+ BKE_mask_point_segment_co(spline, point_next, u + du - 1.0f, next_co);
+ }
+ else {
+ BKE_mask_point_segment_co(spline, point, u + du, next_co);
+ }
- sub_v2_v2v2(vec, r1, r0);
+ sub_v2_v2v2(dir1, co, prev_co);
+ sub_v2_v2v2(dir2, next_co, co);
- n[0] = -vec[1];
- n[1] = vec[0];
+ normalize_v2(dir1);
+ normalize_v2(dir2);
+ add_v2_v2v2(dir, dir1, dir2);
- normalize_v2(n);
+ orthogonal_direction_get(dir, n);
+ }
}
static float mask_point_interp_weight(BezTriple *bezt, BezTriple *bezt_next, const float u)
@@ -693,13 +754,37 @@ void BKE_mask_point_select_set(MaskSplinePoint *point, const bool do_select)
}
}
-void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const bool do_select)
+void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const eMaskWhichHandle which_handle, const bool do_select)
{
if (do_select) {
- MASKPOINT_SEL_HANDLE(point);
+ if (ELEM(which_handle, MASK_WHICH_HANDLE_STICK, MASK_WHICH_HANDLE_BOTH)) {
+ point->bezt.f1 |= SELECT;
+ point->bezt.f3 |= SELECT;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ point->bezt.f1 |= SELECT;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ point->bezt.f3 |= SELECT;
+ }
+ else {
+ BLI_assert(!"Wrong which_handle passed to BKE_mask_point_select_set_handle");
+ }
}
else {
- MASKPOINT_DESEL_HANDLE(point);
+ if (ELEM(which_handle, MASK_WHICH_HANDLE_STICK, MASK_WHICH_HANDLE_BOTH)) {
+ point->bezt.f1 &= ~SELECT;
+ point->bezt.f3 &= ~SELECT;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
+ point->bezt.f1 &= ~SELECT;
+ }
+ else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
+ point->bezt.f3 &= ~SELECT;
+ }
+ else {
+ BLI_assert(!"Wrong which_handle passed to BKE_mask_point_select_set_handle");
+ }
}
}
@@ -1170,7 +1255,7 @@ static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *poin
else if (handle_type == HD_AUTO) {
BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0);
}
- else if (handle_type == HD_ALIGN) {
+ else if (handle_type == HD_ALIGN || handle_type == HD_ALIGN_DOUBLESIDE) {
float v1[3], v2[3];
float vec[3], h[3];