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
path: root/source
diff options
context:
space:
mode:
authorGermano Cavalcante <germano.costa@ig.com.br>2020-05-27 06:14:11 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2020-05-27 06:14:11 +0300
commit2e73e1390e3a87d16fc4016d629253c1228af255 (patch)
tree3df4857e735ea7bb8bacbf918eaf540e497d8b50 /source
parent7ed7901c00867a951bd2bb0e179d7b087cd68d9d (diff)
Gizmo Library: New Snap Gizmo
Generic snap gizmo to be used for different tools. The Gizmo can be configured initially by the following properties: - `"snap_elements_force"`, `"prev_point"` The following properties can be read as return: - `"location"`, `"normal"`, `"snap_elem_index"` This property can be linked to another (tool_setting.snap_elements): - `"snap_elements"` And this 3 extra utilities have been added: - `ED_gizmotypes_snap_3d_draw_util`, - `ED_gizmotypes_snap_3d_context_get`, - `ED_gizmotypes_snap_3d_update`. Differential Revision: https://developer.blender.org/D7071
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/gizmo_library/CMakeLists.txt1
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c530
-rw-r--r--source/blender/editors/include/ED_gizmo_library.h30
-rw-r--r--source/blender/editors/space_api/spacetypes.c1
-rw-r--r--source/blender/editors/transform/transform_snap.c103
5 files changed, 589 insertions, 76 deletions
diff --git a/source/blender/editors/gizmo_library/CMakeLists.txt b/source/blender/editors/gizmo_library/CMakeLists.txt
index 68a204c04a7..1f3edf31b19 100644
--- a/source/blender/editors/gizmo_library/CMakeLists.txt
+++ b/source/blender/editors/gizmo_library/CMakeLists.txt
@@ -53,6 +53,7 @@ set(SRC
gizmo_types/dial3d_gizmo.c
gizmo_types/move3d_gizmo.c
gizmo_types/primitive3d_gizmo.c
+ gizmo_types/snap3d_gizmo.c
)
set(LIB
diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
new file mode 100644
index 00000000000..f6ad589778c
--- /dev/null
+++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
@@ -0,0 +1,530 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file snap3d_gizmo.c
+ * \ingroup edgizmolib
+ *
+ * \name Snap Gizmo
+ *
+ * 3D Gizmo
+ *
+ * \brief Snap gizmo which exposes the location, normal and index in the props.
+ */
+
+#include "BLI_math.h"
+
+#include "DNA_scene_types.h"
+
+#include "BKE_context.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 "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;
+ PropertyRNA *prop_prevpoint;
+ PropertyRNA *prop_location;
+ PropertyRNA *prop_normal;
+ PropertyRNA *prop_elem_index;
+ PropertyRNA *prop_snap_force;
+
+ /* We could have other snap contexts, for now only support 3D view. */
+ SnapObjectContext *snap_context_v3d;
+ int mval[2];
+ short snap_elem;
+
+#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
+ wmKeyMap *keymap;
+ int snap_on;
+ bool invert_snap;
+#endif
+} SnapGizmo3D;
+
+#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
+static bool invert_snap(const wmGizmo *gz, const wmWindowManager *wm, const wmEvent *event)
+{
+ SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
+ wmKeyMap *keymap = WM_keymap_active(wm, gizmo_snap->keymap);
+ if (!keymap) {
+ return false;
+ }
+
+ int snap_on = gizmo_snap->snap_on;
+ 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;
+ }
+ }
+ }
+ return false;
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/** \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)
+{
+ 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_get(wmGizmo *gz)
+{
+ SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
+ return gizmo_snap->snap_context_v3d;
+}
+
+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],
+ float r_loc[3],
+ float r_nor[3])
+{
+ SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
+ float co[3], no[3];
+ short snap_elem = 0;
+ int snap_elem_index[3] = {-1, -1, -1};
+ int index = -1;
+
+#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
+ if (wm) {
+ gizmo_snap->invert_snap = invert_snap(gz, wm, wm->winactive->eventstate);
+ }
+
+ Scene *scene = DEG_get_input_scene(depsgraph);
+ const ToolSettings *ts = scene->toolsettings;
+ if (gizmo_snap->invert_snap != !(ts->snap_flag & SCE_SNAP)) {
+ gizmo_snap->snap_elem = 0;
+ return 0;
+ }
+#else
+ UNUSED_VARS(wm);
+#endif
+
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "snap_elements");
+ int snap_elements = RNA_property_enum_get(&gz_prop->ptr, gz_prop->prop);
+ if (gz_prop->prop != gizmo_snap->prop_snap_force) {
+ int snap_elements_force = RNA_property_enum_get(gz->ptr, gizmo_snap->prop_snap_force);
+ snap_elements |= snap_elements_force;
+ }
+ snap_elements &= (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
+ SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR);
+
+ if (snap_elements) {
+ float prev_co[3] = {0.0f};
+ if (RNA_property_is_set(gz->ptr, gizmo_snap->prop_prevpoint)) {
+ RNA_property_float_get_array(gz->ptr, gizmo_snap->prop_prevpoint, prev_co);
+ }
+ else {
+ snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR;
+ }
+
+ float dist_px = 12.0f * U.pixelsize;
+ snap_elem = ED_transform_snap_object_project_view3d_ex(gizmo_snap->snap_context_v3d,
+ depsgraph,
+ snap_elements,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ .use_occlusion_test = true,
+ },
+ 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;
+ }
+
+ gizmo_snap->snap_elem = snap_elem;
+ RNA_property_float_set_array(gz->ptr, gizmo_snap->prop_location, co);
+ RNA_property_float_set_array(gz->ptr, gizmo_snap->prop_normal, no);
+ RNA_property_int_set_array(gz->ptr, gizmo_snap->prop_elem_index, snap_elem_index);
+
+ if (r_loc) {
+ copy_v3_v3(r_loc, co);
+ }
+ if (r_nor) {
+ copy_v3_v3(r_nor, no);
+ }
+
+ return snap_elem;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name GIZMO_GT_snap_3d
+ * \{ */
+
+static void gizmo_snap_setup(wmGizmo *gz)
+{
+ SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
+
+ /* For quick access to the props. */
+ gizmo_snap->prop_prevpoint = RNA_struct_find_property(gz->ptr, "prev_point");
+ gizmo_snap->prop_location = RNA_struct_find_property(gz->ptr, "location");
+ gizmo_snap->prop_normal = RNA_struct_find_property(gz->ptr, "normal");
+ gizmo_snap->prop_elem_index = RNA_struct_find_property(gz->ptr, "snap_elem_index");
+ gizmo_snap->prop_snap_force = RNA_struct_find_property(gz->ptr, "snap_elements_force");
+
+ /* Prop fallback. */
+ WM_gizmo_target_property_def_rna(gz, "snap_elements", gz->ptr, "snap_elements_force", -1);
+
+ /* Flags. */
+ gz->flag |= WM_GIZMO_NO_TOOLTIP;
+}
+
+static void gizmo_snap_draw(const bContext *C, wmGizmo *gz)
+{
+ SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
+ if (gizmo_snap->snap_elem == 0) {
+ return;
+ }
+
+ /* Ideally, we shouldn't assign values here.
+ * But `test_select` is not called during navigation.
+ * And `snap_elem` is not really useful in this case. */
+ if ((gz->state & WM_GIZMO_STATE_HIGHLIGHT) == 0) {
+ gizmo_snap->snap_elem = 0;
+ return;
+ }
+
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (rv3d->rflag & RV3D_NAVIGATING) {
+ gizmo_snap->snap_elem = 0;
+ return;
+ }
+
+ float location[3], prev_point_stack[3], *prev_point = NULL;
+ uchar color_line[4], color_point[4];
+
+ RNA_property_float_get_array(gz->ptr, gizmo_snap->prop_location, location);
+
+ UI_GetThemeColor3ubv(TH_TRANSFORM, color_line);
+ color_line[3] = 128;
+
+ rgba_float_to_uchar(color_point, gz->color);
+
+ if (RNA_property_is_set(gz->ptr, gizmo_snap->prop_prevpoint)) {
+ RNA_property_float_get_array(gz->ptr, gizmo_snap->prop_prevpoint, prev_point_stack);
+ prev_point = prev_point_stack;
+ }
+
+ GPU_line_smooth(false);
+
+ GPU_line_width(1.0f);
+ ED_gizmotypes_snap_3d_draw_util(
+ rv3d, prev_point, location, NULL, color_line, color_point, gizmo_snap->snap_elem);
+}
+
+static int gizmo_snap_test_select(bContext *C, wmGizmo *gz, const int mval[2])
+{
+ SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
+#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
+ wmWindowManager *wm = CTX_wm_manager(C);
+ bool invert = invert_snap(gz, wm, wm->winactive->eventstate);
+ if (gizmo_snap->invert_snap == invert && gizmo_snap->mval[0] == mval[0] &&
+ gizmo_snap->mval[1] == mval[1]) {
+ /* Performance, do not update. */
+ return gizmo_snap->snap_elem ? 0 : -1;
+ }
+ gizmo_snap->invert_snap = invert;
+#else
+ if (gizmo_snap->mval[0] == mval[0] && gizmo_snap->mval[1] == mval[1]) {
+ /* Performance, do not update. */
+ return gizmo_snap->snap_elem ? 0 : -1;
+ }
+#endif
+ copy_v2_v2_int(gizmo_snap->mval, mval);
+
+ ARegion *region = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ if (gizmo_snap->snap_context_v3d == NULL) {
+ gizmo_snap->snap_context_v3d = ED_transform_snap_object_context_create_view3d(
+ NULL, CTX_data_scene(C), 0, region, v3d);
+
+#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
+ gizmo_snap->keymap = WM_modalkeymap_find(wm->defaultconf, "Generic Gizmo Tweak Modal Map");
+ gizmo_snap->snap_on = -1;
+ RNA_enum_value_from_id(gizmo_snap->keymap->modal_items, "SNAP_ON", &gizmo_snap->snap_on);
+#endif
+ }
+
+ const float mval_fl[2] = {UNPACK2(mval)};
+ short snap_elem = ED_gizmotypes_snap_3d_update(
+ gz, CTX_data_ensure_evaluated_depsgraph(C), region, v3d, NULL, mval_fl, NULL, NULL);
+
+ if (snap_elem) {
+ ED_region_tag_redraw_editor_overlays(region);
+ return 0;
+ }
+
+ return -1;
+}
+
+static int gizmo_snap_modal(bContext *UNUSED(C),
+ wmGizmo *UNUSED(gz),
+ const wmEvent *UNUSED(event),
+ eWM_GizmoFlagTweak UNUSED(tweak_flag))
+{
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int gizmo_snap_invoke(bContext *UNUSED(C),
+ wmGizmo *UNUSED(gz),
+ const wmEvent *UNUSED(event))
+{
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void gizmo_snap_free(wmGizmo *gz)
+{
+ SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
+ if (gizmo_snap->snap_context_v3d) {
+ ED_transform_snap_object_context_destroy(gizmo_snap->snap_context_v3d);
+ gizmo_snap->snap_context_v3d = NULL;
+ }
+}
+
+static void GIZMO_GT_snap_3d(wmGizmoType *gzt)
+{
+ /* identifiers */
+ gzt->idname = "GIZMO_GT_snap_3d";
+
+ /* api callbacks */
+ gzt->setup = gizmo_snap_setup;
+ gzt->draw = gizmo_snap_draw;
+ gzt->test_select = gizmo_snap_test_select;
+ gzt->modal = gizmo_snap_modal;
+ gzt->invoke = gizmo_snap_invoke;
+ gzt->free = gizmo_snap_free;
+
+ gzt->struct_size = sizeof(SnapGizmo3D);
+
+ const EnumPropertyItem *rna_enum_snap_element_items;
+ {
+ /* Get Snap Element Items enum. */
+ bool free;
+ PointerRNA toolsettings_ptr;
+ RNA_pointer_create(NULL, &RNA_ToolSettings, NULL, &toolsettings_ptr);
+ PropertyRNA *prop = RNA_struct_find_property(&toolsettings_ptr, "snap_elements");
+ RNA_property_enum_items(
+ NULL, &toolsettings_ptr, prop, &rna_enum_snap_element_items, NULL, &free);
+
+ BLI_assert(free == false);
+ }
+
+ /* Setup. */
+ RNA_def_enum_flag(gzt->srna,
+ "snap_elements_force",
+ rna_enum_snap_element_items,
+ SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE,
+ "Snap Elements",
+ "");
+
+ RNA_def_float_vector(gzt->srna,
+ "prev_point",
+ 3,
+ NULL,
+ FLT_MIN,
+ FLT_MAX,
+ "Previous Point",
+ "Point that defines the location of the perpendicular snap",
+ FLT_MIN,
+ FLT_MAX);
+
+ /* Returns. */
+ RNA_def_float_vector(gzt->srna,
+ "location",
+ 3,
+ NULL,
+ FLT_MIN,
+ FLT_MAX,
+ "Location",
+ "Snap Point Location",
+ FLT_MIN,
+ FLT_MAX);
+
+ RNA_def_float_vector(gzt->srna,
+ "normal",
+ 3,
+ NULL,
+ FLT_MIN,
+ FLT_MAX,
+ "Normal",
+ "Snap Point Normal",
+ FLT_MIN,
+ FLT_MAX);
+
+ RNA_def_int_vector(gzt->srna,
+ "snap_elem_index",
+ 3,
+ NULL,
+ INT_MIN,
+ INT_MAX,
+ "Snap Element",
+ "Array index of face, edge and vert snapped",
+ INT_MIN,
+ INT_MAX);
+
+ /* Read/Write. */
+ WM_gizmotype_target_property_def(gzt, "snap_elements", PROP_ENUM, 1);
+}
+
+void ED_gizmotypes_snap_3d(void)
+{
+ WM_gizmotype_append(GIZMO_GT_snap_3d);
+}
+
+/** \} */
diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h
index 07eade23506..47ecbd73c9a 100644
--- a/source/blender/editors/include/ED_gizmo_library.h
+++ b/source/blender/editors/include/ED_gizmo_library.h
@@ -40,9 +40,15 @@ void ED_gizmotypes_facemap_3d(void);
void ED_gizmotypes_preselect_3d(void);
void ED_gizmotypes_primitive_3d(void);
void ED_gizmotypes_blank_3d(void);
+void ED_gizmotypes_snap_3d(void);
-struct Object;
+struct ARegion;
struct bContext;
+struct Depsgraph;
+struct Object;
+struct SnapObjectContext;
+struct wmWindowManager;
+struct View3D;
struct wmGizmo;
/* -------------------------------------------------------------------- */
@@ -223,8 +229,9 @@ enum {
};
/* -------------------------------------------------------------------- */
-/* Gizmo Drawing Functions */
+/* Specific gizmos utils */
+/* dial3d_gizmo.c */
struct Dial3dParams {
int draw_options;
float angle_ofs;
@@ -241,6 +248,25 @@ void ED_gizmotypes_dial_3d_draw_util(const float matrix_basis[4][4],
const bool select,
struct Dial3dParams *params);
+/* snap3d_gizmo.c */
+#define USE_SNAP_DETECT_FROM_KEYMAP_HACK
+void ED_gizmotypes_snap_3d_draw_util(struct 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);
+struct SnapObjectContext *ED_gizmotypes_snap_3d_context_get(struct wmGizmo *gz);
+short ED_gizmotypes_snap_3d_update(struct wmGizmo *gz,
+ struct Depsgraph *depsgraph,
+ const struct ARegion *region,
+ const struct View3D *v3d,
+ const struct wmWindowManager *wm,
+ const float mval_fl[2],
+ float r_loc[3],
+ float r_nor[3]);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index f81aaeb0ee4..e084d5fcdf2 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -135,6 +135,7 @@ void ED_spacetypes_init(void)
ED_gizmotypes_blank_3d();
ED_gizmotypes_cage_2d();
ED_gizmotypes_cage_3d();
+ ED_gizmotypes_snap_3d();
/* register types for operators and gizmos */
spacetypes = BKE_spacetypes_list();
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index d3df68b21da..7af616bfb31 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -56,6 +56,7 @@
#include "WM_types.h"
+#include "ED_gizmo_library.h"
#include "ED_image.h"
#include "ED_markers.h"
#include "ED_node.h"
@@ -178,99 +179,53 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
(t->scene->toolsettings->snap_mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR);
if (draw_target || validSnap(t)) {
- TransSnapPoint *p;
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- float imat[4][4];
- float size;
+ const float *loc_cur = NULL;
+ const float *loc_prev = NULL;
+ const float *normal = NULL;
GPU_depth_test(false);
- size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (!BLI_listbase_is_empty(&t->tsnap.points)) {
+ /* Draw snap points. */
- invert_m4_m4(imat, rv3d->viewmat);
+ float size = 2.0f * UI_GetThemeValuef(TH_VERTEX_SIZE);
+ float view_inv[4][4];
+ copy_m4_m4(view_inv, rv3d->viewinv);
- uint pos = GPU_vertformat_attr_add(
- immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- for (p = t->tsnap.points.first; p; p = p->next) {
- if (p == t->tsnap.selectedPoint) {
- immUniformColor4ubv(selectedCol);
- }
- else {
- immUniformColor4ubv(col);
+ LISTBASE_FOREACH (TransSnapPoint *, p, &t->tsnap.points) {
+ if (p == t->tsnap.selectedPoint) {
+ immUniformColor4ubv(selectedCol);
+ }
+ else {
+ immUniformColor4ubv(col);
+ }
+ imm_drawcircball(p->co, ED_view3d_pixel_size(rv3d, p->co) * size, view_inv, pos);
}
- imm_drawcircball(p->co, ED_view3d_pixel_size(rv3d, p->co) * size * 0.75f, imat, pos);
- }
-
- if (t->tsnap.status & POINT_INIT) {
- immUniformColor4ubv(activeCol);
-
- imm_drawcircball(
- t->tsnap.snapPoint, ED_view3d_pixel_size(rv3d, t->tsnap.snapPoint) * size, imat, pos);
+ immUnbindProgram();
}
/* draw normal if needed */
if (usingSnappingNormal(t) && validSnappingNormal(t)) {
- immUniformColor4ubv(activeCol);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex3f(pos, t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
- immVertex3f(pos,
- t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0],
- t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1],
- t->tsnap.snapPoint[2] + t->tsnap.snapNormal[2]);
- immEnd();
+ normal = t->tsnap.snapNormal;
}
if (draw_target) {
- /* Draw snapTarget */
- float targ_co[3], vx[3], vy[3], v1[3], v2[3], v3[3], v4[4];
- copy_v3_v3(targ_co, t->tsnap.snapTarget);
- float px_size = 0.75f * size * ED_view3d_pixel_size(rv3d, targ_co);
-
- mul_v3_v3fl(vx, imat[0], px_size);
- mul_v3_v3fl(vy, imat[1], px_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, targ_co);
- add_v3_v3(v2, targ_co);
- add_v3_v3(v3, targ_co);
- add_v3_v3(v4, targ_co);
-
- immUniformColor4ubv(col);
- immBegin(GPU_PRIM_LINES, 4);
- immVertex3fv(pos, v3);
- immVertex3fv(pos, v1);
- immVertex3fv(pos, v4);
- immVertex3fv(pos, v2);
- immEnd();
-
- if (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE_PERPENDICULAR) {
- 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(col);
+ loc_prev = t->tsnap.snapTarget;
+ }
- immBegin(GPU_PRIM_LINES, 2);
- immVertex3fv(pos, targ_co);
- immVertex3fv(pos, t->tsnap.snapPoint);
- immEnd();
- }
+ if (validSnap(t)) {
+ loc_cur = t->tsnap.snapPoint;
}
- immUnbindProgram();
+ ED_gizmotypes_snap_3d_draw_util(
+ rv3d, loc_prev, loc_cur, normal, col, activeCol, t->tsnap.snapElem);
GPU_depth_test(true);
}