diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_cursor_snap.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_cursor_snap.c | 150 |
1 files changed, 68 insertions, 82 deletions
diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c index 1cb650910ce..baf61befcba 100644 --- a/source/blender/editors/space_view3d/view3d_cursor_snap.c +++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c @@ -37,6 +37,7 @@ #include "BKE_main.h" #include "BKE_object.h" #include "BKE_scene.h" +#include "BKE_screen.h" #include "GPU_immediate.h" #include "GPU_matrix.h" @@ -54,27 +55,25 @@ #include "WM_api.h" -#define STATE_LEN 3 +#define STATE_INTERN_GET(state) \ + (SnapStateIntern *)((char *)state - offsetof(SnapStateIntern, snap_state)) typedef struct SnapStateIntern { + struct SnapStateIntern *next, *prev; V3DSnapCursorState snap_state; - float prevpoint_stack[3]; - int state_active_prev; - bool is_active; } SnapStateIntern; typedef struct SnapCursorDataIntern { V3DSnapCursorState state_default; - SnapStateIntern state_intern[STATE_LEN]; + ListBase state_intern; V3DSnapCursorData snap_data; - int state_active_len; - int state_active; - struct SnapObjectContext *snap_context_v3d; const Scene *scene; short snap_elem_hidden; + float prevpoint_stack[3]; + /* Copy of the parameters of the last event state in order to detect updates. */ struct { int x; @@ -94,17 +93,6 @@ typedef struct SnapCursorDataIntern { bool is_initiated; } SnapCursorDataIntern; -static void UNUSED_FUNCTION(v3d_cursor_snap_state_init)(V3DSnapCursorState *state) -{ - state->prevpoint = NULL; - state->snap_elem_force = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | - SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT); - state->plane_axis = 2; - rgba_uchar_args_set(state->color_point, 255, 255, 255, 255); - rgba_uchar_args_set(state->color_line, 255, 255, 255, 128); - state->draw_point = true; - state->draw_plane = false; -} static SnapCursorDataIntern g_data_intern = { .state_default = {.prevpoint = NULL, .snap_elem_force = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | @@ -113,8 +101,9 @@ static SnapCursorDataIntern g_data_intern = { .plane_axis = 2, .color_point = {255, 255, 255, 255}, .color_line = {255, 255, 255, 128}, - .draw_point = true, - .draw_plane = false}}; + .color_box = {255, 255, 255, 128}, + .box_dimensions = {1.0f, 1.0f, 1.0f}, + .draw_point = true}}; /** * Calculate a 3x3 orientation matrix from the surface under the cursor. @@ -373,6 +362,24 @@ static void v3d_cursor_plane_draw(const RegionView3D *rv3d, } } +static void cursor_box_draw(const float dimensions[3], uchar color[4]) +{ + GPUVertFormat *format = immVertexFormat(); + const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + + GPU_blend(GPU_BLEND_ALPHA); + GPU_line_smooth(true); + GPU_line_width(1.0f); + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + immUniformColor4ubv(color); + imm_draw_cube_corners_3d(pos_id, (const float[3]){0.0f, 0.0f, dimensions[2]}, dimensions, 0.15f); + immUnbindProgram(); + + GPU_line_smooth(false); + GPU_blend(GPU_BLEND_NONE); +} + void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d, const float loc_prev[3], const float loc_curr[3], @@ -601,7 +608,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, ushort snap_elements = v3d_cursor_snap_elements(state, scene); data_intern->snap_elem_hidden = 0; - const bool draw_plane = state->draw_plane; + const bool draw_plane = state->draw_plane || state->draw_box; if (draw_plane && !(snap_elements & SCE_SNAP_MODE_FACE)) { data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE; snap_elements |= SCE_SNAP_MODE_FACE; @@ -674,6 +681,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, } if (draw_plane) { + RegionView3D *rv3d = region->regiondata; bool orient_surface = snap_elem && (state->plane_orient == V3D_PLACE_ORIENT_SURFACE); if (orient_surface) { copy_m3_m4(omat, obmat); @@ -686,7 +694,6 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, ED_transform_calc_orientation_from_type_ex( scene, view_layer, v3d, region->regiondata, ob, ob, orient_index, pivot_point, omat); - RegionView3D *rv3d = region->regiondata; if (state->use_plane_axis_auto) { mat3_align_axis_to_v3(omat, state->plane_axis, rv3d->viewinv[2]); } @@ -699,6 +706,9 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, orthogonalize_m3(omat, state->plane_axis); if (orient_surface) { + if (dot_v3v3(rv3d->viewinv[2], face_nor) < 0.0f) { + negate_v3(face_nor); + } v3d_cursor_poject_surface_normal(face_nor, obmat, omat); } } @@ -755,16 +765,12 @@ static bool v3d_cursor_snap_pool_fn(bContext *C) return false; } - ARegion *region = CTX_wm_region(C); - if (region->regiontype != RGN_TYPE_WINDOW) { - return false; - } - ScrArea *area = CTX_wm_area(C); if (area->spacetype != SPACE_VIEW3D) { return false; } + ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); RegionView3D *rv3d = region->regiondata; if (rv3d->rflag & RV3D_NAVIGATING) { /* Don't draw the cursor while navigating. It can be distracting. */ @@ -781,7 +787,8 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust V3DSnapCursorData *snap_data = &data_intern->snap_data; wmWindowManager *wm = CTX_wm_manager(C); - ARegion *region = CTX_wm_region(C); + ScrArea *area = CTX_wm_area(C); + ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); x -= region->winrct.xmin; y -= region->winrct.ymin; if (v3d_cursor_eventstate_has_changed(data_intern, state, wm, x, y)) { @@ -791,7 +798,7 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust v3d_cursor_snap_update(state, C, wm, depsgraph, scene, region, v3d, x, y); } - const bool draw_plane = state->draw_plane; + const bool draw_plane = state->draw_plane || state->draw_box; if (!snap_data->snap_elem && !draw_plane) { return; } @@ -802,8 +809,6 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust GPU_matrix_projection_set(rv3d->winmat); GPU_matrix_set(rv3d->viewmat); - GPU_blend(GPU_BLEND_ALPHA); - float matrix[4][4]; if (draw_plane) { copy_m4_m3(matrix, snap_data->plane_omat); @@ -812,7 +817,7 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust v3d_cursor_plane_draw(rv3d, state->plane_axis, matrix); } - if (snap_data->snap_elem && state->draw_point) { + if (snap_data->snap_elem && (state->draw_point || state->draw_box)) { const float *prev_point = (snap_data->snap_elem & SCE_SNAP_MODE_EDGE_PERPENDICULAR) ? state->prevpoint : NULL; @@ -829,7 +834,10 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust snap_data->snap_elem); } - GPU_blend(GPU_BLEND_NONE); + if (state->draw_box) { + GPU_matrix_mul(matrix); + cursor_box_draw(state->box_dimensions, state->color_box); + } /* Restore matrix. */ wmWindowViewport(CTX_wm_window(C)); @@ -839,10 +847,11 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust V3DSnapCursorState *ED_view3d_cursor_snap_state_get(void) { - if (!g_data_intern.state_active_len) { + SnapCursorDataIntern *data_intern = &g_data_intern; + if (BLI_listbase_is_empty(&data_intern->state_intern)) { return &g_data_intern.state_default; } - return (V3DSnapCursorState *)&g_data_intern.state_intern[g_data_intern.state_active]; + return &((SnapStateIntern *)data_intern->state_intern.last)->snap_state; } static void v3d_cursor_snap_activate(void) @@ -872,20 +881,16 @@ static void v3d_cursor_snap_activate(void) static void v3d_cursor_snap_free(void) { SnapCursorDataIntern *data_intern = &g_data_intern; - if (data_intern->handle && G_MAIN->wm.first) { - WM_paint_cursor_end(data_intern->handle); + if (data_intern->handle) { + if (G_MAIN->wm.first) { + WM_paint_cursor_end(data_intern->handle); + } data_intern->handle = NULL; } if (data_intern->snap_context_v3d) { ED_transform_snap_object_context_destroy(data_intern->snap_context_v3d); data_intern->snap_context_v3d = NULL; } - - for (SnapStateIntern *state_intern = data_intern->state_intern; - state_intern < &data_intern->state_intern[STATE_LEN]; - state_intern++) { - state_intern->is_active = false; - } } void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state) @@ -896,56 +901,41 @@ void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state) V3DSnapCursorState *ED_view3d_cursor_snap_active(void) { SnapCursorDataIntern *data_intern = &g_data_intern; - if (!data_intern->state_active_len) { + if (!data_intern->handle) { v3d_cursor_snap_activate(); } - data_intern->state_active_len++; - for (int i = 0; i < STATE_LEN; i++) { - SnapStateIntern *state_intern = &g_data_intern.state_intern[i]; - if (!state_intern->is_active) { - state_intern->snap_state = g_data_intern.state_default; - state_intern->is_active = true; - state_intern->state_active_prev = data_intern->state_active; - data_intern->state_active = i; - return (V3DSnapCursorState *)state_intern; - } - } + SnapStateIntern *state_intern = MEM_mallocN(sizeof(*state_intern), __func__); + state_intern->snap_state = g_data_intern.state_default; + BLI_addtail(&g_data_intern.state_intern, state_intern); - BLI_assert(false); - data_intern->state_active_len--; - return NULL; + return (V3DSnapCursorState *)&state_intern->snap_state; } void ED_view3d_cursor_snap_deactive(V3DSnapCursorState *state) { SnapCursorDataIntern *data_intern = &g_data_intern; - if (!data_intern->state_active_len) { - BLI_assert(false); - return; - } - - SnapStateIntern *state_intern = (SnapStateIntern *)state; - if (!state_intern->is_active) { + if (BLI_listbase_is_empty(&data_intern->state_intern)) { return; } - state_intern->is_active = false; - data_intern->state_active_len--; - if (!data_intern->state_active_len) { + SnapStateIntern *state_intern = STATE_INTERN_GET(state); + BLI_remlink(&data_intern->state_intern, state_intern); + MEM_freeN(state_intern); + if (BLI_listbase_is_empty(&data_intern->state_intern)) { v3d_cursor_snap_free(); } - else { - data_intern->state_active = state_intern->state_active_prev; - } } void ED_view3d_cursor_snap_prevpoint_set(V3DSnapCursorState *state, const float prev_point[3]) { - SnapStateIntern *state_intern = (SnapStateIntern *)state; + SnapCursorDataIntern *data_intern = &g_data_intern; + if (!state) { + state = ED_view3d_cursor_snap_state_get(); + } if (prev_point) { - copy_v3_v3(state_intern->prevpoint_stack, prev_point); - state->prevpoint = state_intern->prevpoint_stack; + copy_v3_v3(data_intern->prevpoint_stack, prev_point); + state->prevpoint = data_intern->prevpoint_stack; } else { state->prevpoint = NULL; @@ -958,12 +948,13 @@ V3DSnapCursorData *ED_view3d_cursor_snap_data_get(V3DSnapCursorState *state, const int y) { SnapCursorDataIntern *data_intern = &g_data_intern; - if (C && data_intern->state_active_len) { + if (C) { wmWindowManager *wm = CTX_wm_manager(C); if (v3d_cursor_eventstate_has_changed(data_intern, state, wm, x, y)) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = DEG_get_input_scene(depsgraph); - ARegion *region = CTX_wm_region(C); + ScrArea *area = CTX_wm_area(C); + ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); View3D *v3d = CTX_wm_view3d(C); if (!state) { @@ -982,8 +973,3 @@ struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(Scene *scene) v3d_cursor_snap_context_ensure(scene); return data_intern->snap_context_v3d; } - -void ED_view3d_cursor_snap_exit(void) -{ - v3d_cursor_snap_free(); -} |