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:
authorHans Goudey <h.goudey@me.com>2019-11-21 00:12:32 +0300
committerHans Goudey <h.goudey@me.com>2019-11-21 00:25:28 +0300
commitba1e9ae4733ae956331c7e8899f6939997205298 (patch)
tree007362ed2c9ee4564b67404f552906d6e66848db /source/blender/editors/interface/interface_handlers.c
parent8c6ce742391b2b8798143a4a2c2224ebbeb7f1ec (diff)
Bevel: Custom Profile and CurveProfile Widget
Custom profiles in bevel allows the profile curve to be controlled by manually placed control points. Orientation is regularized along groups of edges, and the 'pipe case' is updated. This commit includes many updates to comments and changed variable names as well. A 'cutoff' vertex mesh method is added to bevel in addition to the existing grid fill option for replacing vertices. The UI of the bevel modifier and tool are updated and unified. Also, a 'CurveProfile' widget is added to BKE for defining the profile in the interface, which may be useful in other situations. Many thanks to Howard, my mentor for this GSoC project. Reviewers: howardt, campbellbarton Differential Revision: https://developer.blender.org/D5516
Diffstat (limited to 'source/blender/editors/interface/interface_handlers.c')
-rw-r--r--source/blender/editors/interface/interface_handlers.c335
1 files changed, 333 insertions, 2 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 806b5789df1..673e4c1a8da 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -32,7 +32,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_brush_types.h"
-
+#include "DNA_curveprofile_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -57,6 +57,7 @@
#include "BKE_tracking.h"
#include "BKE_unit.h"
#include "BKE_paint.h"
+#include "BKE_curveprofile.h"
#include "IMB_colormanagement.h"
@@ -442,6 +443,8 @@ static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut
static ColorBand but_copypaste_coba = {0};
static CurveMapping but_copypaste_curve = {0};
static bool but_copypaste_curve_alive = false;
+static CurveProfile but_copypaste_profile = {0};
+static bool but_copypaste_profile_alive = false;
/** \} */
@@ -1080,6 +1083,13 @@ static void ui_apply_but_CURVE(bContext *C, uiBut *but, uiHandleButtonData *data
data->applied = true;
}
+static void ui_apply_but_CURVEPROFILE(bContext *C, uiBut *but, uiHandleButtonData *data)
+{
+ ui_apply_but_func(C, but);
+ data->retval = but->retval;
+ data->applied = true;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1979,6 +1989,7 @@ static void ui_apply_but(
float *editvec;
ColorBand *editcoba;
CurveMapping *editcumap;
+ CurveProfile *editprofile;
data->retval = 0;
@@ -2036,11 +2047,13 @@ static void ui_apply_but(
editvec = but->editvec;
editcoba = but->editcoba;
editcumap = but->editcumap;
+ editprofile = but->editprofile;
but->editstr = NULL;
but->editval = NULL;
but->editvec = NULL;
but->editcoba = NULL;
but->editcumap = NULL;
+ but->editprofile = NULL;
/* handle different types */
switch (but->type) {
@@ -2100,6 +2113,9 @@ static void ui_apply_but(
case UI_BTYPE_CURVE:
ui_apply_but_CURVE(C, but, data);
break;
+ case UI_BTYPE_CURVEPROFILE:
+ ui_apply_but_CURVEPROFILE(C, but, data);
+ break;
case UI_BTYPE_KEY_EVENT:
case UI_BTYPE_HOTKEY_EVENT:
ui_apply_but_BUT(C, but, data);
@@ -2147,6 +2163,7 @@ static void ui_apply_but(
but->editvec = editvec;
but->editcoba = editcoba;
but->editcumap = editcumap;
+ but->editprofile = editprofile;
}
/** \} */
@@ -2446,6 +2463,29 @@ static void ui_but_paste_curvemapping(bContext *C, uiBut *but)
}
}
+static void ui_but_copy_CurveProfile(uiBut *but)
+{
+ if (but->poin != NULL) {
+ but_copypaste_profile_alive = true;
+ BKE_curveprofile_free_data(&but_copypaste_profile);
+ BKE_curveprofile_copy_data(&but_copypaste_profile, (CurveProfile *)but->poin);
+ }
+}
+
+static void ui_but_paste_CurveProfile(bContext *C, uiBut *but)
+{
+ if (but_copypaste_profile_alive) {
+ if (!but->poin) {
+ but->poin = MEM_callocN(sizeof(CurveProfile), "CurveProfile");
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ BKE_curveprofile_free_data((CurveProfile *)but->poin);
+ BKE_curveprofile_copy_data((CurveProfile *)but->poin, &but_copypaste_profile);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+}
+
static void ui_but_copy_operator(bContext *C, uiBut *but, char *output, int output_len_max)
{
PointerRNA *opptr;
@@ -2540,6 +2580,10 @@ static void ui_but_copy(bContext *C, uiBut *but, const bool copy_array)
ui_but_copy_curvemapping(but);
break;
+ case UI_BTYPE_CURVEPROFILE:
+ ui_but_copy_CurveProfile(but);
+ break;
+
case UI_BTYPE_BUT:
if (!but->optype) {
break;
@@ -2623,6 +2667,10 @@ static void ui_but_paste(bContext *C, uiBut *but, uiHandleButtonData *data, cons
ui_but_paste_curvemapping(C, but);
break;
+ case UI_BTYPE_CURVEPROFILE:
+ ui_but_paste_CurveProfile(C, but);
+ break;
+
default:
break;
}
@@ -2633,6 +2681,7 @@ static void ui_but_paste(bContext *C, uiBut *but, uiHandleButtonData *data, cons
void ui_but_clipboard_free(void)
{
BKE_curvemapping_free_data(&but_copypaste_curve);
+ BKE_curveprofile_free_data(&but_copypaste_profile);
}
/** \} */
@@ -3757,6 +3806,9 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
if (but->type == UI_BTYPE_CURVE) {
but->editcumap = (CurveMapping *)but->poin;
}
+ if (but->type == UI_BTYPE_CURVEPROFILE) {
+ but->editprofile = (CurveProfile *)but->poin;
+ }
else if (but->type == UI_BTYPE_COLORBAND) {
data->coba = (ColorBand *)but->poin;
but->editcoba = data->coba;
@@ -3847,6 +3899,7 @@ static void ui_numedit_end(uiBut *but, uiHandleButtonData *data)
but->editvec = NULL;
but->editcoba = NULL;
but->editcumap = NULL;
+ but->editprofile = NULL;
data->dragstartx = 0;
data->draglastx = 0;
@@ -6803,6 +6856,281 @@ static int ui_do_but_CURVE(
return WM_UI_HANDLER_CONTINUE;
}
+/* Same as ui_numedit_but_CURVE with some smaller changes. */
+static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
+ uiBut *but,
+ uiHandleButtonData *data,
+ int evtx,
+ int evty,
+ bool snap,
+ const bool shift)
+{
+ CurveProfile *profile = (CurveProfile *)but->poin;
+ CurveProfilePoint *pts = profile->path;
+ float fx, fy, zoomx, zoomy;
+ int mx, my, dragx, dragy;
+ int a;
+ bool changed = false;
+
+ /* evtx evty and drag coords are absolute mousecoords,
+ * prevents errors when editing when layout changes */
+ mx = evtx;
+ my = evty;
+ ui_window_to_block(data->region, block, &mx, &my);
+ dragx = data->draglastx;
+ dragy = data->draglasty;
+ ui_window_to_block(data->region, block, &dragx, &dragy);
+
+ zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&profile->view_rect);
+ zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&profile->view_rect);
+
+ if (snap) {
+ float d[2];
+
+ d[0] = mx - data->dragstartx;
+ d[1] = my - data->dragstarty;
+
+ if (len_squared_v2(d) < (3.0f * 3.0f)) {
+ snap = false;
+ }
+ }
+
+ fx = (mx - dragx) / zoomx;
+ fy = (my - dragy) / zoomy;
+
+ if (data->dragsel != -1) {
+ CurveProfilePoint *point_last = NULL;
+ const float mval_factor = ui_mouse_scale_warp_factor(shift);
+ bool moved_point = false; /* for ctrl grid, can't use orig coords because of sorting */
+
+ fx *= mval_factor;
+ fy *= mval_factor;
+
+ /* Move all the points that aren't the last or the first */
+ for (a = 1; a < profile->path_len - 1; a++) {
+ if (pts[a].flag & PROF_SELECT) {
+ float origx = pts[a].x, origy = pts[a].y;
+ pts[a].x += fx;
+ pts[a].y += fy;
+ if (snap) {
+ pts[a].x = 0.125f * roundf(8.0f * pts[a].x);
+ pts[a].y = 0.125f * roundf(8.0f * pts[a].y);
+ }
+ if (!moved_point && (pts[a].x != origx || pts[a].y != origy)) {
+ moved_point = true;
+ }
+
+ point_last = &pts[a];
+ }
+ }
+
+ BKE_curveprofile_update(profile, false);
+
+ if (moved_point) {
+ data->draglastx = evtx;
+ data->draglasty = evty;
+ changed = true;
+#ifdef USE_CONT_MOUSE_CORRECT
+ /* note: using 'cmp_last' is weak since there may be multiple points selected,
+ * but in practice this isnt really an issue */
+ if (ui_but_is_cursor_warp(but)) {
+ /* OK but can go outside bounds */
+ data->ungrab_mval[0] = but->rect.xmin + ((point_last->x - profile->view_rect.xmin) * zoomx);
+ data->ungrab_mval[1] = but->rect.ymin + ((point_last->y - profile->view_rect.ymin) * zoomy);
+ BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
+ }
+#endif
+ }
+ data->dragchange = true; /* mark for selection */
+ }
+ else {
+ /* clamp for clip */
+ if (profile->flag & PROF_USE_CLIP) {
+ if (profile->view_rect.xmin - fx < profile->clip_rect.xmin) {
+ fx = profile->view_rect.xmin - profile->clip_rect.xmin;
+ }
+ else if (profile->view_rect.xmax - fx > profile->clip_rect.xmax) {
+ fx = profile->view_rect.xmax - profile->clip_rect.xmax;
+ }
+ if (profile->view_rect.ymin - fy < profile->clip_rect.ymin) {
+ fy = profile->view_rect.ymin - profile->clip_rect.ymin;
+ }
+ else if (profile->view_rect.ymax - fy > profile->clip_rect.ymax) {
+ fy = profile->view_rect.ymax - profile->clip_rect.ymax;
+ }
+ }
+
+ profile->view_rect.xmin -= fx;
+ profile->view_rect.ymin -= fy;
+ profile->view_rect.xmax -= fx;
+ profile->view_rect.ymax -= fy;
+
+ data->draglastx = evtx;
+ data->draglasty = evty;
+
+ changed = true;
+ }
+
+ return changed;
+}
+
+/** Interaction for curve profile widget.
+ * \note Uses hardcoded keys rather than the keymap. */
+static int ui_do_but_CURVEPROFILE(
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my, i;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ /* Move selected control points. */
+ if (event->type == GKEY && event->val == KM_RELEASE) {
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ CurveProfile *profile = (CurveProfile *)but->poin;
+
+ /* Delete selected control points. */
+ if (event->type == XKEY && event->val == KM_RELEASE) {
+ BKE_curveprofile_remove_by_flag(profile, PROF_SELECT);
+ BKE_curveprofile_update(profile, false);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ /* Selecting, adding, and starting point movements. */
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ CurveProfilePoint *pts; /* Path or table. */
+ const float m_xy[2] = {mx, my};
+ float dist_min_sq;
+ int i_selected = -1;
+
+ if (event->ctrl) {
+ float f_xy[2];
+ BLI_rctf_transform_pt_v(&profile->view_rect, &but->rect, f_xy, m_xy);
+
+ BKE_curveprofile_insert(profile, f_xy[0], f_xy[1]);
+ BKE_curveprofile_update(profile, false);
+ }
+
+ /* Check for selecting of a point by finding closest point in radius. */
+ dist_min_sq = SQUARE(U.dpi_fac * 14.0f); /* 14 pixels radius for selecting points. */
+ pts = profile->path;
+ for (i = 0; i < profile->path_len; i++) {
+ float f_xy[2];
+ BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &pts[i].x);
+ const float dist_sq = len_squared_v2v2(m_xy, f_xy);
+ if (dist_sq < dist_min_sq) {
+ i_selected = i;
+ dist_min_sq = dist_sq;
+ }
+ }
+
+ /* Add a point if the click was close to the path but not a control point. */
+ if (i_selected == -1) { /* No control point selected. */
+ float f_xy[2], f_xy_prev[2];
+ pts = profile->table;
+ BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &pts[0].x);
+
+ dist_min_sq = SQUARE(U.dpi_fac * 8.0f); /* 8 pixel radius from each table point. */
+
+ /* Loop through the path's high resolution table and find what's near the click. */
+ for (i = 1; i <= PROF_N_TABLE(profile->path_len); i++) {
+ copy_v2_v2(f_xy_prev, f_xy);
+ BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &pts[i].x);
+
+ if (dist_squared_to_line_segment_v2(m_xy, f_xy_prev, f_xy) < dist_min_sq) {
+ BLI_rctf_transform_pt_v(&profile->view_rect, &but->rect, f_xy, m_xy);
+
+ CurveProfilePoint *new_pt = BKE_curveprofile_insert(profile, f_xy[0], f_xy[1]);
+ BKE_curveprofile_update(profile, false);
+
+ /* reset pts back to the control points. */
+ pts = profile->path;
+
+ /* Get the index of the newly added point. */
+ for (i = 0; i < profile->path_len; i++) {
+ if (&pts[i] == new_pt) {
+ i_selected = i;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ /* Change the flag for the point(s) if one was selected. */
+ if (i_selected != -1) {
+ /* Deselect all if this one is deselected, except if we hold shift. */
+ if (!event->shift) {
+ for (i = 0; i < profile->path_len; i++) {
+ pts[i].flag &= ~PROF_SELECT;
+ }
+ pts[i_selected].flag |= PROF_SELECT;
+ }
+ else {
+ pts[i_selected].flag ^= PROF_SELECT;
+ }
+ }
+ else {
+ /* Move the view. */
+ data->cancel = true;
+ }
+
+ data->dragsel = i_selected;
+
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) { /* Do control point movement. */
+ if (event->type == MOUSEMOVE) {
+ if (mx != data->draglastx || my != data->draglasty) {
+ if (ui_numedit_but_CURVEPROFILE(
+ block, but, data, mx, my, event->ctrl != 0, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ /* Finish move. */
+ if (data->dragsel != -1) {
+ CurveProfilePoint *pts = profile->path;
+
+ if (data->dragchange == false) {
+ /* Deselect all, select one. */
+ if (!event->shift) {
+ for (i = 0; i < profile->path_len; i++) {
+ pts[i].flag &= ~PROF_SELECT;
+ }
+ pts[data->dragsel].flag |= PROF_SELECT;
+ }
+ }
+ else {
+ BKE_curveprofile_update(profile, true); /* Remove doubles after move. */
+ }
+ }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx, int my)
{
Histogram *hist = (Histogram *)but->poin;
@@ -7208,6 +7536,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case UI_BTYPE_CURVE:
retval = ui_do_but_CURVE(C, block, but, data, event);
break;
+ case UI_BTYPE_CURVEPROFILE:
+ retval = ui_do_but_CURVEPROFILE(C, block, but, data, event);
+ break;
case UI_BTYPE_HSVCUBE:
retval = ui_do_but_HSVCUBE(C, block, but, data, event);
break;
@@ -7599,7 +7930,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU)) {
+ if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_CURVEPROFILE, UI_BTYPE_SEARCH_MENU)) {
/* XXX curve is temp */
}
else {