[Bf-blender-cvs] [81be53bf88c] soc-2021-curves: Improved insert point algorithm
Dilith Jayakody
noreply at git.blender.org
Sat Feb 5 13:28:31 CET 2022
Commit: 81be53bf88ce46870cbd4382afb6ae498f52c307
Author: Dilith Jayakody
Date: Sat Feb 5 17:49:39 2022 +0530
Branches: soc-2021-curves
https://developer.blender.org/rB81be53bf88ce46870cbd4382afb6ae498f52c307
Improved insert point algorithm
===================================================================
M source/blender/editors/curve/editcurve_pen.c
===================================================================
diff --git a/source/blender/editors/curve/editcurve_pen.c b/source/blender/editors/curve/editcurve_pen.c
index f8ffef23ff9..f3f8de715bd 100644
--- a/source/blender/editors/curve/editcurve_pen.c
+++ b/source/blender/editors/curve/editcurve_pen.c
@@ -501,54 +501,6 @@ static void delete_bp_from_nurb(const BPoint *bp, Nurb *nu)
memmove(nu->bp + index, nu->bp + index + 1, (nu->pntsu - index) * sizeof(BPoint));
}
-/* Get the closest point on an edge to a given point based on perpendicular distance. Return true
- * if the closest point falls on the edge. */
-static bool get_closest_point_on_edge(float r_point[3],
- const float pos[2],
- const float pos1[3],
- const float pos2[3],
- const ViewContext *vc,
- float *r_fraction)
-{
- float pos1_2d[2], pos2_2d[2], vec1[2], vec2[2], vec3[2];
-
- /* Get screen space coordinates of points. */
- if (!(worldspace_to_screenspace(pos1, vc, pos1_2d) &&
- worldspace_to_screenspace(pos2, vc, pos2_2d))) {
- return false;
- }
-
- /* Obtain the vectors of each side. */
- sub_v2_v2v2(vec1, pos, pos1_2d);
- sub_v2_v2v2(vec2, pos2_2d, pos);
- sub_v2_v2v2(vec3, pos2_2d, pos1_2d);
-
- const float dot1 = dot_v2v2(vec1, vec3);
- const float dot2 = dot_v2v2(vec2, vec3);
-
- /* Compare the dot products to identify if both angles are optuse/acute or
- opposite to each other. If they're the same, that indicates that there is a
- perpendicular line from the mouse to the line.*/
- if ((dot1 > 0) == (dot2 > 0)) {
- const float len_vec3_sq = len_squared_v2(vec3);
- *r_fraction = 1 - dot2 / len_vec3_sq;
-
- float pos_dif[3];
- sub_v3_v3v3(pos_dif, pos2, pos1);
- madd_v3_v3v3fl(r_point, pos1, pos_dif, *r_fraction);
- return true;
- }
-
- if (len_manhattan_v2(vec1) < len_manhattan_v2(vec2)) {
- copy_v3_v3(r_point, pos1);
- *r_fraction = 0.0f;
- return false;
- }
- copy_v3_v3(r_point, pos2);
- *r_fraction = 1.0f;
- return false;
-}
-
/* Get closest vertex in all nurbs in given #ListBase to a given point.
* Returns true if point is found. */
static bool get_closest_vertex_to_point_in_nurbs(const ListBase *nurbs,
@@ -629,70 +581,6 @@ static bool get_closest_vertex_to_point_in_nurbs(const ListBase *nurbs,
return false;
}
-/* Assign values for several frequently changing attributes of #CutData. */
-static void assign_cut_data(CutData *data,
- Nurb *nu,
- const float min_dist,
- const int bezt_index,
- const int bp_index,
- const float parameter,
- const float cut_loc[3])
-{
- data->min_dist = min_dist;
- data->nurb = nu;
- data->bezt_index = bezt_index;
- data->bp_index = bp_index;
- data->parameter = parameter;
- copy_v3_v3(data->cut_loc, cut_loc);
-}
-
-/* Iterate over all the geometry between the segment formed by bezt1 and bezt2
- * to find the closest edge to #data->mval (mouse location) and update #data->prev_loc
- * and #data->next_loc with the vertices of the edge. */
-static void update_data_if_closest_point_in_segment(const BezTriple *bezt1,
- const BezTriple *bezt2,
- Nurb *nu,
- const int index,
- const ViewContext *vc,
- CutData *data)
-{
- const float resolu = nu->resolu;
- float *points = MEM_mallocN(sizeof(float[3]) * (resolu + 1), __func__);
-
- /* Calculate all points on curve. */
- for (int j = 0; j < 3; j++) {
- BKE_curve_forward_diff_bezier(bezt1->vec[1][j],
- bezt1->vec[2][j],
- bezt2->vec[0][j],
- bezt2->vec[1][j],
- points + j,
- resolu,
- sizeof(float[3]));
- }
-
- for (int k = 0; k <= resolu; k++) {
- float screen_co[2];
- const bool check = worldspace_to_screenspace(points + 3 * k, vc, screen_co);
-
- if (check) {
- const float distance = len_manhattan_v2v2(screen_co, data->mval);
- if (distance < data->min_dist) {
- assign_cut_data(data, nu, distance, index, -1, ((float)k) / resolu, points + 3 * k);
-
- data->has_prev = k > 0;
- data->has_next = k < resolu;
- if (data->has_prev) {
- copy_v3_v3(data->prev_loc, points + 3 * (k - 1));
- }
- if (data->has_next) {
- copy_v3_v3(data->next_loc, points + 3 * (k + 1));
- }
- }
- }
- }
- MEM_freeN(points);
-}
-
/* Interpolate along the Bezier segment by a parameter (between 0 and 1) and get its location. */
static void get_bezier_interpolated_point(float r_point[3],
const BezTriple *bezt1,
@@ -708,38 +596,6 @@ static void get_bezier_interpolated_point(float r_point[3],
interp_v3_v3v3(r_point, tmp1, tmp2, parameter);
}
-/* Update the closest location as cut location in data. */
-static void update_cut_loc_in_data(CutData *data, const ViewContext *vc)
-{
- bool found_min = false;
- float point[3], factor;
-
- if (data->has_prev) {
- found_min = get_closest_point_on_edge(
- point, data->mval, data->cut_loc, data->prev_loc, vc, &factor);
- factor = -factor;
- }
- if (!found_min && data->has_next) {
- found_min = get_closest_point_on_edge(
- point, data->mval, data->cut_loc, data->next_loc, vc, &factor);
- }
- if (found_min) {
- float point_2d[2];
- if (worldspace_to_screenspace(point, vc, point_2d)) {
- return;
- }
- const float dist = len_manhattan_v2v2(point_2d, data->mval);
- data->min_dist = dist;
- data->parameter += factor / data->nurb->resolu;
-
- Nurb *nu = data->nurb;
- get_bezier_interpolated_point(data->cut_loc,
- &nu->bezt[data->bezt_index],
- &nu->bezt[(data->bezt_index + 1) % (nu->pntsu)],
- data->parameter);
- }
-}
-
/* Calculate handle positions of added and adjacent control points such that shape is preserved. */
static void calculate_new_bezier_point(const float point_prev[3],
float handle_prev[3],
@@ -757,75 +613,6 @@ static void calculate_new_bezier_point(const float point_prev[3],
interp_v3_v3v3(new_right_handle, center_point, handle_next, parameter);
}
-/* Update the nearest point data for all nurbs. */
-static void update_data_for_all_nurbs(const ListBase *nurbs, const ViewContext *vc, CutData *data)
-{
- LISTBASE_FOREACH (Nurb *, nu, nurbs) {
- if (nu->type == CU_BEZIER) {
- float screen_co[2];
- if (data->nurb == NULL) {
- worldspace_to_screenspace(nu->bezt->vec[1], vc, screen_co);
- assign_cut_data(data, nu, FLT_MAX, 0, -1, 0.0f, nu->bezt->vec[1]);
- }
-
- BezTriple *bezt = NULL;
- for (int i = 0; i < nu->pntsu - 1; i++) {
- bezt = &nu->bezt[i];
- update_data_if_closest_point_in_segment(bezt, bezt + 1, nu, i, vc, data);
- }
-
- if (nu->flagu & CU_NURB_CYCLIC && bezt) {
- update_data_if_closest_point_in_segment(bezt + 1, nu->bezt, nu, nu->pntsu - 1, vc, data);
- }
-
- float point[3], fraction = 0.0f;
- if (data->has_next) {
- get_closest_point_on_edge(point, data->mval, data->cut_loc, data->next_loc, vc, &fraction);
- worldspace_to_screenspace(point, vc, screen_co);
- const float len = len_manhattan_v2v2(screen_co, data->mval);
- data->min_dist = len;
- }
-
- if (data->has_prev) {
- get_closest_point_on_edge(point, data->mval, data->cut_loc, data->prev_loc, vc, &fraction);
- worldspace_to_screenspace(point, vc, screen_co);
- const float len = len_manhattan_v2v2(screen_co, data->mval);
- if (len < data->min_dist) {
- data->min_dist = len;
- fraction = -fraction;
- }
- }
-
- data->parameter += fraction / nu->resolu;
- }
- else {
- float screen_co[2];
- if (data->nurb == NULL) {
- worldspace_to_screenspace(nu->bp->vec, vc, screen_co);
- assign_cut_data(
- data, nu, len_manhattan_v2v2(screen_co, data->mval), -1, 0, 0.0f, nu->bp->vec);
- }
-
- const int end = (nu->flagu & CU_NURB_CYCLIC) ? nu->pntsu : nu->pntsu - 1;
- for (int i = 0; i < end; i++) {
- float point[3], factor;
- const int next_i = (i + 1) % nu->pntsu;
- const bool found_min = get_closest_point_on_edge(
- point, data->mval, (nu->bp + i)->vec, (nu->bp + next_i)->vec, vc, &factor);
- if (found_min) {
- float point_2d[2];
- if (worldspace_to_screenspace(point, vc, point_2d)) {
- const float dist = len_manhattan_v2v2(point_2d, data->mval);
- if (dist < data->min_dist) {
- assign_cut_data(data, nu, dist, -1, i, 0.0f, point);
- }
- }
- }
- }
- }
- }
-}
-
/* Insert a #BezTriple to a nurb at the location specified by `op_data`. */
static void insert_bezt_to_nurb(Nurb *nu, const CutData *data, Curve *cu)
{
@@ -924,10 +711,141 @@ static void insert_bp_to_nurb(Nurb *nu, const CutData *data, Curve *cu)
new_bp->f1 |= SELECT;
}
-/* Make a cut on the nearest nurb at the closest point. Return true if spline is nearby. */
-static bool insert_point_to_segment(
- const wmEvent *event, Curve *cu, Nurb **r_nu, const float sel_dist_mul, const ViewContext *vc)
+static void get_updated_data_for_edge(const float point[2],
+ const float point1[2],
+ const float point2[2],
+ const int point_idx,
+ const int resolu_idx,
+ float *min_dist,
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list