From 8e059b569b8b9e6c18a8774a806b627d1c98e371 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 6 Jun 2023 19:35:57 +0200 Subject: [PATCH] UI: move 'Face Nearest' snap option to another section The snap mode called "Face Nearest" (and the "Increment" but that's for another time) doesn't behave like the other snap modes. Unlike the other snap modes, "Face Nearest" does not act on a Snap Base (or Snap Source). It always acts on the origin of individually transformed elements, (such as each vertex individually). It works just like the "Project Individual Elements" option. So this commit makes the following changes: - `Snap With` was moved to the beginning of the popover - `Align Rotation to Target` and `Backface Culling` have been moved closer to the snap targets - `Snap With`, `Target Selection` and `Align Rotation to Target` are no longer hidden by varying the mode and options - `Project Individual Elements` has been replaced with the `Face Project` option - `Face Nearest` has been moved to stick together with the `Face Project` option Co-authored-by: Germano Cavalcante Pull Request: https://projects.blender.org/blender/blender/pulls/108555 --- scripts/startup/bl_ui/space_view3d.py | 102 +++++++++--------- .../blender/blenkernel/BKE_blender_version.h | 2 +- .../blenloader/intern/versioning_400.cc | 10 ++ source/blender/editors/curve/editcurve.c | 4 +- .../gizmo_library/gizmo_types/move3d_gizmo.c | 2 +- .../blender/editors/mesh/editmesh_extrude.c | 2 +- source/blender/editors/mesh/editmesh_utils.c | 2 +- .../editors/space_view3d/view3d_cursor_snap.c | 10 +- .../editors/space_view3d/view3d_edit.c | 2 +- .../space_view3d/view3d_gizmo_ruler.cc | 2 +- source/blender/editors/transform/transform.c | 3 +- .../editors/transform/transform_constraints.c | 2 +- .../transform/transform_mode_edge_slide.c | 2 +- .../transform/transform_mode_snapsource.c | 2 +- .../transform/transform_mode_vert_slide.c | 2 +- .../editors/transform/transform_snap.cc | 54 +++------- .../transform/transform_snap_object.cc | 20 ++-- source/blender/makesdna/DNA_scene_types.h | 12 ++- source/blender/makesrna/intern/rna_scene.c | 77 ++++++++----- 19 files changed, 162 insertions(+), 150 deletions(-) diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index f9237cc828a..9408a99d39b 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -7067,72 +7067,70 @@ class VIEW3D_PT_snapping(Panel): def draw(self, context): tool_settings = context.tool_settings - snap_elements = tool_settings.snap_elements obj = context.active_object object_mode = 'OBJECT' if obj is None else obj.mode layout = self.layout col = layout.column() + + col.label(text="Snap With") + row = col.row(align=True) + row.prop(tool_settings, "snap_target", expand=True) + col.label(text="Snap To") - col.prop(tool_settings, "snap_elements", expand=True) + col.prop(tool_settings, "snap_elements_base", expand=True) + + col.label(text="Snap Individual Elements To") + col.prop(tool_settings, "snap_elements_individual", expand=True) col.separator() - if 'INCREMENT' in snap_elements: + + if 'INCREMENT' in tool_settings.snap_elements: col.prop(tool_settings, "use_snap_grid_absolute") - if snap_elements != {'INCREMENT'}: - if snap_elements != {'FACE_NEAREST'}: - col.label(text="Snap With") - row = col.row(align=True) - row.prop(tool_settings, "snap_target", expand=True) + if 'VOLUME' in tool_settings.snap_elements: + col.prop(tool_settings, "use_snap_peel_object") - if obj: - col.label(text="Target Selection") - col_targetsel = col.column(align=True) - if object_mode == 'EDIT' and obj.type not in {'LATTICE', 'META', 'FONT'}: - col_targetsel.prop( - tool_settings, - "use_snap_self", - text="Include Active", - icon='EDITMODE_HLT', - ) - col_targetsel.prop( - tool_settings, - "use_snap_edit", - text="Include Edited", - icon='OUTLINER_DATA_MESH', - ) - col_targetsel.prop( - tool_settings, - "use_snap_nonedit", - text="Include Non-Edited", - icon='OUTLINER_OB_MESH', - ) + if 'FACE_NEAREST' in tool_settings.snap_elements: + col.prop(tool_settings, "use_snap_to_same_target") + if object_mode == 'EDIT': + col.prop(tool_settings, "snap_face_nearest_steps") + + col.separator() + + col.prop(tool_settings, "use_snap_align_rotation") + col.prop(tool_settings, "use_snap_backface_culling") + + col.separator() + + if obj: + col.label(text="Target Selection") + col_targetsel = col.column(align=True) + if object_mode == 'EDIT' and obj.type not in {'LATTICE', 'META', 'FONT'}: col_targetsel.prop( tool_settings, - "use_snap_selectable", - text="Exclude Non-Selectable", - icon='RESTRICT_SELECT_OFF', + "use_snap_self", + text="Include Active", + icon='EDITMODE_HLT', ) - - if object_mode in {'OBJECT', 'POSE', 'EDIT', 'WEIGHT_PAINT'}: - col.prop(tool_settings, "use_snap_align_rotation") - - col.prop(tool_settings, "use_snap_backface_culling") - - is_face_nearest_enabled = 'FACE_NEAREST' in snap_elements - if is_face_nearest_enabled or 'FACE' in snap_elements: - sub = col.column() - sub.active = not is_face_nearest_enabled - sub.prop(tool_settings, "use_snap_project") - - if is_face_nearest_enabled: - col.prop(tool_settings, "use_snap_to_same_target") - if object_mode == 'EDIT': - col.prop(tool_settings, "snap_face_nearest_steps") - - if 'VOLUME' in snap_elements: - col.prop(tool_settings, "use_snap_peel_object") + col_targetsel.prop( + tool_settings, + "use_snap_edit", + text="Include Edited", + icon='OUTLINER_DATA_MESH', + ) + col_targetsel.prop( + tool_settings, + "use_snap_nonedit", + text="Include Non-Edited", + icon='OUTLINER_OB_MESH', + ) + col_targetsel.prop( + tool_settings, + "use_snap_selectable", + text="Exclude Non-Selectable", + icon='RESTRICT_SELECT_OFF', + ) col.label(text="Affect") row = col.row(align=True) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 5fea6059647..91a9c841327 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 4 +#define BLENDER_FILE_SUBVERSION 5 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 0d1d80b7a5a..46582c55d98 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -124,6 +124,16 @@ void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 400, 4)) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { +#define SCE_SNAP_PROJECT (1 << 3) + if (scene->toolsettings->snap_flag & SCE_SNAP_PROJECT) { + scene->toolsettings->snap_mode |= SCE_SNAP_MODE_FACE_RAYCAST; + } +#undef SCE_SNAP_PROJECT + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 3680bdc3147..0c1afc8f52a 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5610,7 +5610,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) Curve *cu; float location[3]; const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && - (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE_RAYCAST)); + (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); Nurb *nu; BezTriple *bezt; @@ -5642,7 +5642,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) vc.depsgraph, vc.region, vc.v3d, - SCE_SNAP_MODE_FACE_RAYCAST, + SCE_SNAP_MODE_FACE, &(const struct SnapObjectParams){ .snap_target_select = (vc.obedit != NULL) ? SCE_SNAP_TARGET_NOT_ACTIVE : SCE_SNAP_TARGET_ALL, diff --git a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c index 09d35eb2642..016e92ed4bd 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c @@ -280,7 +280,7 @@ static int gizmo_move_modal(bContext *C, CTX_data_ensure_evaluated_depsgraph(C), region, CTX_wm_view3d(C), - (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE_RAYCAST), + (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE), &(const struct SnapObjectParams){ .snap_target_select = SCE_SNAP_TARGET_ALL, .edit_mode_type = SNAP_GEOM_EDIT, diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index fd4c058b131..6cd78e7870f 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -710,7 +710,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w const bool rot_src = RNA_boolean_get(op->ptr, "rotate_source"); const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && - (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE_RAYCAST)); + (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); /* First calculate the center of transformation. */ zero_v3(center); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 3e1014e942b..92b6ccfc342 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1946,7 +1946,7 @@ void EDBM_project_snap_verts( depsgraph, region, CTX_wm_view3d(C), - SCE_SNAP_MODE_FACE_RAYCAST, + SCE_SNAP_MODE_FACE, &(const struct SnapObjectParams){ .snap_target_select = target_op, .edit_mode_type = SNAP_GEOM_FINAL, diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c index 2bcdabd5d92..e044c888160 100644 --- a/source/blender/editors/space_view3d/view3d_cursor_snap.c +++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c @@ -611,9 +611,9 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, v3d_cursor_snap_context_ensure(scene); data_intern->snap_elem_hidden = SCE_SNAP_MODE_NONE; - if (calc_plane_omat && !(snap_elements & SCE_SNAP_MODE_FACE_RAYCAST)) { - data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE_RAYCAST; - snap_elements |= SCE_SNAP_MODE_FACE_RAYCAST; + if (calc_plane_omat && !(snap_elements & SCE_SNAP_MODE_FACE)) { + data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE; + snap_elements |= SCE_SNAP_MODE_FACE; } snap_data->is_enabled = true; @@ -628,7 +628,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, snap_data->snap_elem = SCE_SNAP_MODE_NONE; return; } - snap_elements = data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE_RAYCAST; + snap_elements = data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE; } } #endif @@ -771,7 +771,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, { snap_elem_index[1] = index; } - else if (snap_elem == SCE_SNAP_MODE_FACE_RAYCAST) { + else if (snap_elem == SCE_SNAP_MODE_FACE) { snap_elem_index[2] = index; } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 63e54e276d6..4184f4c8579 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -911,7 +911,7 @@ void ED_view3d_cursor3d_position_rotation(bContext *C, CTX_data_ensure_evaluated_depsgraph(C), region, v3d, - SCE_SNAP_MODE_FACE_RAYCAST, + SCE_SNAP_MODE_FACE, &(const struct SnapObjectParams){ .snap_target_select = SCE_SNAP_TARGET_ALL, .edit_mode_type = SNAP_GEOM_FINAL, diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc b/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc index de837600f3a..5a0541a591f 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc @@ -374,7 +374,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C, depsgraph, ruler_info->region, v3d, - SCE_SNAP_MODE_FACE_RAYCAST, + SCE_SNAP_MODE_FACE, &snap_object_params, nullptr, mval_fl, diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 69d7bec6465..27e2d7618b5 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1658,7 +1658,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) if ((prop = RNA_struct_find_property(op->ptr, "snap_elements"))) { RNA_property_enum_set(op->ptr, prop, t->tsnap.mode); - RNA_boolean_set(op->ptr, "use_snap_project", (t->tsnap.flag & SCE_SNAP_PROJECT) != 0); + RNA_boolean_set( + op->ptr, "use_snap_project", (t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST) != 0); RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_operation); eSnapTargetOP target = t->tsnap.target_operation; diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 76cd4b2c3ee..968ca6ed09c 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -399,7 +399,7 @@ static void applyAxisConstraintVec(const TransInfo *t, if (transform_snap_is_active(t)) { if (validSnap(t)) { is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0; - is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE_RAYCAST) != 0; + is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0; is_snap_to_point = !is_snap_to_edge && !is_snap_to_face; } else if (t->tsnap.snapElem & SCE_SNAP_MODE_GRID) { diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 45055def43b..f0d35cadb4a 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1294,7 +1294,7 @@ static void edge_slide_snap_apply(TransInfo *t, float *value) side_index = t_snap >= t_mid; } - if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE_RAYCAST)) { + if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE)) { float co_dir[3]; sub_v3_v3v3(co_dir, co_dest[side_index], co_orig); normalize_v3(co_dir); diff --git a/source/blender/editors/transform/transform_mode_snapsource.c b/source/blender/editors/transform/transform_mode_snapsource.c index 43307022100..0fc6c39edcd 100644 --- a/source/blender/editors/transform/transform_mode_snapsource.c +++ b/source/blender/editors/transform/transform_mode_snapsource.c @@ -105,7 +105,7 @@ static void snapsource_confirm(TransInfo *t) transform_input_reset(t, mval); /* Remote individual snap projection since this mode does not use the new `snap_source`. */ - t->tsnap.flag &= ~SCE_SNAP_PROJECT; + t->tsnap.mode &= ~(SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST); } static eRedrawFlag snapsource_handle_event_fn(TransInfo *t, const wmEvent *event) diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index 969213e5318..d902bc9706b 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -539,7 +539,7 @@ static void vert_slide_snap_apply(TransInfo *t, float *value) getSnapPoint(t, dvec); sub_v3_v3(dvec, t->tsnap.snap_source); - if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE_RAYCAST)) { + if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE)) { float co_dir[3]; sub_v3_v3v3(co_dir, co_curr_3d, co_orig_3d); normalize_v3(co_dir); diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index d6727182f55..d7422baefa2 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -412,10 +412,6 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event) static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td) { - if (!(t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST)) { - return false; - } - float iloc[3], loc[3], no[3]; float mval_fl[2]; @@ -443,7 +439,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td t->depsgraph, t->region, static_cast(t->view), - SCE_SNAP_MODE_FACE_RAYCAST, + SCE_SNAP_MODE_FACE, &snap_object_params, nullptr, mval_fl, @@ -451,7 +447,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td nullptr, loc, no); - if (hit != SCE_SNAP_MODE_FACE_RAYCAST) { + if (hit != SCE_SNAP_MODE_FACE) { return false; } @@ -481,10 +477,6 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td) { - if (!(t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST)) { - return; - } - float init_loc[3]; float prev_loc[3]; float snap_loc[3], snap_no[3]; @@ -539,11 +531,7 @@ bool transform_snap_project_individual_is_active(const TransInfo *t) return false; } - if (!(t->tsnap.flag & SCE_SNAP_PROJECT)) { - return false; - } - - return true; + return (t->tsnap.mode & (SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST)) != 0; } void transform_snap_project_individual_apply(TransInfo *t) @@ -566,8 +554,12 @@ void transform_snap_project_individual_apply(TransInfo *t) /* If both face ray-cast and face nearest methods are enabled, start with face ray-cast and * fallback to face nearest ray-cast does not hit. */ - bool hit = applyFaceProject(t, tc, td); - if (!hit) { + bool hit = false; + if (t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST) { + hit = applyFaceProject(t, tc, td); + } + + if (!hit && t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST) { applyFaceNearest(t, tc, td); } #if 0 /* TODO: support this? */ @@ -583,15 +575,9 @@ static bool transform_snap_mixed_is_active(const TransInfo *t) return false; } - if ((t->tsnap.mode == SCE_SNAP_MODE_FACE_RAYCAST) && (t->tsnap.flag & SCE_SNAP_PROJECT)) { - return false; - } - - if (t->tsnap.mode == SCE_SNAP_MODE_FACE_NEAREST) { - return false; - } - - return true; + return (t->tsnap.mode & + (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_VOLUME | + SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) != 0; } void transform_snap_mixed_apply(TransInfo *t, float *vec) @@ -842,17 +828,9 @@ static void initSnappingMode(TransInfo *t) t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; } - if ((t->spacetype != SPACE_VIEW3D) || - !(t->tsnap.mode & (SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST)) || - (t->flag & T_NO_PROJECT)) - { + if ((t->spacetype != SPACE_VIEW3D) || (t->flag & T_NO_PROJECT)) { /* Force project off when not supported. */ - t->tsnap.flag &= ~SCE_SNAP_PROJECT; - } - - if (t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST) { - /* This mode only works with individual projection. */ - t->tsnap.flag |= SCE_SNAP_PROJECT; + t->tsnap.mode &= ~(SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST); } setSnappingCallback(t); @@ -925,7 +903,7 @@ void initSnapping(TransInfo *t, wmOperator *op) RNA_property_is_set(op->ptr, prop)) { SET_FLAG_FROM_TEST( - t->tsnap.flag, RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_PROJECT); + t->tsnap.mode, RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_MODE_FACE_RAYCAST); } /* use_snap_self is misnamed and should be use_snap_active */ @@ -1473,7 +1451,7 @@ eSnapMode snapObjectsTransform( SnapObjectParams snap_object_params{}; snap_object_params.snap_target_select = t->tsnap.target_operation; snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; - snap_object_params.use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE_RAYCAST; + snap_object_params.use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE; snap_object_params.use_backface_culling = (t->tsnap.flag & SCE_SNAP_BACKFACE_CULLING) != 0; float *target = (t->tsnap.status & SNAP_SOURCE_FOUND) ? t->tsnap.snap_source : t->center_global; diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index bcc384ff684..4507c2b39db 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -1057,7 +1057,7 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx, sctx->ret.ob = ob_eval; sctx->ret.data = ob_data; sctx->ret.is_edit = is_edit; - return SCE_SNAP_MODE_FACE_RAYCAST; + return SCE_SNAP_MODE_FACE; } return SCE_SNAP_MODE_NONE; } @@ -2072,7 +2072,7 @@ static eSnapMode snapArmature(SnapObjectContext *sctx, { eSnapMode retval = SCE_SNAP_MODE_NONE; - if (sctx->runtime.snap_to_flag == SCE_SNAP_MODE_FACE_RAYCAST) { + if (sctx->runtime.snap_to_flag == SCE_SNAP_MODE_FACE) { /* Currently only edge and vert. */ return retval; } @@ -2553,7 +2553,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx, float r_no[3], int *r_index) { - BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE_RAYCAST); + BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE); if (me_eval->totvert == 0) { return SCE_SNAP_MODE_NONE; } @@ -2718,9 +2718,9 @@ static eSnapMode snapEditMesh(SnapObjectContext *sctx, float r_no[3], int *r_index) { - BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE_RAYCAST); + BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE); - if ((sctx->runtime.snap_to_flag & ~SCE_SNAP_MODE_FACE_RAYCAST) == SCE_SNAP_MODE_VERTEX) { + if ((sctx->runtime.snap_to_flag & ~SCE_SNAP_MODE_FACE) == SCE_SNAP_MODE_VERTEX) { if (em->bm->totvert == 0) { return SCE_SNAP_MODE_NONE; } @@ -3275,10 +3275,10 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont const RegionView3D *rv3d = static_cast(region->regiondata); - if (snap_to_flag & (SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST)) { + if (snap_to_flag & (SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_FACE_NEAREST)) { if (params->use_occlusion_test && XRAY_ENABLED(v3d)) { /* Remove Snap to Face with Occlusion Test as they are not visible in wireframe mode. */ - snap_to_flag &= ~(SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST); + snap_to_flag &= ~(SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_FACE_NEAREST); } else if (prev_co == nullptr || init_co == nullptr) { /* No location to work with #SCE_SNAP_MODE_FACE_NEAREST. */ @@ -3312,7 +3312,7 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont bool use_occlusion_test = params->use_occlusion_test && !XRAY_ENABLED(v3d); - if ((snap_to_flag & SCE_SNAP_MODE_FACE_RAYCAST) || use_occlusion_test) { + if ((snap_to_flag & SCE_SNAP_MODE_FACE) || use_occlusion_test) { float ray_start[3], ray_normal[3]; if (!ED_view3d_win_to_ray_clipped_ex( depsgraph, region, v3d, mval, nullptr, ray_normal, ray_start, true)) @@ -3329,8 +3329,8 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont copy_v3_v3(r_face_nor, sctx->ret.no); } - if (snap_to_flag & SCE_SNAP_MODE_FACE_RAYCAST) { - retval = SCE_SNAP_MODE_FACE_RAYCAST; + if (snap_to_flag & SCE_SNAP_MODE_FACE) { + retval = SCE_SNAP_MODE_FACE; copy_v3_v3(r_loc, sctx->ret.loc); if (r_no) { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 79272c0d2db..a7ff620a56c 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2255,7 +2255,7 @@ typedef enum eSnapFlag { SCE_SNAP_ROTATE = (1 << 1), SCE_SNAP_PEEL_OBJECT = (1 << 2), /** Project individual elements instead of whole object. */ - SCE_SNAP_PROJECT = (1 << 3), + /* SCE_SNAP_PROJECT = (1 << 3), DEPRECATED * / /** Was `SCE_SNAP_NO_SELF`, but self should be active. */ SCE_SNAP_NOT_TO_ACTIVE = (1 << 4), SCE_SNAP_ABS_GRID = (1 << 5), @@ -2300,13 +2300,17 @@ ENUM_OPERATORS(eSnapTargetOP, SCE_SNAP_TARGET_NOT_NONEDITED) /** #ToolSettings.snap_mode */ typedef enum eSnapMode { SCE_SNAP_MODE_NONE = 0, + SCE_SNAP_MODE_VERTEX = (1 << 0), SCE_SNAP_MODE_EDGE = (1 << 1), - SCE_SNAP_MODE_FACE_RAYCAST = (1 << 2), + SCE_SNAP_MODE_FACE = (1 << 2), SCE_SNAP_MODE_VOLUME = (1 << 3), SCE_SNAP_MODE_EDGE_MIDPOINT = (1 << 4), SCE_SNAP_MODE_EDGE_PERPENDICULAR = (1 << 5), + + /* For snap individual elements. */ SCE_SNAP_MODE_FACE_NEAREST = (1 << 8), + SCE_SNAP_MODE_FACE_RAYCAST = (1 << 9), /** #ToolSettings.snap_node_mode */ SCE_SNAP_MODE_NODE_X = (1 << 0), @@ -2319,11 +2323,11 @@ typedef enum eSnapMode { /* Due to dependency conflicts with Cycles, header cannot directly include `BLI_utildefines.h`. */ /* TODO: move this macro to a more general place. */ #ifdef ENUM_OPERATORS -ENUM_OPERATORS(eSnapMode, SCE_SNAP_MODE_FACE_NEAREST) +ENUM_OPERATORS(eSnapMode, SCE_SNAP_MODE_FACE_RAYCAST) #endif #define SCE_SNAP_MODE_GEOM \ - (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE_RAYCAST | \ + (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | \ SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_FACE_NEAREST) /** #SequencerToolSettings.snap_mode */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 9215af49b62..c8b324b61ae 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -151,16 +151,21 @@ const EnumPropertyItem rna_enum_mesh_select_mode_uv_items[] = { {0, NULL, 0, NULL, NULL}, }; +/* clang-format off */ +#define RNA_SNAP_ELEMENTS_BASE \ + {SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments"}, \ + {SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, \ + {SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges"}, \ + {SCE_SNAP_MODE_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap by projecting onto faces"}, \ + {SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume"}, \ + {SCE_SNAP_MODE_EDGE_MIDPOINT, "EDGE_MIDPOINT", ICON_SNAP_MIDPOINT, "Edge Center", "Snap to the middle of edges"}, \ + {SCE_SNAP_MODE_EDGE_PERPENDICULAR, "EDGE_PERPENDICULAR", ICON_SNAP_PERPENDICULAR, "Edge Perpendicular", "Snap to the nearest point on an edge"} +/* clang-format on */ + const EnumPropertyItem rna_enum_snap_element_items[] = { - {SCE_SNAP_MODE_INCREMENT, - "INCREMENT", - ICON_SNAP_INCREMENT, - "Increment", - "Snap to increments of grid"}, - {SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, - {SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges"}, + RNA_SNAP_ELEMENTS_BASE, {SCE_SNAP_MODE_FACE_RAYCAST, - "FACE", /* TODO(@gfxcoder): replace with "FACE_RAYCAST" as "FACE" is not descriptive. */ + "FACE_PROJECT", ICON_SNAP_FACE, "Face Project", "Snap by projecting onto faces"}, @@ -169,20 +174,18 @@ const EnumPropertyItem rna_enum_snap_element_items[] = { ICON_SNAP_FACE_NEAREST, "Face Nearest", "Snap to nearest point on faces"}, - {SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume"}, - {SCE_SNAP_MODE_EDGE_MIDPOINT, - "EDGE_MIDPOINT", - ICON_SNAP_MIDPOINT, - "Edge Center", - "Snap to the middle of edges"}, - {SCE_SNAP_MODE_EDGE_PERPENDICULAR, - "EDGE_PERPENDICULAR", - ICON_SNAP_PERPENDICULAR, - "Edge Perpendicular", - "Snap to the nearest point on an edge"}, {0, NULL, 0, NULL, NULL}, }; +const EnumPropertyItem rna_enum_snap_element_base_items[] = { + RNA_SNAP_ELEMENTS_BASE, + {0, NULL, 0, NULL, NULL}, +}; + +/* Last two snap elements from #rna_enum_snap_element_items. */ +const EnumPropertyItem *rna_enum_snap_element_individual_items = + &rna_enum_snap_element_items[ARRAY_SIZE(rna_enum_snap_element_items) - 3]; + const EnumPropertyItem rna_enum_snap_node_element_items[] = { {SCE_SNAP_MODE_GRID, "GRID", ICON_SNAP_GRID, "Grid", "Snap to grid"}, {SCE_SNAP_MODE_NODE_X, "NODE_X", ICON_NODE_SIDE, "Node X", "Snap to left/right node border"}, @@ -738,6 +741,12 @@ static const EnumPropertyItem snap_to_items[] = { # include "FRS_freestyle.h" # endif +static int rna_ToolSettings_snap_mode_get(PointerRNA *ptr) +{ + ToolSettings *ts = (ToolSettings *)(ptr->data); + return ts->snap_mode; +} + static void rna_ToolSettings_snap_mode_set(struct PointerRNA *ptr, int value) { ToolSettings *ts = (ToolSettings *)ptr->data; @@ -3399,11 +3408,31 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "snap_elements", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_mode"); RNA_def_property_enum_items(prop, rna_enum_snap_element_items); - RNA_def_property_enum_funcs(prop, NULL, "rna_ToolSettings_snap_mode_set", NULL); + RNA_def_property_enum_funcs( + prop, "rna_ToolSettings_snap_mode_get", "rna_ToolSettings_snap_mode_set", NULL); RNA_def_property_flag(prop, PROP_ENUM_FLAG); RNA_def_property_ui_text(prop, "Snap Element", "Type of element to snap to"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ + prop = RNA_def_property(srna, "snap_elements_base", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_mode"); + RNA_def_property_enum_items(prop, rna_enum_snap_element_base_items); + RNA_def_property_enum_funcs( + prop, "rna_ToolSettings_snap_mode_get", "rna_ToolSettings_snap_mode_set", NULL); + RNA_def_property_flag(prop, PROP_ENUM_FLAG); + RNA_def_property_ui_text(prop, "Snap Element", "Type of element for the 'Snap With' to snap to"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ + + prop = RNA_def_property(srna, "snap_elements_individual", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_mode"); + RNA_def_property_enum_items(prop, rna_enum_snap_element_individual_items); + RNA_def_property_enum_funcs( + prop, "rna_ToolSettings_snap_mode_get", "rna_ToolSettings_snap_mode_set", NULL); + RNA_def_property_flag(prop, PROP_ENUM_FLAG); + RNA_def_property_ui_text( + prop, "Project Mode", "Type of element for individual transformed elements to snap to"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ + prop = RNA_def_property(srna, "snap_face_nearest_steps", PROP_INT, PROP_FACTOR); RNA_def_property_int_sdna(prop, NULL, "snap_face_nearest_steps"); RNA_def_property_range(prop, 1, 100); @@ -3456,14 +3485,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop, "Snap Peel Object", "Consider objects as whole when finding volume center"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ - prop = RNA_def_property(srna, "use_snap_project", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_PROJECT); - RNA_def_property_ui_text(prop, - "Project Individual Elements", - "Project individual elements on the surface of other objects (Always " - "enabled with Face Nearest)"); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ - prop = RNA_def_property(srna, "use_snap_backface_culling", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_BACKFACE_CULLING); RNA_def_property_ui_text(prop, "Backface Culling", "Exclude back facing geometry from snapping");