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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-01-16 03:29:57 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-01-16 03:36:55 +0300
commitcdfa3feb911164118fcc5b574b3e1a35c8f99c72 (patch)
tree779a402ab25b3d4c95f8e96983f164545511057b
parentc4bbe44e472b97911127ce354954ff7e9e290a3d (diff)
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).
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c13
-rw-r--r--source/blender/editors/include/ED_gizmo_library.h1
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c109
4 files changed, 117 insertions, 8 deletions
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_gizmotype_find("GIZMO_GT_snap_3d", true);
gizmo = WM_gizmo_new_ptr(gzt_snap, gzgroup, NULL);
- RNA_enum_set(gizmo->ptr,
- "snap_elements_force",
- (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));
WM_gizmo_set_color(gizmo, (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
@@ -1630,6 +1715,7 @@ static void gizmo_plane_update_cursor(const bContext *C,
bToolRef *tref = area->runtime.tool;
WM_toolsystem_ref_properties_ensure_from_operator(tref, ot, &ptr);
+ const enum ePlace_SnapTo snap_to = RNA_enum_get(&ptr, "snap_target");
const int plane_axis = RNA_enum_get(&ptr, "plane_axis");
const enum ePlace_Depth plane_depth = RNA_enum_get(&ptr, "plane_depth");
const enum ePlace_Orient plane_orient = RNA_enum_get(&ptr, "plane_orientation");
@@ -1648,12 +1734,19 @@ static void gizmo_plane_update_cursor(const bContext *C,
}
}
+ /* This ensures the snap gizmo has settings from this tool.
+ * This function call could be moved a more appropriate place,
+ * responding to the setting being changed for example,
+ * however setting the value isn't expensive, so do it here. */
+ idp_snap_gizmo_update_snap_elements(scene, snap_to, snap_gizmo);
+
view3d_interactive_add_calc_plane((bContext *)C,
scene,
v3d,
region,
- snap_gizmo,
mval_fl,
+ snap_gizmo,
+ snap_to,
plane_depth,
plane_orient,
plane_axis,