[Bf-blender-cvs] [cdfa3feb911] blender-v2.92-release: Add Object Tool: support incremental snapping

Campbell Barton noreply at git.blender.org
Sat Jan 16 01:38:19 CET 2021


Commit: cdfa3feb911164118fcc5b574b3e1a35c8f99c72
Author: Campbell Barton
Date:   Sat Jan 16 11:29:57 2021 +1100
Branches: blender-v2.92-release
https://developer.blender.org/rBcdfa3feb911164118fcc5b574b3e1a35c8f99c72

Add Object Tool: support incremental snapping

This adds a "Snap to" option that allows using all the scenes snap
settings which includes incremental & absolute grid snapping options.

This is optional because always following scene snapping would not
snap to geometry by default (which seems to be the most useful default).

===================================================================

M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
M	source/blender/editors/include/ED_gizmo_library.h
M	source/blender/editors/space_view3d/view3d_placement.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index d0122536e94..d9661322821 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -462,6 +462,8 @@ class _defs_view3d_add:
         row = layout.row()
         row.scale_x = 0.7
         row.prop(props, "plane_origin")
+        row.scale_x = 0.8
+        row.prop(props, "snap_target")
 
     @ToolDef.from_fn
     def cube_add():
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 8755dea51e1..b8ee1722cb3 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
@@ -80,6 +80,9 @@ typedef struct SnapGizmo3D {
 #endif
   int use_snap_override;
   short snap_elem;
+
+  /** Enabled when snap is activated, even if it didn't find anything. */
+  bool is_enabled;
 } SnapGizmo3D;
 
 /* Checks if the current event is different from the one captured in the last update. */
@@ -284,6 +287,12 @@ void ED_gizmotypes_snap_3d_toggle_clear(wmGizmo *gz)
   snap_gizmo->use_snap_override = -1;
 }
 
+bool ED_gizmotypes_snap_3d_is_enabled(wmGizmo *gz)
+{
+  SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
+  return snap_gizmo->is_enabled;
+}
+
 short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
                                    struct Depsgraph *depsgraph,
                                    const ARegion *region,
@@ -294,6 +303,8 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
                                    float r_nor[3])
 {
   SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
+  snap_gizmo->is_enabled = false;
+
   if (snap_gizmo->use_snap_override != -1) {
     if (snap_gizmo->use_snap_override == false) {
       snap_gizmo->snap_elem = 0;
@@ -318,6 +329,8 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
   }
 #endif
 
+  snap_gizmo->is_enabled = true;
+
   float co[3], no[3];
   short snap_elem = 0;
   int snap_elem_index[3] = {-1, -1, -1};
diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h
index 434ab743d18..dfc8cfea5ce 100644
--- a/source/blender/editors/include/ED_gizmo_library.h
+++ b/source/blender/editors/include/ED_gizmo_library.h
@@ -264,6 +264,7 @@ struct SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(struct Scene *sce
 bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz);
 void ED_gizmotypes_snap_3d_toggle_set(struct wmGizmo *gz, bool enable);
 void ED_gizmotypes_snap_3d_toggle_clear(struct wmGizmo *gz);
+bool ED_gizmotypes_snap_3d_is_enabled(struct wmGizmo *gz);
 
 short ED_gizmotypes_snap_3d_update(struct wmGizmo *gz,
                                    struct Depsgraph *depsgraph,
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index 5bd1b3458e2..2bbe512222c 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -102,6 +102,11 @@ enum ePlace_Orient {
   PLACE_ORIENT_DEFAULT = 2,
 };
 
+enum ePlace_SnapTo {
+  PLACE_SNAP_TO_GEOMETRY = 1,
+  PLACE_SNAP_TO_DEFAULT = 2,
+};
+
 struct InteractivePlaceData {
   /* Window manager variables (set these even when waiting for input). */
   Scene *scene;
@@ -184,6 +189,8 @@ struct InteractivePlaceData {
 
   /** Optional snap gizmo, needed for snapping. */
   wmGizmo *snap_gizmo;
+
+  enum ePlace_SnapTo snap_to;
 };
 
 /** \} */
@@ -359,6 +366,56 @@ static wmGizmoGroup *idp_gizmogroup_from_region(ARegion *region)
   return gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
 }
 
+/**
+ * Calculate 3D view incremental (grid) snapping.
+ *
+ * \note This could be moved to a public function.
+ */
+static bool idp_snap_calc_incremental(
+    Scene *scene, View3D *v3d, ARegion *region, const float co_relative[3], float co[3])
+{
+  if ((scene->toolsettings->snap_mode & SCE_SNAP_MODE_INCREMENT) == 0) {
+    return false;
+  }
+
+  const float grid_size = ED_view3d_grid_view_scale(scene, v3d, region, NULL);
+  if (UNLIKELY(grid_size == 0.0f)) {
+    return false;
+  }
+
+  if (scene->toolsettings->snap_flag & SCE_SNAP_ABS_GRID) {
+    co_relative = NULL;
+  }
+
+  if (co_relative != NULL) {
+    sub_v3_v3(co, co_relative);
+  }
+  mul_v3_fl(co, 1.0f / grid_size);
+  co[0] = roundf(co[0]);
+  co[1] = roundf(co[1]);
+  co[2] = roundf(co[2]);
+  mul_v3_fl(co, grid_size);
+  if (co_relative != NULL) {
+    add_v3_v3(co, co_relative);
+  }
+
+  return true;
+}
+
+static void idp_snap_gizmo_update_snap_elements(Scene *scene,
+                                                enum ePlace_SnapTo snap_to,
+                                                wmGizmo *gizmo)
+{
+  const int snap_mode =
+      (snap_to == PLACE_SNAP_TO_GEOMETRY) ?
+          (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
+           /* SCE_SNAP_MODE_VOLUME | SCE_SNAP_MODE_GRID | SCE_SNAP_MODE_INCREMENT | */
+           SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT) :
+          scene->toolsettings->snap_mode;
+
+  RNA_enum_set(gizmo->ptr, "snap_elements_force", snap_mode);
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -784,8 +841,9 @@ static void view3d_interactive_add_calc_plane(bContext *C,
                                               Scene *scene,
                                               View3D *v3d,
                                               ARegion *region,
-                                              wmGizmo *snap_gizmo,
                                               const float mval_fl[2],
+                                              wmGizmo *snap_gizmo,
+                                              const enum ePlace_SnapTo snap_to,
                                               const enum ePlace_Depth plane_depth,
                                               const enum ePlace_Orient plane_orient,
                                               const int plane_axis,
@@ -914,6 +972,12 @@ static void view3d_interactive_add_calc_plane(bContext *C,
     }
   }
 
+  if (!is_snap_found && ((snap_gizmo != NULL) && ED_gizmotypes_snap_3d_is_enabled(snap_gizmo))) {
+    if (snap_to == PLACE_SNAP_TO_DEFAULT) {
+      idp_snap_calc_incremental(scene, v3d, region, NULL, r_co_src);
+    }
+  }
+
   if (snap_context_free) {
     ED_transform_snap_object_context_destroy(snap_context);
   }
@@ -929,6 +993,7 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
 {
 
   const int plane_axis = RNA_enum_get(op->ptr, "plane_axis");
+  const enum ePlace_SnapTo snap_to = RNA_enum_get(op->ptr, "snap_target");
   const enum ePlace_Depth plane_depth = RNA_enum_get(op->ptr, "plane_depth");
   const enum ePlace_Origin plane_origin = RNA_enum_get(op->ptr, "plane_origin");
   const enum ePlace_Orient plane_orient = RNA_enum_get(op->ptr, "plane_orientation");
@@ -976,8 +1041,9 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
                                     ipd->scene,
                                     ipd->v3d,
                                     ipd->region,
-                                    ipd->snap_gizmo,
                                     mval_fl,
+                                    ipd->snap_gizmo,
+                                    snap_to,
                                     plane_depth,
                                     plane_orient,
                                     plane_axis,
@@ -989,6 +1055,7 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
   ipd->step[0].is_centered = ipd->is_centered_init;
   ipd->step[1].is_centered = ipd->is_centered_init;
   ipd->step_index = STEP_BASE;
+  ipd->snap_to = snap_to;
 
   plane_from_point_normal_v3(ipd->step[0].plane, ipd->co_src, ipd->matrix_orient[plane_axis]);
 
@@ -1415,6 +1482,12 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
                 ipd->step[STEP_BASE].co_dst)) {
           /* pass */
         }
+
+        if (ipd->use_snap && (ipd->snap_to == PLACE_SNAP_TO_DEFAULT)) {
+          if (idp_snap_calc_incremental(
+                  ipd->scene, ipd->v3d, ipd->region, ipd->co_src, ipd->step[STEP_BASE].co_dst)) {
+          }
+        }
       }
     }
     else if (ipd->step_index == STEP_DEPTH) {
@@ -1431,6 +1504,12 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
                 ipd->step[STEP_DEPTH].co_dst)) {
           /* pass */
         }
+
+        if (ipd->use_snap && (ipd->snap_to == PLACE_SNAP_TO_DEFAULT)) {
+          if (idp_snap_calc_incremental(
+                  ipd->scene, ipd->v3d, ipd->region, ipd->co_src, ipd->step[STEP_DEPTH].co_dst)) {
+          }
+        }
       }
 
       /* Correct the point so it's aligned with the 'ipd->step[0].co_dst'. */
@@ -1550,6 +1629,17 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
   RNA_def_property_enum_items(prop, plane_orientation_items);
   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 
+  static const EnumPropertyItem snap_to_items[] = {
+      {PLACE_SNAP_TO_GEOMETRY, "GEOMETRY", 0, "Geometry", "Snap to all geometry"},
+      {PLACE_SNAP_TO_DEFAULT, "DEFAULT", 0, "Default", "Use the current snap settings"},
+      {0, NULL, 0, NULL, NULL},
+  };
+  prop = RNA_def_property(ot->srna, "snap_target", PROP_ENUM, PROP_NONE);
+  RNA_def_property_ui_text(prop, "Snap to", "The target to use while snapping");
+  RNA_def_property_enum_default(prop, PLACE_SNAP_TO_GEOMETRY);
+  RNA_def_property_enum_items(prop, snap_to_items);
+  RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
   /* When not accessed via a tool. */
   prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
@@ -1573,11 +1663,6 @@ static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup
     const wmGizmoType *gzt_snap;
     gzt_snap = WM_gi

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list