WIP: UI: Snapping Redesign: Presets and filter support #108734
|
@ -0,0 +1,29 @@
|
|||
|
||||
attributes = (
|
||||
"snap_target",
|
||||
"snap_elements",
|
||||
"snap_filter_active",
|
||||
"snap_filter_edit",
|
||||
"snap_filter_nonedit",
|
||||
"snap_filter_nonselectable",
|
||||
"use_snap_grid_absolute",
|
||||
"use_snap_peel_object",
|
||||
"use_snap_to_same_target",
|
||||
"snap_face_nearest_steps",
|
||||
"use_snap_align_rotation",
|
||||
"use_snap_backface_culling",
|
||||
"use_snap_translate",
|
||||
"use_snap_rotate",
|
||||
"use_snap_scale",
|
||||
"show_snap_filter",
|
||||
)
|
||||
|
||||
import bpy
|
||||
toolsettings = bpy.context.scene.tool_settings
|
||||
props = bpy.types.ToolSettings.bl_rna.properties
|
||||
for attr in attributes:
|
||||
prop = props[attr]
|
||||
if prop.is_enum_flag:
|
||||
setattr(toolsettings, attr, prop.default_flag)
|
||||
else:
|
||||
setattr(toolsettings, attr, prop.default)
|
|
@ -0,0 +1,19 @@
|
|||
import bpy
|
||||
toolsettings = bpy.context.scene.tool_settings
|
||||
|
||||
toolsettings.snap_target = 'MEDIAN'
|
||||
toolsettings.snap_elements = {'FACE_PROJECT', 'FACE_NEAREST', 'VERTEX'}
|
||||
toolsettings.snap_filter_active = {'FACE', 'EDGE_MIDPOINT', 'VOLUME', 'EDGE', 'EDGE_PERPENDICULAR', 'VERTEX'}
|
||||
toolsettings.snap_filter_edit = {'FACE', 'EDGE_MIDPOINT', 'VOLUME', 'FACE_PROJECT', 'EDGE', 'EDGE_PERPENDICULAR', 'FACE_NEAREST', 'VERTEX'}
|
||||
toolsettings.snap_filter_nonedit = {'FACE_PROJECT', 'FACE_NEAREST'}
|
||||
toolsettings.snap_filter_nonselectable = {'FACE', 'EDGE_MIDPOINT', 'VOLUME', 'FACE_PROJECT', 'EDGE', 'EDGE_PERPENDICULAR', 'FACE_NEAREST', 'VERTEX'}
|
||||
toolsettings.use_snap_grid_absolute = False
|
||||
toolsettings.use_snap_peel_object = False
|
||||
toolsettings.use_snap_to_same_target = False
|
||||
toolsettings.snap_face_nearest_steps = 1
|
||||
toolsettings.use_snap_align_rotation = False
|
||||
toolsettings.use_snap_backface_culling = False
|
||||
toolsettings.use_snap_translate = True
|
||||
toolsettings.use_snap_rotate = False
|
||||
toolsettings.use_snap_scale = False
|
||||
toolsettings.show_snap_filter = {'NONEDITED', 'ACTIVE'}
|
|
@ -413,6 +413,38 @@ class AddPresetHairDynamics(AddPresetBase, Operator):
|
|||
]
|
||||
|
||||
|
||||
class AddPresetSnapping(AddPresetBase, Operator):
|
||||
"""Add or remove a Snapping Preset"""
|
||||
bl_idname = "scene.preset_add"
|
||||
bl_label = "Add Snapping Preset"
|
||||
preset_menu = "VIEW3D_MT_snapping_presets"
|
||||
|
||||
preset_defines = [
|
||||
"toolsettings = bpy.context.scene.tool_settings"
|
||||
]
|
||||
|
||||
preset_values = [
|
||||
"toolsettings.snap_target",
|
||||
"toolsettings.snap_elements",
|
||||
"toolsettings.snap_filter_active",
|
||||
"toolsettings.snap_filter_edit",
|
||||
"toolsettings.snap_filter_nonedit",
|
||||
"toolsettings.snap_filter_nonselectable",
|
||||
"toolsettings.use_snap_grid_absolute",
|
||||
"toolsettings.use_snap_peel_object",
|
||||
"toolsettings.use_snap_to_same_target",
|
||||
"toolsettings.snap_face_nearest_steps",
|
||||
"toolsettings.use_snap_align_rotation",
|
||||
"toolsettings.use_snap_backface_culling",
|
||||
"toolsettings.use_snap_translate",
|
||||
"toolsettings.use_snap_rotate",
|
||||
"toolsettings.use_snap_scale",
|
||||
"toolsettings.show_snap_filter",
|
||||
]
|
||||
|
||||
preset_subdir = "snapping"
|
||||
|
||||
|
||||
class AddPresetTextEditor(AddPresetBase, Operator):
|
||||
"""Add or remove a Text Editor Preset"""
|
||||
bl_idname = "text_editor.preset_add"
|
||||
|
@ -710,6 +742,7 @@ classes = (
|
|||
AddPresetOperator,
|
||||
AddPresetRender,
|
||||
AddPresetCameraSafeAreas,
|
||||
AddPresetSnapping,
|
||||
AddPresetTextEditor,
|
||||
AddPresetTrackingCamera,
|
||||
AddPresetTrackingSettings,
|
||||
|
|
|
@ -7060,11 +7060,48 @@ class VIEW3D_PT_overlay_weight_paint(Panel):
|
|||
col.prop(overlay, "show_paint_wire")
|
||||
|
||||
|
||||
class VIEW3D_MT_snapping_presets(Menu):
|
||||
bl_label = "Presets"
|
||||
preset_subdir = "snapping"
|
||||
preset_operator = "script.execute_preset"
|
||||
draw = Menu.draw_preset
|
||||
|
||||
|
||||
class VIEW3D_PT_snapping(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Snapping"
|
||||
|
||||
@staticmethod
|
||||
def draw_elements(layout, ts, prop):
|
||||
def draw_filters(row, value):
|
||||
if 'ACTIVE' in ts.show_snap_filter:
|
||||
row.prop_enum(ts, "snap_filter_active", value, text="", icon='EDITMODE_HLT')
|
||||
if 'EDITED' in ts.show_snap_filter:
|
||||
row.prop_enum(ts, "snap_filter_edit", value, text="", icon='OUTLINER_DATA_MESH')
|
||||
if 'NONEDITED' in ts.show_snap_filter:
|
||||
row.prop_enum(ts, "snap_filter_nonedit", value, text="", icon='OUTLINER_OB_MESH')
|
||||
if 'NONSELECTABLE' in ts.show_snap_filter:
|
||||
row.prop_enum(ts, "snap_filter_nonselectable", value, text="", icon='RESTRICT_SELECT_ON')
|
||||
|
||||
if not ts.show_snap_filter:
|
||||
layout.prop(ts, prop)
|
||||
return
|
||||
|
||||
row = layout.row()
|
||||
row.column().prop(ts, prop)
|
||||
row_col = row.column()
|
||||
for item in bpy.types.ToolSettings.bl_rna.properties[prop].enum_items:
|
||||
row = row_col.row(align=True)
|
||||
if item.identifier == 'INCREMENT':
|
||||
row.ui_units_y = 0.92
|
||||
row.separator()
|
||||
continue
|
||||
|
||||
row.active = item.identifier in ts.snap_elements
|
||||
row.scale_y = 0.92
|
||||
draw_filters(row, item.identifier)
|
||||
|
||||
def draw(self, context):
|
||||
tool_settings = context.tool_settings
|
||||
obj = context.active_object
|
||||
|
@ -7073,15 +7110,26 @@ class VIEW3D_PT_snapping(Panel):
|
|||
layout = self.layout
|
||||
col = layout.column()
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.alignment = 'RIGHT'
|
||||
row.menu("VIEW3D_MT_snapping_presets", text=VIEW3D_MT_snapping_presets.bl_label)
|
||||
row.operator("scene.preset_add", text="", icon='ADD')
|
||||
row.operator("scene.preset_add", text="", icon='REMOVE').remove_active = True
|
||||
row.separator()
|
||||
row.prop_menu_enum(tool_settings, "show_snap_filter", text="", icon='FILTER')
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Snap With")
|
||||
row = col.row(align=True)
|
||||
row.prop(tool_settings, "snap_target", expand=True)
|
||||
|
||||
col.separator()
|
||||
col.label(text="Snap To")
|
||||
col.prop(tool_settings, "snap_elements_base", expand=True)
|
||||
self.draw_elements(col, tool_settings, "snap_elements_base")
|
||||
|
||||
col.separator()
|
||||
col.label(text="Snap Individual Elements To")
|
||||
col.prop(tool_settings, "snap_elements_individual", expand=True)
|
||||
self.draw_elements(col, tool_settings, "snap_elements_individual")
|
||||
|
||||
col.separator()
|
||||
|
||||
|
@ -7103,35 +7151,6 @@ class VIEW3D_PT_snapping(Panel):
|
|||
|
||||
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_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',
|
||||
)
|
||||
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)
|
||||
row.prop(tool_settings, "use_snap_translate", text="Move", toggle=True)
|
||||
|
@ -8354,6 +8373,7 @@ classes = (
|
|||
VIEW3D_MT_wpaint_vgroup_lock_pie,
|
||||
VIEW3D_MT_sculpt_face_sets_edit_pie,
|
||||
VIEW3D_MT_sculpt_curves,
|
||||
VIEW3D_MT_snapping_presets,
|
||||
VIEW3D_PT_active_tool,
|
||||
VIEW3D_PT_active_tool_duplicate,
|
||||
VIEW3D_PT_view3d_properties,
|
||||
|
|
|
@ -3874,7 +3874,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
/* Minimum of snap steps for face nearest is 1. */
|
||||
tool_settings->snap_face_nearest_steps = 1;
|
||||
/* Set snap to edited and non-edited as default. */
|
||||
tool_settings->snap_flag |= SCE_SNAP_TO_INCLUDE_EDITED | SCE_SNAP_TO_INCLUDE_NONEDITED;
|
||||
tool_settings->snap_flag |= SCE_SNAP_INCLUDE_EDITED | SCE_SNAP_INCLUDE_NONEDITED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "DNA_defaults.h"
|
||||
#include "DNA_movieclip_types.h"
|
||||
|
||||
#include "BLI_assert.h"
|
||||
|
@ -182,13 +183,26 @@ void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
|
|||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 400, 5)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
const ToolSettings *ts_default = DNA_struct_default_get(ToolSettings);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
eSnapFlag view_filter_flag = (SCE_SNAP_INCLUDE_ACTIVE | SCE_SNAP_INCLUDE_EDITED |
|
||||
SCE_SNAP_INCLUDE_NONEDITED | SCE_SNAP_INCLUDE_NONSELECTABLE);
|
||||
|
||||
if (ts->snap_mode_tools != SCE_SNAP_MODE_NONE) {
|
||||
ts->snap_mode_tools = SCE_SNAP_MODE_GEOM;
|
||||
}
|
||||
|
||||
ts->snap_mode = ts_default->snap_mode;
|
||||
ts->snap_filter_active = ts_default->snap_filter_active;
|
||||
ts->snap_filter_edit = ts_default->snap_filter_edit;
|
||||
ts->snap_filter_nonedit = ts_default->snap_filter_nonedit;
|
||||
ts->snap_filter_nonselectable = ts_default->snap_filter_nonselectable;
|
||||
ts->snap_flag &= ~view_filter_flag;
|
||||
ts->snap_flag |= ts_default->snap_flag & view_filter_flag;
|
||||
|
||||
#define SCE_SNAP_PROJECT (1 << 3)
|
||||
if (ts->snap_flag & SCE_SNAP_PROJECT) {
|
||||
ts->snap_flag &= ~SCE_SNAP_PROJECT;
|
||||
ts->snap_mode |= SCE_SNAP_MODE_FACE_RAYCAST;
|
||||
}
|
||||
#undef SCE_SNAP_PROJECT
|
||||
|
|
|
@ -5644,9 +5644,8 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
vc.v3d,
|
||||
SCE_SNAP_MODE_FACE,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_target_select = (vc.obedit != NULL) ? SCE_SNAP_TARGET_NOT_ACTIVE :
|
||||
SCE_SNAP_TARGET_ALL,
|
||||
.edit_mode_type = SNAP_GEOM_FINAL,
|
||||
.exclude_active = (vc.obedit != NULL) ? SCE_SNAP_MODE_GEOM_ALL : SCE_SNAP_MODE_NONE,
|
||||
},
|
||||
NULL,
|
||||
mval,
|
||||
|
|
|
@ -282,7 +282,6 @@ static int gizmo_move_modal(bContext *C,
|
|||
CTX_wm_view3d(C),
|
||||
(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,
|
||||
.use_occlusion_test = true,
|
||||
},
|
||||
|
|
|
@ -1152,9 +1152,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
|
|||
if (ED_transform_snap_object_project_ray(sctx,
|
||||
depsgraph,
|
||||
v3d,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_target_select = SCE_SNAP_TARGET_ALL,
|
||||
},
|
||||
&(const struct SnapObjectParams){0},
|
||||
&ray_start[0],
|
||||
&ray_normal[0],
|
||||
&depth,
|
||||
|
|
|
@ -54,18 +54,26 @@ struct SnapObjectHitDepth {
|
|||
|
||||
/** parameters that define which objects will be used to snap. */
|
||||
struct SnapObjectParams {
|
||||
/* Special context sensitive handling for the active or selected object. */
|
||||
eSnapTargetOP snap_target_select;
|
||||
/* Geometry for snapping in edit mode. */
|
||||
eSnapEditType edit_mode_type;
|
||||
|
||||
/* Filters. */
|
||||
eSnapMode exclude_active;
|
||||
eSnapMode exclude_selected;
|
||||
eSnapMode exclude_edited;
|
||||
eSnapMode exclude_nonedited;
|
||||
eSnapMode exclude_nonselectable;
|
||||
|
||||
/* snap to the closest element, use when using more than one snap type */
|
||||
bool exclude_moving : 1;
|
||||
/* snap to the closest element, use when using more than one snap type */
|
||||
bool use_occlusion_test : 1;
|
||||
/* exclude back facing geometry from snapping */
|
||||
bool use_backface_culling : 1;
|
||||
/* Break nearest face snapping into steps to improve transformations across U-shaped targets. */
|
||||
short face_nearest_steps;
|
||||
/* Enable to force nearest face snapping to snap to target the source was initially near. */
|
||||
bool keep_on_same_target : 1;
|
||||
/* Break nearest face snapping into steps to improve transformations across U-shaped targets. */
|
||||
short face_nearest_steps;
|
||||
};
|
||||
|
||||
typedef struct SnapObjectContext SnapObjectContext;
|
||||
|
|
|
@ -1925,17 +1925,18 @@ void EDBM_project_snap_verts(
|
|||
ED_view3d_init_mats_rv3d(obedit, region->regiondata);
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
SnapObjectContext *snap_context = ED_transform_snap_object_context_create(scene, 0);
|
||||
|
||||
eSnapTargetOP target_op = SCE_SNAP_TARGET_NOT_ACTIVE;
|
||||
const int snap_flag = scene->toolsettings->snap_flag;
|
||||
struct SnapObjectParams snap_params = {0};
|
||||
snap_params.edit_mode_type = SNAP_GEOM_FINAL;
|
||||
snap_params.exclude_active = SCE_SNAP_MODE_GEOM_ALL;
|
||||
snap_params.exclude_edited = ~ts->snap_filter_edit;
|
||||
snap_params.exclude_nonedited = ~ts->snap_filter_nonedit;
|
||||
snap_params.exclude_nonselectable = ~ts->snap_filter_nonselectable;
|
||||
snap_params.use_occlusion_test = true;
|
||||
|
||||
SET_FLAG_FROM_TEST(
|
||||
target_op, !(snap_flag & SCE_SNAP_TO_INCLUDE_EDITED), SCE_SNAP_TARGET_NOT_EDITED);
|
||||
SET_FLAG_FROM_TEST(
|
||||
target_op, !(snap_flag & SCE_SNAP_TO_INCLUDE_NONEDITED), SCE_SNAP_TARGET_NOT_NONEDITED);
|
||||
SET_FLAG_FROM_TEST(
|
||||
target_op, (snap_flag & SCE_SNAP_TO_ONLY_SELECTABLE), SCE_SNAP_TARGET_ONLY_SELECTABLE);
|
||||
const int snap_flag = scene->toolsettings->snap_flag;
|
||||
|
||||
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
|
||||
|
@ -1947,11 +1948,7 @@ void EDBM_project_snap_verts(
|
|||
region,
|
||||
CTX_wm_view3d(C),
|
||||
SCE_SNAP_MODE_FACE,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_target_select = target_op,
|
||||
.edit_mode_type = SNAP_GEOM_FINAL,
|
||||
.use_occlusion_test = true,
|
||||
},
|
||||
&snap_params,
|
||||
NULL,
|
||||
mval,
|
||||
NULL,
|
||||
|
|
|
@ -660,7 +660,6 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
|
|||
v3d,
|
||||
snap_elements,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_target_select = SCE_SNAP_TARGET_ALL,
|
||||
.edit_mode_type = edit_mode_type,
|
||||
.use_occlusion_test = use_occlusion_test,
|
||||
},
|
||||
|
|
|
@ -913,7 +913,6 @@ void ED_view3d_cursor3d_position_rotation(bContext *C,
|
|||
v3d,
|
||||
SCE_SNAP_MODE_FACE,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_target_select = SCE_SNAP_TARGET_ALL,
|
||||
.edit_mode_type = SNAP_GEOM_FINAL,
|
||||
.use_occlusion_test = true,
|
||||
},
|
||||
|
|
|
@ -367,7 +367,6 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
|
|||
float3 &co_other = ruler_item->co[inter->co_index == 0 ? 2 : 0];
|
||||
|
||||
SnapObjectParams snap_object_params{};
|
||||
snap_object_params.snap_target_select = SCE_SNAP_TARGET_ALL;
|
||||
snap_object_params.edit_mode_type = SNAP_GEOM_CAGE;
|
||||
|
||||
eSnapMode hit = ED_transform_snap_object_project_view3d(snap_context,
|
||||
|
|
|
@ -408,7 +408,6 @@ static bool walk_floor_distance_get(RegionView3D *rv3d,
|
|||
walk->depsgraph,
|
||||
walk->v3d,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_target_select = SCE_SNAP_TARGET_ALL,
|
||||
/* Avoid having to convert the edit-mesh to a regular mesh. */
|
||||
.edit_mode_type = SNAP_GEOM_EDIT,
|
||||
},
|
||||
|
@ -449,9 +448,7 @@ static bool walk_ray_cast(RegionView3D *rv3d,
|
|||
ret = ED_transform_snap_object_project_ray(walk->snap_context,
|
||||
walk->depsgraph,
|
||||
walk->v3d,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_target_select = SCE_SNAP_TARGET_ALL,
|
||||
},
|
||||
&(const struct SnapObjectParams){0},
|
||||
ray_start,
|
||||
ray_normal,
|
||||
NULL,
|
||||
|
|
|
@ -1658,16 +1658,12 @@ 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.mode & SCE_SNAP_MODE_FACE_RAYCAST) != 0);
|
||||
RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_operation);
|
||||
|
||||
eSnapTargetOP target = t->tsnap.target_operation;
|
||||
RNA_boolean_set(op->ptr, "use_snap_self", (target & SCE_SNAP_TARGET_NOT_ACTIVE) == 0);
|
||||
RNA_boolean_set(op->ptr, "use_snap_edit", (target & SCE_SNAP_TARGET_NOT_EDITED) == 0);
|
||||
RNA_boolean_set(op->ptr, "use_snap_nonedit", (target & SCE_SNAP_TARGET_NOT_NONEDITED) == 0);
|
||||
RNA_boolean_set(
|
||||
op->ptr, "use_snap_selectable", (target & SCE_SNAP_TARGET_ONLY_SELECTABLE) != 0);
|
||||
RNA_boolean_set(op->ptr, "use_snap_self", t->tsnap.exclude_active == 0);
|
||||
RNA_boolean_set(op->ptr, "use_snap_edit", t->tsnap.exclude_edited == 0);
|
||||
RNA_boolean_set(op->ptr, "use_snap_nonedit", t->tsnap.exclude_nonedited == 0);
|
||||
RNA_boolean_set(op->ptr, "use_snap_nonselectable", t->tsnap.exclude_nonselectable == 0);
|
||||
}
|
||||
|
||||
/* Update `ToolSettings` for properties that change during modal. */
|
||||
|
|
|
@ -298,7 +298,11 @@ typedef struct TransSnap {
|
|||
/* Part of source to snap to target */
|
||||
eSnapSourceOP source_operation;
|
||||
/* Determines which objects are possible target */
|
||||
eSnapTargetOP target_operation;
|
||||
eSnapMode exclude_active;
|
||||
eSnapMode exclude_selected;
|
||||
eSnapMode exclude_edited;
|
||||
eSnapMode exclude_nonedited;
|
||||
eSnapMode exclude_nonselectable;
|
||||
short face_nearest_steps;
|
||||
eTSnap status;
|
||||
/* Snapped Element Type (currently for objects only). */
|
||||
|
|
|
@ -37,7 +37,8 @@ struct SnapSouceCustomData {
|
|||
TransModeInfo *mode_info_prev;
|
||||
void *customdata_mode_prev;
|
||||
|
||||
eSnapTargetOP target_operation_prev;
|
||||
eSnapMode exclude_active_prev;
|
||||
eSnapMode exclude_selected_prev;
|
||||
|
||||
struct {
|
||||
void (*apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]);
|
||||
|
@ -55,7 +56,8 @@ static void snapsource_end(TransInfo *t)
|
|||
t->mode_info = customdata->mode_info_prev;
|
||||
t->custom.mode.data = customdata->customdata_mode_prev;
|
||||
|
||||
t->tsnap.target_operation = customdata->target_operation_prev;
|
||||
t->tsnap.exclude_active = customdata->exclude_active_prev;
|
||||
t->tsnap.exclude_selected = customdata->exclude_selected_prev;
|
||||
|
||||
t->mouse.apply = customdata->mouse_prev.apply;
|
||||
t->mouse.post = customdata->mouse_prev.post;
|
||||
|
@ -165,7 +167,8 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator *UNUSED(op))
|
|||
struct SnapSouceCustomData *customdata = MEM_callocN(sizeof(*customdata), __func__);
|
||||
customdata->mode_info_prev = t->mode_info;
|
||||
|
||||
customdata->target_operation_prev = t->tsnap.target_operation;
|
||||
customdata->exclude_active_prev = t->tsnap.exclude_active;
|
||||
customdata->exclude_selected_prev = t->tsnap.exclude_selected;
|
||||
|
||||
customdata->mouse_prev.apply = t->mouse.apply;
|
||||
customdata->mouse_prev.post = t->mouse.post;
|
||||
|
@ -179,7 +182,8 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator *UNUSED(op))
|
|||
}
|
||||
|
||||
t->mode_info = &TransMode_snapsource;
|
||||
t->tsnap.target_operation = SCE_SNAP_TARGET_ALL;
|
||||
t->tsnap.exclude_active = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.exclude_selected = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.status &= ~SNAP_SOURCE_FOUND;
|
||||
|
||||
if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) {
|
||||
|
|
|
@ -606,15 +606,6 @@ static bool transform_poll_property(const bContext *C, wmOperator *op, const Pro
|
|||
}
|
||||
}
|
||||
|
||||
/* Snapping. */
|
||||
{
|
||||
if (STREQ(prop_id, "use_snap_project")) {
|
||||
if (RNA_boolean_get(op->ptr, "snap") == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -705,8 +696,6 @@ void Transform_Properties(wmOperatorType *ot, int flags)
|
|||
"");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_ENUM_FLAG);
|
||||
|
||||
RNA_def_boolean(ot->srna, "use_snap_project", false, "Project Individual Elements", "");
|
||||
|
||||
/* TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of
|
||||
* "target" (now, "source" is geometry to be moved and "target" is geometry to which moved
|
||||
* geometry is snapped). Use "Source snap point" and "Point on source that will snap to
|
||||
|
@ -722,7 +711,7 @@ void Transform_Properties(wmOperatorType *ot, int flags)
|
|||
prop = RNA_def_boolean(ot->srna, "use_snap_nonedit", true, "Target: Include Non-Edited", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
prop = RNA_def_boolean(
|
||||
ot->srna, "use_snap_selectable", false, "Target: Exclude Non-Selectable", "");
|
||||
ot->srna, "use_snap_selectable", true, "Target: Include Non-Selectable", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
prop = RNA_def_float_vector(
|
||||
|
|
|
@ -77,7 +77,6 @@ static void snap_source_active_fn(TransInfo *t);
|
|||
/** \name Implementations
|
||||
* \{ */
|
||||
|
||||
static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetOP snap_target_select);
|
||||
static NodeBorder snapNodeBorder(eSnapMode snap_node_mode);
|
||||
|
||||
#if 0
|
||||
|
@ -362,11 +361,32 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td
|
|||
}
|
||||
|
||||
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.exclude_active = t->tsnap.exclude_active & ~SCE_SNAP_MODE_FACE;
|
||||
snap_object_params.exclude_selected = t->tsnap.exclude_selected & ~SCE_SNAP_MODE_FACE;
|
||||
snap_object_params.exclude_edited = t->tsnap.exclude_edited & ~SCE_SNAP_MODE_FACE;
|
||||
snap_object_params.exclude_nonedited = t->tsnap.exclude_nonedited & ~SCE_SNAP_MODE_FACE;
|
||||
snap_object_params.exclude_nonselectable = t->tsnap.exclude_nonselectable & ~SCE_SNAP_MODE_FACE;
|
||||
snap_object_params.exclude_moving = !(t->modifiers & MOD_EDIT_SNAP_SOURCE);
|
||||
snap_object_params.use_occlusion_test = false;
|
||||
snap_object_params.use_backface_culling = (t->tsnap.flag & SCE_SNAP_BACKFACE_CULLING) != 0;
|
||||
|
||||
SET_FLAG_FROM_TEST(snap_object_params.exclude_active,
|
||||
snap_object_params.exclude_active & SCE_SNAP_MODE_FACE_RAYCAST,
|
||||
SCE_SNAP_MODE_FACE);
|
||||
SET_FLAG_FROM_TEST(snap_object_params.exclude_selected,
|
||||
snap_object_params.exclude_selected & SCE_SNAP_MODE_FACE_RAYCAST,
|
||||
SCE_SNAP_MODE_FACE);
|
||||
SET_FLAG_FROM_TEST(snap_object_params.exclude_edited,
|
||||
snap_object_params.exclude_edited & SCE_SNAP_MODE_FACE_RAYCAST,
|
||||
SCE_SNAP_MODE_FACE);
|
||||
SET_FLAG_FROM_TEST(snap_object_params.exclude_nonedited,
|
||||
snap_object_params.exclude_nonedited & SCE_SNAP_MODE_FACE_RAYCAST,
|
||||
SCE_SNAP_MODE_FACE);
|
||||
SET_FLAG_FROM_TEST(snap_object_params.exclude_nonselectable,
|
||||
snap_object_params.exclude_nonselectable & SCE_SNAP_MODE_FACE_RAYCAST,
|
||||
SCE_SNAP_MODE_FACE);
|
||||
|
||||
eSnapMode hit = ED_transform_snap_object_project_view3d(t->tsnap.object_context,
|
||||
t->depsgraph,
|
||||
t->region,
|
||||
|
@ -425,8 +445,13 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td
|
|||
}
|
||||
|
||||
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.exclude_active = t->tsnap.exclude_active;
|
||||
snap_object_params.exclude_selected = t->tsnap.exclude_selected;
|
||||
snap_object_params.exclude_edited = t->tsnap.exclude_edited;
|
||||
snap_object_params.exclude_nonedited = t->tsnap.exclude_nonedited;
|
||||
snap_object_params.exclude_nonselectable = t->tsnap.exclude_nonselectable;
|
||||
snap_object_params.exclude_moving = !(t->modifiers & MOD_EDIT_SNAP_SOURCE);
|
||||
snap_object_params.use_occlusion_test = false;
|
||||
snap_object_params.use_backface_culling = false;
|
||||
snap_object_params.face_nearest_steps = t->tsnap.face_nearest_steps;
|
||||
|
@ -545,7 +570,11 @@ void resetSnapping(TransInfo *t)
|
|||
t->tsnap.status = SNAP_RESETTED;
|
||||
t->tsnap.snapElem = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.mode = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.target_operation = SCE_SNAP_TARGET_ALL;
|
||||
t->tsnap.exclude_active = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.exclude_selected = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.exclude_edited = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.exclude_nonedited = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.exclude_nonselectable = SCE_SNAP_MODE_NONE;
|
||||
t->tsnap.source_operation = SCE_SNAP_SOURCE_CLOSEST;
|
||||
t->tsnap.last = 0;
|
||||
|
||||
|
@ -671,20 +700,26 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t)
|
|||
return SCE_SNAP_MODE_INCREMENT;
|
||||
}
|
||||
|
||||
static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t)
|
||||
static void snap_target_select_from_spacetype(TransInfo *t,
|
||||
eSnapMode *r_exclude_active,
|
||||
eSnapMode *r_exclude_selected,
|
||||
eSnapMode *r_exclude_edited,
|
||||
eSnapMode *r_exclude_nonedited,
|
||||
eSnapMode *r_exclude_nonselectable)
|
||||
{
|
||||
BKE_view_layer_synced_ensure(t->scene, t->view_layer);
|
||||
Base *base_act = BKE_view_layer_active_base_get(t->view_layer);
|
||||
|
||||
eSnapTargetOP ret = SCE_SNAP_TARGET_ALL;
|
||||
|
||||
/* `t->tsnap.target_operation` not initialized yet. */
|
||||
BLI_assert(t->tsnap.target_operation == SCE_SNAP_TARGET_ALL);
|
||||
*r_exclude_active = SCE_SNAP_MODE_NONE;
|
||||
*r_exclude_selected = SCE_SNAP_MODE_NONE;
|
||||
*r_exclude_edited = SCE_SNAP_MODE_NONE;
|
||||
*r_exclude_nonedited = SCE_SNAP_MODE_NONE;
|
||||
*r_exclude_nonselectable = SCE_SNAP_MODE_NONE;
|
||||
|
||||
if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) {
|
||||
if (base_act && (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) {
|
||||
/* Particles edit mode. */
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) {
|
||||
|
@ -693,7 +728,7 @@ static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t)
|
|||
* TODO: perform self snap in gpencil_strokes.
|
||||
*
|
||||
* When we're moving the origins, allow snapping onto our own geometry (see #69132). */
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
const int obedit_type = t->obedit_type;
|
||||
|
@ -703,28 +738,27 @@ static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t)
|
|||
/* Editing a mesh */
|
||||
if ((t->flag & T_PROP_EDIT) != 0) {
|
||||
/* Exclude editmesh when using proportional edit */
|
||||
ret |= SCE_SNAP_TARGET_NOT_EDITED;
|
||||
*r_exclude_edited = SCE_SNAP_MODE_GEOM_ALL;
|
||||
}
|
||||
/* UV editing must never snap to the selection as this is what is transformed. */
|
||||
if (t->spacetype == SPACE_IMAGE) {
|
||||
ret |= SCE_SNAP_TARGET_NOT_SELECTED;
|
||||
*r_exclude_selected = SCE_SNAP_MODE_GEOM_ALL;
|
||||
}
|
||||
}
|
||||
else if (ELEM(obedit_type, OB_ARMATURE, OB_CURVES_LEGACY, OB_SURF, OB_LATTICE, OB_MBALL)) {
|
||||
/* Temporary limited to edit mode armature, curves, surfaces, lattices, and metaballs. */
|
||||
ret |= SCE_SNAP_TARGET_NOT_SELECTED;
|
||||
*r_exclude_selected = SCE_SNAP_MODE_GEOM_ALL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Object or pose mode. */
|
||||
ret |= SCE_SNAP_TARGET_NOT_SELECTED | SCE_SNAP_TARGET_NOT_ACTIVE;
|
||||
*r_exclude_active = SCE_SNAP_MODE_GEOM_ALL;
|
||||
*r_exclude_selected = SCE_SNAP_MODE_GEOM_ALL;
|
||||
}
|
||||
}
|
||||
else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
|
||||
ret |= SCE_SNAP_TARGET_NOT_SELECTED;
|
||||
*r_exclude_selected = SCE_SNAP_MODE_GEOM_ALL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void snap_object_context_init(TransInfo *t)
|
||||
|
@ -793,9 +827,15 @@ void initSnapping(TransInfo *t, wmOperator *op)
|
|||
resetSnapping(t);
|
||||
t->tsnap.mode = snap_mode_from_spacetype(t);
|
||||
t->tsnap.flag = snap_flag_from_spacetype(t);
|
||||
t->tsnap.target_operation = snap_target_select_from_spacetype(t);
|
||||
t->tsnap.face_nearest_steps = max_ii(ts->snap_face_nearest_steps, 1);
|
||||
|
||||
snap_target_select_from_spacetype(t,
|
||||
&t->tsnap.exclude_active,
|
||||
&t->tsnap.exclude_selected,
|
||||
&t->tsnap.exclude_edited,
|
||||
&t->tsnap.exclude_nonedited,
|
||||
&t->tsnap.exclude_nonselectable);
|
||||
|
||||
/* if snap property exists */
|
||||
PropertyRNA *prop;
|
||||
if (op && (prop = RNA_struct_find_property(op->ptr, "snap")) &&
|
||||
|
@ -835,44 +875,37 @@ void initSnapping(TransInfo *t, wmOperator *op)
|
|||
normalize_v3(t->tsnap.snapNormal);
|
||||
}
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "use_snap_project")) &&
|
||||
RNA_property_is_set(op->ptr, prop))
|
||||
{
|
||||
SET_FLAG_FROM_TEST(
|
||||
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 */
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "use_snap_self")) &&
|
||||
RNA_property_is_set(op->ptr, prop))
|
||||
{
|
||||
SET_FLAG_FROM_TEST(t->tsnap.target_operation,
|
||||
SET_FLAG_FROM_TEST(t->tsnap.exclude_active,
|
||||
!RNA_property_boolean_get(op->ptr, prop),
|
||||
SCE_SNAP_TARGET_NOT_ACTIVE);
|
||||
SCE_SNAP_MODE_GEOM_ALL);
|
||||
}
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "use_snap_edit")) &&
|
||||
RNA_property_is_set(op->ptr, prop))
|
||||
{
|
||||
SET_FLAG_FROM_TEST(t->tsnap.target_operation,
|
||||
SET_FLAG_FROM_TEST(t->tsnap.exclude_edited,
|
||||
!RNA_property_boolean_get(op->ptr, prop),
|
||||
SCE_SNAP_TARGET_NOT_EDITED);
|
||||
SCE_SNAP_MODE_GEOM_ALL);
|
||||
}
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "use_snap_nonedit")) &&
|
||||
RNA_property_is_set(op->ptr, prop))
|
||||
{
|
||||
SET_FLAG_FROM_TEST(t->tsnap.target_operation,
|
||||
SET_FLAG_FROM_TEST(t->tsnap.exclude_nonedited,
|
||||
!RNA_property_boolean_get(op->ptr, prop),
|
||||
SCE_SNAP_TARGET_NOT_NONEDITED);
|
||||
SCE_SNAP_MODE_GEOM_ALL);
|
||||
}
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "use_snap_selectable")) &&
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "use_snap_nonselectable")) &&
|
||||
RNA_property_is_set(op->ptr, prop))
|
||||
{
|
||||
SET_FLAG_FROM_TEST(t->tsnap.target_operation,
|
||||
RNA_property_boolean_get(op->ptr, prop),
|
||||
SCE_SNAP_TARGET_ONLY_SELECTABLE);
|
||||
SET_FLAG_FROM_TEST(t->tsnap.exclude_nonselectable,
|
||||
!RNA_property_boolean_get(op->ptr, prop),
|
||||
SCE_SNAP_MODE_GEOM_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -881,19 +914,11 @@ void initSnapping(TransInfo *t, wmOperator *op)
|
|||
if (t->tsnap.flag & SCE_SNAP) {
|
||||
t->modifiers |= MOD_SNAP;
|
||||
}
|
||||
|
||||
SET_FLAG_FROM_TEST(t->tsnap.target_operation,
|
||||
(ts->snap_flag & SCE_SNAP_NOT_TO_ACTIVE),
|
||||
SCE_SNAP_TARGET_NOT_ACTIVE);
|
||||
SET_FLAG_FROM_TEST(t->tsnap.target_operation,
|
||||
!(ts->snap_flag & SCE_SNAP_TO_INCLUDE_EDITED),
|
||||
SCE_SNAP_TARGET_NOT_EDITED);
|
||||
SET_FLAG_FROM_TEST(t->tsnap.target_operation,
|
||||
!(ts->snap_flag & SCE_SNAP_TO_INCLUDE_NONEDITED),
|
||||
SCE_SNAP_TARGET_NOT_NONEDITED);
|
||||
SET_FLAG_FROM_TEST(t->tsnap.target_operation,
|
||||
(ts->snap_flag & SCE_SNAP_TO_ONLY_SELECTABLE),
|
||||
SCE_SNAP_TARGET_ONLY_SELECTABLE);
|
||||
t->tsnap.exclude_active |= SCE_SNAP_MODE_GEOM_ALL & ~eSnapMode(ts->snap_filter_active);
|
||||
t->tsnap.exclude_edited |= SCE_SNAP_MODE_GEOM_ALL & ~eSnapMode(ts->snap_filter_edit);
|
||||
t->tsnap.exclude_nonedited |= SCE_SNAP_MODE_GEOM_ALL & ~eSnapMode(ts->snap_filter_nonedit);
|
||||
t->tsnap.exclude_nonselectable |= SCE_SNAP_MODE_GEOM_ALL &
|
||||
~eSnapMode(ts->snap_filter_nonselectable);
|
||||
}
|
||||
|
||||
t->tsnap.source_operation = snap_source;
|
||||
|
@ -1138,7 +1163,7 @@ static void snap_target_uv_fn(TransInfo *t, float * /*vec*/)
|
|||
objects,
|
||||
objects_len,
|
||||
t->mval,
|
||||
t->tsnap.target_operation & SCE_SNAP_TARGET_NOT_SELECTED,
|
||||
t->tsnap.exclude_selected != SCE_SNAP_MODE_NONE,
|
||||
&dist_sq,
|
||||
t->tsnap.snap_target))
|
||||
{
|
||||
|
@ -1385,8 +1410,13 @@ eSnapMode snapObjectsTransform(
|
|||
TransInfo *t, const float mval[2], float *dist_px, float r_loc[3], float r_no[3])
|
||||
{
|
||||
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.exclude_active = t->tsnap.exclude_active;
|
||||
snap_object_params.exclude_selected = t->tsnap.exclude_selected;
|
||||
snap_object_params.exclude_edited = t->tsnap.exclude_edited;
|
||||
snap_object_params.exclude_nonedited = t->tsnap.exclude_nonedited;
|
||||
snap_object_params.exclude_nonselectable = t->tsnap.exclude_nonselectable;
|
||||
snap_object_params.exclude_moving = !(t->modifiers & MOD_EDIT_SNAP_SOURCE);
|
||||
snap_object_params.use_occlusion_test = true;
|
||||
snap_object_params.use_backface_culling = (t->tsnap.flag & SCE_SNAP_BACKFACE_CULLING) != 0;
|
||||
|
||||
|
@ -1395,7 +1425,7 @@ eSnapMode snapObjectsTransform(
|
|||
t->depsgraph,
|
||||
t->region,
|
||||
static_cast<const View3D *>(t->view),
|
||||
t->tsnap.mode,
|
||||
t->tsnap.mode & SCE_SNAP_MODE_GEOM,
|
||||
&snap_object_params,
|
||||
nullptr,
|
||||
mval,
|
||||
|
@ -1420,8 +1450,13 @@ bool peelObjectsTransform(TransInfo *t,
|
|||
float *r_thickness)
|
||||
{
|
||||
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.exclude_active = t->tsnap.exclude_active;
|
||||
snap_object_params.exclude_selected = t->tsnap.exclude_selected;
|
||||
snap_object_params.exclude_edited = t->tsnap.exclude_edited;
|
||||
snap_object_params.exclude_nonedited = t->tsnap.exclude_nonedited;
|
||||
snap_object_params.exclude_nonselectable = t->tsnap.exclude_nonselectable;
|
||||
snap_object_params.exclude_moving = !(t->modifiers & MOD_EDIT_SNAP_SOURCE);
|
||||
|
||||
ListBase depths_peel = {nullptr};
|
||||
ED_transform_snap_object_project_all_view3d_ex(t->tsnap.object_context,
|
||||
|
@ -1498,11 +1533,11 @@ bool peelObjectsTransform(TransInfo *t,
|
|||
/** \name snap Nodes
|
||||
* \{ */
|
||||
|
||||
static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetOP snap_target_select)
|
||||
static bool snapNodeTest(View2D *v2d, bNode *node, bool exclude_selected)
|
||||
{
|
||||
/* node is use for snapping only if a) snap mode matches and b) node is inside the view */
|
||||
return (((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && !(node->flag & NODE_SELECT)) ||
|
||||
(snap_target_select == SCE_SNAP_TARGET_ALL && !(node->flag & NODE_ACTIVE))) &&
|
||||
return ((exclude_selected && !(node->flag & NODE_SELECT)) ||
|
||||
(!exclude_selected && !(node->flag & NODE_ACTIVE))) &&
|
||||
(node->runtime->totr.xmin < v2d->cur.xmax && node->runtime->totr.xmax > v2d->cur.xmin &&
|
||||
node->runtime->totr.ymin < v2d->cur.ymax && node->runtime->totr.ymax > v2d->cur.ymin);
|
||||
}
|
||||
|
@ -1583,7 +1618,7 @@ static bool snapNodes(ToolSettings *ts,
|
|||
SpaceNode *snode,
|
||||
ARegion *region,
|
||||
const int mval[2],
|
||||
eSnapTargetOP snap_target_select,
|
||||
bool exclude_selected,
|
||||
float r_loc[2],
|
||||
float *r_dist_px,
|
||||
char *r_node_border)
|
||||
|
@ -1595,7 +1630,7 @@ static bool snapNodes(ToolSettings *ts,
|
|||
*r_node_border = 0;
|
||||
|
||||
for (node = static_cast<bNode *>(ntree->nodes.first); node; node = node->next) {
|
||||
if (snapNodeTest(®ion->v2d, node, snap_target_select)) {
|
||||
if (snapNodeTest(®ion->v2d, node, exclude_selected)) {
|
||||
retval |= snapNode(ts, snode, region, node, mval, r_loc, r_dist_px, r_node_border);
|
||||
}
|
||||
}
|
||||
|
@ -1610,7 +1645,7 @@ bool snapNodesTransform(
|
|||
static_cast<SpaceNode *>(t->area->spacedata.first),
|
||||
t->region,
|
||||
mval,
|
||||
t->tsnap.target_operation,
|
||||
t->tsnap.exclude_selected != SCE_SNAP_MODE_NONE,
|
||||
r_loc,
|
||||
r_dist_px,
|
||||
r_node_border);
|
||||
|
|
|
@ -117,8 +117,10 @@ struct SnapObjectContext {
|
|||
|
||||
struct {
|
||||
Depsgraph *depsgraph;
|
||||
ViewLayer *view_layer;
|
||||
const ARegion *region;
|
||||
const View3D *v3d;
|
||||
const Base *base_act;
|
||||
|
||||
float mval[2];
|
||||
float pmat[4][4]; /* perspective matrix */
|
||||
|
@ -143,6 +145,7 @@ struct SnapObjectContext {
|
|||
/* List of #SnapObjectHitDepth (caller must free). */
|
||||
ListBase *hit_list;
|
||||
/* Snapped object. */
|
||||
Base *base;
|
||||
Object *ob;
|
||||
/* Snapped data. */
|
||||
ID *data;
|
||||
|
@ -410,25 +413,31 @@ using IterSnapObjsCallback = eSnapMode (*)(SnapObjectContext *sctx,
|
|||
bool use_hide,
|
||||
void *data);
|
||||
|
||||
static bool snap_object_is_snappable(const SnapObjectContext *sctx,
|
||||
const eSnapTargetOP snap_target_select,
|
||||
const Base *base_act,
|
||||
const Base *base)
|
||||
static eSnapMode snap_object_mode_filter(const SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const eSnapMode snap_mode,
|
||||
const Base *base)
|
||||
{
|
||||
if (!BASE_VISIBLE(sctx->runtime.v3d, base)) {
|
||||
return false;
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
if ((snap_target_select == SCE_SNAP_TARGET_ALL) ||
|
||||
(base->flag_legacy & BA_TRANSFORM_LOCKED_IN_PLACE))
|
||||
if (base->flag_legacy & BA_TRANSFORM_LOCKED_IN_PLACE ||
|
||||
(params->exclude_active == SCE_SNAP_MODE_NONE &&
|
||||
params->exclude_selected == SCE_SNAP_MODE_NONE &&
|
||||
params->exclude_edited == SCE_SNAP_MODE_NONE &&
|
||||
params->exclude_nonedited == SCE_SNAP_MODE_NONE &&
|
||||
params->exclude_nonselectable == SCE_SNAP_MODE_NONE))
|
||||
{
|
||||
return true;
|
||||
return snap_mode;
|
||||
}
|
||||
|
||||
if (base->flag_legacy & BA_SNAP_FIX_DEPS_FIASCO) {
|
||||
return false;
|
||||
if (params->exclude_moving && base->flag_legacy & BA_SNAP_FIX_DEPS_FIASCO) {
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
const Base *base_act = sctx->runtime.base_act;
|
||||
|
||||
/* Get attributes of potential target. */
|
||||
const bool is_active = (base_act == base);
|
||||
const bool is_selected = (base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL);
|
||||
|
@ -440,30 +449,31 @@ static bool snap_object_is_snappable(const SnapObjectContext *sctx,
|
|||
|
||||
if (is_in_object_mode) {
|
||||
/* Handle target selection options that make sense for object mode. */
|
||||
if ((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && is_selected) {
|
||||
if (is_selected) {
|
||||
/* What is selectable or not is part of the object and depends on the mode. */
|
||||
return false;
|
||||
return snap_mode & ~params->exclude_selected;
|
||||
}
|
||||
return snap_mode & ~params->exclude_nonedited;
|
||||
}
|
||||
else {
|
||||
/* Handle target selection options that make sense for edit/pose mode. */
|
||||
if ((snap_target_select & SCE_SNAP_TARGET_NOT_ACTIVE) && is_active) {
|
||||
return false;
|
||||
if (is_active) {
|
||||
return snap_mode & ~params->exclude_active;
|
||||
}
|
||||
if ((snap_target_select & SCE_SNAP_TARGET_NOT_EDITED) && is_edited && !is_active) {
|
||||
if (is_edited && !is_active) {
|
||||
/* Base is edited, but not active. */
|
||||
return false;
|
||||
return snap_mode & ~params->exclude_edited;
|
||||
}
|
||||
if ((snap_target_select & SCE_SNAP_TARGET_NOT_NONEDITED) && !is_edited) {
|
||||
return false;
|
||||
if (!is_edited) {
|
||||
return snap_mode & ~params->exclude_nonedited;
|
||||
}
|
||||
}
|
||||
|
||||
if ((snap_target_select & SCE_SNAP_TARGET_ONLY_SELECTABLE) && !is_selectable) {
|
||||
return false;
|
||||
if (!is_selectable) {
|
||||
return snap_mode & ~params->exclude_nonselectable;
|
||||
}
|
||||
|
||||
return true;
|
||||
return snap_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -476,18 +486,22 @@ static eSnapMode iter_snap_objects(SnapObjectContext *sctx,
|
|||
{
|
||||
eSnapMode ret = SCE_SNAP_MODE_NONE;
|
||||
eSnapMode tmp;
|
||||
eSnapMode snap_to_flag = sctx->runtime.snap_to_flag;
|
||||
const Base *base_act = sctx->runtime.base_act;
|
||||
|
||||
Scene *scene = DEG_get_input_scene(sctx->runtime.depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_input_view_layer(sctx->runtime.depsgraph);
|
||||
const eSnapTargetOP snap_target_select = params->snap_target_select;
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
Base *base_act = BKE_view_layer_active_base_get(view_layer);
|
||||
const bool is_occlusion_test = params->use_occlusion_test && snap_to_flag == SCE_SNAP_MODE_NONE;
|
||||
|
||||
LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
|
||||
if (!snap_object_is_snappable(sctx, snap_target_select, base_act, base)) {
|
||||
continue;
|
||||
LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(sctx->runtime.view_layer)) {
|
||||
eSnapMode snap_mode_filtered = snap_to_flag;
|
||||
if (!is_occlusion_test) {
|
||||
snap_mode_filtered = snap_object_mode_filter(sctx, params, snap_to_flag, base);
|
||||
if (snap_mode_filtered == SCE_SNAP_MODE_NONE) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
sctx->runtime.snap_to_flag = snap_mode_filtered;
|
||||
|
||||
const bool is_object_active = (base == base_act);
|
||||
Object *obj_eval = DEG_get_evaluated_object(sctx->runtime.depsgraph, base->object);
|
||||
if (obj_eval->transflag & OB_DUPLI || BKE_object_has_geometry_set_instances(obj_eval)) {
|
||||
|
@ -503,6 +517,7 @@ static eSnapMode iter_snap_objects(SnapObjectContext *sctx,
|
|||
false,
|
||||
data)) != SCE_SNAP_MODE_NONE)
|
||||
{
|
||||
sctx->ret.base = base;
|
||||
ret = tmp;
|
||||
}
|
||||
}
|
||||
|
@ -520,6 +535,7 @@ static eSnapMode iter_snap_objects(SnapObjectContext *sctx,
|
|||
use_hide,
|
||||
data)) != SCE_SNAP_MODE_NONE)
|
||||
{
|
||||
sctx->ret.base = base;
|
||||
ret = tmp;
|
||||
}
|
||||
}
|
||||
|
@ -1767,6 +1783,12 @@ static eSnapMode snap_mesh_polygon(SnapObjectContext *sctx,
|
|||
float *dist_px)
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
eSnapMode snap_mode_filtered = snap_object_mode_filter(
|
||||
sctx, params, sctx->runtime.snap_to_flag, sctx->ret.base);
|
||||
|
||||
if (snap_mode_filtered == SCE_SNAP_MODE_NONE) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, sctx->ret.obmat);
|
||||
|
@ -2101,7 +2123,8 @@ static eSnapMode snapArmature(SnapObjectContext *sctx,
|
|||
|
||||
const bool is_posemode = is_object_active && (ob_eval->mode & OB_MODE_POSE);
|
||||
const bool skip_selected = (is_editmode || is_posemode) &&
|
||||
(params->snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED);
|
||||
(params->exclude_selected &
|
||||
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE));
|
||||
const bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP;
|
||||
|
||||
if (arm->edbo) {
|
||||
|
@ -2280,7 +2303,7 @@ static eSnapMode snapCurve(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP;
|
||||
bool skip_selected = params->snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED;
|
||||
bool skip_selected = params->exclude_selected & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE);
|
||||
|
||||
LISTBASE_FOREACH (Nurb *, nu, (use_obedit ? &cu->editnurb->nurbs : &cu->nurb)) {
|
||||
for (int u = 0; u < nu->pntsu; u++) {
|
||||
|
@ -3034,6 +3057,32 @@ static eSnapMode snapObjectsRay(SnapObjectContext *sctx,
|
|||
return iter_snap_objects(sctx, params, snap_obj_fn, &data);
|
||||
}
|
||||
|
||||
static void snap_object_context_runtime_init(SnapObjectContext *sctx,
|
||||
Depsgraph *depsgraph,
|
||||
const ARegion *region,
|
||||
const View3D *v3d,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
sctx->runtime.depsgraph = depsgraph;
|
||||
sctx->runtime.region = region;
|
||||
sctx->runtime.v3d = v3d;
|
||||
|
||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||
sctx->runtime.view_layer = DEG_get_input_view_layer(depsgraph);
|
||||
BKE_view_layer_synced_ensure(scene, sctx->runtime.view_layer);
|
||||
sctx->runtime.base_act = BKE_view_layer_active_base_get(sctx->runtime.view_layer);
|
||||
|
||||
zero_v3(sctx->ret.loc);
|
||||
zero_v3(sctx->ret.no);
|
||||
sctx->ret.index = -1;
|
||||
zero_m4(sctx->ret.obmat);
|
||||
sctx->ret.hit_list = r_hit_list;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_sq = FLT_MAX;
|
||||
sctx->ret.is_edit = false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -3099,19 +3148,9 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
|
|||
Object **r_ob,
|
||||
float r_obmat[4][4])
|
||||
{
|
||||
sctx->runtime.depsgraph = depsgraph;
|
||||
sctx->runtime.v3d = v3d;
|
||||
|
||||
zero_v3(sctx->ret.loc);
|
||||
zero_v3(sctx->ret.no);
|
||||
sctx->ret.index = -1;
|
||||
zero_m4(sctx->ret.obmat);
|
||||
sctx->ret.hit_list = nullptr;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_sq = FLT_MAX;
|
||||
sctx->ret.is_edit = false;
|
||||
snap_object_context_runtime_init(sctx, depsgraph, nullptr, v3d, nullptr);
|
||||
|
||||
sctx->runtime.snap_to_flag = SCE_SNAP_MODE_FACE;
|
||||
if (raycastObjects(sctx,
|
||||
params,
|
||||
ray_start,
|
||||
|
@ -3148,18 +3187,7 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
|
|||
bool sort,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
sctx->runtime.depsgraph = depsgraph;
|
||||
sctx->runtime.v3d = v3d;
|
||||
|
||||
zero_v3(sctx->ret.loc);
|
||||
zero_v3(sctx->ret.no);
|
||||
sctx->ret.index = -1;
|
||||
zero_m4(sctx->ret.obmat);
|
||||
sctx->ret.hit_list = r_hit_list;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_sq = FLT_MAX;
|
||||
sctx->ret.is_edit = false;
|
||||
snap_object_context_runtime_init(sctx, depsgraph, nullptr, v3d, r_hit_list);
|
||||
|
||||
if (ray_depth == -1.0f) {
|
||||
ray_depth = BVH_RAYCAST_DIST_MAX;
|
||||
|
@ -3169,6 +3197,7 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
|
|||
float ray_depth_prev = ray_depth;
|
||||
#endif
|
||||
|
||||
sctx->runtime.snap_to_flag = SCE_SNAP_MODE_FACE;
|
||||
if (raycastObjects(sctx,
|
||||
params,
|
||||
ray_start,
|
||||
|
@ -3262,21 +3291,7 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
|||
float r_obmat[4][4],
|
||||
float r_face_nor[3])
|
||||
{
|
||||
sctx->runtime.depsgraph = depsgraph;
|
||||
sctx->runtime.region = region;
|
||||
sctx->runtime.v3d = v3d;
|
||||
|
||||
zero_v3(sctx->ret.loc);
|
||||
zero_v3(sctx->ret.no);
|
||||
sctx->ret.index = -1;
|
||||
zero_m4(sctx->ret.obmat);
|
||||
sctx->ret.hit_list = nullptr;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_sq = FLT_MAX;
|
||||
sctx->ret.is_edit = false;
|
||||
|
||||
BLI_assert(snap_to_flag & (SCE_SNAP_MODE_GEOM | SCE_SNAP_MODE_FACE_NEAREST));
|
||||
snap_object_context_runtime_init(sctx, depsgraph, region, v3d, nullptr);
|
||||
|
||||
eSnapMode retval = SCE_SNAP_MODE_NONE;
|
||||
|
||||
|
@ -3301,9 +3316,12 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
|||
snap_to_flag &= ~SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
|
||||
BLI_assert(snap_to_flag & (SCE_SNAP_MODE_GEOM | SCE_SNAP_MODE_FACE_NEAREST));
|
||||
|
||||
/* NOTE: if both face ray-cast and face nearest are enabled, first find result of nearest, then
|
||||
* override with ray-cast. */
|
||||
if ((snap_to_flag & SCE_SNAP_MODE_FACE_NEAREST) && !has_hit) {
|
||||
sctx->runtime.snap_to_flag = (snap_to_flag & SCE_SNAP_MODE_FACE_NEAREST);
|
||||
has_hit = nearestWorldObjects(sctx, params, init_co, prev_co);
|
||||
|
||||
if (has_hit) {
|
||||
|
@ -3335,6 +3353,7 @@ static eSnapMode transform_snap_context_project_view3d_mixed_impl(SnapObjectCont
|
|||
|
||||
float dummy_ray_depth = BVH_RAYCAST_DIST_MAX;
|
||||
|
||||
sctx->runtime.snap_to_flag = (snap_to_flag & SCE_SNAP_MODE_FACE);
|
||||
has_hit = raycastObjects(sctx,
|
||||
params,
|
||||
ray_start,
|
||||
|
|
|
@ -336,10 +336,14 @@
|
|||
.autokey_mode = AUTOKEY_MODE_NORMAL, \
|
||||
\
|
||||
.transform_pivot_point = V3D_AROUND_CENTER_MEDIAN, \
|
||||
.snap_mode = SCE_SNAP_MODE_INCREMENT, \
|
||||
.snap_mode = SCE_SNAP_MODE_GEOM, \
|
||||
.snap_filter_active = SCE_SNAP_MODE_GEOM_ALL, \
|
||||
.snap_filter_edit = SCE_SNAP_MODE_GEOM_ALL, \
|
||||
.snap_filter_nonedit = SCE_SNAP_MODE_GEOM_ALL, \
|
||||
.snap_filter_nonselectable = SCE_SNAP_MODE_GEOM_ALL, \
|
||||
.snap_node_mode = SCE_SNAP_MODE_GRID, \
|
||||
.snap_uv_mode = SCE_SNAP_MODE_INCREMENT, \
|
||||
.snap_flag = SCE_SNAP_TO_INCLUDE_EDITED | SCE_SNAP_TO_INCLUDE_NONEDITED, \
|
||||
.snap_flag = SCE_SNAP_INCLUDE_ACTIVE, \
|
||||
.snap_transform_mode_flag = SCE_SNAP_TRANSFORM_MODE_TRANSLATE, \
|
||||
.snap_face_nearest_steps = 1, \
|
||||
\
|
||||
|
|
|
@ -1617,6 +1617,10 @@ typedef struct ToolSettings {
|
|||
/** Snap elements (per space-type), #eSnapMode. */
|
||||
char _pad1[1];
|
||||
short snap_mode;
|
||||
short snap_filter_active;
|
||||
short snap_filter_edit;
|
||||
short snap_filter_nonedit;
|
||||
short snap_filter_nonselectable;
|
||||
char snap_node_mode;
|
||||
char snap_uv_mode;
|
||||
/** Generic flags (per space-type), #eSnapFlag. */
|
||||
|
@ -2254,16 +2258,15 @@ typedef enum eSnapFlag {
|
|||
SCE_SNAP = (1 << 0),
|
||||
SCE_SNAP_ROTATE = (1 << 1),
|
||||
SCE_SNAP_PEEL_OBJECT = (1 << 2),
|
||||
// SCE_SNAP_PROJECT = (1 << 3), /* DEPRECATED, see #SCE_SNAP_MODE_FACE_RAYCAST. */
|
||||
/** Was `SCE_SNAP_NO_SELF`, but self should be active. */
|
||||
SCE_SNAP_NOT_TO_ACTIVE = (1 << 4),
|
||||
SCE_SNAP_KEEP_ON_SAME_OBJECT = (1 << 3),
|
||||
// SCE_SNAP_NOT_TO_ACTIVE = (1 << 4), /* DEPRECATED */
|
||||
SCE_SNAP_ABS_GRID = (1 << 5),
|
||||
SCE_SNAP_BACKFACE_CULLING = (1 << 6),
|
||||
SCE_SNAP_KEEP_ON_SAME_OBJECT = (1 << 7),
|
||||
/** see #eSnapTargetOP */
|
||||
SCE_SNAP_TO_INCLUDE_EDITED = (1 << 8),
|
||||
SCE_SNAP_TO_INCLUDE_NONEDITED = (1 << 9),
|
||||
SCE_SNAP_TO_ONLY_SELECTABLE = (1 << 10),
|
||||
SCE_SNAP_INCLUDE_ACTIVE = (1 << 7),
|
||||
SCE_SNAP_INCLUDE_EDITED = (1 << 8),
|
||||
SCE_SNAP_INCLUDE_NONEDITED = (1 << 9),
|
||||
SCE_SNAP_INCLUDE_NONSELECTABLE = (1 << 10),
|
||||
} eSnapFlag;
|
||||
/* Due to dependency conflicts with Cycles, header cannot directly include `BLI_utildefines.h`. */
|
||||
/* TODO: move this macro to a more general place. */
|
||||
|
@ -2281,21 +2284,6 @@ typedef enum eSnapSourceOP {
|
|||
|
||||
ENUM_OPERATORS(eSnapSourceOP, SCE_SNAP_SOURCE_ACTIVE)
|
||||
|
||||
/**
|
||||
* #TransSnap.target_operation and #ToolSettings.snap_flag
|
||||
* (#SCE_SNAP_NOT_TO_ACTIVE, #SCE_SNAP_TO_INCLUDE_EDITED, #SCE_SNAP_TO_INCLUDE_NONEDITED,
|
||||
* #SCE_SNAP_TO_ONLY_SELECTABLE).
|
||||
*/
|
||||
typedef enum eSnapTargetOP {
|
||||
SCE_SNAP_TARGET_ALL = 0,
|
||||
SCE_SNAP_TARGET_NOT_SELECTED = (1 << 0),
|
||||
SCE_SNAP_TARGET_NOT_ACTIVE = (1 << 1),
|
||||
SCE_SNAP_TARGET_NOT_EDITED = (1 << 2),
|
||||
SCE_SNAP_TARGET_ONLY_SELECTABLE = (1 << 3),
|
||||
SCE_SNAP_TARGET_NOT_NONEDITED = (1 << 4),
|
||||
} eSnapTargetOP;
|
||||
ENUM_OPERATORS(eSnapTargetOP, SCE_SNAP_TARGET_NOT_NONEDITED)
|
||||
|
||||
/** #ToolSettings.snap_mode */
|
||||
typedef enum eSnapMode {
|
||||
SCE_SNAP_MODE_NONE = 0,
|
||||
|
@ -2330,6 +2318,10 @@ ENUM_OPERATORS(eSnapMode, 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)
|
||||
|
||||
#define SCE_SNAP_MODE_GEOM_ALL \
|
||||
(SCE_SNAP_MODE_GEOM | SCE_SNAP_MODE_VOLUME | SCE_SNAP_MODE_FACE_NEAREST | \
|
||||
SCE_SNAP_MODE_FACE_RAYCAST)
|
||||
|
||||
/** #SequencerToolSettings.snap_mode */
|
||||
#define SEQ_SNAP_TO_STRIPS (1 << 0)
|
||||
#define SEQ_SNAP_TO_CURRENT_FRAME (1 << 1)
|
||||
|
|
|
@ -157,9 +157,9 @@ const EnumPropertyItem rna_enum_mesh_select_mode_uv_items[] = {
|
|||
{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"}
|
||||
{SCE_SNAP_MODE_EDGE_PERPENDICULAR, "EDGE_PERPENDICULAR", ICON_SNAP_PERPENDICULAR, "Edge Perpendicular", "Snap to the nearest point on an edge"}, \
|
||||
{SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume"}
|
||||
/* clang-format on */
|
||||
|
||||
const EnumPropertyItem rna_enum_snap_element_items[] = {
|
||||
|
@ -186,6 +186,18 @@ const EnumPropertyItem rna_enum_snap_element_base_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_select_filter_items[] = {
|
||||
{SCE_SNAP_INCLUDE_ACTIVE, "ACTIVE", ICON_EDITMODE_HLT, "Active", ""},
|
||||
{SCE_SNAP_INCLUDE_EDITED, "EDITED", ICON_OUTLINER_DATA_MESH, "Edited", ""},
|
||||
{SCE_SNAP_INCLUDE_NONEDITED, "NONEDITED", ICON_OUTLINER_OB_MESH, "Non-edited", ""},
|
||||
{SCE_SNAP_INCLUDE_NONSELECTABLE,
|
||||
"NONSELECTABLE",
|
||||
ICON_RESTRICT_SELECT_ON,
|
||||
"Non-selectable",
|
||||
""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
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"},
|
||||
|
@ -755,6 +767,12 @@ static void rna_ToolSettings_snap_mode_set(struct PointerRNA *ptr, int value)
|
|||
}
|
||||
}
|
||||
|
||||
static int rna_ToolSettings_snap_flag_get(PointerRNA *ptr)
|
||||
{
|
||||
ToolSettings *ts = (ToolSettings *)(ptr->data);
|
||||
return ts->snap_flag;
|
||||
}
|
||||
|
||||
/* Grease Pencil update cache */
|
||||
static void rna_GPencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
|
@ -3411,6 +3429,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
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_enum_default(prop, SCE_SNAP_MODE_GEOM);
|
||||
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 */
|
||||
|
||||
|
@ -3433,6 +3452,48 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
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_filter_active", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_filter_active");
|
||||
RNA_def_property_enum_items(prop, rna_enum_snap_element_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_enum_default(prop, SCE_SNAP_MODE_GEOM_ALL);
|
||||
RNA_def_property_ui_text(prop, "Snap onto Active", "Snap onto itself if in Edit Mode");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "snap_filter_edit", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_filter_edit");
|
||||
RNA_def_property_enum_items(prop, rna_enum_snap_element_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_enum_default(prop, SCE_SNAP_MODE_GEOM_ALL);
|
||||
RNA_def_property_ui_text(prop, "Snap onto Edited", "Snap onto non-active objects in Edit Mode");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "snap_filter_nonedit", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_filter_nonedit");
|
||||
RNA_def_property_enum_items(prop, rna_enum_snap_element_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_enum_default(prop, SCE_SNAP_MODE_GEOM_ALL);
|
||||
RNA_def_property_ui_text(prop, "Snap onto Non-edited", "Snap onto objects not in Edit Mode");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "snap_filter_nonselectable", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_filter_nonselectable");
|
||||
RNA_def_property_enum_items(prop, rna_enum_snap_element_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_enum_default(prop, SCE_SNAP_MODE_GEOM_ALL);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Snap onto Non-selectable", "Snap onto objects that are non-selectable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "show_snap_filter", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_flag");
|
||||
RNA_def_property_enum_items(prop, rna_enum_snap_select_filter_items);
|
||||
RNA_def_property_enum_funcs(prop, "rna_ToolSettings_snap_flag_get", NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_enum_default(prop, SCE_SNAP_INCLUDE_ACTIVE);
|
||||
RNA_def_property_ui_text(prop, "Show Snap Filter", "");
|
||||
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);
|
||||
|
@ -3476,6 +3537,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "snap_target", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "snap_target");
|
||||
RNA_def_property_enum_items(prop, rna_enum_snap_source_items);
|
||||
RNA_def_property_enum_default(prop, SCE_SNAP_SOURCE_CLOSEST);
|
||||
RNA_def_property_ui_text(prop, "Snap Target", "Which part to snap onto the target");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
|
@ -3490,32 +3552,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Backface Culling", "Exclude back facing geometry from snapping");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
/* TODO(@gfxcoder): Rename `use_snap_self` to `use_snap_active`, because active is correct but
|
||||
* self is not (breaks API). This only makes a difference when more than one mesh is edited. */
|
||||
prop = RNA_def_property(srna, "use_snap_self", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_flag", SCE_SNAP_NOT_TO_ACTIVE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Snap onto Active", "Snap onto itself only if enabled (Edit Mode Only)");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "use_snap_edit", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_TO_INCLUDE_EDITED);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Snap onto Edited", "Snap onto non-active objects in Edit Mode (Edit Mode Only)");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "use_snap_nonedit", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_TO_INCLUDE_NONEDITED);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Snap onto Non-edited", "Snap onto objects not in Edit Mode (Edit Mode Only)");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "use_snap_selectable", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_TO_ONLY_SELECTABLE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Snap onto Selectable Only", "Snap only onto objects that are selectable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
|
||||
|
||||
prop = RNA_def_property(srna, "use_snap_translate", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(
|
||||
prop, NULL, "snap_transform_mode_flag", SCE_SNAP_TRANSFORM_MODE_TRANSLATE);
|
||||
|
|
|
@ -141,9 +141,7 @@ static void rna_Scene_ray_cast(Scene *scene,
|
|||
bool ret = ED_transform_snap_object_project_ray_ex(sctx,
|
||||
depsgraph,
|
||||
NULL,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_target_select = SCE_SNAP_TARGET_ALL,
|
||||
},
|
||||
&(const struct SnapObjectParams){0},
|
||||
origin,
|
||||
direction,
|
||||
&ray_dist,
|
||||
|
|
|
@ -733,9 +733,9 @@ static void wm_xr_raycast(Scene *scene,
|
|||
sctx,
|
||||
depsgraph,
|
||||
NULL,
|
||||
&(const struct SnapObjectParams){.snap_target_select = (selectable_only ?
|
||||
SCE_SNAP_TARGET_ONLY_SELECTABLE :
|
||||
SCE_SNAP_TARGET_ALL)},
|
||||
&(const struct SnapObjectParams){.exclude_nonselectable = (selectable_only ?
|
||||
SCE_SNAP_MODE_GEOM_ALL :
|
||||
SCE_SNAP_MODE_NONE)},
|
||||
origin,
|
||||
direction,
|
||||
ray_dist,
|
||||
|
|
Loading…
Reference in New Issue