WIP: Snapping Redesign: Defaults | Navigation | Drawing | Removals #109062

Draft
Germano Cavalcante wants to merge 29 commits from mano-wii/blender:snap_defaults into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
44 changed files with 834 additions and 644 deletions

View File

@ -252,15 +252,6 @@ class Prefs(bpy.types.KeyConfigPreferences):
update=update_fn, update=update_fn,
) )
use_transform_navigation: BoolProperty(
name="Navigate during Transform",
description=(
"Enable view navigation while using transform operators. "
"Proportional Influence, Automatic Constraints and Auto IK Chain Length shortcuts will require holding Alt key"),
default=False,
update=update_fn,
)
def draw(self, layout): def draw(self, layout):
from bpy import context from bpy import context
@ -324,7 +315,6 @@ class Prefs(bpy.types.KeyConfigPreferences):
sub.prop(self, "use_v3d_tab_menu") sub.prop(self, "use_v3d_tab_menu")
sub.prop(self, "use_pie_click_drag") sub.prop(self, "use_pie_click_drag")
sub.prop(self, "use_v3d_shade_ex_pie") sub.prop(self, "use_v3d_shade_ex_pie")
sub.prop(self, "use_transform_navigation")
# File Browser settings. # File Browser settings.
col = layout.column() col = layout.column()
@ -385,7 +375,6 @@ def load():
use_pie_click_drag=kc_prefs.use_pie_click_drag, use_pie_click_drag=kc_prefs.use_pie_click_drag,
use_file_single_click=kc_prefs.use_file_single_click, use_file_single_click=kc_prefs.use_file_single_click,
experimental=prefs.experimental, experimental=prefs.experimental,
use_transform_navigation=kc_prefs.use_transform_navigation,
), ),
) )

View File

@ -99,8 +99,6 @@ class Params:
"tool_maybe_tweak_event", "tool_maybe_tweak_event",
# Access to bpy.context.preferences.experimental # Access to bpy.context.preferences.experimental
"experimental", "experimental",
# Changes some transformers modal key-map items to avoid conflicts with navigation operations
"use_transform_navigation",
) )
def __init__( def __init__(
@ -129,7 +127,6 @@ class Params:
v3d_tilde_action='VIEW', v3d_tilde_action='VIEW',
v3d_alt_mmb_drag_action='RELATIVE', v3d_alt_mmb_drag_action='RELATIVE',
experimental=None, experimental=None,
use_transform_navigation=False,
): ):
from sys import platform from sys import platform
self.apple = (platform == 'darwin') self.apple = (platform == 'darwin')
@ -228,7 +225,6 @@ class Params:
self.pie_value = 'CLICK_DRAG' if use_pie_click_drag else 'PRESS' self.pie_value = 'CLICK_DRAG' if use_pie_click_drag else 'PRESS'
self.tool_tweak_event = {"type": self.tool_mouse, "value": 'CLICK_DRAG'} self.tool_tweak_event = {"type": self.tool_mouse, "value": 'CLICK_DRAG'}
self.tool_maybe_tweak_event = {"type": self.tool_mouse, "value": self.tool_maybe_tweak_value} self.tool_maybe_tweak_event = {"type": self.tool_mouse, "value": self.tool_maybe_tweak_value}
self.use_transform_navigation = use_transform_navigation
self.experimental = experimental self.experimental = experimental
@ -1608,16 +1604,13 @@ def km_view3d(params):
# Transform. # Transform.
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None), ("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
op_tool_optional( op_tool_optional(
("transform.translate", {"type": 'G', "value": 'PRESS'}, ("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.move"), params), (op_tool_cycle, "builtin.move"), params),
op_tool_optional( op_tool_optional(
("transform.rotate", {"type": 'R', "value": 'PRESS'}, ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None),
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.rotate"), params), (op_tool_cycle, "builtin.rotate"), params),
op_tool_optional( op_tool_optional(
("transform.resize", {"type": 'S', "value": 'PRESS'}, ("transform.resize", {"type": 'S', "value": 'PRESS'}, None),
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.scale"), params), (op_tool_cycle, "builtin.scale"), params),
op_tool_optional( op_tool_optional(
("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None),
@ -3675,8 +3668,7 @@ def km_grease_pencil_stroke_edit_mode(params):
("gpencil.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None), ("gpencil.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
# Extrude and move selected points # Extrude and move selected points
op_tool_optional( op_tool_optional(
("gpencil.extrude_move", {"type": 'E', "value": 'PRESS'}, ("gpencil.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
(op_tool_cycle, "builtin.extrude"), params), (op_tool_cycle, "builtin.extrude"), params),
# Delete # Delete
op_menu("VIEW3D_MT_edit_gpencil_delete", {"type": 'X', "value": 'PRESS'}), op_menu("VIEW3D_MT_edit_gpencil_delete", {"type": 'X', "value": 'PRESS'}),
@ -4685,10 +4677,8 @@ def km_object_mode(params):
op_menu("VIEW3D_MT_add", {"type": 'A', "value": 'PRESS', "shift": True}), op_menu("VIEW3D_MT_add", {"type": 'A', "value": 'PRESS', "shift": True}),
op_menu("VIEW3D_MT_object_apply", {"type": 'A', "value": 'PRESS', "ctrl": True}), op_menu("VIEW3D_MT_object_apply", {"type": 'A', "value": 'PRESS', "ctrl": True}),
op_menu("VIEW3D_MT_make_links", {"type": 'L', "value": 'PRESS', "ctrl": True}), op_menu("VIEW3D_MT_make_links", {"type": 'L', "value": 'PRESS', "ctrl": True}),
("object.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, ("object.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}), ("object.duplicate_move_linked", {"type": 'D', "value": 'PRESS', "alt": True}, None),
("object.duplicate_move_linked", {"type": 'D', "value": 'PRESS', "alt": True},
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
("object.join", {"type": 'J', "value": 'PRESS', "ctrl": True}, None), ("object.join", {"type": 'J', "value": 'PRESS', "ctrl": True}, None),
("wm.context_toggle", {"type": 'PERIOD', "value": 'PRESS', "ctrl": True}, ("wm.context_toggle", {"type": 'PERIOD', "value": 'PRESS', "ctrl": True},
{"properties": [("data_path", 'tool_settings.use_transform_data_origin')]}), {"properties": [("data_path", 'tool_settings.use_transform_data_origin')]}),
@ -4754,13 +4744,10 @@ def km_paint_curve(params):
("paintcurve.delete_point", {"type": 'DEL', "value": 'PRESS'}, None), ("paintcurve.delete_point", {"type": 'DEL', "value": 'PRESS'}, None),
("paintcurve.draw", {"type": 'RET', "value": 'PRESS'}, None), ("paintcurve.draw", {"type": 'RET', "value": 'PRESS'}, None),
("paintcurve.draw", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None), ("paintcurve.draw", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None),
("transform.translate", {"type": 'G', "value": 'PRESS'}, ("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None), ("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
("transform.rotate", {"type": 'R', "value": 'PRESS'}, ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None),
{"properties": [("allow_navigation", params.use_transform_navigation)]}), ("transform.resize", {"type": 'S', "value": 'PRESS'}, None),
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
]) ])
return keymap return keymap
@ -4793,8 +4780,7 @@ def km_curve(params):
("curve.separate", {"type": 'P', "value": 'PRESS'}, None), ("curve.separate", {"type": 'P', "value": 'PRESS'}, None),
("curve.split", {"type": 'Y', "value": 'PRESS'}, None), ("curve.split", {"type": 'Y', "value": 'PRESS'}, None),
op_tool_optional( op_tool_optional(
("curve.extrude_move", {"type": 'E', "value": 'PRESS'}, ("curve.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
(op_tool_cycle, "builtin.extrude"), params), (op_tool_cycle, "builtin.extrude"), params),
("curve.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None), ("curve.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
("curve.make_segment", {"type": 'F', "value": 'PRESS'}, None), ("curve.make_segment", {"type": 'F', "value": 'PRESS'}, None),
@ -5403,8 +5389,7 @@ def km_mesh(params):
("mesh.normals_make_consistent", {"type": 'N', "value": 'PRESS', "shift": True, "ctrl": True}, ("mesh.normals_make_consistent", {"type": 'N', "value": 'PRESS', "shift": True, "ctrl": True},
{"properties": [("inside", True)]}), {"properties": [("inside", True)]}),
op_tool_optional( op_tool_optional(
("view3d.edit_mesh_extrude_move_normal", {"type": 'E', "value": 'PRESS'}, ("view3d.edit_mesh_extrude_move_normal", {"type": 'E', "value": 'PRESS'}, None),
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.extrude_region"), params), (op_tool_cycle, "builtin.extrude_region"), params),
op_menu("VIEW3D_MT_edit_mesh_extrude", {"type": 'E', "value": 'PRESS', "alt": True}), op_menu("VIEW3D_MT_edit_mesh_extrude", {"type": 'E', "value": 'PRESS', "alt": True}),
("transform.edge_crease", {"type": 'E', "value": 'PRESS', "shift": True}, None), ("transform.edge_crease", {"type": 'E', "value": 'PRESS', "shift": True}, None),
@ -5421,13 +5406,11 @@ def km_mesh(params):
# No tool is available for this. # No tool is available for this.
("mesh.rip_move", {"type": 'V', "value": 'PRESS', "alt": True}, ("mesh.rip_move", {"type": 'V', "value": 'PRESS', "alt": True},
{"properties": [("MESH_OT_rip", [("use_fill", True)],)]}), {"properties": [("MESH_OT_rip", [("use_fill", True)],)]}),
("mesh.rip_edge_move", {"type": 'D', "value": 'PRESS', "alt": True}, ("mesh.rip_edge_move", {"type": 'D', "value": 'PRESS', "alt": True}, None),
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
op_menu("VIEW3D_MT_edit_mesh_merge", {"type": 'M', "value": 'PRESS'}), op_menu("VIEW3D_MT_edit_mesh_merge", {"type": 'M', "value": 'PRESS'}),
op_menu("VIEW3D_MT_edit_mesh_split", {"type": 'M', "value": 'PRESS', "alt": True}), op_menu("VIEW3D_MT_edit_mesh_split", {"type": 'M', "value": 'PRESS', "alt": True}),
("mesh.edge_face_add", {"type": 'F', "value": 'PRESS', "repeat": True}, None), ("mesh.edge_face_add", {"type": 'F', "value": 'PRESS', "repeat": True}, None),
("mesh.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, ("mesh.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
op_menu("VIEW3D_MT_mesh_add", {"type": 'A', "value": 'PRESS', "shift": True}), op_menu("VIEW3D_MT_mesh_add", {"type": 'A', "value": 'PRESS', "shift": True}),
("mesh.separate", {"type": 'P', "value": 'PRESS'}, None), ("mesh.separate", {"type": 'P', "value": 'PRESS'}, None),
("mesh.split", {"type": 'Y', "value": 'PRESS'}, None), ("mesh.split", {"type": 'Y', "value": 'PRESS'}, None),
@ -5545,8 +5528,7 @@ def km_armature(params):
("armature.dissolve", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), ("armature.dissolve", {"type": 'X', "value": 'PRESS', "ctrl": True}, None),
("armature.dissolve", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, None), ("armature.dissolve", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, None),
op_tool_optional( op_tool_optional(
("armature.extrude_move", {"type": 'E', "value": 'PRESS'}, ("armature.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
(op_tool_cycle, "builtin.extrude"), params), (op_tool_cycle, "builtin.extrude"), params),
("armature.extrude_forked", {"type": 'E', "value": 'PRESS', "shift": True}, None), ("armature.extrude_forked", {"type": 'E', "value": 'PRESS', "shift": True}, None),
("armature.click_extrude", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, None), ("armature.click_extrude", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, None),
@ -5965,24 +5947,24 @@ def km_transform_modal_map(params):
("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": True}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": True}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY', "alt": params.use_transform_navigation}, None), ("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY', "alt": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None), ("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None),
("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None), ("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None),
("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None), ("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None),
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY', "alt": params.use_transform_navigation}, None), ("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY', "alt": True}, None),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True, "alt": params.use_transform_navigation}, None), ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True, "alt": True}, None),
("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None), ("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None), ("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None),
]) ])

View File

@ -15,12 +15,6 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
bl_label = "Extrude Individual and Move" bl_label = "Extrude Individual and Move"
bl_idname = "view3d.edit_mesh_extrude_individual_move" bl_idname = "view3d.edit_mesh_extrude_individual_move"
allow_navigation: BoolProperty(
name="allow_navigation",
default=False,
description="Allow navigation",
)
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
obj = context.active_object obj = context.active_object
@ -40,27 +34,27 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
TRANSFORM_OT_translate={ TRANSFORM_OT_translate={
"orient_type": 'NORMAL', "orient_type": 'NORMAL',
"constraint_axis": (False, False, True), "constraint_axis": (False, False, True),
"allow_navigation": self.allow_navigation, "release_confirm": False,
}, },
) )
elif select_mode[2] and totface > 1: elif select_mode[2] and totface > 1:
bpy.ops.mesh.extrude_faces_move( bpy.ops.mesh.extrude_faces_move(
'INVOKE_REGION_WIN', 'INVOKE_REGION_WIN',
TRANSFORM_OT_shrink_fatten={ TRANSFORM_OT_shrink_fatten={
"allow_navigation": self.allow_navigation, "release_confirm": False,
}) })
elif select_mode[1] and totedge >= 1: elif select_mode[1] and totedge >= 1:
bpy.ops.mesh.extrude_edges_move( bpy.ops.mesh.extrude_edges_move(
'INVOKE_REGION_WIN', 'INVOKE_REGION_WIN',
TRANSFORM_OT_translate={ TRANSFORM_OT_translate={
"allow_navigation": self.allow_navigation, "release_confirm": False,
}, },
) )
else: else:
bpy.ops.mesh.extrude_vertices_move( bpy.ops.mesh.extrude_vertices_move(
'INVOKE_REGION_WIN', 'INVOKE_REGION_WIN',
TRANSFORM_OT_translate={ TRANSFORM_OT_translate={
"allow_navigation": self.allow_navigation, "release_confirm": False,
}, },
) )
@ -83,19 +77,13 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
description="Dissolves adjacent faces and intersects new geometry", description="Dissolves adjacent faces and intersects new geometry",
) )
allow_navigation: BoolProperty(
name="allow_navigation",
default=False,
description="Allow navigation",
)
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
obj = context.active_object obj = context.active_object
return (obj is not None and obj.mode == 'EDIT') return (obj is not None and obj.mode == 'EDIT')
@staticmethod @staticmethod
def extrude_region(context, use_vert_normals, dissolve_and_intersect, allow_navigation): def extrude_region(context, use_vert_normals, dissolve_and_intersect):
mesh = context.object.data mesh = context.object.data
totface = mesh.total_face_sel totface = mesh.total_face_sel
@ -107,7 +95,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
bpy.ops.mesh.extrude_region_shrink_fatten( bpy.ops.mesh.extrude_region_shrink_fatten(
'INVOKE_REGION_WIN', 'INVOKE_REGION_WIN',
TRANSFORM_OT_shrink_fatten={ TRANSFORM_OT_shrink_fatten={
"allow_navigation": allow_navigation, "release_confirm": False,
}, },
) )
elif dissolve_and_intersect: elif dissolve_and_intersect:
@ -119,7 +107,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
TRANSFORM_OT_translate={ TRANSFORM_OT_translate={
"orient_type": 'NORMAL', "orient_type": 'NORMAL',
"constraint_axis": (False, False, True), "constraint_axis": (False, False, True),
"allow_navigation": allow_navigation, "release_confirm": False,
}, },
) )
else: else:
@ -128,7 +116,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
TRANSFORM_OT_translate={ TRANSFORM_OT_translate={
"orient_type": 'NORMAL', "orient_type": 'NORMAL',
"constraint_axis": (False, False, True), "constraint_axis": (False, False, True),
"allow_navigation": allow_navigation, "release_confirm": False,
}, },
) )
@ -142,13 +130,13 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
# Not a popular choice, too restrictive for retopo. # Not a popular choice, too restrictive for retopo.
# "constraint_axis": (True, True, False)}) # "constraint_axis": (True, True, False)})
"constraint_axis": (False, False, False), "constraint_axis": (False, False, False),
"allow_navigation": allow_navigation, "release_confirm": False,
}) })
else: else:
bpy.ops.mesh.extrude_region_move( bpy.ops.mesh.extrude_region_move(
'INVOKE_REGION_WIN', 'INVOKE_REGION_WIN',
TRANSFORM_OT_translate={ TRANSFORM_OT_translate={
"allow_navigation": allow_navigation, "release_confirm": False,
}, },
) )
@ -157,8 +145,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
return {'FINISHED'} return {'FINISHED'}
def execute(self, context): def execute(self, context):
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region( return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False, self.dissolve_and_intersect)
context, False, self.dissolve_and_intersect, self.allow_navigation)
def invoke(self, context, _event): def invoke(self, context, _event):
return self.execute(context) return self.execute(context)
@ -169,19 +156,13 @@ class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator):
bl_label = "Extrude and Move on Individual Normals" bl_label = "Extrude and Move on Individual Normals"
bl_idname = "view3d.edit_mesh_extrude_move_shrink_fatten" bl_idname = "view3d.edit_mesh_extrude_move_shrink_fatten"
allow_navigation: BoolProperty(
name="allow_navigation",
default=False,
description="Allow navigation",
)
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
obj = context.active_object obj = context.active_object
return (obj is not None and obj.mode == 'EDIT') return (obj is not None and obj.mode == 'EDIT')
def execute(self, context): def execute(self, context):
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True, False, self.allow_navigation) return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True, False)
def invoke(self, context, _event): def invoke(self, context, _event):
return self.execute(context) return self.execute(context)
@ -192,12 +173,6 @@ class VIEW3D_OT_edit_mesh_extrude_manifold_normal(Operator):
bl_label = "Extrude Manifold Along Normals" bl_label = "Extrude Manifold Along Normals"
bl_idname = "view3d.edit_mesh_extrude_manifold_normal" bl_idname = "view3d.edit_mesh_extrude_manifold_normal"
allow_navigation: BoolProperty(
name="allow_navigation",
default=False,
description="Allow navigation",
)
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
obj = context.active_object obj = context.active_object
@ -212,7 +187,7 @@ class VIEW3D_OT_edit_mesh_extrude_manifold_normal(Operator):
TRANSFORM_OT_translate={ TRANSFORM_OT_translate={
"orient_type": 'NORMAL', "orient_type": 'NORMAL',
"constraint_axis": (False, False, True), "constraint_axis": (False, False, True),
"allow_navigation": self.allow_navigation, "release_confirm": False,
}, },
) )
return {'FINISHED'} return {'FINISHED'}

View File

@ -513,8 +513,6 @@ class _defs_view3d_add:
row.label(text="Orientation:") row.label(text="Orientation:")
row = layout.row() row = layout.row()
row.prop(tool_settings, "plane_orientation", text="") row.prop(tool_settings, "plane_orientation", text="")
row = layout.row()
row.prop(tool_settings, "snap_elements_tool")
region_is_header = bpy.context.region.type == 'TOOL_HEADER' region_is_header = bpy.context.region.type == 'TOOL_HEADER'
if region_is_header: if region_is_header:

View File

@ -641,7 +641,7 @@ class VIEW3D_HT_header(Header):
icon = snap_items[elem].icon icon = snap_items[elem].icon
break break
else: else:
text = "Mix" text = "Multi"
icon = 'NONE' icon = 'NONE'
del snap_items, snap_elements del snap_items, snap_elements
@ -1049,14 +1049,10 @@ class VIEW3D_MT_transform_base:
# TODO: get rid of the custom text strings? # TODO: get rid of the custom text strings?
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
layout.operator("transform.translate").allow_navigation = allow_navigation layout.operator("transform.translate").release_confirm = False
layout.operator("transform.rotate").allow_navigation = allow_navigation layout.operator("transform.rotate").release_confirm = False
layout.operator("transform.resize", text="Scale").allow_navigation = allow_navigation layout.operator("transform.resize", text="Scale").release_confirm = False
layout.separator() layout.separator()
@ -1076,18 +1072,13 @@ class VIEW3D_MT_transform_base:
# Generic transform menu - geometry types # Generic transform menu - geometry types
class VIEW3D_MT_transform(VIEW3D_MT_transform_base, Menu): class VIEW3D_MT_transform(VIEW3D_MT_transform_base, Menu):
def draw(self, context): def draw(self, context):
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
# base menu # base menu
VIEW3D_MT_transform_base.draw(self, context) VIEW3D_MT_transform_base.draw(self, context)
# generic... # generic...
layout = self.layout layout = self.layout
if context.mode == 'EDIT_MESH': if context.mode == 'EDIT_MESH':
layout.operator("transform.shrink_fatten", text="Shrink/Fatten").allow_navigation = allow_navigation layout.operator("transform.shrink_fatten", text="Shrink/Fatten").release_confirm = False
layout.operator("transform.skin_resize") layout.operator("transform.skin_resize")
elif context.mode == 'EDIT_CURVE': elif context.mode == 'EDIT_CURVE':
layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN' layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
@ -1096,10 +1087,11 @@ class VIEW3D_MT_transform(VIEW3D_MT_transform_base, Menu):
layout.separator() layout.separator()
props = layout.operator("transform.translate", text="Move Texture Space") props = layout.operator("transform.translate", text="Move Texture Space")
props.texture_space = True props.texture_space = True
props.allow_navigation = allow_navigation props.release_confirm = False
props = layout.operator("transform.resize", text="Scale Texture Space") props = layout.operator("transform.resize", text="Scale Texture Space")
props.texture_space = True props.texture_space = True
props.allow_navigation = allow_navigation props.release_confirm = False
# Object-specific extensions to Transform menu # Object-specific extensions to Transform menu
@ -4209,11 +4201,6 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
col.operator("mesh.delete", text="Delete Edges").type = 'EDGE' col.operator("mesh.delete", text="Delete Edges").type = 'EDGE'
if is_face_mode: if is_face_mode:
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
col = row.column(align=True) col = row.column(align=True)
col.label(text="Face Context Menu", icon='FACESEL') col.label(text="Face Context Menu", icon='FACESEL')
@ -4225,11 +4212,11 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
col.separator() col.separator()
col.operator("view3d.edit_mesh_extrude_move_normal", col.operator("view3d.edit_mesh_extrude_move_normal",
text="Extrude Faces").allow_navigation = allow_navigation text="Extrude Faces").release_confirm = False
col.operator("view3d.edit_mesh_extrude_move_shrink_fatten", col.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
text="Extrude Faces Along Normals").allow_navigation = allow_navigation text="Extrude Faces Along Normals").release_confirm = False
col.operator("mesh.extrude_faces_move", col.operator("mesh.extrude_faces_move",
text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.allow_navigation = allow_navigation text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.release_confirm = False
col.operator("mesh.inset") col.operator("mesh.inset")
col.operator("mesh.poke") col.operator("mesh.poke")
@ -4281,11 +4268,6 @@ class VIEW3D_MT_edit_mesh_extrude(Menu):
def draw(self, context): def draw(self, context):
from math import pi from math import pi
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
layout = self.layout layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN' layout.operator_context = 'INVOKE_REGION_WIN'
@ -4295,22 +4277,22 @@ class VIEW3D_MT_edit_mesh_extrude(Menu):
if mesh.total_face_sel: if mesh.total_face_sel:
layout.operator("view3d.edit_mesh_extrude_move_normal", layout.operator("view3d.edit_mesh_extrude_move_normal",
text="Extrude Faces").allow_navigation = allow_navigation text="Extrude Faces").release_confirm = False
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
text="Extrude Faces Along Normals").allow_navigation = allow_navigation text="Extrude Faces Along Normals").release_confirm = False
layout.operator( layout.operator(
"mesh.extrude_faces_move", "mesh.extrude_faces_move",
text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.allow_navigation = allow_navigation text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.release_confirm = False
layout.operator("view3d.edit_mesh_extrude_manifold_normal", layout.operator("view3d.edit_mesh_extrude_manifold_normal",
text="Extrude Manifold").allow_navigation = allow_navigation text="Extrude Manifold").release_confirm = False
if mesh.total_edge_sel and (select_mode[0] or select_mode[1]): if mesh.total_edge_sel and (select_mode[0] or select_mode[1]):
layout.operator("mesh.extrude_edges_move", layout.operator("mesh.extrude_edges_move",
text="Extrude Edges").TRANSFORM_OT_translate.allow_navigation = allow_navigation text="Extrude Edges").TRANSFORM_OT_translate.release_confirm = False
if mesh.total_vert_sel and select_mode[0]: if mesh.total_vert_sel and select_mode[0]:
layout.operator("mesh.extrude_vertices_move", layout.operator("mesh.extrude_vertices_move",
text="Extrude Vertices").TRANSFORM_OT_translate.allow_navigation = allow_navigation text="Extrude Vertices").TRANSFORM_OT_translate.release_confirm = False
layout.separator() layout.separator()
@ -4463,22 +4445,17 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
bl_idname = "VIEW3D_MT_edit_mesh_faces" bl_idname = "VIEW3D_MT_edit_mesh_faces"
def draw(self, context): def draw(self, context):
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
layout = self.layout layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN' layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("view3d.edit_mesh_extrude_move_normal", layout.operator("view3d.edit_mesh_extrude_move_normal",
text="Extrude Faces").allow_navigation = allow_navigation text="Extrude Faces").release_confirm = False
layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten",
text="Extrude Faces Along Normals").allow_navigation = allow_navigation text="Extrude Faces Along Normals").release_confirm = False
layout.operator( layout.operator(
"mesh.extrude_faces_move", "mesh.extrude_faces_move",
text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.allow_navigation = allow_navigation text="Extrude Individual Faces").TRANSFORM_OT_shrink_fatten.release_confirm = False
layout.separator() layout.separator()

View File

@ -27,7 +27,7 @@ extern "C" {
/* Blender file format version. */ /* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION #define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 7 #define BLENDER_FILE_SUBVERSION 9
/* Minimum Blender version that supports reading file written with the current /* 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 * version. Older Blender versions will test this and show a warning if the file

View File

@ -78,7 +78,7 @@ typedef enum BVHCacheType {
BVHTREE_FROM_LOOSEVERTS, BVHTREE_FROM_LOOSEVERTS,
BVHTREE_FROM_LOOSEEDGES, BVHTREE_FROM_LOOSEEDGES,
BVHTREE_FROM_EM_VERTS, BVHTREE_FROM_EM_LOOSEVERTS,
BVHTREE_FROM_EM_EDGES, BVHTREE_FROM_EM_EDGES,
BVHTREE_FROM_EM_LOOPTRI, BVHTREE_FROM_EM_LOOPTRI,

View File

@ -618,7 +618,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
r_data->nearest_callback = mesh_looptri_nearest_point; r_data->nearest_callback = mesh_looptri_nearest_point;
r_data->raycast_callback = mesh_looptri_spherecast; r_data->raycast_callback = mesh_looptri_spherecast;
break; break;
case BVHTREE_FROM_EM_VERTS: case BVHTREE_FROM_EM_LOOSEVERTS:
case BVHTREE_FROM_EM_EDGES: case BVHTREE_FROM_EM_EDGES:
case BVHTREE_FROM_EM_LOOPTRI: case BVHTREE_FROM_EM_LOOPTRI:
case BVHTREE_MAX_ITEM: case BVHTREE_MAX_ITEM:
@ -639,7 +639,7 @@ static void bvhtree_from_editmesh_setup_data(BVHTree *tree,
r_data->em = em; r_data->em = em;
switch (bvh_cache_type) { switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS: case BVHTREE_FROM_EM_LOOSEVERTS:
r_data->nearest_callback = nullptr; r_data->nearest_callback = nullptr;
r_data->raycast_callback = editmesh_verts_spherecast; r_data->raycast_callback = editmesh_verts_spherecast;
break; break;
@ -754,7 +754,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
bvhtree_balance(tree, false); bvhtree_balance(tree, false);
if (data) { if (data) {
bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_VERTS, em, data); bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOSEVERTS, em, data);
} }
return tree; return tree;
@ -1223,7 +1223,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
0.0f, tree_type, 6, positions, corner_verts.data(), looptris, {}, -1); 0.0f, tree_type, 6, positions, corner_verts.data(), looptris, {}, -1);
break; break;
} }
case BVHTREE_FROM_EM_VERTS: case BVHTREE_FROM_EM_LOOSEVERTS:
case BVHTREE_FROM_EM_EDGES: case BVHTREE_FROM_EM_EDGES:
case BVHTREE_FROM_EM_LOOPTRI: case BVHTREE_FROM_EM_LOOPTRI:
case BVHTREE_MAX_ITEM: case BVHTREE_MAX_ITEM:
@ -1253,6 +1253,25 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
return data->tree; return data->tree;
} }
static BitVector<> bmverts_loose_map_get(BMesh *bm, int *r_bmvert_active_len)
{
BitVector<> bmvert_mask(bm->totvert);
int i, bmvert_loose_len = 0;
BMIter iter;
BMVert *v;
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
if (v->e == nullptr) {
bmvert_mask[i].set();
bmvert_loose_len++;
}
}
*r_bmvert_active_len = bmvert_loose_len;
return bmvert_mask;
}
BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data, BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
BMEditMesh *em, BMEditMesh *em,
const int tree_type, const int tree_type,
@ -1275,9 +1294,13 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
} }
switch (bvh_cache_type) { switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS: case BVHTREE_FROM_EM_LOOSEVERTS: {
data->tree = bvhtree_from_editmesh_verts_create_tree(0.0f, tree_type, 6, em, {}, -1); int mask_bits_act_len = -1;
const BitVector<> mask = bmverts_loose_map_get(em->bm, &mask_bits_act_len);
data->tree = bvhtree_from_editmesh_verts_create_tree(
0.0f, tree_type, 6, em, mask, mask_bits_act_len);
break; break;
}
case BVHTREE_FROM_EM_EDGES: case BVHTREE_FROM_EM_EDGES:
data->tree = bvhtree_from_editmesh_edges_create_tree(0.0f, tree_type, 6, em, {}, -1); data->tree = bvhtree_from_editmesh_edges_create_tree(0.0f, tree_type, 6, em, {}, -1);
break; break;

View File

@ -5749,8 +5749,8 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 281, 15)) { if (!MAIN_VERSION_ATLEAST(bmain, 281, 15)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->toolsettings->snap_node_mode == SCE_SNAP_MODE_NODE_X) { if (scene->toolsettings->snap_node_mode == SCE_SNAP_TO_NODE_X) {
scene->toolsettings->snap_node_mode = SCE_SNAP_MODE_GRID; scene->toolsettings->snap_node_mode = SCE_SNAP_TO_GRID;
} }
} }

View File

@ -4472,7 +4472,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 306, 10)) { if (!MAIN_VERSION_ATLEAST(bmain, 306, 10)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
/* Set default values for new members. */ /* Set default values for new members. */
scene->toolsettings->snap_mode_tools = SCE_SNAP_MODE_GEOM;
scene->toolsettings->plane_axis = 2; scene->toolsettings->plane_axis = 2;
} }
} }

View File

@ -10,6 +10,7 @@
#include "CLG_log.h" #include "CLG_log.h"
#include "DNA_defaults.h"
#include "DNA_lightprobe_types.h" #include "DNA_lightprobe_types.h"
#include "DNA_modifier_types.h" #include "DNA_modifier_types.h"
#include "DNA_movieclip_types.h" #include "DNA_movieclip_types.h"
@ -229,13 +230,10 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 400, 5)) { if (!MAIN_VERSION_ATLEAST(bmain, 400, 5)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *ts = scene->toolsettings; ToolSettings *ts = scene->toolsettings;
if (ts->snap_mode_tools != SCE_SNAP_MODE_NONE) {
ts->snap_mode_tools = SCE_SNAP_MODE_GEOM;
}
#define SCE_SNAP_PROJECT (1 << 3) #define SCE_SNAP_PROJECT (1 << 3)
if (ts->snap_flag & SCE_SNAP_PROJECT) { if (ts->snap_flag & SCE_SNAP_PROJECT) {
ts->snap_mode |= SCE_SNAP_MODE_FACE_RAYCAST; ts->snap_flag &= ~SCE_SNAP_PROJECT;
ts->snap_mode |= SCE_SNAP_INDIVIDUAL_PROJECT;
} }
#undef SCE_SNAP_PROJECT #undef SCE_SNAP_PROJECT
} }
@ -258,6 +256,15 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
} }
} }
if (!MAIN_VERSION_ATLEAST(bmain, 400, 8)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
const ToolSettings *ts_default = DNA_struct_default_get(ToolSettings);
ToolSettings *ts = scene->toolsettings;
ts->snap_mode = ts_default->snap_mode;
ts->snap_transform_mode_flag = ts_default->snap_transform_mode_flag;
}
}
/** /**
* Versioning code until next subversion bump goes here. * Versioning code until next subversion bump goes here.
* *

View File

@ -5609,7 +5609,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Curve *cu; Curve *cu;
float location[3]; float location[3];
const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) &&
(vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); (vc.scene->toolsettings->snap_mode == SCE_SNAP_TO_FACE));
Nurb *nu; Nurb *nu;
BezTriple *bezt; BezTriple *bezt;
@ -5641,7 +5641,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
vc.depsgraph, vc.depsgraph,
vc.region, vc.region,
vc.v3d, vc.v3d,
SCE_SNAP_MODE_FACE, SCE_SNAP_TO_FACE,
&(const struct SnapObjectParams){ &(const struct SnapObjectParams){
.snap_target_select = (vc.obedit != NULL) ? SCE_SNAP_TARGET_NOT_ACTIVE : .snap_target_select = (vc.obedit != NULL) ? SCE_SNAP_TARGET_NOT_ACTIVE :
SCE_SNAP_TARGET_ALL, SCE_SNAP_TARGET_ALL,

View File

@ -280,7 +280,7 @@ static int gizmo_move_modal(bContext *C,
CTX_data_ensure_evaluated_depsgraph(C), CTX_data_ensure_evaluated_depsgraph(C),
region, region,
CTX_wm_view3d(C), CTX_wm_view3d(C),
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE), (SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE),
&(const struct SnapObjectParams){ &(const struct SnapObjectParams){
.snap_target_select = SCE_SNAP_TARGET_ALL, .snap_target_select = SCE_SNAP_TARGET_ALL,
.edit_mode_type = SNAP_GEOM_EDIT, .edit_mode_type = SNAP_GEOM_EDIT,

View File

@ -96,7 +96,7 @@ void ED_gizmotypes_snap_3d_data_get(const bContext *C,
copy_v3_v3_int(r_elem_index, snap_data->elem_index); copy_v3_v3_int(r_elem_index, snap_data->elem_index);
} }
if (r_snap_elem) { if (r_snap_elem) {
*r_snap_elem = snap_data->snap_elem; *r_snap_elem = snap_data->type_target;
} }
} }
@ -171,6 +171,21 @@ static void gizmo_snap_rna_snap_elem_index_get_fn(PointerRNA *UNUSED(ptr),
copy_v3_v3_int(values, snap_data->elem_index); copy_v3_v3_int(values, snap_data->elem_index);
} }
static int gizmo_snap_rna_snap_srouce_type_get_fn(PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop))
{
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
return (int)snap_data->type_source;
}
static void gizmo_snap_rna_snap_srouce_type_set_fn(PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop),
const int value)
{
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
snap_data->type_source = (eSnapMode)value;
}
/** \} */ /** \} */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
@ -266,7 +281,7 @@ static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
ED_view3d_cursor_snap_data_update(snap_gizmo->snap_state, C, x, y); ED_view3d_cursor_snap_data_update(snap_gizmo->snap_state, C, x, y);
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
if (snap_data->snap_elem != SCE_SNAP_MODE_NONE) { if (snap_data->type_target != SCE_SNAP_TO_NONE) {
return 0; return 0;
} }
return -1; return -1;
@ -373,6 +388,15 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt)
INT_MAX); INT_MAX);
RNA_def_property_int_array_funcs_runtime( RNA_def_property_int_array_funcs_runtime(
prop, gizmo_snap_rna_snap_elem_index_get_fn, NULL, NULL); prop, gizmo_snap_rna_snap_elem_index_get_fn, NULL, NULL);
prop = RNA_def_enum(gzt->srna,
"snap_source_type",
rna_enum_snap_element_items,
SCE_SNAP_TO_NONE,
"Snap Source Type",
"Snap Source type (influences drawing)");
RNA_def_property_enum_funcs_runtime(
prop, gizmo_snap_rna_snap_srouce_type_get_fn, gizmo_snap_rna_snap_srouce_type_set_fn, NULL);
} }
void ED_gizmotypes_snap_3d(void) void ED_gizmotypes_snap_3d(void)

View File

@ -126,7 +126,6 @@ int BIF_countTransformOrientation(const struct bContext *C);
#define P_CURSOR_EDIT (1 << 16) #define P_CURSOR_EDIT (1 << 16)
#define P_CLNOR_INVALIDATE (1 << 17) #define P_CLNOR_INVALIDATE (1 << 17)
#define P_VIEW2D_EDGE_PAN (1 << 18) #define P_VIEW2D_EDGE_PAN (1 << 18)
#define P_VIEW3D_NAVIGATION (1 << 19)
/* For properties performed when confirming the transformation. */ /* For properties performed when confirming the transformation. */
#define P_POST_TRANSFORM (1 << 20) #define P_POST_TRANSFORM (1 << 20)

View File

@ -307,7 +307,8 @@ typedef enum {
} eV3DSnapCursor; } eV3DSnapCursor;
typedef struct V3DSnapCursorData { typedef struct V3DSnapCursorData {
eSnapMode snap_elem; eSnapMode type_source;
eSnapMode type_target;
float loc[3]; float loc[3];
float nor[3]; float nor[3];
float obmat[4][4]; float obmat[4][4];
@ -348,13 +349,14 @@ void ED_view3d_cursor_snap_data_update(V3DSnapCursorState *state,
int y); int y);
V3DSnapCursorData *ED_view3d_cursor_snap_data_get(void); V3DSnapCursorData *ED_view3d_cursor_snap_data_get(void);
struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(struct Scene *scene); struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(struct Scene *scene);
void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d, void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
const float loc_prev[3], const float source_loc[3],
const float loc_curr[3], const float target_loc[3],
const float normal[3], const float target_normal[3],
const eSnapMode source_type,
const eSnapMode target_type,
const uchar color_line[4], const uchar color_line[4],
const uchar color_point[4], const uchar color_point[4]);
eSnapMode snap_elem_type);
/* view3d_iterators.cc */ /* view3d_iterators.cc */

View File

@ -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 rot_src = RNA_boolean_get(op->ptr, "rotate_source");
const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) &&
(vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); (vc.scene->toolsettings->snap_mode == SCE_SNAP_TO_FACE));
/* First calculate the center of transformation. */ /* First calculate the center of transformation. */
zero_v3(center); zero_v3(center);

View File

@ -1951,7 +1951,7 @@ void EDBM_project_snap_verts(
depsgraph, depsgraph,
region, region,
CTX_wm_view3d(C), CTX_wm_view3d(C),
SCE_SNAP_MODE_FACE, SCE_SNAP_TO_FACE,
&params, &params,
nullptr, nullptr,
mval, mval,

View File

@ -25,12 +25,14 @@
#include "GPU_immediate.h" #include "GPU_immediate.h"
#include "GPU_matrix.h" #include "GPU_matrix.h"
#include "GPU_state.h"
#include "ED_screen.h" #include "ED_screen.h"
#include "ED_transform.h" #include "ED_transform.h"
#include "ED_transform_snap_object_context.h" #include "ED_transform_snap_object_context.h"
#include "ED_view3d.h" #include "ED_view3d.h"
#include "UI_interface_icons.h"
#include "UI_resources.h" #include "UI_resources.h"
#include "RNA_access.h" #include "RNA_access.h"
@ -366,52 +368,136 @@ static void cursor_box_draw(const float dimensions[3], uchar color[4])
GPU_blend(GPU_BLEND_NONE); GPU_blend(GPU_BLEND_NONE);
} }
void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d, static void cursor_x_draw(uint pos, float size)
const float loc_prev[3],
const float loc_curr[3],
const float normal[3],
const uchar color_line[4],
const uchar color_point[4],
const eSnapMode snap_elem_type)
{ {
if (!loc_prev && !loc_curr) { immBegin(GPU_PRIM_LINES, 4);
return; immVertex3f(pos, -size, -size, 0.0f);
} immVertex3f(pos, +size, +size, 0.0f);
immVertex3f(pos, -size, +size, 0.0f);
immVertex3f(pos, +size, -size, 0.0f);
immEnd();
}
float view_inv[4][4]; static void cursor_point_draw(uint attr_pos,
copy_m4_m4(view_inv, rv3d->viewinv); const float loc[3],
const float size,
eSnapMode snap_type,
int icon_id,
const uchar color[4])
{
immUniformColor4ubv(color);
/* The size of the circle is larger than the vertex size. #if 1
* This prevents a drawing overlaps the other. */ GPU_matrix_push();
float radius = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); float model_view[4][4];
GPU_matrix_model_view_get(model_view);
translate_m4(model_view, UNPACK3(loc));
copy_v3_fl3(model_view[0], size, 0.0f, 0.0f);
copy_v3_fl3(model_view[1], 0.0f, size, 0.0f);
copy_v3_fl3(model_view[2], 0.0f, 0.0f, size);
GPU_matrix_set(model_view);
if (loc_curr) { float size_b = 1.0f;
immUniformColor4ubv(color_point); switch (snap_type) {
imm_drawcircball(loc_curr, ED_view3d_pixel_size(rv3d, loc_curr) * radius, view_inv, pos); case SCE_SNAP_TO_POINT:
imm_draw_circle_wire_3d(attr_pos, 0.0f, 0.0f, 1.0f, 24);
/* draw normal if needed */ immBegin(GPU_PRIM_LINES, 4);
if (normal) { immVertex3f(attr_pos, -size_b, -size_b, 0.0f);
immBegin(GPU_PRIM_LINES, 2); immVertex3f(attr_pos, +size_b, +size_b, 0.0f);
immVertex3fv(pos, loc_curr); immVertex3f(attr_pos, -size_b, +size_b, 0.0f);
immVertex3f(pos, loc_curr[0] + normal[0], loc_curr[1] + normal[1], loc_curr[2] + normal[2]); immVertex3f(attr_pos, +size_b, -size_b, 0.0f);
immEnd(); immEnd();
} break;
case SCE_SNAP_TO_EDGE_ENDPOINT:
immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex3f(attr_pos, -size_b, -size_b, 0.0f);
immVertex3f(attr_pos, -size_b, +size_b, 0.0f);
immVertex3f(attr_pos, +size_b, +size_b, 0.0f);
immVertex3f(attr_pos, +size_b, -size_b, 0.0f);
immEnd();
break;
case SCE_SNAP_TO_EDGE_MIDPOINT:
immBegin(GPU_PRIM_LINE_LOOP, 3);
immVertex3f(attr_pos, -size_b, -size_b, 0.0f);
immVertex3f(attr_pos, 0.0f, 0.866f * size_b, 0.0f);
immVertex3f(attr_pos, +size_b, -size_b, 0.0f);
immEnd();
break;
case SCE_SNAP_TO_EDGE_PERPENDICULAR:
immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex3f(attr_pos, -size_b, +size_b, 0.0f);
immVertex3f(attr_pos, -size_b, -size_b, 0.0f);
immVertex3f(attr_pos, +size_b, -size_b, 0.0f);
immEnd();
immBegin(GPU_PRIM_LINE_STRIP, 3);
immVertex3f(attr_pos, -size_b, 0.0f, 0.0f);
immVertex3f(attr_pos, 0.0f, 0.0f, 0.0f);
immVertex3f(attr_pos, 0.0f, -size_b, 0.0f);
immEnd();
break;
case SCE_SNAP_TO_EDGE:
immBegin(GPU_PRIM_LINE_LOOP, 4);
immVertex3f(attr_pos, -size_b, -size_b, 0.0f);
immVertex3f(attr_pos, +size_b, +size_b, 0.0f);
immVertex3f(attr_pos, -size_b, +size_b, 0.0f);
immVertex3f(attr_pos, +size_b, -size_b, 0.0f);
immEnd();
break;
case SCE_SNAP_TO_FACE:
default:
imm_draw_circle_wire_3d(attr_pos, 0.0f, 0.0f, 1.0f, 24);
break;
} }
if (loc_prev) { if (false && icon_id != ICON_NONE) {
/* Draw an "X" indicating where the previous snap point is. float icon_size = 0.1f * size;
* This is useful for indicating perpendicular snap. */ copy_v3_fl3(model_view[0], icon_size, 0.0f, 0.0f);
copy_v3_fl3(model_view[1], 0.0f, icon_size, 0.0f);
copy_v3_fl3(model_view[2], 0.0f, 0.0f, icon_size);
model_view[3][0] += 10 * icon_size;
model_view[3][1] -= 25 * icon_size;
GPU_matrix_set(model_view);
/* v1, v2, v3 and v4 indicate the coordinates of the ends of the "X". */ GPU_blend(true);
UI_icon_draw_ex(0.0f, 0.0f, icon_id, 1.0f, 0.5f, 0.0f, color, false, UI_NO_ICON_OVERLAY_TEXT);
GPU_blend(false);
}
GPU_matrix_pop();
#else
if (snap_type & SCE_SNAP_MODE_EDGE_MIDPOINT) {
/* Draw a triangle. */
float v1[3], v2[3], v3[3], tmp[3];
float x_size = size;
mul_v3_v3fl(v1, view_inv[1], x_size);
mul_v3_v3fl(v2, v1, -0.5f);
mul_v3_v3fl(v3, v1, -0.5f);
mul_v3_v3fl(tmp, view_inv[0], 0.8f * x_size);
add_v3_v3(v2, tmp);
sub_v3_v3(v3, tmp);
add_v3_v3(v1, loc);
add_v3_v3(v2, loc);
add_v3_v3(v3, loc);
immBegin(GPU_PRIM_LINES, 6);
immVertex3fv(attr_pos, v1);
immVertex3fv(attr_pos, v2);
immVertex3fv(attr_pos, v2);
immVertex3fv(attr_pos, v3);
immVertex3fv(attr_pos, v3);
immVertex3fv(attr_pos, v1);
immEnd();
}
else if (snap_type & SCE_SNAP_MODE_VERTEX) {
/* Draw a rectangle. */
float vx[3], vy[3], v1[3], v2[3], v3[3], v4[4]; float vx[3], vy[3], v1[3], v2[3], v3[3], v4[4];
float x_size = 0.8f * size;
/* Multiply by 0.75f so that the final size of the "X" is close to that of
* the circle.
* (A closer value is 0.7071f, but we don't need to be exact here). */
float x_size = 0.75f * radius * ED_view3d_pixel_size(rv3d, loc_prev);
mul_v3_v3fl(vx, view_inv[0], x_size); mul_v3_v3fl(vx, view_inv[0], x_size);
mul_v3_v3fl(vy, view_inv[1], x_size); mul_v3_v3fl(vy, view_inv[1], x_size);
@ -421,20 +507,133 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
negate_v3_v3(v3, v1); negate_v3_v3(v3, v1);
negate_v3_v3(v4, v2); negate_v3_v3(v4, v2);
add_v3_v3(v1, loc_prev); add_v3_v3(v1, loc);
add_v3_v3(v2, loc_prev); add_v3_v3(v2, loc);
add_v3_v3(v3, loc_prev); add_v3_v3(v3, loc);
add_v3_v3(v4, loc_prev); add_v3_v3(v4, loc);
immUniformColor4ubv(color_line); immBegin(GPU_PRIM_LINES, 8);
immBegin(GPU_PRIM_LINES, 4); immVertex3fv(attr_pos, v1);
immVertex3fv(pos, v3); immVertex3fv(attr_pos, v2);
immVertex3fv(pos, v1); immVertex3fv(attr_pos, v2);
immVertex3fv(pos, v4); immVertex3fv(attr_pos, v3);
immVertex3fv(pos, v2); immVertex3fv(attr_pos, v3);
immVertex3fv(attr_pos, v4);
immVertex3fv(attr_pos, v4);
immVertex3fv(attr_pos, v1);
immEnd(); immEnd();
}
else if (snap_type & SCE_SNAP_MODE_EDGE) {
/* Draw an "X". */
float vx[3], vy[3], v1[3], v2[3], v3[3], v4[4];
float x_size = 0.8f * size;
if (loc_curr && (snap_elem_type & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { mul_v3_v3fl(vx, view_inv[0], x_size);
mul_v3_v3fl(vy, view_inv[1], x_size);
add_v3_v3v3(v1, vx, vy);
sub_v3_v3v3(v2, vx, vy);
negate_v3_v3(v3, v1);
negate_v3_v3(v4, v2);
add_v3_v3(v1, loc);
add_v3_v3(v2, loc);
add_v3_v3(v3, loc);
add_v3_v3(v4, loc);
immBegin(GPU_PRIM_LINES, 4);
immVertex3fv(attr_pos, v3);
immVertex3fv(attr_pos, v1);
immVertex3fv(attr_pos, v4);
immVertex3fv(attr_pos, v2);
immEnd();
}
else {
imm_drawcircball(loc, size, view_inv, attr_pos);
}
#endif
}
void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
const float source_loc[3],
const float target_loc[3],
const float target_normal[3],
const eSnapMode source_type,
const eSnapMode target_type,
const uchar color_line[4],
const uchar color_point[4])
{
if (!source_loc && !target_loc) {
return;
}
float view_inv[4][4];
copy_m4_m4(view_inv, rv3d->viewinv);
/* The size of the symbol is larger than the vertex size.
* This prevents overlaps. */
float radius = 3.2f * UI_GetThemeValuef(TH_VERTEX_SIZE);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
GPU_line_width(1.5f);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (target_loc) {
int icon_id = ICON_NONE;
switch (target_type) {
case SCE_SNAP_TO_POINT:
case SCE_SNAP_TO_EDGE_ENDPOINT:
icon_id = ICON_SNAP_VERTEX;
break;
case SCE_SNAP_TO_EDGE:
icon_id = ICON_SNAP_EDGE;
break;
case SCE_SNAP_TO_FACE:
icon_id = ICON_SNAP_FACE;
break;
case SCE_SNAP_TO_VOLUME:
icon_id = ICON_SNAP_VOLUME;
break;
case SCE_SNAP_TO_EDGE_MIDPOINT:
icon_id = ICON_SNAP_MIDPOINT;
break;
case SCE_SNAP_TO_EDGE_PERPENDICULAR:
icon_id = ICON_SNAP_PERPENDICULAR;
break;
default:
break;
}
cursor_point_draw(pos,
target_loc,
radius * ED_view3d_pixel_size(rv3d, target_loc),
target_type,
icon_id,
color_point);
/* Draw normal if needed. */
if (target_normal) {
immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, target_loc);
immVertex3f(pos,
target_loc[0] + target_normal[0],
target_loc[1] + target_normal[1],
target_loc[2] + target_normal[2]);
immEnd();
}
}
if (source_loc) {
cursor_point_draw(pos,
source_loc,
radius * ED_view3d_pixel_size(rv3d, source_loc),
source_type,
ICON_NONE,
color_line);
if (target_loc && (target_type & SCE_SNAP_TO_EDGE_PERPENDICULAR)) {
/* Dashed line. */ /* Dashed line. */
immUnbindProgram(); immUnbindProgram();
@ -447,12 +646,14 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
immUniformColor4ubv(color_line); immUniformColor4ubv(color_line);
immBegin(GPU_PRIM_LINES, 2); immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, loc_prev); immVertex3fv(pos, source_loc);
immVertex3fv(pos, loc_curr); immVertex3fv(pos, target_loc);
immEnd(); immEnd();
} }
} }
GPU_line_smooth(false);
GPU_blend(GPU_BLEND_NONE);
immUnbindProgram(); immUnbindProgram();
} }
@ -550,8 +751,11 @@ static bool v3d_cursor_is_snap_invert(SnapCursorDataIntern *data_intern, const w
static eSnapMode v3d_cursor_snap_elements(ToolSettings *tool_settings) static eSnapMode v3d_cursor_snap_elements(ToolSettings *tool_settings)
{ {
return tool_settings->snap_mode_tools == SCE_SNAP_MODE_NONE ? tool_settings->snap_mode : eSnapMode snap_mode = tool_settings->snap_mode & SCE_SNAP_TO_GEOM;
tool_settings->snap_mode_tools; if (snap_mode == SCE_SNAP_TO_NONE) {
snap_mode = SCE_SNAP_TO_GEOM;
}
return snap_mode;
} }
static void v3d_cursor_snap_context_ensure(Scene *scene) static void v3d_cursor_snap_context_ensure(Scene *scene)
@ -597,7 +801,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
const bool calc_plane_omat = v3d_cursor_snap_calc_plane(); const bool calc_plane_omat = v3d_cursor_snap_calc_plane();
float co[3], no[3], face_nor[3], obmat[4][4], omat[3][3]; float co[3], no[3], face_nor[3], obmat[4][4], omat[3][3];
eSnapMode snap_elem = SCE_SNAP_MODE_NONE; eSnapMode snap_elem = SCE_SNAP_TO_NONE;
eSnapMode snap_elements = v3d_cursor_snap_elements(tool_settings); eSnapMode snap_elements = v3d_cursor_snap_elements(tool_settings);
int snap_elem_index[3] = {-1, -1, -1}; int snap_elem_index[3] = {-1, -1, -1};
int index = -1; int index = -1;
@ -610,10 +814,10 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
if (use_surface_nor || use_surface_co) { if (use_surface_nor || use_surface_co) {
v3d_cursor_snap_context_ensure(scene); v3d_cursor_snap_context_ensure(scene);
data_intern->snap_elem_hidden = SCE_SNAP_MODE_NONE; data_intern->snap_elem_hidden = SCE_SNAP_TO_NONE;
if (calc_plane_omat && !(snap_elements & SCE_SNAP_MODE_FACE)) { if (calc_plane_omat && !(snap_elements & SCE_SNAP_TO_FACE)) {
data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE; data_intern->snap_elem_hidden = SCE_SNAP_TO_FACE;
snap_elements |= SCE_SNAP_MODE_FACE; snap_elements |= SCE_SNAP_TO_FACE;
} }
snap_data->is_enabled = true; snap_data->is_enabled = true;
@ -625,21 +829,21 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
if (snap_data->is_snap_invert != !(ts->snap_flag & SCE_SNAP)) { if (snap_data->is_snap_invert != !(ts->snap_flag & SCE_SNAP)) {
snap_data->is_enabled = false; snap_data->is_enabled = false;
if (!calc_plane_omat) { if (!calc_plane_omat) {
snap_data->snap_elem = SCE_SNAP_MODE_NONE; snap_data->type_target = SCE_SNAP_TO_NONE;
return; return;
} }
snap_elements = data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE; snap_elements = data_intern->snap_elem_hidden = SCE_SNAP_TO_FACE;
} }
} }
#endif #endif
if (snap_elements & SCE_SNAP_MODE_GEOM) { if (snap_elements & SCE_SNAP_TO_GEOM) {
float prev_co[3] = {0.0f}; float prev_co[3] = {0.0f};
if (state->prevpoint) { if (state->prevpoint) {
copy_v3_v3(prev_co, state->prevpoint); copy_v3_v3(prev_co, state->prevpoint);
} }
else { else {
snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR; snap_elements &= ~SCE_SNAP_TO_EDGE_PERPENDICULAR;
} }
eSnapEditType edit_mode_type = (state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL) ? eSnapEditType edit_mode_type = (state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL) ?
@ -684,7 +888,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
if (calc_plane_omat) { if (calc_plane_omat) {
RegionView3D *rv3d = region->regiondata; RegionView3D *rv3d = region->regiondata;
bool orient_surface = use_surface_nor && (snap_elem != SCE_SNAP_MODE_NONE); bool orient_surface = use_surface_nor && (snap_elem != SCE_SNAP_TO_NONE);
if (orient_surface) { if (orient_surface) {
copy_m3_m4(omat, obmat); copy_m3_m4(omat, obmat);
} }
@ -713,7 +917,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
/* Negate the face normal according to the view. */ /* Negate the face normal according to the view. */
float ray_dir[3]; float ray_dir[3];
if (rv3d->is_persp) { if (rv3d->is_persp) {
BLI_assert_msg(snap_elem != SCE_SNAP_MODE_NONE, BLI_assert_msg(snap_elem != SCE_SNAP_TO_NONE,
"Use of variable `co` without it being computed"); "Use of variable `co` without it being computed");
sub_v3_v3v3(ray_dir, co, rv3d->viewinv[3]); /* No need to normalize. */ sub_v3_v3v3(ray_dir, co, rv3d->viewinv[3]); /* No need to normalize. */
@ -737,12 +941,12 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
} }
if (!use_surface_co) { if (!use_surface_co) {
snap_elem = SCE_SNAP_MODE_NONE; snap_elem = SCE_SNAP_TO_NONE;
} }
float *co_depth = (snap_elem != SCE_SNAP_MODE_NONE) ? co : scene->cursor.location; float *co_depth = (snap_elem != SCE_SNAP_TO_NONE) ? co : scene->cursor.location;
snap_elem &= ~data_intern->snap_elem_hidden; snap_elem &= ~data_intern->snap_elem_hidden;
if (snap_elem == SCE_SNAP_MODE_NONE) { if (snap_elem == SCE_SNAP_TO_NONE) {
RegionView3D *rv3d = region->regiondata; RegionView3D *rv3d = region->regiondata;
const float *plane_normal = omat[tool_settings->plane_axis]; const float *plane_normal = omat[tool_settings->plane_axis];
bool do_plane_isect = (tool_settings->plane_depth != V3D_PLACE_DEPTH_CURSOR_VIEW) && bool do_plane_isect = (tool_settings->plane_depth != V3D_PLACE_DEPTH_CURSOR_VIEW) &&
@ -759,23 +963,23 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
ED_view3d_win_to_3d(v3d, region, co_depth, mval_fl, co); ED_view3d_win_to_3d(v3d, region, co_depth, mval_fl, co);
} }
if (snap_data->is_enabled && (snap_elements & SCE_SNAP_MODE_INCREMENT)) { if (snap_data->is_enabled && (snap_elements & SCE_SNAP_TO_INCREMENT)) {
v3d_cursor_snap_calc_incremental(scene, v3d, region, state->prevpoint, co); v3d_cursor_snap_calc_incremental(scene, v3d, region, state->prevpoint, co);
} }
} }
else if (snap_elem == SCE_SNAP_MODE_VERTEX) { else if (snap_elem & SCE_SNAP_TO_VERTEX) {
snap_elem_index[0] = index; snap_elem_index[0] = index;
} }
else if (snap_elem & else if (snap_elem &
(SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT | SCE_SNAP_TO_EDGE_PERPENDICULAR))
{ {
snap_elem_index[1] = index; snap_elem_index[1] = index;
} }
else if (snap_elem == SCE_SNAP_MODE_FACE) { else if (snap_elem == SCE_SNAP_TO_FACE) {
snap_elem_index[2] = index; snap_elem_index[2] = index;
} }
snap_data->snap_elem = snap_elem; snap_data->type_target = snap_elem;
copy_v3_v3(snap_data->loc, co); copy_v3_v3(snap_data->loc, co);
copy_v3_v3(snap_data->nor, no); copy_v3_v3(snap_data->nor, no);
copy_m4_m4(snap_data->obmat, obmat); copy_m4_m4(snap_data->obmat, obmat);
@ -853,7 +1057,7 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust
} }
const bool draw_plane = state->draw_plane || state->draw_box; const bool draw_plane = state->draw_plane || state->draw_box;
if (snap_data->snap_elem == SCE_SNAP_MODE_NONE && !draw_plane) { if (snap_data->type_target == SCE_SNAP_TO_NONE && !draw_plane) {
return; return;
} }
@ -871,21 +1075,19 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust
v3d_cursor_plane_draw(rv3d, scene->toolsettings->plane_axis, matrix); v3d_cursor_plane_draw(rv3d, scene->toolsettings->plane_axis, matrix);
} }
if (snap_data->snap_elem != SCE_SNAP_MODE_NONE && (state->draw_point || state->draw_box)) { if (snap_data->type_target != SCE_SNAP_TO_NONE && (state->draw_point || state->draw_box)) {
const float *prev_point = (snap_data->snap_elem & SCE_SNAP_MODE_EDGE_PERPENDICULAR) ? const float *source_loc = (snap_data->type_target & SCE_SNAP_TO_EDGE_PERPENDICULAR) ?
state->prevpoint : state->prevpoint :
NULL; NULL;
GPU_line_smooth(false);
GPU_line_width(1.0f);
ED_view3d_cursor_snap_draw_util(rv3d, ED_view3d_cursor_snap_draw_util(rv3d,
prev_point, source_loc,
snap_data->loc, snap_data->loc,
NULL, NULL,
snap_data->type_source,
snap_data->type_target,
state->color_line, state->color_line,
state->color_point, state->color_point);
snap_data->snap_elem);
} }
if (state->draw_box) { if (state->draw_box) {

View File

@ -911,7 +911,7 @@ void ED_view3d_cursor3d_position_rotation(bContext *C,
CTX_data_ensure_evaluated_depsgraph(C), CTX_data_ensure_evaluated_depsgraph(C),
region, region,
v3d, v3d,
SCE_SNAP_MODE_FACE, SCE_SNAP_TO_FACE,
&(const struct SnapObjectParams){ &(const struct SnapObjectParams){
.snap_target_select = SCE_SNAP_TARGET_ALL, .snap_target_select = SCE_SNAP_TARGET_ALL,
.edit_mode_type = SNAP_GEOM_FINAL, .edit_mode_type = SNAP_GEOM_FINAL,

View File

@ -153,7 +153,8 @@ struct RulerInfo {
struct { struct {
wmGizmo *gizmo; wmGizmo *gizmo;
PropertyRNA *prop_prevpoint; PropertyRNA *prop_snap_source;
PropertyRNA *prop_snap_source_type;
} snap_data; } snap_data;
}; };
@ -168,6 +169,7 @@ struct RulerItem {
int flag; int flag;
int raycast_dir; /* RULER_DIRECTION_* */ int raycast_dir; /* RULER_DIRECTION_* */
eSnapMode snap_type[3];
}; };
struct RulerInteraction { struct RulerInteraction {
@ -314,7 +316,7 @@ static void ruler_state_set(RulerInfo *ruler_info, int state)
if (state == RULER_STATE_NORMAL) { if (state == RULER_STATE_NORMAL) {
WM_gizmo_set_flag(ruler_info->snap_data.gizmo, WM_GIZMO_DRAW_VALUE, false); WM_gizmo_set_flag(ruler_info->snap_data.gizmo, WM_GIZMO_DRAW_VALUE, false);
RNA_property_float_set_array( RNA_property_float_set_array(
ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint, nullptr); ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_snap_source, nullptr);
} }
else if (state == RULER_STATE_DRAG) { else if (state == RULER_STATE_DRAG) {
memset(&ruler_info->drag_state_prev, 0x0, sizeof(ruler_info->drag_state_prev)); memset(&ruler_info->drag_state_prev, 0x0, sizeof(ruler_info->drag_state_prev));
@ -356,6 +358,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
if (ruler_item) { if (ruler_item) {
RulerInteraction *inter = static_cast<RulerInteraction *>(ruler_item->gz.interaction_data); RulerInteraction *inter = static_cast<RulerInteraction *>(ruler_item->gz.interaction_data);
float3 &co = ruler_item->co[inter->co_index]; float3 &co = ruler_item->co[inter->co_index];
eSnapMode *snap_source_type = &ruler_item->snap_type[inter->co_index];
/* restore the initial depth */ /* restore the initial depth */
co = inter->drag_start_co; co = inter->drag_start_co;
view3d_ruler_item_project(ruler_info, co, mval); view3d_ruler_item_project(ruler_info, co, mval);
@ -376,7 +379,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
depsgraph, depsgraph,
ruler_info->region, ruler_info->region,
v3d, v3d,
SCE_SNAP_MODE_FACE, SCE_SNAP_TO_FACE,
&snap_object_params, &snap_object_params,
nullptr, nullptr,
mval_fl, mval_fl,
@ -402,25 +405,31 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
View3D *v3d = static_cast<View3D *>(ruler_info->area->spacedata.first); View3D *v3d = static_cast<View3D *>(ruler_info->area->spacedata.first);
if (do_snap) { if (do_snap) {
float3 *prev_point = nullptr; float3 *prev_point = nullptr;
eSnapMode snap_type;
BLI_assert(ED_gizmotypes_snap_3d_is_enabled(snap_gizmo)); BLI_assert(ED_gizmotypes_snap_3d_is_enabled(snap_gizmo));
if (inter->co_index != 1) { if (inter->co_index != 1) {
if (ruler_item->flag & RULERITEM_USE_ANGLE) { if (ruler_item->flag & RULERITEM_USE_ANGLE) {
prev_point = &ruler_item->co[1]; prev_point = &ruler_item->co[1];
snap_type = ruler_item->snap_type[1];
} }
else if (inter->co_index == 0) { else if (inter->co_index == 0) {
prev_point = &ruler_item->co[2]; prev_point = &ruler_item->co[2];
snap_type = ruler_item->snap_type[2];
} }
else { else {
prev_point = &ruler_item->co[0]; prev_point = &ruler_item->co[0];
snap_type = ruler_item->snap_type[0];
} }
} }
if (prev_point != nullptr) { if (prev_point != nullptr) {
RNA_property_float_set_array( RNA_property_float_set_array(
snap_gizmo->ptr, ruler_info->snap_data.prop_prevpoint, *prev_point); snap_gizmo->ptr, ruler_info->snap_data.prop_snap_source, *prev_point);
RNA_property_enum_set(
snap_gizmo->ptr, ruler_info->snap_data.prop_snap_source_type, snap_type);
} }
ED_gizmotypes_snap_3d_data_get(C, snap_gizmo, co, nullptr, nullptr, nullptr); ED_gizmotypes_snap_3d_data_get(C, snap_gizmo, co, nullptr, nullptr, snap_source_type);
} }
#ifdef USE_AXIS_CONSTRAINTS #ifdef USE_AXIS_CONSTRAINTS
@ -1154,22 +1163,29 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
{ {
/* Set Snap prev point. */ /* Set Snap prev point. */
float3 *prev_point; float3 *prev_point;
eSnapMode snap_type;
if (ruler_item_pick->flag & RULERITEM_USE_ANGLE) { if (ruler_item_pick->flag & RULERITEM_USE_ANGLE) {
prev_point = (inter->co_index != 1) ? &ruler_item_pick->co[1] : nullptr; prev_point = (inter->co_index != 1) ? &ruler_item_pick->co[1] : nullptr;
snap_type = (inter->co_index != 1) ? ruler_item_pick->snap_type[1] : SCE_SNAP_TO_VERTEX;
} }
else if (inter->co_index == 0) { else if (inter->co_index == 0) {
prev_point = &ruler_item_pick->co[2]; prev_point = &ruler_item_pick->co[2];
snap_type = ruler_item_pick->snap_type[2];
} }
else { else {
prev_point = &ruler_item_pick->co[0]; prev_point = &ruler_item_pick->co[0];
snap_type = ruler_item_pick->snap_type[2];
} }
if (prev_point) { if (prev_point) {
RNA_property_float_set_array( RNA_property_float_set_array(
ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint, *prev_point); ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_snap_source, *prev_point);
RNA_property_enum_set(ruler_info->snap_data.gizmo->ptr,
ruler_info->snap_data.prop_snap_source_type,
snap_type);
} }
else { else {
RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint); RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_snap_source);
} }
} }
@ -1185,7 +1201,7 @@ static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel)
if (!cancel) { if (!cancel) {
if (ruler_info->state == RULER_STATE_DRAG) { if (ruler_info->state == RULER_STATE_DRAG) {
RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint); RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_snap_source);
ruler_state_set(ruler_info, RULER_STATE_NORMAL); ruler_state_set(ruler_info, RULER_STATE_NORMAL);
} }
/* We could convert only the current gizmo, for now just re-generate. */ /* We could convert only the current gizmo, for now just re-generate. */
@ -1259,7 +1275,9 @@ static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *gzgroup)
ruler_info->area = area; ruler_info->area = area;
ruler_info->region = region; ruler_info->region = region;
ruler_info->snap_data.gizmo = gizmo; ruler_info->snap_data.gizmo = gizmo;
ruler_info->snap_data.prop_prevpoint = RNA_struct_find_property(gizmo->ptr, "prev_point"); ruler_info->snap_data.prop_snap_source = RNA_struct_find_property(gizmo->ptr, "prev_point");
ruler_info->snap_data.prop_snap_source_type = RNA_struct_find_property(gizmo->ptr,
"snap_source_type");
gzgroup->customdata = ruler_info; gzgroup->customdata = ruler_info;
} }
@ -1340,8 +1358,11 @@ static int view3d_ruler_add_invoke(bContext *C, wmOperator *op, const wmEvent *e
view3d_ruler_item_mousemove(C, depsgraph, ruler_info, ruler_item, mval, false, do_snap); view3d_ruler_item_mousemove(C, depsgraph, ruler_info, ruler_item, mval, false, do_snap);
copy_v3_v3(inter->drag_start_co, ruler_item->co[inter->co_index]); copy_v3_v3(inter->drag_start_co, ruler_item->co[inter->co_index]);
RNA_property_float_set_array(ruler_info->snap_data.gizmo->ptr, RNA_property_float_set_array(ruler_info->snap_data.gizmo->ptr,
ruler_info->snap_data.prop_prevpoint, ruler_info->snap_data.prop_snap_source,
inter->drag_start_co); inter->drag_start_co);
RNA_property_enum_set(ruler_info->snap_data.gizmo->ptr,
ruler_info->snap_data.prop_snap_source_type,
ruler_item->snap_type[inter->co_index]);
copy_v3_v3(ruler_item->co[2], ruler_item->co[0]); copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
ruler_item->gz.highlight_part = inter->co_index = 2; ruler_item->gz.highlight_part = inter->co_index = 2;

View File

@ -690,7 +690,7 @@ static bool view3d_interactive_add_calc_snap(bContext *UNUSED(C),
if (r_is_snap_invert) { if (r_is_snap_invert) {
*r_is_snap_invert = snap_data->is_snap_invert; *r_is_snap_invert = snap_data->is_snap_invert;
} }
return snap_data->snap_elem != SCE_SNAP_MODE_NONE; return snap_data->type_target != SCE_SNAP_TO_NONE;
} }
/** \} */ /** \} */
@ -761,9 +761,9 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
ipd->step_index = STEP_BASE; ipd->step_index = STEP_BASE;
ipd->snap_to = tool_settings->snap_mode_tools; ipd->snap_to = tool_settings->snap_mode & SCE_SNAP_TO_GEOM;
if (ipd->snap_to == SCE_SNAP_MODE_NONE) { if (ipd->snap_to == SCE_SNAP_TO_NONE) {
ipd->snap_to = tool_settings->snap_mode; ipd->snap_to = SCE_SNAP_TO_GEOM;
} }
plane_from_point_normal_v3(ipd->step[0].plane, ipd->co_src, ipd->matrix_orient[plane_axis]); plane_from_point_normal_v3(ipd->step[0].plane, ipd->co_src, ipd->matrix_orient[plane_axis]);
@ -1204,7 +1204,7 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
/* pass */ /* pass */
} }
if (ipd->use_snap && (ipd->snap_to & SCE_SNAP_MODE_INCREMENT)) { if (ipd->use_snap && (ipd->snap_to & SCE_SNAP_TO_INCREMENT)) {
if (idp_snap_calc_incremental( if (idp_snap_calc_incremental(
ipd->scene, ipd->v3d, ipd->region, ipd->co_src, ipd->step[STEP_BASE].co_dst)) ipd->scene, ipd->v3d, ipd->region, ipd->co_src, ipd->step[STEP_BASE].co_dst))
{ {
@ -1228,7 +1228,7 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
/* pass */ /* pass */
} }
if (ipd->use_snap && (ipd->snap_to & SCE_SNAP_MODE_INCREMENT)) { if (ipd->use_snap && (ipd->snap_to & SCE_SNAP_TO_INCREMENT)) {
if (idp_snap_calc_incremental( if (idp_snap_calc_incremental(
ipd->scene, ipd->v3d, ipd->region, ipd->co_src, ipd->step[STEP_DEPTH].co_dst)) ipd->scene, ipd->v3d, ipd->region, ipd->co_src, ipd->step[STEP_DEPTH].co_dst))
{ {

View File

@ -577,7 +577,7 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
if (t->spacetype != SPACE_VIEW3D) { if (t->spacetype != SPACE_VIEW3D) {
return false; return false;
} }
if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) { if ((t->tsnap.mode & ~(SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID)) == 0) {
return false; return false;
} }
if (value == TFM_MODAL_ADD_SNAP) { if (value == TFM_MODAL_ADD_SNAP) {
@ -1659,7 +1659,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
if ((prop = RNA_struct_find_property(op->ptr, "snap_elements"))) { if ((prop = RNA_struct_find_property(op->ptr, "snap_elements"))) {
RNA_property_enum_set(op->ptr, prop, t->tsnap.mode); RNA_property_enum_set(op->ptr, prop, t->tsnap.mode);
RNA_boolean_set( RNA_boolean_set(
op->ptr, "use_snap_project", (t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST) != 0); op->ptr, "use_snap_project", (t->tsnap.mode & SCE_SNAP_INDIVIDUAL_PROJECT) != 0);
RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_operation); RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_operation);
eSnapTargetOP target = t->tsnap.target_operation; eSnapTargetOP target = t->tsnap.target_operation;

View File

@ -302,7 +302,8 @@ typedef struct TransSnap {
short face_nearest_steps; short face_nearest_steps;
eTSnap status; eTSnap status;
/* Snapped Element Type (currently for objects only). */ /* Snapped Element Type (currently for objects only). */
eSnapMode snapElem; eSnapMode source_type;
eSnapMode target_type;
/** snapping from this point (in global-space). */ /** snapping from this point (in global-space). */
float snap_source[3]; float snap_source[3];
/** to this point (in global-space). */ /** to this point (in global-space). */

View File

@ -399,11 +399,11 @@ static void applyAxisConstraintVec(const TransInfo *t,
if (transform_snap_is_active(t)) { if (transform_snap_is_active(t)) {
if (validSnap(t)) { if (validSnap(t)) {
is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0; is_snap_to_edge = (t->tsnap.target_type & SCE_SNAP_TO_EDGE) != 0;
is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0; is_snap_to_face = (t->tsnap.target_type & SCE_SNAP_TO_FACE) != 0;
is_snap_to_point = !is_snap_to_edge && !is_snap_to_face; is_snap_to_point = !is_snap_to_edge && !is_snap_to_face;
} }
else if (t->tsnap.snapElem & SCE_SNAP_MODE_GRID) { else if (t->tsnap.target_type & SCE_SNAP_TO_GRID) {
is_snap_to_point = true; is_snap_to_point = true;
} }
} }

View File

@ -154,8 +154,7 @@ static void node_snap_grid_apply(TransInfo *t)
using namespace blender; using namespace blender;
if (!(transform_snap_is_active(t) && if (!(transform_snap_is_active(t) &&
(t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) (t->tsnap.mode & (SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID)))) {
{
return; return;
} }

View File

@ -658,9 +658,14 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->flag |= T_NO_CURSOR_WRAP; t->flag |= T_NO_CURSOR_WRAP;
} }
if (op && (t->flag & T_MODAL) && if (op && (t->flag & T_MODAL) && !(t->flag & T_RELEASE_CONFIRM) &&
(prop = RNA_struct_find_property(op->ptr, "allow_navigation")) && ELEM(t->mode,
RNA_property_boolean_get(op->ptr, prop)) TFM_TRANSLATION,
TFM_RESIZE,
TFM_ROTATION,
TFM_SHRINKFATTEN,
TFM_EDGE_SLIDE,
TFM_VERT_SLIDE))
{ {
t->vod = ED_view3d_navigation_init(C); t->vod = ED_view3d_navigation_init(C);
} }

View File

@ -204,7 +204,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
#else #else
/* hrmf, snapping radius is using 'angle' steps, need to convert to something else /* hrmf, snapping radius is using 'angle' steps, need to convert to something else
* this isn't essential but nicer to give reasonable snapping values for radius. */ * this isn't essential but nicer to give reasonable snapping values for radius. */
if (t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) { if (t->tsnap.mode & SCE_SNAP_TO_INCREMENT) {
const float radius_snap = 0.1f; const float radius_snap = 0.1f;
const float snap_hack = (t->snap[0] * bend_data->warp_init_dist) / radius_snap; const float snap_hack = (t->snap[0] * bend_data->warp_init_dist) / radius_snap;
values.scale *= snap_hack; values.scale *= snap_hack;

View File

@ -1294,11 +1294,11 @@ static void edge_slide_snap_apply(TransInfo *t, float *value)
side_index = t_snap >= t_mid; side_index = t_snap >= t_mid;
} }
if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE)) { if (t->tsnap.target_type & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE)) {
float co_dir[3]; float co_dir[3];
sub_v3_v3v3(co_dir, co_dest[side_index], co_orig); sub_v3_v3v3(co_dir, co_dest[side_index], co_orig);
normalize_v3(co_dir); normalize_v3(co_dir);
if (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) { if (t->tsnap.target_type & SCE_SNAP_TO_EDGE) {
transform_constraint_snap_axis_to_edge(t, co_dir, dvec); transform_constraint_snap_axis_to_edge(t, co_dir, dvec);
} }
else { else {

View File

@ -75,6 +75,11 @@ static void snapsource_confirm(TransInfo *t)
getSnapPoint(t, t->tsnap.snap_source); getSnapPoint(t, t->tsnap.snap_source);
t->tsnap.snap_source_fn = NULL; t->tsnap.snap_source_fn = NULL;
t->tsnap.status |= SNAP_SOURCE_FOUND; t->tsnap.status |= SNAP_SOURCE_FOUND;
if (!(t->tsnap.status & SNAP_MULTI_POINTS)) {
t->tsnap.source_type = t->tsnap.target_type;
}
t->flag |= T_DRAW_SNAP_SOURCE; t->flag |= T_DRAW_SNAP_SOURCE;
struct SnapSouceCustomData *customdata = t->custom.mode.data; struct SnapSouceCustomData *customdata = t->custom.mode.data;
@ -110,7 +115,7 @@ static void snapsource_confirm(TransInfo *t)
transform_input_reset(t, mval); transform_input_reset(t, mval);
/* Remote individual snap projection since this mode does not use the new `snap_source`. */ /* Remote individual snap projection since this mode does not use the new `snap_source`. */
t->tsnap.mode &= ~(SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST); t->tsnap.mode &= ~(SCE_SNAP_INDIVIDUAL_PROJECT | SCE_SNAP_INDIVIDUAL_NEAREST);
} }
static eRedrawFlag snapsource_handle_event_fn(TransInfo *t, const wmEvent *event) static eRedrawFlag snapsource_handle_event_fn(TransInfo *t, const wmEvent *event)
@ -152,6 +157,7 @@ static void snapsource_transform_fn(TransInfo *t, const int UNUSED(mval[2]))
BLI_assert(t->modifiers & MOD_EDIT_SNAP_SOURCE); BLI_assert(t->modifiers & MOD_EDIT_SNAP_SOURCE);
t->tsnap.snap_target_fn(t, NULL); t->tsnap.snap_target_fn(t, NULL);
getSnapPoint(t, t->tsnap.snap_source);
t->redraw |= TREDRAW_SOFT; t->redraw |= TREDRAW_SOFT;
} }
@ -188,15 +194,15 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator *UNUSED(op))
t->tsnap.status &= ~SNAP_SOURCE_FOUND; t->tsnap.status &= ~SNAP_SOURCE_FOUND;
customdata->snap_mode_confirm = t->tsnap.mode; customdata->snap_mode_confirm = t->tsnap.mode;
t->tsnap.mode &= ~(SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_FACE_RAYCAST | t->tsnap.mode &= ~(SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_INDIVIDUAL_PROJECT |
SCE_SNAP_MODE_FACE_NEAREST); SCE_SNAP_INDIVIDUAL_NEAREST);
if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) { if ((t->tsnap.mode & ~(SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID)) == 0) {
/* Initialize snap modes for geometry. */ /* Initialize snap modes for geometry. */
t->tsnap.mode &= ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID); t->tsnap.mode &= ~(SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID);
t->tsnap.mode |= SCE_SNAP_MODE_GEOM; t->tsnap.mode |= SCE_SNAP_TO_GEOM;
if (!(customdata->snap_mode_confirm & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { if (!(customdata->snap_mode_confirm & SCE_SNAP_TO_EDGE_PERPENDICULAR)) {
customdata->snap_mode_confirm = t->tsnap.mode; customdata->snap_mode_confirm = t->tsnap.mode;
} }
} }

View File

@ -384,7 +384,7 @@ static void translate_snap_grid_apply(TransInfo *t,
float in[3]; float in[3];
if (t->con.mode & CON_APPLY) { if (t->con.mode & CON_APPLY) {
BLI_assert(t->tsnap.snapElem == SCE_SNAP_MODE_NONE); BLI_assert(t->tsnap.target_type == SCE_SNAP_TO_NONE);
t->con.applyVec(t, NULL, NULL, loc, in); t->con.applyVec(t, NULL, NULL, loc, in);
} }
else { else {
@ -403,7 +403,7 @@ static bool translate_snap_grid(TransInfo *t, float *val)
return false; return false;
} }
if (!(t->tsnap.mode & SCE_SNAP_MODE_GRID) || validSnap(t)) { if (!(t->tsnap.mode & SCE_SNAP_TO_GRID) || validSnap(t)) {
/* Don't do grid snapping if there is a valid snap point. */ /* Don't do grid snapping if there is a valid snap point. */
return false; return false;
} }
@ -429,7 +429,7 @@ static bool translate_snap_grid(TransInfo *t, float *val)
} }
translate_snap_grid_apply(t, t->idx_max, grid_dist, val, val); translate_snap_grid_apply(t, t->idx_max, grid_dist, val, val);
t->tsnap.snapElem = SCE_SNAP_MODE_GRID; t->tsnap.target_type = SCE_SNAP_TO_GRID;
return true; return true;
} }
@ -627,7 +627,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
/* Test for mixed snap with grid. */ /* Test for mixed snap with grid. */
float snap_dist_sq = FLT_MAX; float snap_dist_sq = FLT_MAX;
if (t->tsnap.snapElem != SCE_SNAP_MODE_NONE) { if (t->tsnap.target_type != SCE_SNAP_TO_NONE) {
snap_dist_sq = len_squared_v3v3(t->values, global_dir); snap_dist_sq = len_squared_v3v3(t->values, global_dir);
} }
if ((snap_dist_sq == FLT_MAX) || (len_squared_v3v3(global_dir, incr_dir) < snap_dist_sq)) { if ((snap_dist_sq == FLT_MAX) || (len_squared_v3v3(global_dir, incr_dir) < snap_dist_sq)) {

View File

@ -539,11 +539,11 @@ static void vert_slide_snap_apply(TransInfo *t, float *value)
getSnapPoint(t, dvec); getSnapPoint(t, dvec);
sub_v3_v3(dvec, t->tsnap.snap_source); sub_v3_v3(dvec, t->tsnap.snap_source);
if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE)) { if (t->tsnap.target_type & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE)) {
float co_dir[3]; float co_dir[3];
sub_v3_v3v3(co_dir, co_curr_3d, co_orig_3d); sub_v3_v3v3(co_dir, co_curr_3d, co_orig_3d);
normalize_v3(co_dir); normalize_v3(co_dir);
if (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) { if (t->tsnap.target_type & SCE_SNAP_TO_EDGE) {
transform_constraint_snap_axis_to_edge(t, co_dir, dvec); transform_constraint_snap_axis_to_edge(t, co_dir, dvec);
} }
else { else {

View File

@ -700,7 +700,7 @@ void Transform_Properties(wmOperatorType *ot, int flags)
prop = RNA_def_enum(ot->srna, prop = RNA_def_enum(ot->srna,
"snap_elements", "snap_elements",
rna_enum_snap_element_items, rna_enum_snap_element_items,
SCE_SNAP_MODE_INCREMENT, SCE_SNAP_TO_INCREMENT,
"Snap to Elements", "Snap to Elements",
""); "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_ENUM_FLAG); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_ENUM_FLAG);
@ -793,15 +793,6 @@ void Transform_Properties(wmOperatorType *ot, int flags)
RNA_def_property_flag(prop, PROP_HIDDEN); RNA_def_property_flag(prop, PROP_HIDDEN);
} }
if (flags & P_VIEW3D_NAVIGATION) {
prop = RNA_def_boolean(ot->srna,
"allow_navigation",
0,
"Allow Navigation",
"Allow navigation while transforming");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
if (flags & P_POST_TRANSFORM) { if (flags & P_POST_TRANSFORM) {
prop = RNA_def_boolean(ot->srna, prop = RNA_def_boolean(ot->srna,
"use_automerge_and_split", "use_automerge_and_split",
@ -836,7 +827,7 @@ static void TRANSFORM_OT_translate(wmOperatorType *ot)
Transform_Properties(ot, Transform_Properties(ot,
P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP |
P_OPTIONS | P_GPENCIL_EDIT | P_CURSOR_EDIT | P_VIEW2D_EDGE_PAN | P_OPTIONS | P_GPENCIL_EDIT | P_CURSOR_EDIT | P_VIEW2D_EDGE_PAN |
P_VIEW3D_NAVIGATION | P_POST_TRANSFORM); P_POST_TRANSFORM);
} }
static void TRANSFORM_OT_resize(wmOperatorType *ot) static void TRANSFORM_OT_resize(wmOperatorType *ot)
@ -875,7 +866,7 @@ static void TRANSFORM_OT_resize(wmOperatorType *ot)
Transform_Properties(ot, Transform_Properties(ot,
P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP |
P_OPTIONS | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION); P_OPTIONS | P_GPENCIL_EDIT | P_CENTER);
} }
static void TRANSFORM_OT_skin_resize(wmOperatorType *ot) static void TRANSFORM_OT_skin_resize(wmOperatorType *ot)
@ -952,7 +943,7 @@ static void TRANSFORM_OT_rotate(wmOperatorType *ot)
Transform_Properties(ot, Transform_Properties(ot,
P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR |
P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION); P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER);
} }
static void TRANSFORM_OT_tilt(wmOperatorType *ot) static void TRANSFORM_OT_tilt(wmOperatorType *ot)
@ -1091,7 +1082,7 @@ static void TRANSFORM_OT_shrink_fatten(wmOperatorType *ot)
WM_operatortype_props_advanced_begin(ot); WM_operatortype_props_advanced_begin(ot);
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_VIEW3D_NAVIGATION); Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
} }
static void TRANSFORM_OT_tosphere(wmOperatorType *ot) static void TRANSFORM_OT_tosphere(wmOperatorType *ot)
@ -1197,7 +1188,7 @@ static void TRANSFORM_OT_edge_slide(wmOperatorType *ot)
"When Even mode is active, flips between the two adjacent edge loops"); "When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents"); RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV | P_VIEW3D_NAVIGATION); Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV);
} }
static void TRANSFORM_OT_vert_slide(wmOperatorType *ot) static void TRANSFORM_OT_vert_slide(wmOperatorType *ot)
@ -1232,7 +1223,7 @@ static void TRANSFORM_OT_vert_slide(wmOperatorType *ot)
"When Even mode is active, flips between the two adjacent edge loops"); "When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents"); RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV | P_VIEW3D_NAVIGATION); Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV);
} }
static void TRANSFORM_OT_edge_crease(wmOperatorType *ot) static void TRANSFORM_OT_edge_crease(wmOperatorType *ot)
@ -1380,8 +1371,7 @@ static void TRANSFORM_OT_transform(wmOperatorType *ot)
Transform_Properties(ot, Transform_Properties(ot,
P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR |
P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION | P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER | P_POST_TRANSFORM);
P_POST_TRANSFORM);
} }
static int transform_from_gizmo_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) static int transform_from_gizmo_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)

View File

@ -174,7 +174,9 @@ void drawSnapping(const bContext *C, TransInfo *t)
return; return;
} }
const bool draw_source = (t->tsnap.status & SNAP_SOURCE_FOUND) && (t->flag & T_DRAW_SNAP_SOURCE); const bool draw_source = (t->tsnap.status & SNAP_MULTI_POINTS) ||
((t->tsnap.status & SNAP_SOURCE_FOUND) &&
(t->flag & T_DRAW_SNAP_SOURCE));
const bool draw_target = (t->tsnap.status & (SNAP_TARGET_FOUND | SNAP_MULTI_POINTS)); const bool draw_target = (t->tsnap.status & (SNAP_TARGET_FOUND | SNAP_MULTI_POINTS));
if (!(draw_source || draw_target)) { if (!(draw_source || draw_target)) {
@ -197,9 +199,9 @@ void drawSnapping(const bContext *C, TransInfo *t)
} }
if (t->spacetype == SPACE_VIEW3D) { if (t->spacetype == SPACE_VIEW3D) {
const float *loc_cur = nullptr; const float *source_loc = nullptr;
const float *loc_prev = nullptr; const float *target_loc = nullptr;
const float *normal = nullptr; const float *target_normal = nullptr;
GPU_depth_test(GPU_DEPTH_NONE); GPU_depth_test(GPU_DEPTH_NONE);
@ -233,19 +235,25 @@ void drawSnapping(const bContext *C, TransInfo *t)
/* draw normal if needed */ /* draw normal if needed */
if (usingSnappingNormal(t) && validSnappingNormal(t)) { if (usingSnappingNormal(t) && validSnappingNormal(t)) {
normal = t->tsnap.snapNormal; target_normal = t->tsnap.snapNormal;
} }
if (draw_source) { if (draw_source) {
loc_prev = t->tsnap.snap_source; source_loc = t->tsnap.snap_source;
} }
if (t->tsnap.status & SNAP_TARGET_FOUND) { if (t->tsnap.status & SNAP_TARGET_FOUND) {
loc_cur = t->tsnap.snap_target; target_loc = t->tsnap.snap_target;
} }
ED_view3d_cursor_snap_draw_util( ED_view3d_cursor_snap_draw_util(rv3d,
rv3d, loc_prev, loc_cur, normal, col, activeCol, t->tsnap.snapElem); source_loc,
target_loc,
target_normal,
t->tsnap.source_type,
t->tsnap.target_type,
col,
activeCol);
GPU_depth_test(GPU_DEPTH_LESS_EQUAL); GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
} }
@ -371,7 +379,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td
t->depsgraph, t->depsgraph,
t->region, t->region,
static_cast<const View3D *>(t->view), static_cast<const View3D *>(t->view),
SCE_SNAP_MODE_FACE, SCE_SNAP_TO_FACE,
&snap_object_params, &snap_object_params,
nullptr, nullptr,
mval_fl, mval_fl,
@ -379,7 +387,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td
nullptr, nullptr,
loc, loc,
no); no);
if (hit != SCE_SNAP_MODE_FACE) { if (hit != SCE_SNAP_TO_FACE) {
return false; return false;
} }
@ -436,7 +444,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td
t->depsgraph, t->depsgraph,
t->region, t->region,
static_cast<const View3D *>(t->view), static_cast<const View3D *>(t->view),
SCE_SNAP_MODE_FACE_NEAREST, SCE_SNAP_INDIVIDUAL_NEAREST,
&snap_object_params, &snap_object_params,
init_loc, init_loc,
nullptr, nullptr,
@ -445,7 +453,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td
snap_loc, snap_loc,
snap_no); snap_no);
if (hit != SCE_SNAP_MODE_FACE_NEAREST) { if (hit != SCE_SNAP_INDIVIDUAL_NEAREST) {
return; return;
} }
@ -454,7 +462,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td
mul_m3_v3(td->smtx, tvec); mul_m3_v3(td->smtx, tvec);
add_v3_v3(td->loc, tvec); add_v3_v3(td->loc, tvec);
/* TODO: support snap alignment similar to #SCE_SNAP_MODE_FACE_RAYCAST? */ /* TODO: support snap alignment similar to #SCE_SNAP_TO_FACE_RAYCAST? */
} }
bool transform_snap_project_individual_is_active(const TransInfo *t) bool transform_snap_project_individual_is_active(const TransInfo *t)
@ -463,7 +471,7 @@ bool transform_snap_project_individual_is_active(const TransInfo *t)
return false; return false;
} }
return (t->tsnap.mode & (SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST)) != 0; return (t->tsnap.mode & (SCE_SNAP_INDIVIDUAL_PROJECT | SCE_SNAP_INDIVIDUAL_NEAREST)) != 0;
} }
void transform_snap_project_individual_apply(TransInfo *t) void transform_snap_project_individual_apply(TransInfo *t)
@ -487,11 +495,11 @@ 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 /* 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. */ * fallback to face nearest ray-cast does not hit. */
bool hit = false; bool hit = false;
if (t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST) { if (t->tsnap.mode & SCE_SNAP_INDIVIDUAL_PROJECT) {
hit = applyFaceProject(t, tc, td); hit = applyFaceProject(t, tc, td);
} }
if (!hit && t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST) { if (!hit && t->tsnap.mode & SCE_SNAP_INDIVIDUAL_NEAREST) {
applyFaceNearest(t, tc, td); applyFaceNearest(t, tc, td);
} }
#if 0 /* TODO: support this? */ #if 0 /* TODO: support this? */
@ -508,8 +516,8 @@ static bool transform_snap_mixed_is_active(const TransInfo *t)
} }
return (t->tsnap.mode & return (t->tsnap.mode &
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_VOLUME | (SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE | SCE_SNAP_TO_VOLUME |
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) != 0; SCE_SNAP_TO_EDGE_MIDPOINT | SCE_SNAP_TO_EDGE_PERPENDICULAR)) != 0;
} }
void transform_snap_mixed_apply(TransInfo *t, float *vec) void transform_snap_mixed_apply(TransInfo *t, float *vec)
@ -518,7 +526,7 @@ void transform_snap_mixed_apply(TransInfo *t, float *vec)
return; return;
} }
if (t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) { if (t->tsnap.mode & ~(SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID)) {
double current = PIL_check_seconds_timer(); double current = PIL_check_seconds_timer();
/* Time base quirky code to go around find-nearest slowness. */ /* Time base quirky code to go around find-nearest slowness. */
@ -543,8 +551,9 @@ void transform_snap_mixed_apply(TransInfo *t, float *vec)
void resetSnapping(TransInfo *t) void resetSnapping(TransInfo *t)
{ {
t->tsnap.status = SNAP_RESETTED; t->tsnap.status = SNAP_RESETTED;
t->tsnap.snapElem = SCE_SNAP_MODE_NONE; t->tsnap.source_type = SCE_SNAP_TO_NONE;
t->tsnap.mode = SCE_SNAP_MODE_NONE; t->tsnap.target_type = SCE_SNAP_TO_NONE;
t->tsnap.mode = SCE_SNAP_TO_NONE;
t->tsnap.target_operation = SCE_SNAP_TARGET_ALL; t->tsnap.target_operation = SCE_SNAP_TARGET_ALL;
t->tsnap.source_operation = SCE_SNAP_SOURCE_CLOSEST; t->tsnap.source_operation = SCE_SNAP_SOURCE_CLOSEST;
t->tsnap.last = 0; t->tsnap.last = 0;
@ -634,11 +643,11 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t)
if (t->spacetype == SPACE_IMAGE) { if (t->spacetype == SPACE_IMAGE) {
eSnapMode snap_mode = eSnapMode(ts->snap_uv_mode); eSnapMode snap_mode = eSnapMode(ts->snap_uv_mode);
if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) && if ((snap_mode & SCE_SNAP_TO_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) &&
(t->mode == TFM_TRANSLATION)) (t->mode == TFM_TRANSLATION))
{ {
snap_mode &= ~SCE_SNAP_MODE_INCREMENT; snap_mode &= ~SCE_SNAP_TO_INCREMENT;
snap_mode |= SCE_SNAP_MODE_GRID; snap_mode |= SCE_SNAP_TO_GRID;
} }
return snap_mode; return snap_mode;
} }
@ -649,16 +658,16 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) { if (t->spacetype == SPACE_VIEW3D) {
if (t->options & (CTX_CAMERA | CTX_EDGE_DATA | CTX_PAINT_CURVE)) { if (t->options & (CTX_CAMERA | CTX_EDGE_DATA | CTX_PAINT_CURVE)) {
return SCE_SNAP_MODE_INCREMENT; return SCE_SNAP_TO_INCREMENT;
} }
eSnapMode snap_mode = eSnapMode(ts->snap_mode); eSnapMode snap_mode = eSnapMode(ts->snap_mode);
if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) && if ((snap_mode & SCE_SNAP_TO_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) &&
(t->mode == TFM_TRANSLATION)) (t->mode == TFM_TRANSLATION))
{ {
/* Special case in which snap to increments is transformed to snap to grid. */ /* Special case in which snap to increments is transformed to snap to grid. */
snap_mode &= ~SCE_SNAP_MODE_INCREMENT; snap_mode &= ~SCE_SNAP_TO_INCREMENT;
snap_mode |= SCE_SNAP_MODE_GRID; snap_mode |= SCE_SNAP_TO_GRID;
} }
return snap_mode; return snap_mode;
} }
@ -668,7 +677,7 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t)
return eSnapMode(0); return eSnapMode(0);
} }
return SCE_SNAP_MODE_INCREMENT; return SCE_SNAP_TO_INCREMENT;
} }
static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t) static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t)
@ -757,15 +766,15 @@ static void initSnappingMode(TransInfo *t)
} }
if (doForceIncrementSnap(t)) { if (doForceIncrementSnap(t)) {
t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; t->tsnap.mode = SCE_SNAP_TO_INCREMENT;
} }
if ((t->spacetype != SPACE_VIEW3D) || (t->flag & T_NO_PROJECT)) { if ((t->spacetype != SPACE_VIEW3D) || (t->flag & T_NO_PROJECT)) {
/* Force project off when not supported. */ /* Force project off when not supported. */
t->tsnap.mode &= ~(SCE_SNAP_MODE_FACE_RAYCAST | SCE_SNAP_MODE_FACE_NEAREST); t->tsnap.mode &= ~(SCE_SNAP_INDIVIDUAL_PROJECT | SCE_SNAP_INDIVIDUAL_NEAREST);
} }
if (t->tsnap.mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR) { if (t->tsnap.mode & SCE_SNAP_TO_EDGE_PERPENDICULAR) {
t->flag |= T_DRAW_SNAP_SOURCE; t->flag |= T_DRAW_SNAP_SOURCE;
} }
@ -839,7 +848,7 @@ void initSnapping(TransInfo *t, wmOperator *op)
RNA_property_is_set(op->ptr, prop)) RNA_property_is_set(op->ptr, prop))
{ {
SET_FLAG_FROM_TEST( SET_FLAG_FROM_TEST(
t->tsnap.mode, RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_MODE_FACE_RAYCAST); t->tsnap.mode, RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_INDIVIDUAL_PROJECT);
} }
/* use_snap_self is misnamed and should be use_snap_active */ /* use_snap_self is misnamed and should be use_snap_active */
@ -1093,23 +1102,23 @@ static void snap_target_view3d_fn(TransInfo *t, float * /*vec*/)
float no[3]; float no[3];
float mval[2]; float mval[2];
bool found = false; bool found = false;
eSnapMode snap_elem = SCE_SNAP_MODE_NONE; eSnapMode snap_elem = SCE_SNAP_TO_NONE;
float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */ float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */
mval[0] = t->mval[0]; mval[0] = t->mval[0];
mval[1] = t->mval[1]; mval[1] = t->mval[1];
if (t->tsnap.mode & SCE_SNAP_MODE_GEOM) { if (t->tsnap.mode & SCE_SNAP_TO_GEOM) {
zero_v3(no); /* objects won't set this */ zero_v3(no); /* objects won't set this */
snap_elem = snapObjectsTransform(t, mval, &dist_px, loc, no); snap_elem = snapObjectsTransform(t, mval, &dist_px, loc, no);
found = (snap_elem != SCE_SNAP_MODE_NONE); found = (snap_elem != SCE_SNAP_TO_NONE);
} }
if ((found == false) && (t->tsnap.mode & SCE_SNAP_MODE_VOLUME)) { if ((found == false) && (t->tsnap.mode & SCE_SNAP_TO_VOLUME)) {
bool use_peel = (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0; bool use_peel = (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0;
found = peelObjectsTransform(t, mval, use_peel, loc, no, nullptr); found = peelObjectsTransform(t, mval, use_peel, loc, no, nullptr);
if (found) { if (found) {
snap_elem = SCE_SNAP_MODE_VOLUME; snap_elem = SCE_SNAP_TO_VOLUME;
} }
} }
@ -1123,13 +1132,13 @@ static void snap_target_view3d_fn(TransInfo *t, float * /*vec*/)
t->tsnap.status &= ~SNAP_TARGET_FOUND; t->tsnap.status &= ~SNAP_TARGET_FOUND;
} }
t->tsnap.snapElem = snap_elem; t->tsnap.target_type = snap_elem;
} }
static void snap_target_uv_fn(TransInfo *t, float * /*vec*/) static void snap_target_uv_fn(TransInfo *t, float * /*vec*/)
{ {
BLI_assert(t->spacetype == SPACE_IMAGE); BLI_assert(t->spacetype == SPACE_IMAGE);
if (t->tsnap.mode & SCE_SNAP_MODE_VERTEX) { if (t->tsnap.mode & SCE_SNAP_TO_VERTEX) {
uint objects_len = 0; uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
t->scene, t->view_layer, nullptr, &objects_len); t->scene, t->view_layer, nullptr, &objects_len);
@ -1159,7 +1168,7 @@ static void snap_target_uv_fn(TransInfo *t, float * /*vec*/)
static void snap_target_node_fn(TransInfo *t, float * /*vec*/) static void snap_target_node_fn(TransInfo *t, float * /*vec*/)
{ {
BLI_assert(t->spacetype == SPACE_NODE); BLI_assert(t->spacetype == SPACE_NODE);
if (t->tsnap.mode & (SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y)) { if (t->tsnap.mode & (SCE_SNAP_TO_NODE_X | SCE_SNAP_TO_NODE_Y)) {
float loc[2]; float loc[2];
float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */ float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */
char node_border; char node_border;
@ -1258,32 +1267,7 @@ static void snap_source_center_fn(TransInfo *t)
TargetSnapOffset(t, nullptr); TargetSnapOffset(t, nullptr);
t->tsnap.status |= SNAP_SOURCE_FOUND; t->tsnap.status |= SNAP_SOURCE_FOUND;
} t->tsnap.source_type = SCE_SNAP_TO_NONE;
}
static void snap_source_active_fn(TransInfo *t)
{
/* Only need to calculate once */
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
if (calculateCenterActive(t, true, t->tsnap.snap_source)) {
TargetSnapOffset(t, nullptr);
t->tsnap.status |= SNAP_SOURCE_FOUND;
}
else {
/* No active, default to median, */
t->tsnap.source_operation = SCE_SNAP_SOURCE_MEDIAN;
t->tsnap.snap_source_fn = snap_source_median_fn;
snap_source_median_fn(t);
}
}
}
static void snap_source_median_fn(TransInfo *t)
{
/* Only need to calculate once. */
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
tranform_snap_target_median_calc(t, t->tsnap.snap_source);
t->tsnap.status |= SNAP_SOURCE_FOUND;
} }
} }
@ -1374,6 +1358,35 @@ static void snap_source_closest_fn(TransInfo *t)
TargetSnapOffset(t, closest); TargetSnapOffset(t, closest);
t->tsnap.status |= SNAP_SOURCE_FOUND; t->tsnap.status |= SNAP_SOURCE_FOUND;
t->tsnap.source_type = SCE_SNAP_TO_NONE;
}
}
static void snap_source_active_fn(TransInfo *t)
{
/* Only need to calculate once */
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
if (calculateCenterActive(t, true, t->tsnap.snap_source)) {
TargetSnapOffset(t, nullptr);
t->tsnap.status |= SNAP_SOURCE_FOUND;
t->tsnap.source_type = SCE_SNAP_TO_NONE;
}
else {
/* No active, default to median, */
t->tsnap.source_operation = SCE_SNAP_SOURCE_MEDIAN;
t->tsnap.snap_source_fn = snap_source_median_fn;
snap_source_median_fn(t);
}
}
}
static void snap_source_median_fn(TransInfo *t)
{
/* Only need to calculate once. */
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
tranform_snap_target_median_calc(t, t->tsnap.snap_source);
t->tsnap.status |= SNAP_SOURCE_FOUND;
t->tsnap.source_type = SCE_SNAP_TO_NONE;
} }
} }
@ -1513,10 +1526,10 @@ static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetOP snap_target_sel
static NodeBorder snapNodeBorder(eSnapMode snap_node_mode) static NodeBorder snapNodeBorder(eSnapMode snap_node_mode)
{ {
NodeBorder flag = NodeBorder(0); NodeBorder flag = NodeBorder(0);
if (snap_node_mode & SCE_SNAP_MODE_NODE_X) { if (snap_node_mode & SCE_SNAP_TO_NODE_X) {
flag |= NODE_LEFT | NODE_RIGHT; flag |= NODE_LEFT | NODE_RIGHT;
} }
if (snap_node_mode & SCE_SNAP_MODE_NODE_Y) { if (snap_node_mode & SCE_SNAP_TO_NODE_Y) {
flag |= NODE_TOP | NODE_BOTTOM; flag |= NODE_TOP | NODE_BOTTOM;
} }
return flag; return flag;
@ -1644,7 +1657,7 @@ static void snap_increment_apply(const TransInfo *t,
const float increment_dist, const float increment_dist,
float *r_val) float *r_val)
{ {
BLI_assert(t->tsnap.mode & SCE_SNAP_MODE_INCREMENT); BLI_assert(t->tsnap.mode & SCE_SNAP_TO_INCREMENT);
BLI_assert(max_index <= 2); BLI_assert(max_index <= 2);
/* Early bailing out if no need to snap */ /* Early bailing out if no need to snap */
@ -1678,7 +1691,7 @@ bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float
return false; return false;
} }
if (!(t->tsnap.mode & SCE_SNAP_MODE_INCREMENT)) { if (!(t->tsnap.mode & SCE_SNAP_TO_INCREMENT)) {
return false; return false;
} }
@ -1710,8 +1723,7 @@ bool transform_snap_increment(const TransInfo *t, float *r_val)
float transform_snap_increment_get(const TransInfo *t) float transform_snap_increment_get(const TransInfo *t)
{ {
if (transform_snap_is_active(t) && if (transform_snap_is_active(t) && (t->tsnap.mode & (SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID)))
(t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))
{ {
return (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0]; return (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0];
} }

View File

@ -226,9 +226,9 @@ bool Nearest2dUserData::snap_edge(const float3 &va, const float3 &vb, int edge_i
return false; return false;
} }
eSnapMode Nearest2dUserData::snap_edge_points(int edge_index, float dist_px_sq_orig) eSnapMode Nearest2dUserData::snap_edge_points_impl(int edge_index, float dist_px_sq_orig)
{ {
eSnapMode elem = SCE_SNAP_MODE_EDGE; eSnapMode elem = SCE_SNAP_TO_EDGE;
SnapObjectContext *sctx = this->sctx_; SnapObjectContext *sctx = this->sctx_;
int vindex[2]; int vindex[2];
@ -251,13 +251,13 @@ eSnapMode Nearest2dUserData::snap_edge_points(int edge_index, float dist_px_sq_o
this->nearest_point.dist_sq = dist_px_sq_orig; this->nearest_point.dist_sq = dist_px_sq_orig;
eSnapMode snap_to = sctx->runtime.snap_to_flag; eSnapMode snap_to = sctx->runtime.snap_to_flag;
int e_mode_len = ((snap_to & SCE_SNAP_MODE_EDGE) != 0) + int e_mode_len = ((snap_to & SCE_SNAP_TO_EDGE) != 0) +
((snap_to & SCE_SNAP_MODE_VERTEX) != 0) + ((snap_to & SCE_SNAP_TO_EDGE_ENDPOINT) != 0) +
((snap_to & SCE_SNAP_MODE_EDGE_MIDPOINT) != 0); ((snap_to & SCE_SNAP_TO_EDGE_MIDPOINT) != 0);
float range = 1.0f / (2 * e_mode_len - 1); float range = 1.0f / (2 * e_mode_len - 1);
if (snap_to & SCE_SNAP_MODE_EDGE_MIDPOINT) { if (snap_to & SCE_SNAP_TO_EDGE_MIDPOINT) {
range *= e_mode_len - 1; range *= e_mode_len - 1;
if ((range) < lambda && lambda < (1.0f - range)) { if ((range) < lambda && lambda < (1.0f - range)) {
float vmid[3]; float vmid[3];
@ -265,12 +265,12 @@ eSnapMode Nearest2dUserData::snap_edge_points(int edge_index, float dist_px_sq_o
if (this->snap_point(vmid, edge_index)) { if (this->snap_point(vmid, edge_index)) {
sub_v3_v3v3(this->nearest_point.no, v_pair[1], v_pair[0]); sub_v3_v3v3(this->nearest_point.no, v_pair[1], v_pair[0]);
elem = SCE_SNAP_MODE_EDGE_MIDPOINT; elem = SCE_SNAP_TO_EDGE_MIDPOINT;
} }
} }
} }
if (snap_to & SCE_SNAP_MODE_EDGE_PERPENDICULAR) { if (snap_to & SCE_SNAP_TO_EDGE_PERPENDICULAR) {
float v_near[3], va_g[3], vb_g[3]; float v_near[3], va_g[3], vb_g[3];
mul_v3_m4v3(va_g, this->obmat_.ptr(), v_pair[0]); mul_v3_m4v3(va_g, this->obmat_.ptr(), v_pair[0]);
@ -282,18 +282,18 @@ eSnapMode Nearest2dUserData::snap_edge_points(int edge_index, float dist_px_sq_o
if (this->snap_point(v_near, edge_index)) { if (this->snap_point(v_near, edge_index)) {
sub_v3_v3v3(this->nearest_point.no, v_pair[1], v_pair[0]); sub_v3_v3v3(this->nearest_point.no, v_pair[1], v_pair[0]);
elem = SCE_SNAP_MODE_EDGE_PERPENDICULAR; elem = SCE_SNAP_TO_EDGE_PERPENDICULAR;
} }
} }
} }
/* Leave this one for last so it doesn't change the normal. */ /* Leave this one for last so it doesn't change the normal. */
if (snap_to & SCE_SNAP_MODE_VERTEX) { if (snap_to & SCE_SNAP_TO_EDGE_ENDPOINT) {
if (lambda < (range) || (1.0f - range) < lambda) { if (lambda < (range) || (1.0f - range) < lambda) {
int v_id = lambda < 0.5f ? 0 : 1; int v_id = lambda < 0.5f ? 0 : 1;
if (this->snap_point(v_pair[v_id], v_id)) { if (this->snap_point(v_pair[v_id], v_id)) {
elem = SCE_SNAP_MODE_VERTEX; elem = SCE_SNAP_TO_EDGE_ENDPOINT;
this->copy_vert_no(vindex[v_id], this->nearest_point.no); this->copy_vert_no(vindex[v_id], this->nearest_point.no);
} }
} }
@ -432,7 +432,7 @@ static bool snap_object_is_snappable(const SnapObjectContext *sctx,
*/ */
static eSnapMode iter_snap_objects(SnapObjectContext *sctx, IterSnapObjsCallback sob_callback) static eSnapMode iter_snap_objects(SnapObjectContext *sctx, IterSnapObjsCallback sob_callback)
{ {
eSnapMode ret = SCE_SNAP_MODE_NONE; eSnapMode ret = SCE_SNAP_TO_NONE;
eSnapMode tmp; eSnapMode tmp;
Scene *scene = DEG_get_input_scene(sctx->runtime.depsgraph); Scene *scene = DEG_get_input_scene(sctx->runtime.depsgraph);
@ -455,7 +455,7 @@ static eSnapMode iter_snap_objects(SnapObjectContext *sctx, IterSnapObjsCallback
BLI_assert(DEG_is_evaluated_object(dupli_ob->ob)); BLI_assert(DEG_is_evaluated_object(dupli_ob->ob));
if ((tmp = sob_callback( if ((tmp = sob_callback(
sctx, dupli_ob->ob, dupli_ob->ob_data, dupli_ob->mat, is_object_active, false)) != sctx, dupli_ob->ob, dupli_ob->ob_data, dupli_ob->mat, is_object_active, false)) !=
SCE_SNAP_MODE_NONE) SCE_SNAP_TO_NONE)
{ {
ret = tmp; ret = tmp;
} }
@ -467,7 +467,7 @@ static eSnapMode iter_snap_objects(SnapObjectContext *sctx, IterSnapObjsCallback
ID *ob_data = data_for_snap(obj_eval, sctx->runtime.params.edit_mode_type, &use_hide); ID *ob_data = data_for_snap(obj_eval, sctx->runtime.params.edit_mode_type, &use_hide);
if ((tmp = sob_callback( if ((tmp = sob_callback(
sctx, obj_eval, ob_data, obj_eval->object_to_world, is_object_active, use_hide)) != sctx, obj_eval, ob_data, obj_eval->object_to_world, is_object_active, use_hide)) !=
SCE_SNAP_MODE_NONE) SCE_SNAP_TO_NONE)
{ {
ret = tmp; ret = tmp;
} }
@ -551,38 +551,38 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
if (ob_data == nullptr) { if (ob_data == nullptr) {
if (sctx->runtime.use_occlusion_test_edit && ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) { if (sctx->runtime.use_occlusion_test_edit && ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) {
/* Do not hit objects that are in wire or bounding box display mode. */ /* Do not hit objects that are in wire or bounding box display mode. */
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
if (ob_eval->type == OB_MESH) { if (ob_eval->type == OB_MESH) {
if (snap_object_editmesh(sctx, ob_eval, nullptr, obmat, SCE_SNAP_MODE_FACE, use_hide)) { if (snap_object_editmesh(sctx, ob_eval, nullptr, obmat, SCE_SNAP_TO_FACE, use_hide)) {
retval = true; retval = true;
} }
} }
else { else {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
} }
else if (sctx->runtime.params.use_occlusion_test && ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) { else if (sctx->runtime.params.use_occlusion_test && ELEM(ob_eval->dt, OB_BOUNDBOX, OB_WIRE)) {
/* Do not hit objects that are in wire or bounding box display mode. */ /* Do not hit objects that are in wire or bounding box display mode. */
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
else if (GS(ob_data->name) != ID_ME) { else if (GS(ob_data->name) != ID_ME) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) { else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
else { else {
retval = snap_object_mesh(sctx, ob_eval, ob_data, obmat, SCE_SNAP_MODE_FACE, use_hide); retval = snap_object_mesh(sctx, ob_eval, ob_data, obmat, SCE_SNAP_TO_FACE, use_hide);
} }
if (retval) { if (retval) {
copy_m4_m4(sctx->ret.obmat, obmat); copy_m4_m4(sctx->ret.obmat, obmat);
sctx->ret.ob = ob_eval; sctx->ret.ob = ob_eval;
sctx->ret.data = ob_data; sctx->ret.data = ob_data;
return SCE_SNAP_MODE_FACE; return SCE_SNAP_TO_FACE;
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
/** /**
@ -601,7 +601,7 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
*/ */
static bool raycastObjects(SnapObjectContext *sctx) static bool raycastObjects(SnapObjectContext *sctx)
{ {
return iter_snap_objects(sctx, raycast_obj_fn) != SCE_SNAP_MODE_NONE; return iter_snap_objects(sctx, raycast_obj_fn) != SCE_SNAP_TO_NONE;
} }
/** \} */ /** \} */
@ -610,11 +610,6 @@ static bool raycastObjects(SnapObjectContext *sctx)
/** \name Surface Snap Functions /** \name Surface Snap Functions
* \{ */ * \{ */
struct NearestWorldObjUserData {
const float *init_co;
const float *curr_co;
};
static void nearest_world_tree_co(BVHTree *tree, static void nearest_world_tree_co(BVHTree *tree,
BVHTree_NearestPointCallback nearest_cb, BVHTree_NearestPointCallback nearest_cb,
void *treedata, void *treedata,
@ -718,21 +713,22 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
if (ob_data == nullptr) { if (ob_data == nullptr) {
if (ob_eval->type == OB_MESH) { if (ob_eval->type == OB_MESH) {
if (snap_object_editmesh( if (snap_object_editmesh(
sctx, ob_eval, nullptr, obmat, SCE_SNAP_MODE_FACE_NEAREST, use_hide)) { sctx, ob_eval, nullptr, obmat, SCE_SNAP_INDIVIDUAL_NEAREST, use_hide)) {
retval = true; retval = true;
} }
} }
else { else {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
} }
else if (GS(ob_data->name) != ID_ME) { else if (GS(ob_data->name) != ID_ME) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) { else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
else if (snap_object_mesh(sctx, ob_eval, ob_data, obmat, SCE_SNAP_MODE_FACE_NEAREST, use_hide)) { else if (snap_object_mesh(sctx, ob_eval, ob_data, obmat, SCE_SNAP_INDIVIDUAL_NEAREST, use_hide))
{
retval = true; retval = true;
} }
@ -740,9 +736,9 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
copy_m4_m4(sctx->ret.obmat, obmat); copy_m4_m4(sctx->ret.obmat, obmat);
sctx->ret.ob = ob_eval; sctx->ret.ob = ob_eval;
sctx->ret.data = ob_data; sctx->ret.data = ob_data;
return SCE_SNAP_MODE_FACE_NEAREST; return SCE_SNAP_INDIVIDUAL_NEAREST;
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
/** /**
@ -758,7 +754,7 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
*/ */
static bool nearestWorldObjects(SnapObjectContext *sctx) static bool nearestWorldObjects(SnapObjectContext *sctx)
{ {
return iter_snap_objects(sctx, nearest_world_object_fn) != SCE_SNAP_MODE_NONE; return iter_snap_objects(sctx, nearest_world_object_fn) != SCE_SNAP_TO_NONE;
} }
/** \} */ /** \} */
@ -818,11 +814,11 @@ void cb_snap_edge(void *userdata,
static eSnapMode snap_polygon(SnapObjectContext *sctx, eSnapMode snap_to_flag) static eSnapMode snap_polygon(SnapObjectContext *sctx, eSnapMode snap_to_flag)
{ {
if (sctx->ret.ob->type != OB_MESH) { if (sctx->ret.ob->type != OB_MESH) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
if (sctx->ret.data && GS(sctx->ret.data->name) != ID_ME) { if (sctx->ret.data && GS(sctx->ret.data->name) != ID_ME) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
if (sctx->ret.data) { if (sctx->ret.data) {
@ -837,7 +833,7 @@ static eSnapMode snap_polygon(SnapObjectContext *sctx, eSnapMode snap_to_flag)
static eSnapMode snap_edge_points(SnapObjectContext *sctx, const float dist_px_sq_orig) static eSnapMode snap_edge_points(SnapObjectContext *sctx, const float dist_px_sq_orig)
{ {
eSnapMode elem = SCE_SNAP_MODE_EDGE; eSnapMode elem = SCE_SNAP_TO_EDGE;
if (sctx->ret.ob->type != OB_MESH) { if (sctx->ret.ob->type != OB_MESH) {
return elem; return elem;
@ -864,22 +860,22 @@ eSnapMode snap_object_center(SnapObjectContext *sctx,
eSnapMode snap_to_flag) eSnapMode snap_to_flag)
{ {
if (ob_eval->transflag & OB_DUPLI) { if (ob_eval->transflag & OB_DUPLI) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
/* For now only vertex supported. */ /* For now only vertex supported. */
if ((snap_to_flag & SCE_SNAP_MODE_VERTEX) == 0) { if ((snap_to_flag & SCE_SNAP_TO_POINT) == 0) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
Nearest2dUserData nearest2d( Nearest2dUserData nearest2d(
sctx, ob_eval, static_cast<const ID *>(ob_eval->data), float4x4(obmat)); sctx, ob_eval, static_cast<const ID *>(ob_eval->data), float4x4(obmat));
if (nearest2d.snap_point(float3(0.0f))) { if (nearest2d.snap_point(float3(0.0f))) {
return SCE_SNAP_MODE_VERTEX; return SCE_SNAP_TO_POINT;
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
/** /**
@ -892,7 +888,7 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
bool is_object_active, bool is_object_active,
bool use_hide) bool use_hide)
{ {
eSnapMode retval = SCE_SNAP_MODE_NONE; eSnapMode retval = SCE_SNAP_TO_NONE;
if (ob_data == nullptr && (ob_eval->type == OB_MESH)) { if (ob_data == nullptr && (ob_eval->type == OB_MESH)) {
retval = snap_object_editmesh( retval = snap_object_editmesh(
@ -906,7 +902,7 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
case OB_MESH: { case OB_MESH: {
if (ob_eval->dt == OB_BOUNDBOX) { if (ob_eval->dt == OB_BOUNDBOX) {
/* Do not snap to objects that are in bounding box display mode */ /* Do not snap to objects that are in bounding box display mode */
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
if (GS(ob_data->name) == ID_ME) { if (GS(ob_data->name) == ID_ME) {
retval = snap_object_mesh( retval = snap_object_mesh(
@ -1031,22 +1027,22 @@ static bool snap_object_context_runtime_init(SnapObjectContext *sctx,
ListBase *hit_list, ListBase *hit_list,
bool use_occlusion_test) bool use_occlusion_test)
{ {
if (snap_to_flag & (SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_FACE_NEAREST)) { if (snap_to_flag & (SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_INDIVIDUAL_NEAREST)) {
if (prev_co) { if (prev_co) {
copy_v3_v3(sctx->runtime.curr_co, prev_co); copy_v3_v3(sctx->runtime.curr_co, prev_co);
if (init_co) { if (init_co) {
copy_v3_v3(sctx->runtime.init_co, init_co); copy_v3_v3(sctx->runtime.init_co, init_co);
} }
else { else {
snap_to_flag &= ~SCE_SNAP_MODE_FACE_NEAREST; snap_to_flag &= ~SCE_SNAP_INDIVIDUAL_NEAREST;
} }
} }
else { else {
snap_to_flag &= ~(SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_FACE_NEAREST); snap_to_flag &= ~(SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_INDIVIDUAL_NEAREST);
} }
} }
if (snap_to_flag == SCE_SNAP_MODE_NONE) { if (snap_to_flag == SCE_SNAP_TO_NONE) {
return false; return false;
} }
@ -1057,7 +1053,7 @@ static bool snap_object_context_runtime_init(SnapObjectContext *sctx,
sctx->runtime.params = *params; sctx->runtime.params = *params;
sctx->runtime.params.use_occlusion_test = use_occlusion_test; sctx->runtime.params.use_occlusion_test = use_occlusion_test;
sctx->runtime.use_occlusion_test_edit = use_occlusion_test && sctx->runtime.use_occlusion_test_edit = use_occlusion_test &&
(snap_to_flag & SCE_SNAP_MODE_FACE) == 0; (snap_to_flag & SCE_SNAP_TO_FACE) == 0;
sctx->runtime.has_occlusion_plane = false; sctx->runtime.has_occlusion_plane = false;
sctx->runtime.object_index = 0; sctx->runtime.object_index = 0;
@ -1115,7 +1111,7 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
depsgraph, depsgraph,
nullptr, nullptr,
v3d, v3d,
SCE_SNAP_MODE_FACE, SCE_SNAP_TO_FACE,
params, params,
ray_start, ray_start,
ray_normal, ray_normal,
@ -1167,7 +1163,7 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
depsgraph, depsgraph,
nullptr, nullptr,
v3d, v3d,
SCE_SNAP_MODE_FACE, SCE_SNAP_TO_FACE,
params, params,
ray_start, ray_start,
ray_normal, ray_normal,
@ -1246,18 +1242,18 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
float r_obmat[4][4], float r_obmat[4][4],
float r_face_nor[3]) float r_face_nor[3])
{ {
eSnapMode retval = SCE_SNAP_MODE_NONE; eSnapMode retval = SCE_SNAP_TO_NONE;
bool use_occlusion_test = params->use_occlusion_test; bool use_occlusion_test = params->use_occlusion_test;
if (use_occlusion_test && XRAY_ENABLED(v3d)) { if (use_occlusion_test && XRAY_ENABLED(v3d)) {
if (snap_to_flag != SCE_SNAP_MODE_FACE) { if (snap_to_flag != SCE_SNAP_TO_FACE) {
/* In theory everything is visible in X-Ray except faces. */ /* In theory everything is visible in X-Ray except faces. */
snap_to_flag &= ~SCE_SNAP_MODE_FACE; snap_to_flag &= ~SCE_SNAP_TO_FACE;
use_occlusion_test = false; use_occlusion_test = false;
} }
} }
if (use_occlusion_test || (snap_to_flag & SCE_SNAP_MODE_FACE)) { if (use_occlusion_test || (snap_to_flag & SCE_SNAP_TO_FACE)) {
if (!ED_view3d_win_to_ray_clipped_ex(depsgraph, if (!ED_view3d_win_to_ray_clipped_ex(depsgraph,
region, region,
v3d, v3d,
@ -1267,7 +1263,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
sctx->runtime.ray_start, sctx->runtime.ray_start,
true)) true))
{ {
snap_to_flag &= ~SCE_SNAP_MODE_FACE; snap_to_flag &= ~SCE_SNAP_TO_FACE;
use_occlusion_test = false; use_occlusion_test = false;
} }
} }
@ -1297,17 +1293,17 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
snap_to_flag = sctx->runtime.snap_to_flag; snap_to_flag = sctx->runtime.snap_to_flag;
BLI_assert(snap_to_flag & (SCE_SNAP_MODE_GEOM | SCE_SNAP_MODE_FACE_NEAREST)); BLI_assert(snap_to_flag & (SCE_SNAP_TO_GEOM | SCE_SNAP_INDIVIDUAL_NEAREST));
bool has_hit = false; bool has_hit = false;
/* NOTE: if both face ray-cast and face nearest are enabled, first find result of nearest, then /* NOTE: if both face ray-cast and face nearest are enabled, first find result of nearest, then
* override with ray-cast. */ * override with ray-cast. */
if ((snap_to_flag & SCE_SNAP_MODE_FACE_NEAREST) && !has_hit) { if ((snap_to_flag & SCE_SNAP_INDIVIDUAL_NEAREST) && !has_hit) {
has_hit = nearestWorldObjects(sctx); has_hit = nearestWorldObjects(sctx);
if (has_hit) { if (has_hit) {
retval = SCE_SNAP_MODE_FACE_NEAREST; retval = SCE_SNAP_INDIVIDUAL_NEAREST;
copy_v3_v3(r_loc, sctx->ret.loc); copy_v3_v3(r_loc, sctx->ret.loc);
if (r_no) { if (r_no) {
@ -1325,7 +1321,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
} }
} }
if ((snap_to_flag & SCE_SNAP_MODE_FACE) || sctx->runtime.params.use_occlusion_test) { if ((snap_to_flag & SCE_SNAP_TO_FACE) || sctx->runtime.params.use_occlusion_test) {
has_hit = raycastObjects(sctx); has_hit = raycastObjects(sctx);
if (has_hit) { if (has_hit) {
@ -1333,8 +1329,8 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
copy_v3_v3(r_face_nor, sctx->ret.no); copy_v3_v3(r_face_nor, sctx->ret.no);
} }
if (snap_to_flag & SCE_SNAP_MODE_FACE) { if (snap_to_flag & SCE_SNAP_TO_FACE) {
retval = SCE_SNAP_MODE_FACE; retval = SCE_SNAP_TO_FACE;
copy_v3_v3(r_loc, sctx->ret.loc); copy_v3_v3(r_loc, sctx->ret.loc);
if (r_no) { if (r_no) {
@ -1353,16 +1349,8 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
} }
} }
if (snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | if (snap_to_flag & (SCE_SNAP_TO_POINT | SNAP_TO_EDGE_ELEMENTS)) {
SCE_SNAP_MODE_EDGE_PERPENDICULAR)) eSnapMode elem_test, elem = SCE_SNAP_TO_NONE;
{
eSnapMode elem_test, elem = SCE_SNAP_MODE_NONE;
/* First snap to edge instead of middle or perpendicular. */
sctx->runtime.snap_to_flag &= (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE);
if (snap_to_flag & (SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
sctx->runtime.snap_to_flag |= SCE_SNAP_MODE_EDGE;
}
/* By convention we only snap to the original elements of a curve. */ /* By convention we only snap to the original elements of a curve. */
if (has_hit && sctx->ret.ob->type != OB_CURVES_LEGACY) { if (has_hit && sctx->ret.ob->type != OB_CURVES_LEGACY) {
@ -1398,11 +1386,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
elem = elem_test; elem = elem_test;
} }
if ((elem == SCE_SNAP_MODE_EDGE) && if ((elem == SCE_SNAP_TO_EDGE) && (snap_to_flag & SNAP_TO_EDGE_ELEMENTS)) {
(snap_to_flag &
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)))
{
sctx->runtime.snap_to_flag = snap_to_flag;
elem = snap_edge_points(sctx, square_f(*dist_px)); elem = snap_edge_points(sctx, square_f(*dist_px));
} }

View File

@ -10,6 +10,10 @@
#define MAX_CLIPPLANE_LEN 3 #define MAX_CLIPPLANE_LEN 3
#define SNAP_TO_EDGE_ELEMENTS \
(SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_ENDPOINT | SCE_SNAP_TO_EDGE_MIDPOINT | \
SCE_SNAP_TO_EDGE_PERPENDICULAR)
struct SnapData_EditMesh; struct SnapData_EditMesh;
struct SnapObjectContext { struct SnapObjectContext {
@ -118,7 +122,7 @@ class Nearest2dUserData {
bool snap_boundbox(const blender::float3 &min, const blender::float3 &max); bool snap_boundbox(const blender::float3 &min, const blender::float3 &max);
bool snap_point(const blender::float3 &co, int index = -1); bool snap_point(const blender::float3 &co, int index = -1);
bool snap_edge(const blender::float3 &va, const blender::float3 &vb, int edge_index = -1); bool snap_edge(const blender::float3 &va, const blender::float3 &vb, int edge_index = -1);
eSnapMode snap_edge_points(int edge_index, float dist_px_sq_orig); eSnapMode snap_edge_points_impl(int edge_index, float dist_px_sq_orig);
virtual void get_vert_co(const int /*index*/, const float ** /*r_co*/){}; virtual void get_vert_co(const int /*index*/, const float ** /*r_co*/){};
virtual void get_edge_verts_index(const int /*index*/, int /*r_v_index*/[2]){}; virtual void get_edge_verts_index(const int /*index*/, int /*r_v_index*/[2]){};
@ -186,7 +190,7 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
/* transform_snap_object_editmesh.cc */ /* transform_snap_object_editmesh.cc */
struct SnapData_EditMesh { struct SnapData_EditMesh {
/* Verts, Edges. */ /* Loose Verts, Edges. */
BVHTree *bvhtree[2]; BVHTree *bvhtree[2];
bool cached[2]; bool cached[2];

View File

@ -25,9 +25,9 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
const float obmat[4][4], const float obmat[4][4],
bool is_object_active) bool is_object_active)
{ {
eSnapMode retval = SCE_SNAP_MODE_NONE; eSnapMode retval = SCE_SNAP_TO_NONE;
if (sctx->runtime.snap_to_flag == SCE_SNAP_MODE_FACE) { if (sctx->runtime.snap_to_flag == SCE_SNAP_TO_FACE) {
/* Currently only edge and vert. */ /* Currently only edge and vert. */
return retval; return retval;
} }
@ -95,16 +95,16 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
} }
if (nearest2d.nearest_point.index != -2) { if (nearest2d.nearest_point.index != -2) {
retval = sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE; retval = sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE;
if (retval == SCE_SNAP_MODE_NONE) { if (retval == SCE_SNAP_TO_NONE) {
nearest2d.nearest_point.index = -2; nearest2d.nearest_point.index = -2;
} }
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX) {
float dist_px_sq_edge = nearest2d.nearest_point.dist_sq; float dist_px_sq_edge = nearest2d.nearest_point.dist_sq;
nearest2d.nearest_point.dist_sq = sctx->ret.dist_px_sq; nearest2d.nearest_point.dist_sq = sctx->ret.dist_px_sq;
if (nearest2d.snap_point(head_vec) || nearest2d.snap_point(tail_vec)) { if (nearest2d.snap_point(head_vec) || nearest2d.snap_point(tail_vec)) {
retval = SCE_SNAP_MODE_VERTEX; retval = SCE_SNAP_TO_POINT;
} }
else if (retval) { else if (retval) {
nearest2d.nearest_point.dist_sq = dist_px_sq_edge; nearest2d.nearest_point.dist_sq = dist_px_sq_edge;

View File

@ -23,9 +23,9 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
const float obmat[4][4], const float obmat[4][4],
eSnapMode snap_to_flag) eSnapMode snap_to_flag)
{ {
eSnapMode retval = SCE_SNAP_MODE_NONE; eSnapMode retval = SCE_SNAP_TO_NONE;
if (!(sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX)) { if (!(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT)) {
return retval; return retval;
} }
@ -77,10 +77,10 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
mul_m4_v3(vertex_obmat, bundle_pos); mul_m4_v3(vertex_obmat, bundle_pos);
if (nearest2d.snap_point(bundle_pos)) { if (nearest2d.snap_point(bundle_pos)) {
retval = SCE_SNAP_MODE_VERTEX; retval = SCE_SNAP_TO_POINT;
} }
} }
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }

View File

@ -27,8 +27,8 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
bool has_snap = false; bool has_snap = false;
/* Only vertex snapping mode (eg control points and handles) supported for now). */ /* Only vertex snapping mode (eg control points and handles) supported for now). */
if ((sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) == 0) { if ((sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT) == 0) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
Curve *cu = static_cast<Curve *>(ob_eval->data); Curve *cu = static_cast<Curve *>(ob_eval->data);
@ -41,7 +41,7 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
/* Test BoundBox */ /* Test BoundBox */
BoundBox *bb = BKE_curve_boundbox_get(ob_eval); BoundBox *bb = BKE_curve_boundbox_get(ob_eval);
if (bb && !nearest2d.snap_boundbox(bb->vec[0], bb->vec[6])) { if (bb && !nearest2d.snap_boundbox(bb->vec[0], bb->vec[6])) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
} }
@ -52,62 +52,60 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
LISTBASE_FOREACH (Nurb *, nu, (use_obedit ? &cu->editnurb->nurbs : &cu->nurb)) { LISTBASE_FOREACH (Nurb *, nu, (use_obedit ? &cu->editnurb->nurbs : &cu->nurb)) {
for (int u = 0; u < nu->pntsu; u++) { for (int u = 0; u < nu->pntsu; u++) {
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (use_obedit) {
if (use_obedit) { if (nu->bezt) {
if (nu->bezt) { if (nu->bezt[u].hide) {
if (nu->bezt[u].hide) { /* Skip hidden. */
/* Skip hidden. */ continue;
continue;
}
bool is_selected = (nu->bezt[u].f2 & SELECT) != 0;
if (is_selected && skip_selected) {
continue;
}
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]);
/* Don't snap if handle is selected (moving),
* or if it is aligning to a moving handle. */
bool is_selected_h1 = (nu->bezt[u].f1 & SELECT) != 0;
bool is_selected_h2 = (nu->bezt[u].f3 & SELECT) != 0;
bool is_autoalign_h1 = (nu->bezt[u].h1 & HD_ALIGN) != 0;
bool is_autoalign_h2 = (nu->bezt[u].h2 & HD_ALIGN) != 0;
if (!skip_selected || !(is_selected_h1 || (is_autoalign_h1 && is_selected_h2))) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[0]);
}
if (!skip_selected || !(is_selected_h2 || (is_autoalign_h2 && is_selected_h1))) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[2]);
}
} }
else {
if (nu->bp[u].hide) {
/* Skip hidden. */
continue;
}
bool is_selected = (nu->bp[u].f1 & SELECT) != 0; bool is_selected = (nu->bezt[u].f2 & SELECT) != 0;
if (is_selected && skip_selected) { if (is_selected && skip_selected) {
continue; continue;
} }
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]);
has_snap |= nearest2d.snap_point(nu->bp[u].vec); /* Don't snap if handle is selected (moving),
* or if it is aligning to a moving handle. */
bool is_selected_h1 = (nu->bezt[u].f1 & SELECT) != 0;
bool is_selected_h2 = (nu->bezt[u].f3 & SELECT) != 0;
bool is_autoalign_h1 = (nu->bezt[u].h1 & HD_ALIGN) != 0;
bool is_autoalign_h2 = (nu->bezt[u].h2 & HD_ALIGN) != 0;
if (!skip_selected || !(is_selected_h1 || (is_autoalign_h1 && is_selected_h2))) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[0]);
}
if (!skip_selected || !(is_selected_h2 || (is_autoalign_h2 && is_selected_h1))) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[2]);
} }
} }
else { else {
/* Curve is not visible outside editmode if nurb length less than two. */ if (nu->bp[u].hide) {
if (nu->pntsu > 1) { /* Skip hidden. */
if (nu->bezt) { continue;
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]); }
}
else { bool is_selected = (nu->bp[u].f1 & SELECT) != 0;
has_snap |= nearest2d.snap_point(nu->bp[u].vec); if (is_selected && skip_selected) {
} continue;
}
has_snap |= nearest2d.snap_point(nu->bp[u].vec);
}
}
else {
/* Curve is not visible outside editmode if nurb length less than two. */
if (nu->pntsu > 1) {
if (nu->bezt) {
has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]);
}
else {
has_snap |= nearest2d.snap_point(nu->bp[u].vec);
} }
} }
} }
} }
} }
return has_snap ? SCE_SNAP_MODE_VERTEX : SCE_SNAP_MODE_NONE; return has_snap ? SCE_SNAP_TO_POINT : SCE_SNAP_TO_NONE;
} }

View File

@ -196,16 +196,16 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapData_Edit
static eSnapMode editmesh_snap_mode_supported(BMEditMesh *em) static eSnapMode editmesh_snap_mode_supported(BMEditMesh *em)
{ {
eSnapMode snap_mode_supported = SCE_SNAP_MODE_NONE; eSnapMode snap_mode_supported = SCE_SNAP_TO_NONE;
if (em->bm->totface) { if (em->bm->totface) {
snap_mode_supported |= SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_FACE_NEAREST; snap_mode_supported |= SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST;
} }
if (em->bm->totedge) { if (em->bm->totedge) {
snap_mode_supported |= SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | snap_mode_supported |= SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_MODE_EDGE_PERPENDICULAR; SCE_SNAP_TO_EDGE_PERPENDICULAR;
} }
if (em->bm->totvert) { if (em->bm->totvert) {
snap_mode_supported |= SCE_SNAP_MODE_VERTEX; snap_mode_supported |= SCE_SNAP_TO_VERTEX;
} }
return snap_mode_supported; return snap_mode_supported;
} }
@ -225,7 +225,7 @@ static SnapData_EditMesh *editmesh_snapdata_init(SnapObjectContext *sctx,
} }
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em); eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
if (snap_mode_used == SCE_SNAP_MODE_NONE) { if (snap_mode_used == SCE_SNAP_TO_NONE) {
return nullptr; return nullptr;
} }
@ -447,7 +447,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
eSnapMode snap_to_flag, eSnapMode snap_to_flag,
int polygon) int polygon)
{ {
eSnapMode elem = SCE_SNAP_MODE_NONE; eSnapMode elem = SCE_SNAP_TO_NONE;
BMEditMesh *em = BKE_editmesh_from_object(ob_eval); BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat)); Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat));
@ -461,8 +461,8 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
BMFace *f = BM_face_at_index(em->bm, polygon); BMFace *f = BM_face_at_index(em->bm, polygon);
BMLoop *l_iter, *l_first; BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f); l_iter = l_first = BM_FACE_FIRST_LOOP(f);
if (snap_to_flag & SCE_SNAP_MODE_EDGE) { if (snap_to_flag & SCE_SNAP_TO_EDGE) {
elem = SCE_SNAP_MODE_EDGE; elem = SCE_SNAP_TO_EDGE;
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_EDGE); BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_EDGE);
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE); BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE);
do { do {
@ -475,7 +475,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
} while ((l_iter = l_iter->next) != l_first); } while ((l_iter = l_iter->next) != l_first);
} }
else { else {
elem = SCE_SNAP_MODE_VERTEX; elem = SCE_SNAP_TO_EDGE_ENDPOINT;
BM_mesh_elem_index_ensure(em->bm, BM_VERT); BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_mesh_elem_table_ensure(em->bm, BM_VERT); BM_mesh_elem_table_ensure(em->bm, BM_VERT);
do { do {
@ -493,7 +493,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
return elem; return elem;
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
eSnapMode snap_edge_points_editmesh(SnapObjectContext *sctx, eSnapMode snap_edge_points_editmesh(SnapObjectContext *sctx,
@ -505,7 +505,7 @@ eSnapMode snap_edge_points_editmesh(SnapObjectContext *sctx,
{ {
BMEditMesh *em = BKE_editmesh_from_object(ob_eval); BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat)); Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat));
return nearest2d.snap_edge_points(edge, dist_pex_sq_orig); return nearest2d.snap_edge_points_impl(edge, dist_pex_sq_orig);
} }
static eSnapMode snapEditMesh(SnapData_EditMesh *sod, static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
@ -515,28 +515,32 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
const float obmat[4][4], const float obmat[4][4],
eSnapMode snap_to_flag) eSnapMode snap_to_flag)
{ {
BLI_assert(snap_to_flag != SCE_SNAP_MODE_FACE); BLI_assert(snap_to_flag != SCE_SNAP_TO_FACE);
Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat)); Nearest2dUserData_EditMesh nearest2d(sctx, ob_eval, em->bm, float4x4(obmat));
/* Was BKE_boundbox_ray_hit_check, see: cf6ca226fa58. */ /* Was BKE_boundbox_ray_hit_check, see: cf6ca226fa58. */
if (!nearest2d.snap_boundbox(sod->min, sod->max)) { if (!nearest2d.snap_boundbox(sod->min, sod->max)) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
if (snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (snap_to_flag & SCE_SNAP_TO_POINT) {
BVHTreeFromEditMesh treedata{}; BVHTreeFromEditMesh treedata{};
treedata.tree = sod->bvhtree[0]; treedata.tree = sod->bvhtree[0];
if (treedata.tree == nullptr) { if (treedata.tree == nullptr) {
if (sctx->callbacks.edit_mesh.test_vert_fn) { if (sctx->callbacks.edit_mesh.test_vert_fn) {
auto test_looseverts_fn = [](BMElem *elem, void *user_data) {
SnapObjectContext *sctx_ = static_cast<SnapObjectContext *>(user_data);
BMVert *v = reinterpret_cast<BMVert *>(elem);
if (v->e) {
return false;
}
return sctx_->callbacks.edit_mesh.test_vert_fn(v, sctx_->callbacks.edit_mesh.user_data);
};
blender::BitVector<> verts_mask(em->bm->totvert); blender::BitVector<> verts_mask(em->bm->totvert);
const int verts_num_active = BM_iter_mesh_bitmap_from_filter( const int verts_num_active = BM_iter_mesh_bitmap_from_filter(
BM_VERTS_OF_MESH, BM_VERTS_OF_MESH, em->bm, verts_mask, test_looseverts_fn, sctx);
em->bm,
verts_mask,
(bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
sctx->callbacks.edit_mesh.user_data);
bvhtree_from_editmesh_verts_ex(&treedata, em, verts_mask, verts_num_active, 0.0f, 2, 6); bvhtree_from_editmesh_verts_ex(&treedata, em, verts_mask, verts_num_active, 0.0f, 2, 6);
} }
@ -544,7 +548,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
BKE_bvhtree_from_editmesh_get(&treedata, BKE_bvhtree_from_editmesh_get(&treedata,
em, em,
2, 2,
BVHTREE_FROM_EM_VERTS, BVHTREE_FROM_EM_LOOSEVERTS,
/* WORKAROUND: avoid updating while transforming. */ /* WORKAROUND: avoid updating while transforming. */
G.moving ? nullptr : &sod->mesh_runtime->bvh_cache, G.moving ? nullptr : &sod->mesh_runtime->bvh_cache,
&sod->mesh_runtime->eval_mutex); &sod->mesh_runtime->eval_mutex);
@ -554,7 +558,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
} }
} }
if (snap_to_flag & SCE_SNAP_MODE_EDGE) { if (snap_to_flag & SNAP_TO_EDGE_ELEMENTS) {
BVHTreeFromEditMesh treedata{}; BVHTreeFromEditMesh treedata{};
treedata.tree = sod->bvhtree[1]; treedata.tree = sod->bvhtree[1];
@ -590,9 +594,9 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
nearest.index = -1; nearest.index = -1;
nearest.dist_sq = sctx->ret.dist_px_sq; nearest.dist_sq = sctx->ret.dist_px_sq;
eSnapMode elem = SCE_SNAP_MODE_VERTEX; eSnapMode elem = SCE_SNAP_TO_POINT;
if (sod->bvhtree[0] && (snap_to_flag & SCE_SNAP_MODE_VERTEX)) { if (sod->bvhtree[0] && (snap_to_flag & SCE_SNAP_TO_POINT)) {
BM_mesh_elem_table_ensure(em->bm, BM_VERT); BM_mesh_elem_table_ensure(em->bm, BM_VERT);
BM_mesh_elem_index_ensure(em->bm, BM_VERT); BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BLI_bvhtree_find_nearest_projected(sod->bvhtree[0], BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
@ -606,7 +610,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
&nearest2d); &nearest2d);
} }
if (sod->bvhtree[1] && (snap_to_flag & SCE_SNAP_MODE_EDGE)) { if (sod->bvhtree[1] && (snap_to_flag & SNAP_TO_EDGE_ELEMENTS)) {
int last_index = nearest.index; int last_index = nearest.index;
nearest.index = -1; nearest.index = -1;
BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT); BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT);
@ -622,7 +626,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
&nearest2d); &nearest2d);
if (nearest.index != -1) { if (nearest.index != -1) {
elem = SCE_SNAP_MODE_EDGE; elem = SCE_SNAP_TO_EDGE;
} }
else { else {
nearest.index = last_index; nearest.index = last_index;
@ -634,7 +638,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
return elem; return elem;
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
/** \} */ /** \} */
@ -646,7 +650,7 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
eSnapMode snap_to_flag, eSnapMode snap_to_flag,
bool /*use_hide*/) bool /*use_hide*/)
{ {
eSnapMode elem = SCE_SNAP_MODE_NONE; eSnapMode elem = SCE_SNAP_TO_NONE;
SnapData_EditMesh *sod = editmesh_snapdata_init(sctx, ob_eval, snap_to_flag); SnapData_EditMesh *sod = editmesh_snapdata_init(sctx, ob_eval, snap_to_flag);
if (sod == nullptr) { if (sod == nullptr) {
@ -656,8 +660,8 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
BMEditMesh *em = sod->treedata_editmesh.em; BMEditMesh *em = sod->treedata_editmesh.em;
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em); eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
if (snap_mode_used & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | if (snap_mode_used & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX)) SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_TO_VERTEX))
{ {
elem = snapEditMesh(sod, sctx, ob_eval, em, obmat, snap_to_flag); elem = snapEditMesh(sod, sctx, ob_eval, em, obmat, snap_to_flag);
if (elem) { if (elem) {
@ -665,17 +669,17 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
} }
} }
if (snap_mode_used & SCE_SNAP_MODE_FACE) { if (snap_mode_used & SCE_SNAP_TO_FACE) {
if (raycastEditMesh(sod, sctx, em, obmat, sctx->runtime.object_index++)) { if (raycastEditMesh(sod, sctx, em, obmat, sctx->runtime.object_index++)) {
return SCE_SNAP_MODE_FACE; return SCE_SNAP_TO_FACE;
} }
} }
if (snap_mode_used & SCE_SNAP_MODE_FACE_NEAREST) { if (snap_mode_used & SCE_SNAP_INDIVIDUAL_NEAREST) {
if (nearest_world_editmesh(sod, sctx, em, obmat)) { if (nearest_world_editmesh(sod, sctx, em, obmat)) {
return SCE_SNAP_MODE_FACE_NEAREST; return SCE_SNAP_INDIVIDUAL_NEAREST;
} }
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }

View File

@ -408,7 +408,7 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
eSnapMode snap_to_flag, eSnapMode snap_to_flag,
int polygon) int polygon)
{ {
eSnapMode elem = SCE_SNAP_MODE_NONE; eSnapMode elem = SCE_SNAP_TO_NONE;
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id); const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id);
@ -421,8 +421,8 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
const blender::IndexRange poly = mesh_eval->polys()[polygon]; const blender::IndexRange poly = mesh_eval->polys()[polygon];
if (snap_to_flag & SCE_SNAP_MODE_EDGE) { if (snap_to_flag & SCE_SNAP_TO_EDGE) {
elem = SCE_SNAP_MODE_EDGE; elem = SCE_SNAP_TO_EDGE;
BLI_assert(nearest2d.edges != nullptr); BLI_assert(nearest2d.edges != nullptr);
const int *poly_edges = &nearest2d.corner_edges[poly.start()]; const int *poly_edges = &nearest2d.corner_edges[poly.start()];
for (int i = poly.size(); i--;) { for (int i = poly.size(); i--;) {
@ -435,7 +435,7 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
} }
} }
else { else {
elem = SCE_SNAP_MODE_VERTEX; elem = SCE_SNAP_TO_VERTEX;
const int *poly_verts = &nearest2d.corner_verts[poly.start()]; const int *poly_verts = &nearest2d.corner_verts[poly.start()];
for (int i = poly.size(); i--;) { for (int i = poly.size(); i--;) {
cb_snap_vert(&nearest2d, cb_snap_vert(&nearest2d,
@ -452,7 +452,7 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
return elem; return elem;
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx, eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx,
@ -463,7 +463,7 @@ eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx,
int edge) int edge)
{ {
Nearest2dUserData_Mesh nearest2d(sctx, ob_eval, id, float4x4(obmat)); Nearest2dUserData_Mesh nearest2d(sctx, ob_eval, id, float4x4(obmat));
return nearest2d.snap_edge_points(edge, dist_pex_sq_orig); return nearest2d.snap_edge_points_impl(edge, dist_pex_sq_orig);
} }
static eSnapMode snapMesh(SnapObjectContext *sctx, static eSnapMode snapMesh(SnapObjectContext *sctx,
@ -472,12 +472,12 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
const float obmat[4][4], const float obmat[4][4],
bool use_hide) bool use_hide)
{ {
BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE); BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_TO_FACE);
if (me_eval->totvert == 0) { if (me_eval->totvert == 0) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
if (me_eval->totedge == 0 && !(sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX)) { if (me_eval->totedge == 0 && !(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT)) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
Nearest2dUserData_Mesh nearest2d(sctx, ob_eval, &me_eval->id, float4x4(obmat)); Nearest2dUserData_Mesh nearest2d(sctx, ob_eval, &me_eval->id, float4x4(obmat));
@ -485,7 +485,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
if (ob_eval->data == me_eval) { if (ob_eval->data == me_eval) {
const BoundBox *bb = BKE_mesh_boundbox_get(ob_eval); const BoundBox *bb = BKE_mesh_boundbox_get(ob_eval);
if (!nearest2d.snap_boundbox(bb->vec[0], bb->vec[6])) { if (!nearest2d.snap_boundbox(bb->vec[0], bb->vec[6])) {
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
} }
@ -495,7 +495,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
BVHTree *bvhtree[2] = {nullptr}; BVHTree *bvhtree[2] = {nullptr};
bvhtree[0] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEEDGES, 2); bvhtree[0] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEEDGES, 2);
BLI_assert(treedata_dummy.cached); BLI_assert(treedata_dummy.cached);
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT) {
bvhtree[1] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEVERTS, 2); bvhtree[1] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEVERTS, 2);
BLI_assert(treedata_dummy.cached); BLI_assert(treedata_dummy.cached);
} }
@ -507,10 +507,10 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
nearest.dist_sq = sctx->ret.dist_px_sq; nearest.dist_sq = sctx->ret.dist_px_sq;
int last_index = nearest.index; int last_index = nearest.index;
eSnapMode elem = SCE_SNAP_MODE_VERTEX; eSnapMode elem = SCE_SNAP_TO_POINT;
if (bvhtree[1]) { if (bvhtree[1]) {
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX); BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT);
/* snap to loose verts */ /* snap to loose verts */
BLI_bvhtree_find_nearest_projected(bvhtree[1], BLI_bvhtree_find_nearest_projected(bvhtree[1],
nearest2d.pmat_local.ptr(), nearest2d.pmat_local.ptr(),
@ -525,7 +525,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
last_index = nearest.index; last_index = nearest.index;
} }
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) { if (sctx->runtime.snap_to_flag & (SNAP_TO_EDGE_ELEMENTS & ~SCE_SNAP_TO_EDGE_ENDPOINT)) {
if (bvhtree[0]) { if (bvhtree[0]) {
/* Snap to loose edges. */ /* Snap to loose edges. */
BLI_bvhtree_find_nearest_projected( BLI_bvhtree_find_nearest_projected(
@ -555,11 +555,11 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
} }
if (last_index != nearest.index) { if (last_index != nearest.index) {
elem = SCE_SNAP_MODE_EDGE; elem = SCE_SNAP_TO_EDGE;
} }
} }
else { else {
BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX); BLI_assert(sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE_ENDPOINT);
if (bvhtree[0]) { if (bvhtree[0]) {
/* Snap to loose edge verts. */ /* Snap to loose edge verts. */
BLI_bvhtree_find_nearest_projected( BLI_bvhtree_find_nearest_projected(
@ -594,23 +594,23 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
return elem; return elem;
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }
/** \} */ /** \} */
static eSnapMode mesh_snap_mode_supported(const Mesh *mesh) static eSnapMode mesh_snap_mode_supported(const Mesh *mesh)
{ {
eSnapMode snap_mode_supported = SCE_SNAP_MODE_NONE; eSnapMode snap_mode_supported = SCE_SNAP_TO_NONE;
if (mesh->totpoly) { if (mesh->totpoly) {
snap_mode_supported |= SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_FACE_NEAREST; snap_mode_supported |= SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST;
} }
if (mesh->totedge) { if (mesh->totedge) {
snap_mode_supported |= SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | snap_mode_supported |= SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_MODE_EDGE_PERPENDICULAR; SCE_SNAP_TO_EDGE_PERPENDICULAR;
} }
if (mesh->totvert) { if (mesh->totvert) {
snap_mode_supported |= SCE_SNAP_MODE_VERTEX; snap_mode_supported |= SCE_SNAP_TO_VERTEX;
} }
return snap_mode_supported; return snap_mode_supported;
} }
@ -622,13 +622,13 @@ eSnapMode snap_object_mesh(SnapObjectContext *sctx,
eSnapMode snap_to_flag, eSnapMode snap_to_flag,
bool use_hide) bool use_hide)
{ {
eSnapMode elem = SCE_SNAP_MODE_NONE; eSnapMode elem = SCE_SNAP_TO_NONE;
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id); const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id);
eSnapMode snap_mode_used = snap_to_flag & mesh_snap_mode_supported(mesh_eval); eSnapMode snap_mode_used = snap_to_flag & mesh_snap_mode_supported(mesh_eval);
if (snap_mode_used & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT | if (snap_mode_used & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX)) SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_TO_VERTEX))
{ {
elem = snapMesh(sctx, ob_eval, mesh_eval, obmat, use_hide); elem = snapMesh(sctx, ob_eval, mesh_eval, obmat, use_hide);
if (elem) { if (elem) {
@ -636,17 +636,17 @@ eSnapMode snap_object_mesh(SnapObjectContext *sctx,
} }
} }
if (snap_mode_used & SCE_SNAP_MODE_FACE) { if (snap_mode_used & SCE_SNAP_TO_FACE) {
if (raycastMesh(sctx, ob_eval, mesh_eval, obmat, sctx->runtime.object_index++, use_hide)) { if (raycastMesh(sctx, ob_eval, mesh_eval, obmat, sctx->runtime.object_index++, use_hide)) {
return SCE_SNAP_MODE_FACE; return SCE_SNAP_TO_FACE;
} }
} }
if (snap_mode_used & SCE_SNAP_MODE_FACE_NEAREST) { if (snap_mode_used & SCE_SNAP_INDIVIDUAL_NEAREST) {
if (nearest_world_mesh(sctx, mesh_eval, obmat, use_hide)) { if (nearest_world_mesh(sctx, mesh_eval, obmat, use_hide)) {
return SCE_SNAP_MODE_FACE_NEAREST; return SCE_SNAP_INDIVIDUAL_NEAREST;
} }
} }
return SCE_SNAP_MODE_NONE; return SCE_SNAP_TO_NONE;
} }

View File

@ -336,11 +336,11 @@
.autokey_mode = AUTOKEY_MODE_NORMAL, \ .autokey_mode = AUTOKEY_MODE_NORMAL, \
\ \
.transform_pivot_point = V3D_AROUND_CENTER_MEDIAN, \ .transform_pivot_point = V3D_AROUND_CENTER_MEDIAN, \
.snap_mode = SCE_SNAP_MODE_INCREMENT, \ .snap_mode = SCE_SNAP_TO_GEOM, \
.snap_node_mode = SCE_SNAP_MODE_GRID, \ .snap_node_mode = SCE_SNAP_TO_GRID, \
.snap_uv_mode = SCE_SNAP_MODE_INCREMENT, \ .snap_uv_mode = SCE_SNAP_TO_INCREMENT, \
.snap_flag = SCE_SNAP_TO_INCLUDE_EDITED | SCE_SNAP_TO_INCLUDE_NONEDITED, \ .snap_flag = SCE_SNAP_TO_INCLUDE_EDITED | SCE_SNAP_TO_INCLUDE_NONEDITED, \
.snap_transform_mode_flag = SCE_SNAP_TRANSFORM_MODE_TRANSLATE, \ .snap_transform_mode_flag = (SCE_SNAP_TRANSFORM_MODE_TRANSLATE | SCE_SNAP_TRANSFORM_MODE_ROTATE |SCE_SNAP_TRANSFORM_MODE_SCALE), \
.snap_face_nearest_steps = 1, \ .snap_face_nearest_steps = 1, \
\ \
.curve_paint_settings = _DNA_DEFAULTS_CurvePaintSettings, \ .curve_paint_settings = _DNA_DEFAULTS_CurvePaintSettings, \
@ -370,7 +370,6 @@
.uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN, \ .uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN, \
\ \
/* Placement */ \ /* Placement */ \
.snap_mode_tools = SCE_SNAP_MODE_GEOM,\
.plane_axis = 2,\ .plane_axis = 2,\
} }

View File

@ -1697,12 +1697,11 @@ typedef struct ToolSettings {
struct SequencerToolSettings *sequencer_tool_settings; struct SequencerToolSettings *sequencer_tool_settings;
short snap_mode_tools; /* If SCE_SNAP_MODE_NONE, use #ToolSettings::snap_mode. #eSnapMode. */ char plane_axis; /* X, Y or Z. */
char plane_axis; /* X, Y or Z. */ char plane_depth; /* #eV3DPlaceDepth. */
char plane_depth; /* #eV3DPlaceDepth. */ char plane_orient; /* #eV3DPlaceOrient. */
char plane_orient; /* #eV3DPlaceOrient. */
char use_plane_axis_auto; char use_plane_axis_auto;
char _pad7[2]; char _pad7[4];
} ToolSettings; } ToolSettings;
@ -2274,8 +2273,8 @@ ENUM_OPERATORS(eSnapFlag, SCE_SNAP_BACKFACE_CULLING)
/** See #ToolSettings.snap_target (to be renamed `snap_source`) and #TransSnap.source_operation */ /** See #ToolSettings.snap_target (to be renamed `snap_source`) and #TransSnap.source_operation */
typedef enum eSnapSourceOP { typedef enum eSnapSourceOP {
SCE_SNAP_SOURCE_CLOSEST = 0, SCE_SNAP_SOURCE_CLOSEST = 0,
SCE_SNAP_SOURCE_CENTER = 1, SCE_SNAP_SOURCE_MEDIAN = 1,
SCE_SNAP_SOURCE_MEDIAN = 2, SCE_SNAP_SOURCE_CENTER = 2,
SCE_SNAP_SOURCE_ACTIVE = 3, SCE_SNAP_SOURCE_ACTIVE = 3,
} eSnapSourceOP; } eSnapSourceOP;
@ -2298,37 +2297,41 @@ ENUM_OPERATORS(eSnapTargetOP, SCE_SNAP_TARGET_NOT_NONEDITED)
/** #ToolSettings.snap_mode */ /** #ToolSettings.snap_mode */
typedef enum eSnapMode { typedef enum eSnapMode {
SCE_SNAP_MODE_NONE = 0, SCE_SNAP_TO_NONE = 0,
SCE_SNAP_MODE_VERTEX = (1 << 0), SCE_SNAP_TO_POINT = (1 << 0),
SCE_SNAP_MODE_EDGE = (1 << 1),
SCE_SNAP_MODE_FACE = (1 << 2), SCE_SNAP_TO_EDGE = (1 << 1),
SCE_SNAP_MODE_VOLUME = (1 << 3), SCE_SNAP_TO_EDGE_ENDPOINT = (1 << 2),
SCE_SNAP_MODE_EDGE_MIDPOINT = (1 << 4), SCE_SNAP_TO_EDGE_MIDPOINT = (1 << 3),
SCE_SNAP_MODE_EDGE_PERPENDICULAR = (1 << 5), SCE_SNAP_TO_EDGE_PERPENDICULAR = (1 << 4),
SCE_SNAP_TO_FACE = (1 << 5),
SCE_SNAP_TO_VOLUME = (1 << 6),
/* For snap individual elements. */ /* For snap individual elements. */
SCE_SNAP_MODE_FACE_NEAREST = (1 << 8), SCE_SNAP_INDIVIDUAL_PROJECT = (1 << 7),
/** Project individual elements instead of whole object. */ SCE_SNAP_INDIVIDUAL_NEAREST = (1 << 8),
SCE_SNAP_MODE_FACE_RAYCAST = (1 << 9),
/** #ToolSettings.snap_node_mode */ /** #ToolSettings.snap_node_mode */
SCE_SNAP_MODE_NODE_X = (1 << 0), SCE_SNAP_TO_NODE_X = (1 << 0),
SCE_SNAP_MODE_NODE_Y = (1 << 1), SCE_SNAP_TO_NODE_Y = (1 << 1),
/** #ToolSettings.snap_mode and #ToolSettings.snap_node_mode and #ToolSettings.snap_uv_mode */ /** #ToolSettings.snap_mode and #ToolSettings.snap_node_mode and #ToolSettings.snap_uv_mode */
SCE_SNAP_MODE_INCREMENT = (1 << 6), SCE_SNAP_TO_INCREMENT = (1 << 9),
SCE_SNAP_MODE_GRID = (1 << 7), SCE_SNAP_TO_GRID = (1 << 10),
} eSnapMode; } eSnapMode;
/* Due to dependency conflicts with Cycles, header cannot directly include `BLI_utildefines.h`. */ /* Due to dependency conflicts with Cycles, header cannot directly include `BLI_utildefines.h`. */
/* TODO: move this macro to a more general place. */ /* TODO: move this macro to a more general place. */
#ifdef ENUM_OPERATORS #ifdef ENUM_OPERATORS
ENUM_OPERATORS(eSnapMode, SCE_SNAP_MODE_FACE_RAYCAST) ENUM_OPERATORS(eSnapMode, SCE_SNAP_TO_GRID)
#endif #endif
#define SCE_SNAP_MODE_GEOM \ #define SCE_SNAP_TO_VERTEX (SCE_SNAP_TO_POINT | SCE_SNAP_TO_EDGE_ENDPOINT)
(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_TO_GEOM \
(SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE | SCE_SNAP_TO_EDGE_MIDPOINT | \
SCE_SNAP_TO_EDGE_PERPENDICULAR)
/** #SequencerToolSettings.snap_mode */ /** #SequencerToolSettings.snap_mode */
#define SEQ_SNAP_TO_STRIPS (1 << 0) #define SEQ_SNAP_TO_STRIPS (1 << 0)

View File

@ -153,23 +153,23 @@ const EnumPropertyItem rna_enum_mesh_select_mode_uv_items[] = {
/* clang-format off */ /* clang-format off */
#define RNA_SNAP_ELEMENTS_BASE \ #define RNA_SNAP_ELEMENTS_BASE \
{SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments"}, \ {SCE_SNAP_TO_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments"}, \
{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, \ {SCE_SNAP_TO_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, \
{SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges"}, \ {SCE_SNAP_TO_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_TO_EDGE_MIDPOINT, "EDGE_MIDPOINT", ICON_SNAP_MIDPOINT, "Edge Center", "Snap to the middle of edges"}, \
{SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume"}, \ {SCE_SNAP_TO_EDGE_PERPENDICULAR, "EDGE_PERPENDICULAR", ICON_SNAP_PERPENDICULAR, "Edge Perpendicular", "Snap to the nearest point on an edge"}, \
{SCE_SNAP_MODE_EDGE_MIDPOINT, "EDGE_MIDPOINT", ICON_SNAP_MIDPOINT, "Edge Center", "Snap to the middle of edges"}, \ {SCE_SNAP_TO_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap by projecting onto faces"}, \
{SCE_SNAP_MODE_EDGE_PERPENDICULAR, "EDGE_PERPENDICULAR", ICON_SNAP_PERPENDICULAR, "Edge Perpendicular", "Snap to the nearest point on an edge"} {SCE_SNAP_TO_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume"}
/* clang-format on */ /* clang-format on */
const EnumPropertyItem rna_enum_snap_element_items[] = { const EnumPropertyItem rna_enum_snap_element_items[] = {
RNA_SNAP_ELEMENTS_BASE, RNA_SNAP_ELEMENTS_BASE,
{SCE_SNAP_MODE_FACE_RAYCAST, {SCE_SNAP_INDIVIDUAL_PROJECT,
"FACE_PROJECT", "FACE_PROJECT",
ICON_SNAP_FACE, ICON_SNAP_FACE,
"Face Project", "Face Project",
"Snap by projecting onto faces"}, "Snap by projecting onto faces"},
{SCE_SNAP_MODE_FACE_NEAREST, {SCE_SNAP_INDIVIDUAL_NEAREST,
"FACE_NEAREST", "FACE_NEAREST",
ICON_SNAP_FACE_NEAREST, ICON_SNAP_FACE_NEAREST,
"Face Nearest", "Face Nearest",
@ -189,10 +189,10 @@ static const EnumPropertyItem *rna_enum_snap_element_individual_items =
#endif #endif
const EnumPropertyItem rna_enum_snap_node_element_items[] = { const EnumPropertyItem rna_enum_snap_node_element_items[] = {
{SCE_SNAP_MODE_GRID, "GRID", ICON_SNAP_GRID, "Grid", "Snap to grid"}, {SCE_SNAP_TO_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"}, {SCE_SNAP_TO_NODE_X, "NODE_X", ICON_NODE_SIDE, "Node X", "Snap to left/right node border"},
{SCE_SNAP_MODE_NODE_Y, "NODE_Y", ICON_NODE_TOP, "Node Y", "Snap to top/bottom node border"}, {SCE_SNAP_TO_NODE_Y, "NODE_Y", ICON_NODE_TOP, "Node Y", "Snap to top/bottom node border"},
{SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y, {SCE_SNAP_TO_NODE_X | SCE_SNAP_TO_NODE_Y,
"NODE_XY", "NODE_XY",
ICON_NODE_CORNER, ICON_NODE_CORNER,
"Node X / Y", "Node X / Y",
@ -202,12 +202,12 @@ const EnumPropertyItem rna_enum_snap_node_element_items[] = {
#ifndef RNA_RUNTIME #ifndef RNA_RUNTIME
static const EnumPropertyItem snap_uv_element_items[] = { static const EnumPropertyItem snap_uv_element_items[] = {
{SCE_SNAP_MODE_INCREMENT, {SCE_SNAP_TO_INCREMENT,
"INCREMENT", "INCREMENT",
ICON_SNAP_INCREMENT, ICON_SNAP_INCREMENT,
"Increment", "Increment",
"Snap to increments of grid"}, "Snap to increments of grid"},
{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, {SCE_SNAP_TO_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"},
{0, NULL, 0, NULL, NULL}, {0, NULL, 0, NULL, NULL},
}; };
@ -678,12 +678,6 @@ static const EnumPropertyItem plane_orientation_items[] = {
{0, NULL, 0, NULL, NULL}, {0, NULL, 0, NULL, NULL},
}; };
static const EnumPropertyItem snap_to_items[] = {
{SCE_SNAP_MODE_GEOM, "GEOMETRY", 0, "Geometry", "Snap to all geometry"},
{SCE_SNAP_MODE_NONE, "DEFAULT", 0, "Default", "Use the current snap settings"},
{0, NULL, 0, NULL, NULL},
};
#ifdef RNA_RUNTIME #ifdef RNA_RUNTIME
# include "BLI_string_utils.h" # include "BLI_string_utils.h"
@ -3413,6 +3407,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_funcs( RNA_def_property_enum_funcs(
prop, "rna_ToolSettings_snap_mode_get", "rna_ToolSettings_snap_mode_set", NULL); prop, "rna_ToolSettings_snap_mode_get", "rna_ToolSettings_snap_mode_set", NULL);
RNA_def_property_flag(prop, PROP_ENUM_FLAG); RNA_def_property_flag(prop, PROP_ENUM_FLAG);
RNA_def_property_enum_default(prop, SCE_SNAP_TO_GEOM);
RNA_def_property_ui_text(prop, "Snap Element", "Type of element to snap to"); 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 */ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
@ -3528,7 +3523,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_snap_rotate", PROP_BOOLEAN, PROP_NONE); prop = RNA_def_property(srna, "use_snap_rotate", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna( RNA_def_property_boolean_sdna(
prop, NULL, "snap_transform_mode_flag", SCE_SNAP_TRANSFORM_MODE_ROTATE); prop, NULL, "snap_transform_mode_flag", SCE_SNAP_TRANSFORM_MODE_ROTATE);
RNA_def_property_boolean_default(prop, false);
RNA_def_property_ui_text( RNA_def_property_ui_text(
prop, "Use Snap for Rotation", "Rotate is affected by the snapping settings"); prop, "Use Snap for Rotation", "Rotate is affected by the snapping settings");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
@ -3536,7 +3530,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_snap_scale", PROP_BOOLEAN, PROP_NONE); prop = RNA_def_property(srna, "use_snap_scale", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna( RNA_def_property_boolean_sdna(
prop, NULL, "snap_transform_mode_flag", SCE_SNAP_TRANSFORM_MODE_SCALE); prop, NULL, "snap_transform_mode_flag", SCE_SNAP_TRANSFORM_MODE_SCALE);
RNA_def_property_boolean_default(prop, false);
RNA_def_property_ui_text(prop, "Use Snap for Scale", "Scale is affected by snapping settings"); RNA_def_property_ui_text(prop, "Use Snap for Scale", "Scale is affected by snapping settings");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
@ -3566,12 +3559,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_default(prop, V3D_PLACE_ORIENT_SURFACE); RNA_def_property_enum_default(prop, V3D_PLACE_ORIENT_SURFACE);
RNA_def_property_ui_text(prop, "Orientation", "The initial depth used when placing the cursor"); RNA_def_property_ui_text(prop, "Orientation", "The initial depth used when placing the cursor");
prop = RNA_def_property(srna, "snap_elements_tool", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "snap_mode_tools");
RNA_def_property_enum_items(prop, snap_to_items);
RNA_def_property_enum_default(prop, SCE_SNAP_MODE_GEOM);
RNA_def_property_ui_text(prop, "Snap to", "The target to use while snapping");
/* Grease Pencil */ /* Grease Pencil */
prop = RNA_def_property(srna, "use_gpencil_draw_additive", PROP_BOOLEAN, PROP_NONE); prop = RNA_def_property(srna, "use_gpencil_draw_additive", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_RETAIN_LAST); RNA_def_property_boolean_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_RETAIN_LAST);