From 69d6222481b4342dc2a153e62752145aa37ea101 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Mon, 18 Oct 2021 00:32:23 -0300 Subject: Snap and Placement Gizmo Refactor Move most of the gizmo snap and placement code to `view_cursor_snap.c`. Simplify and extend the snap API. Differential Revision: https://developer.blender.org/D12868 --- .../gizmo_library/gizmo_types/snap3d_gizmo.c | 589 ++++----------------- 1 file changed, 102 insertions(+), 487 deletions(-) (limited to 'source/blender/editors/gizmo_library') diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c index 322ae87befa..fccb65bad68 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c @@ -27,420 +27,122 @@ * \brief Snap gizmo which exposes the location, normal and index in the props. */ +#include "MEM_guardedalloc.h" + #include "BLI_listbase.h" #include "BLI_math.h" -#include "DNA_scene_types.h" - #include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" -#include "GPU_immediate.h" -#include "GPU_state.h" - #include "ED_gizmo_library.h" #include "ED_screen.h" #include "ED_transform_snap_object_context.h" #include "ED_view3d.h" -#include "UI_resources.h" /* icons */ +#include "UI_resources.h" #include "RNA_access.h" #include "RNA_define.h" -#include "DEG_depsgraph_query.h" - #include "WM_api.h" -#include "WM_types.h" /* own includes */ -#include "../gizmo_geometry.h" #include "../gizmo_library_intern.h" typedef struct SnapGizmo3D { wmGizmo gizmo; - - /* We could have other snap contexts, for now only support 3D view. */ - SnapObjectContext *snap_context_v3d; - - /* Copy of the parameters of the last event state in order to detect updates. */ - struct { - int x; - int y; -#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK - short shift, ctrl, alt, oskey; -#endif - } last_eventstate; - -#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK - wmKeyMap *keymap; - int snap_on; - bool invert_snap; -#endif - - /* Setup. */ - eSnapGizmo flag; - float *prevpoint; - float prevpoint_stack[3]; - short snap_elem_force; - - /* Return values. */ - short snap_elem; - float loc[3]; - float nor[3]; - int elem_index[3]; - - /** Enabled when snap is activated, even if it didn't find anything. */ - bool is_enabled; + V3DSnapCursorData *cursor_handle; } SnapGizmo3D; -/* Checks if the current event is different from the one captured in the last update. */ -static bool eventstate_has_changed(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm) +static void snap_gizmo_snap_elements_update(SnapGizmo3D *snap_gizmo) { - if (wm && wm->winactive) { - const wmEvent *event = wm->winactive->eventstate; - if ((event->x != snap_gizmo->last_eventstate.x) || - (event->y != snap_gizmo->last_eventstate.y)) { - return true; - } -#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK - if (!(snap_gizmo->flag & ED_SNAPGIZMO_TOGGLE_ALWAYS_TRUE)) { - if ((event->ctrl != snap_gizmo->last_eventstate.ctrl) || - (event->shift != snap_gizmo->last_eventstate.shift) || - (event->alt != snap_gizmo->last_eventstate.alt) || - (event->oskey != snap_gizmo->last_eventstate.oskey)) { - return true; - } - } -#endif - } - return false; -} + V3DSnapCursorData *snap_data = snap_gizmo->cursor_handle; + wmGizmoProperty *gz_prop_snap; + gz_prop_snap = WM_gizmo_target_property_find(&snap_gizmo->gizmo, "snap_elements"); -/* Copies the current eventstate. */ -static void eventstate_save_xy(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm) -{ - if (wm && wm->winactive) { - const wmEvent *event = wm->winactive->eventstate; - snap_gizmo->last_eventstate.x = event->x; - snap_gizmo->last_eventstate.y = event->y; - } -} - -#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK -static bool invert_snap(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm) -{ - if (!wm || !wm->winactive) { - return false; - } - - const wmEvent *event = wm->winactive->eventstate; - if ((event->ctrl == snap_gizmo->last_eventstate.ctrl) && - (event->shift == snap_gizmo->last_eventstate.shift) && - (event->alt == snap_gizmo->last_eventstate.alt) && - (event->oskey == snap_gizmo->last_eventstate.oskey)) { - /* Nothing has changed. */ - return snap_gizmo->invert_snap; - } - - /* Save new eventstate. */ - snap_gizmo->last_eventstate.ctrl = event->ctrl; - snap_gizmo->last_eventstate.shift = event->shift; - snap_gizmo->last_eventstate.alt = event->alt; - snap_gizmo->last_eventstate.oskey = event->oskey; - - const int snap_on = snap_gizmo->snap_on; - - wmKeyMap *keymap = WM_keymap_active(wm, snap_gizmo->keymap); - for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) { - if (kmi->flag & KMI_INACTIVE) { - continue; - } - - if (kmi->propvalue == snap_on) { - if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && event->ctrl) || - (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && event->shift) || - (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && event->alt) || - ((kmi->type == EVT_OSKEY) && event->oskey)) { - return true; - } - } + if (gz_prop_snap->prop) { + snap_data->snap_elem_force |= RNA_property_enum_get(&gz_prop_snap->ptr, gz_prop_snap->prop); } - return false; -} -#endif - -static short snap_gizmo_snap_elements(SnapGizmo3D *snap_gizmo) -{ - int snap_elements = snap_gizmo->snap_elem_force; - wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(&snap_gizmo->gizmo, "snap_elements"); - if (gz_prop->prop) { - snap_elements |= RNA_property_enum_get(&gz_prop->ptr, gz_prop->prop); - } - snap_elements &= (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | - SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR); - return (ushort)snap_elements; + UI_GetThemeColor3ubv(TH_TRANSFORM, snap_data->color_line); + snap_data->color_line[3] = 128; + rgba_float_to_uchar(snap_data->color_point, snap_gizmo->gizmo.color); } /* -------------------------------------------------------------------- */ /** \name ED_gizmo_library specific API * \{ */ -void ED_gizmotypes_snap_3d_draw_util(RegionView3D *rv3d, - const float loc_prev[3], - const float loc_curr[3], - const float normal[3], - const uchar color_line[4], - const uchar color_point[4], - const short snap_elem_type) +SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(Scene *scene, wmGizmo *UNUSED(gz)) { - if (!loc_prev && !loc_curr) { - return; - } - - float view_inv[4][4]; - copy_m4_m4(view_inv, rv3d->viewinv); - - /* The size of the circle is larger than the vertex size. - * This prevents a drawing overlaps the other. */ - float radius = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - if (loc_curr) { - immUniformColor4ubv(color_point); - imm_drawcircball(loc_curr, ED_view3d_pixel_size(rv3d, loc_curr) * radius, view_inv, pos); - - /* draw normal if needed */ - if (normal) { - immBegin(GPU_PRIM_LINES, 2); - immVertex3fv(pos, loc_curr); - immVertex3f(pos, loc_curr[0] + normal[0], loc_curr[1] + normal[1], loc_curr[2] + normal[2]); - immEnd(); - } - } - - if (loc_prev) { - /* Draw an "X" indicating where the previous snap point is. - * This is useful for indicating perpendicular snap. */ - - /* v1, v2, v3 and v4 indicate the coordinates of the ends of the "X". */ - float vx[3], vy[3], v1[3], v2[3], v3[3], v4[4]; - - /* Multiply by 0.75f so that the final size of the "X" is close to that of - * the circle. - * (A closer value is 0.7071f, but we don't need to be exact here). */ - float x_size = 0.75f * radius * ED_view3d_pixel_size(rv3d, loc_prev); - - mul_v3_v3fl(vx, view_inv[0], x_size); - mul_v3_v3fl(vy, view_inv[1], x_size); - - add_v3_v3v3(v1, vx, vy); - sub_v3_v3v3(v2, vx, vy); - negate_v3_v3(v3, v1); - negate_v3_v3(v4, v2); - - add_v3_v3(v1, loc_prev); - add_v3_v3(v2, loc_prev); - add_v3_v3(v3, loc_prev); - add_v3_v3(v4, loc_prev); - - immUniformColor4ubv(color_line); - immBegin(GPU_PRIM_LINES, 4); - immVertex3fv(pos, v3); - immVertex3fv(pos, v1); - immVertex3fv(pos, v4); - immVertex3fv(pos, v2); - immEnd(); - - if (loc_curr && (snap_elem_type & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { - /* Dashed line. */ - immUnbindProgram(); - - immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); - float viewport_size[4]; - GPU_viewport_size_get_f(viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - immUniform1f("dash_width", 6.0f * U.pixelsize); - immUniform1f("dash_factor", 1.0f / 4.0f); - immUniformColor4ubv(color_line); - - immBegin(GPU_PRIM_LINES, 2); - immVertex3fv(pos, loc_prev); - immVertex3fv(pos, loc_curr); - immEnd(); - } - } - - immUnbindProgram(); -} - -SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(Scene *scene, wmGizmo *gz) -{ - SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - if (snap_gizmo->snap_context_v3d == NULL) { - snap_gizmo->snap_context_v3d = ED_transform_snap_object_context_create(scene, 0); - } - return snap_gizmo->snap_context_v3d; + ED_view3d_cursor_snap_activate_point(); + return ED_view3d_cursor_snap_context_ensure(scene); } -void ED_gizmotypes_snap_3d_flag_set(struct wmGizmo *gz, eSnapGizmo flag) +void ED_gizmotypes_snap_3d_flag_set(struct wmGizmo *gz, int flag) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - snap_gizmo->flag |= flag; + snap_gizmo->cursor_handle->flag |= flag; } -void ED_gizmotypes_snap_3d_flag_clear(struct wmGizmo *gz, eSnapGizmo flag) +void ED_gizmotypes_snap_3d_flag_clear(struct wmGizmo *gz, int flag) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - snap_gizmo->flag &= ~flag; + snap_gizmo->cursor_handle->flag &= ~flag; } -bool ED_gizmotypes_snap_3d_flag_test(struct wmGizmo *gz, eSnapGizmo flag) +bool ED_gizmotypes_snap_3d_flag_test(struct wmGizmo *gz, int flag) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - return (snap_gizmo->flag & flag) != 0; + return (snap_gizmo->cursor_handle->flag & flag) != 0; } bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz) { -#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - return snap_gizmo->invert_snap; -#else - return false; -#endif + return snap_gizmo->cursor_handle->is_snap_invert; } bool ED_gizmotypes_snap_3d_is_enabled(const wmGizmo *gz) { const SnapGizmo3D *snap_gizmo = (const SnapGizmo3D *)gz; - return snap_gizmo->is_enabled; + return snap_gizmo->cursor_handle->is_enabled; } -short ED_gizmotypes_snap_3d_update(wmGizmo *gz, - struct Depsgraph *depsgraph, - const ARegion *region, - const View3D *v3d, - const wmWindowManager *wm, - const float mval_fl[2]) +void ED_gizmotypes_snap_3d_data_get(const struct bContext *C, + wmGizmo *gz, + float r_loc[3], + float r_nor[3], + int r_elem_index[3], + int *r_snap_elem) { - SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - snap_gizmo->is_enabled = false; - - Scene *scene = DEG_get_input_scene(depsgraph); - -#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK - if (!(snap_gizmo->flag & ED_SNAPGIZMO_TOGGLE_ALWAYS_TRUE)) { - snap_gizmo->invert_snap = invert_snap(snap_gizmo, wm); - - const ToolSettings *ts = scene->toolsettings; - if (snap_gizmo->invert_snap != !(ts->snap_flag & SCE_SNAP)) { - snap_gizmo->snap_elem = 0; - return 0; - } - } -#endif - eventstate_save_xy(snap_gizmo, wm); - - snap_gizmo->is_enabled = true; - - float co[3], no[3]; - short snap_elem = 0; - int snap_elem_index[3] = {-1, -1, -1}; - int index = -1; - - ushort snap_elements = snap_gizmo_snap_elements(snap_gizmo); - - if (snap_elements) { - float prev_co[3] = {0.0f}; - if (snap_gizmo->prevpoint) { - copy_v3_v3(prev_co, snap_gizmo->prevpoint); + V3DSnapCursorData *snap_data = ((SnapGizmo3D *)gz)->cursor_handle; + + if (C) { + /* Snap values are updated too late at the cursor. Be sure to update ahead of time. */ + wmWindowManager *wm = CTX_wm_manager(C); + const wmEvent *event = wm->winactive ? wm->winactive->eventstate : NULL; + if (event) { + ARegion *region = CTX_wm_region(C); + int x = event->x - region->winrct.xmin; + int y = event->y - region->winrct.ymin; + ED_view3d_cursor_snap_update(C, x, y, snap_data); } - else { - snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR; - } - - eSnapSelect snap_select = (snap_gizmo->flag & ED_SNAPGIZMO_SNAP_ONLY_ACTIVE) ? - SNAP_ONLY_ACTIVE : - SNAP_ALL; - - eSnapEditType edit_mode_type = (snap_gizmo->flag & ED_SNAPGIZMO_SNAP_EDIT_GEOM_FINAL) ? - SNAP_GEOM_FINAL : - (snap_gizmo->flag & ED_SNAPGIZMO_SNAP_EDIT_GEOM_CAGE) ? - SNAP_GEOM_CAGE : - SNAP_GEOM_EDIT; - - bool use_occlusion_test = (snap_gizmo->flag & ED_SNAPGIZMO_OCCLUSION_ALWAYS_TRUE) ? false : - true; - - float dist_px = 12.0f * U.pixelsize; - - ED_gizmotypes_snap_3d_context_ensure(scene, gz); - snap_elem = ED_transform_snap_object_project_view3d_ex( - snap_gizmo->snap_context_v3d, - depsgraph, - region, - v3d, - snap_elements, - &(const struct SnapObjectParams){ - .snap_select = snap_select, - .edit_mode_type = edit_mode_type, - .use_occlusion_test = use_occlusion_test, - }, - mval_fl, - prev_co, - &dist_px, - co, - no, - &index, - NULL, - NULL); } - if (snap_elem == 0) { - RegionView3D *rv3d = region->regiondata; - ED_view3d_win_to_3d(v3d, region, rv3d->ofs, mval_fl, co); - zero_v3(no); - } - else if (snap_elem == SCE_SNAP_MODE_VERTEX) { - snap_elem_index[0] = index; - } - else if (snap_elem & - (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { - snap_elem_index[1] = index; - } - else if (snap_elem == SCE_SNAP_MODE_FACE) { - snap_elem_index[2] = index; - } - - snap_gizmo->snap_elem = snap_elem; - copy_v3_v3(snap_gizmo->loc, co); - copy_v3_v3(snap_gizmo->nor, no); - copy_v3_v3_int(snap_gizmo->elem_index, snap_elem_index); - - return snap_elem; -} - -void ED_gizmotypes_snap_3d_data_get( - wmGizmo *gz, float r_loc[3], float r_nor[3], int r_elem_index[3], int *r_snap_elem) -{ - SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - BLI_assert(snap_gizmo->is_enabled); if (r_loc) { - copy_v3_v3(r_loc, snap_gizmo->loc); + copy_v3_v3(r_loc, snap_data->loc); } if (r_nor) { - copy_v3_v3(r_nor, snap_gizmo->nor); + copy_v3_v3(r_nor, snap_data->nor); } if (r_elem_index) { - copy_v3_v3_int(r_elem_index, snap_gizmo->elem_index); + copy_v3_v3_int(r_elem_index, snap_data->elem_index); } if (r_snap_elem) { - *r_snap_elem = snap_gizmo->snap_elem; + *r_snap_elem = snap_data->snap_elem; } } @@ -450,115 +152,80 @@ void ED_gizmotypes_snap_3d_data_get( /** \name RNA callbacks * \{ */ -/* Based on 'rna_GizmoProperties_find_operator'. */ -static struct SnapGizmo3D *gizmo_snap_rna_find_operator(PointerRNA *ptr) -{ - IDProperty *properties = ptr->data; - for (bScreen *screen = G_MAIN->screens.first; screen; screen = screen->id.next) { - LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { - if (area->spacetype != SPACE_VIEW3D) { - continue; - } - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region->regiontype == RGN_TYPE_WINDOW && region->gizmo_map) { - wmGizmoMap *gzmap = region->gizmo_map; - LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(gzmap)) { - LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) { - if (gz->properties == properties) { - return (SnapGizmo3D *)gz; - } - } - } - } - } - } - } - return NULL; -} - -static int gizmo_snap_rna_snap_elements_force_get_fn(struct PointerRNA *ptr, +static int gizmo_snap_rna_snap_elements_force_get_fn(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop)) { - SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr); - if (snap_gizmo) { - return snap_gizmo->snap_elem_force; + V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); + if (snap_data) { + return snap_data->snap_elem_force; } return 0; } -static void gizmo_snap_rna_snap_elements_force_set_fn(struct PointerRNA *ptr, +static void gizmo_snap_rna_snap_elements_force_set_fn(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), int value) { - SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr); - if (snap_gizmo) { - snap_gizmo->snap_elem_force = (short)value; + V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); + if (snap_data) { + snap_data->snap_elem_force = (short)value; } } -static void gizmo_snap_rna_prevpoint_get_fn(struct PointerRNA *ptr, +static void gizmo_snap_rna_prevpoint_get_fn(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), float *values) { - SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr); - if (snap_gizmo) { - copy_v3_v3(values, snap_gizmo->prevpoint_stack); + V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); + if (snap_data && snap_data->prevpoint) { + copy_v3_v3(values, snap_data->prevpoint); } } -static void gizmo_snap_rna_prevpoint_set_fn(struct PointerRNA *ptr, +static void gizmo_snap_rna_prevpoint_set_fn(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), const float *values) { - SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr); - if (snap_gizmo) { - if (values) { - copy_v3_v3(snap_gizmo->prevpoint_stack, values); - snap_gizmo->prevpoint = snap_gizmo->prevpoint_stack; - } - else { - snap_gizmo->prevpoint = NULL; - } - } + ED_view3d_cursor_snap_prevpoint_set(values); } -static void gizmo_snap_rna_location_get_fn(struct PointerRNA *ptr, +static void gizmo_snap_rna_location_get_fn(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), float *values) { - SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr); - if (snap_gizmo) { - copy_v3_v3(values, snap_gizmo->loc); + V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); + if (snap_data) { + copy_v3_v3(values, snap_data->loc); } } -static void gizmo_snap_rna_location_set_fn(struct PointerRNA *ptr, +static void gizmo_snap_rna_location_set_fn(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), const float *values) { - SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr); - if (snap_gizmo) { - copy_v3_v3(snap_gizmo->loc, values); + V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); + if (snap_data) { + copy_v3_v3(snap_data->loc, values); } } -static void gizmo_snap_rna_normal_get_fn(struct PointerRNA *ptr, +static void gizmo_snap_rna_normal_get_fn(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), float *values) { - SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr); - if (snap_gizmo) { - copy_v3_v3(values, snap_gizmo->nor); + V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); + if (snap_data) { + copy_v3_v3(values, snap_data->nor); } } -static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *ptr, +static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), int *values) { - SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr); - if (snap_gizmo) { - copy_v3_v3_int(values, snap_gizmo->elem_index); + V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); + if (snap_data) { + copy_v3_v3_int(values, snap_data->elem_index); } } @@ -571,91 +238,44 @@ static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *ptr, static void snap_gizmo_setup(wmGizmo *gz) { gz->flag |= WM_GIZMO_NO_TOOLTIP; - -#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - wmKeyConfig *keyconf = gz->parent_gzgroup->type->keyconf; - if (!keyconf) { - /* It can happen when gizmo-group-type is not linked at startup. */ - keyconf = ((wmWindowManager *)G.main->wm.first)->defaultconf; - } - snap_gizmo->keymap = WM_modalkeymap_find(keyconf, "Generic Gizmo Tweak Modal Map"); - RNA_enum_value_from_id(snap_gizmo->keymap->modal_items, "SNAP_ON", &snap_gizmo->snap_on); -#endif + ED_view3d_cursor_snap_activate_point(); + snap_gizmo->cursor_handle = ED_view3d_cursor_snap_data_get(); } -static void snap_gizmo_draw(const bContext *C, wmGizmo *gz) +static void snap_gizmo_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz)) { - SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - if (snap_gizmo->snap_elem == 0) { - return; - } - - wmWindowManager *wm = CTX_wm_manager(C); - if (eventstate_has_changed(snap_gizmo, wm)) { - /* The eventstate has changed but the snap has not been updated. - * This means that the current position is no longer valid. */ - snap_gizmo->snap_elem = 0; - return; - } - - RegionView3D *rv3d = CTX_wm_region_data(C); - if (rv3d->rflag & RV3D_NAVIGATING) { - /* Don't draw the gizmo while navigating. It can be distracting. */ - snap_gizmo->snap_elem = 0; - return; - } - - uchar color_line[4], color_point[4]; - UI_GetThemeColor3ubv(TH_TRANSFORM, color_line); - color_line[3] = 128; - - rgba_float_to_uchar(color_point, gz->color); - - GPU_line_smooth(false); - - GPU_line_width(1.0f); - - const float *prev_point = (snap_gizmo_snap_elements(snap_gizmo) & - SCE_SNAP_MODE_EDGE_PERPENDICULAR) ? - snap_gizmo->prevpoint : - NULL; - - ED_gizmotypes_snap_3d_draw_util( - rv3d, prev_point, snap_gizmo->loc, NULL, color_line, color_point, snap_gizmo->snap_elem); + /* All drawing is handled at the paint cursor. */ } static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2]) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - wmWindowManager *wm = CTX_wm_manager(C); - ARegion *region = CTX_wm_region(C); - - /* FIXME: this hack is to ignore drag events, otherwise drag events - * cause momentary snap gizmo re-positioning at the drag-start location, see: T87511. */ - if (wm && wm->winactive) { - const wmEvent *event = wm->winactive->eventstate; - int mval_compare[2] = {event->x - region->winrct.xmin, event->y - region->winrct.ymin}; - if (!equals_v2v2_int(mval_compare, mval)) { - return snap_gizmo->snap_elem ? 0 : -1; - } - } + V3DSnapCursorData *snap_data = snap_gizmo->cursor_handle; - if (!eventstate_has_changed(snap_gizmo, wm)) { - /* Performance, do not update. */ - return snap_gizmo->snap_elem ? 0 : -1; - } + /* Snap Elements can change while the gizmo is active. Need to be updated somewhere. */ + snap_gizmo_snap_elements_update(snap_gizmo); - View3D *v3d = CTX_wm_view3d(C); - const float mval_fl[2] = {UNPACK2(mval)}; - short snap_elem = ED_gizmotypes_snap_3d_update( - gz, CTX_data_ensure_evaluated_depsgraph(C), region, v3d, wm, mval_fl); + /* Snap values are updated too late at the cursor. Be sure to update ahead of time. */ + int x, y; + { + wmWindowManager *wm = CTX_wm_manager(C); + const wmEvent *event = wm->winactive ? wm->winactive->eventstate : NULL; + if (event) { + ARegion *region = CTX_wm_region(C); + x = event->x - region->winrct.xmin; + y = event->y - region->winrct.ymin; + } + else { + x = mval[0]; + y = mval[1]; + } + } + ED_view3d_cursor_snap_update(C, x, y, snap_data); - if (snap_elem) { - ED_region_tag_redraw_editor_overlays(region); + if (snap_data && snap_data->snap_elem) { return 0; } - return -1; } @@ -677,9 +297,9 @@ static int snap_gizmo_invoke(bContext *UNUSED(C), static void snap_gizmo_free(wmGizmo *gz) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - if (snap_gizmo->snap_context_v3d) { - ED_transform_snap_object_context_destroy(snap_gizmo->snap_context_v3d); - snap_gizmo->snap_context_v3d = NULL; + V3DSnapCursorData *snap_data = snap_gizmo->cursor_handle; + if (snap_data) { + ED_view3d_cursor_snap_deactivate_point(); } } @@ -719,7 +339,6 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt) SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE, "Snap Elements", ""); - RNA_def_property_enum_funcs_runtime(prop, gizmo_snap_rna_snap_elements_force_get_fn, gizmo_snap_rna_snap_elements_force_set_fn, @@ -735,7 +354,6 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt) "Point that defines the location of the perpendicular snap", FLT_MIN, FLT_MAX); - RNA_def_property_float_array_funcs_runtime( prop, gizmo_snap_rna_prevpoint_get_fn, gizmo_snap_rna_prevpoint_set_fn, NULL); @@ -750,7 +368,6 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt) "Snap Point Location", FLT_MIN, FLT_MAX); - RNA_def_property_float_array_funcs_runtime( prop, gizmo_snap_rna_location_get_fn, gizmo_snap_rna_location_set_fn, NULL); @@ -764,7 +381,6 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt) "Snap Point Normal", FLT_MIN, FLT_MAX); - RNA_def_property_float_array_funcs_runtime(prop, gizmo_snap_rna_normal_get_fn, NULL, NULL); prop = RNA_def_int_vector(gzt->srna, @@ -777,7 +393,6 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt) "Array index of face, edge and vert snapped", INT_MIN, INT_MAX); - RNA_def_property_int_array_funcs_runtime( prop, gizmo_snap_rna_snap_elem_index_get_fn, NULL, NULL); -- cgit v1.2.3