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

Reply via email to