Commit: 2e73e1390e3a87d16fc4016d629253c1228af255 Author: Germano Cavalcante Date: Wed May 27 00:14:11 2020 -0300 Branches: master https://developer.blender.org/rB2e73e1390e3a87d16fc4016d629253c1228af255
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 =================================================================== M source/blender/editors/gizmo_library/CMakeLists.txt A source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c M source/blender/editors/include/ED_gizmo_library.h M source/blender/editors/space_api/spacetypes.c M source/blender/editors/transform/transform_snap.c =================================================================== 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_ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs