[Bf-blender-cvs] [cb537a49000] soc-2021-curves: Move handles of all extruded points
Dilith Jayakody
noreply at git.blender.org
Sat Jan 8 04:05:23 CET 2022
Commit: cb537a49000357f621dd7e825981ba443f86eff6
Author: Dilith Jayakody
Date: Thu Jan 6 07:41:35 2022 +0530
Branches: soc-2021-curves
https://developer.blender.org/rBcb537a49000357f621dd7e825981ba443f86eff6
Move handles of all extruded points
===================================================================
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 384613cfc6e..8557da53816 100644
--- a/source/blender/editors/curve/editcurve_pen.c
+++ b/source/blender/editors/curve/editcurve_pen.c
@@ -46,6 +46,19 @@
#include "float.h"
+#define FOREACH_SELECTED_BEZT_BEGIN(bezt, editnurb) \
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) { \
+ if (nu->type == CU_BEZIER) { \
+ for (int i = 0; i < nu->pntsu; i++) { \
+ BezTriple *bezt = nu->bezt + i; \
+ if (BEZT_ISSEL_ANY(bezt)) {
+
+#define FOREACH_SELECTED_BEZT_END \
+ } \
+ } \
+ } \
+ }
+
/* Data structure to keep track of details about the cut location */
typedef struct CutData {
/* Index of the last #BezTriple or BPoint before the cut. */
@@ -108,13 +121,26 @@ static const EnumPropertyItem prop_extra_key_types[] = {
{0, NULL, 0, NULL, NULL},
};
-static void screenspace_to_worldspace(const int pos_2d[2],
+static void screenspace_to_worldspace_int(const int pos_2d[2],
+ const float depth[3],
+ const ViewContext *vc,
+ float r_pos_3d[3])
+{
+ mul_v3_m4v3(r_pos_3d, vc->obedit->obmat, depth);
+ ED_view3d_win_to_3d_int(vc->v3d, vc->region, r_pos_3d, pos_2d, r_pos_3d);
+
+ float imat[4][4];
+ invert_m4_m4(imat, vc->obedit->obmat);
+ mul_m4_v3(imat, r_pos_3d);
+}
+
+static void screenspace_to_worldspace(const float pos_2d[2],
const float depth[3],
const ViewContext *vc,
float r_pos_3d[3])
{
mul_v3_m4v3(r_pos_3d, vc->obedit->obmat, depth);
- ED_view3d_win_to_3d_int(vc->v3d, vc->region, r_pos_3d, pos_2d, r_pos_3d);
+ ED_view3d_win_to_3d(vc->v3d, vc->region, r_pos_3d, pos_2d, r_pos_3d);
float imat[4][4];
invert_m4_m4(imat, vc->obedit->obmat);
@@ -142,26 +168,58 @@ static bool worldspace_to_screenspace_int(const float pos_3d[3],
return check;
}
+static void get_displacement_to_avg_selected_point(const ListBase *editnurb,
+ float change[2],
+ const wmEvent *event,
+ const ViewContext *vc)
+{
+ float total[3] = {0.0f, 0.0f, 0.0f};
+ int count = 0;
+ FOREACH_SELECTED_BEZT_BEGIN(bezt, editnurb)
+ add_v3_v3(total, bezt->vec[1]);
+ count++;
+ FOREACH_SELECTED_BEZT_END
+
+ if (count) {
+ mul_v3_fl(total, 1.0f / count);
+ worldspace_to_screenspace(total, vc, change);
+ float mval[2] = {(float)(event->mval[0]), (float)(event->mval[1])};
+ negate_v2(change);
+ add_v2_v2(change, mval);
+ }
+}
+
/* Move the handle of the newly added #BezTriple to mouse. */
-static void move_bezt_handles_to_mouse(BezTriple *bezt,
- const bool is_end_point,
- const wmEvent *event,
- const ViewContext *vc)
+static void move_bezt_handles_to_mouse(const wmEvent *event,
+ const ViewContext *vc,
+ ListBase *editnurb)
{
+ float change[2];
+ get_displacement_to_avg_selected_point(editnurb, change, event, vc);
+
+ FOREACH_SELECTED_BEZT_BEGIN(bezt, editnurb)
if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
bezt->h1 = HD_ALIGN;
bezt->h2 = HD_ALIGN;
}
+ const bool is_endpoint = (nu->bezt + nu->pntsu - 1 == bezt && !(nu->flagu & CU_NURB_CYCLIC)) ||
+ (nu->bezt == bezt && (nu->flagu & CU_NURB_CYCLIC));
+
+ float bezt_loc[2];
+ worldspace_to_screenspace(bezt->vec[1], vc, bezt_loc);
+ add_v2_v2(bezt_loc, change);
+
float location[3];
- screenspace_to_worldspace(event->mval, bezt->vec[1], vc, location);
+ screenspace_to_worldspace(bezt_loc, bezt->vec[1], vc, location);
/* If the new point is the last point of the curve, move the second handle to the mouse. */
- if (is_end_point) {
+ if (is_endpoint) {
+
copy_v3_v3(bezt->vec[2], location);
if (bezt->h2 != HD_FREE) {
- mul_v3_fl(location, -1.0f);
+ negate_v3(location);
madd_v3_v3v3fl(bezt->vec[0], location, bezt->vec[1], 2.0f);
}
}
@@ -169,10 +227,11 @@ static void move_bezt_handles_to_mouse(BezTriple *bezt,
copy_v3_v3(bezt->vec[0], location);
if (bezt->h1 != HD_FREE) {
- mul_v3_fl(location, -1.0f);
+ negate_v3(location);
madd_v3_v3v3fl(bezt->vec[2], location, bezt->vec[1], 2.0f);
}
}
+ FOREACH_SELECTED_BEZT_END
}
/* Move entire control point to given worldspace location. */
@@ -214,7 +273,7 @@ static void move_bezt_handle_or_vertex_to_location(BezTriple *bezt,
const ViewContext *vc)
{
float location[3];
- screenspace_to_worldspace(mval, bezt->vec[cp_index], vc, location);
+ screenspace_to_worldspace_int(mval, bezt->vec[cp_index], vc, location);
if (cp_index == 1) {
move_bezt_to_location(bezt, location);
}
@@ -252,7 +311,7 @@ static void move_selected_bezt_to_location(BezTriple *bezt,
static void move_bp_to_location(BPoint *bp, const int mval[2], const ViewContext *vc)
{
float location[3];
- screenspace_to_worldspace(mval, bp->vec, vc, location);
+ screenspace_to_worldspace_int(mval, bp->vec, vc, location);
copy_v3_v3(bp->vec, location);
}
@@ -321,6 +380,23 @@ static void move_all_selected_points(ListBase *editnurb,
}
}
+static void select_all_next_handles(ListBase *editnurb)
+{
+ FOREACH_SELECTED_BEZT_BEGIN(bezt, editnurb)
+ const bool invert = (nu->bezt + nu->pntsu - 1 == bezt && !(nu->flagu & CU_NURB_CYCLIC)) ||
+ (nu->bezt == bezt && (nu->flagu & CU_NURB_CYCLIC));
+
+ if (invert) {
+ bezt->f3 = SELECT;
+ bezt->f1 = bezt->f2 = ~SELECT;
+ }
+ else {
+ bezt->f1 = SELECT;
+ bezt->f2 = bezt->f3 = ~SELECT;
+ }
+ FOREACH_SELECTED_BEZT_END
+}
+
static int get_nurb_index(const ListBase *nurbs, const Nurb *nurb)
{
int index = 0;
@@ -961,11 +1037,12 @@ static void extrude_point_from_selected_vertex(const ViewContext *vc,
new_last_nu->flagu = ~CU_NURB_CYCLIC;
}
- get_selected_points(cu, vc->v3d, &nu, &bezt, &bp);
+ FOREACH_SELECTED_BEZT_BEGIN(bezt, &cu->editnurb->nurbs)
if (bezt) {
bezt->h1 = HD_VECT;
bezt->h2 = HD_VECT;
}
+ FOREACH_SELECTED_BEZT_END
}
/* Check if a spline segment is nearby. */
@@ -1026,7 +1103,7 @@ static void move_segment(MoveSegmentData *seg_data, const wmEvent *event, ViewCo
float depth[3];
/* Use the center of the spline segment as depth. */
get_bezier_interpolated_point(depth, bezt1, bezt2, t);
- screenspace_to_worldspace(event->mval, depth, vc, mouse_3d);
+ screenspace_to_worldspace_int(event->mval, depth, vc, mouse_3d);
/*
* Equation of Bezier Curve
@@ -1077,14 +1154,18 @@ static void move_segment(MoveSegmentData *seg_data, const wmEvent *event, ViewCo
}
/* Toggle between `free` and `align` handles of the given `BezTriple` */
-static void toggle_bezt_free_align_handles(BezTriple *bezt)
+static void toggle_bezt_free_align_handles(ListBase *editnurb)
{
+ FOREACH_SELECTED_BEZT_BEGIN(bezt, editnurb)
if (bezt->h1 != HD_FREE || bezt->h2 != HD_FREE) {
bezt->h1 = bezt->h2 = HD_FREE;
}
else {
bezt->h1 = bezt->h2 = HD_ALIGN;
}
+
+ BKE_nurb_handles_calc(nu);
+ FOREACH_SELECTED_BEZT_END
}
/* Returns true if point was found under mouse. */
@@ -1137,28 +1218,24 @@ static bool delete_point_under_mouse(ViewContext *vc,
return deleted;
}
-static void move_adjacent_handle(ViewContext *vc, const wmEvent *event)
+static void move_adjacent_handle(ViewContext *vc, const wmEvent *event, ListBase *editnurb)
{
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- get_selected_points(vc->obedit->data, vc->v3d, &nu, &bezt, &bp);
-
- if (!bezt) {
- return;
- }
-
+ FOREACH_SELECTED_BEZT_BEGIN(bezt, editnurb)
/* Get the adjacent `BezTriple` */
BezTriple *adj_bezt = BKE_nurb_bezt_get_prev(nu, bezt);
int cp_index = 2;
if (!adj_bezt) {
adj_bezt = BKE_nurb_bezt_get_next(nu, bezt);
cp_index = 0;
+ if (!adj_bezt) {
+ continue;
+ }
}
adj_bezt->h1 = adj_bezt->h2 = HD_FREE;
float screen_co_fl[2];
- int displacement[2], screen_co_int[2];
+ int displacement[2];
+ int screen_co_int[2];
/* Get the screen space coordinates of moved handle. */
ED_view3d_project_float_object(vc->region,
adj_bezt->vec[cp_index],
@@ -1172,6 +1249,7 @@ static void move_adjacent_handle(ViewContext *vc, const wmEvent *event)
add_v2_v2v2_int(screen_co_int, screen_co_int, displacement);
move_bezt_handle_or_vertex_to_location(adj_bezt, screen_co_int, cp_index, vc);
BKE_nurb_handles_calc(nu);
+ FOREACH_SELECTED_BEZT_END
}
/* Close the spline if endpoints are selected consecutively. Return true if cycle was created. */
@@ -1326,12 +1404,8 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
const int link_handles = RNA_enum_get(op->ptr, "link_handles");
if (!cpd->free_toggle_pressed && is_event_key_equal_to_extra_key(event->type, free_toggle)) {
- get_selected_points(vc.obedit->data, vc.v3d, &nu, &bezt, &bp);
- if (bezt) {
- toggle_bezt_free_align_handles(bezt);
- BKE_nurb_handles_calc(nu);
- cpd->dragging = true;
- }
+ toggle_bezt_free_align_handles(&cu->editnurb->nurbs);
+ cpd->dragging = true;
}
cpd->free_toggle_pressed = is_extra_key_pressed(event, free_toggle);
@@ -1348,21 +1422,22 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
cpd->acted = true;
}
else if (is_extra_key_pressed(event, adj_handle)) {
- move_adjacent_handle(&vc, event);
+ move_adjacent_handle(&vc, event, &cu->editnurb->nurbs);
cpd->acted = true;
}
/* If dragging a new control point, move handle point with mouse cursor. Else move entire
* control point. */
else if (cpd->new_point) {
- get_selected_points(vc.obedit->data, vc.v3d, &nu,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list