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,
)
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):
from bpy import context
@ -324,7 +315,6 @@ class Prefs(bpy.types.KeyConfigPreferences):
sub.prop(self, "use_v3d_tab_menu")
sub.prop(self, "use_pie_click_drag")
sub.prop(self, "use_v3d_shade_ex_pie")
sub.prop(self, "use_transform_navigation")
# File Browser settings.
col = layout.column()
@ -385,7 +375,6 @@ def load():
use_pie_click_drag=kc_prefs.use_pie_click_drag,
use_file_single_click=kc_prefs.use_file_single_click,
experimental=prefs.experimental,
use_transform_navigation=kc_prefs.use_transform_navigation,
),
)

View File

@ -99,8 +99,6 @@ class Params:
"tool_maybe_tweak_event",
# Access to bpy.context.preferences.experimental
"experimental",
# Changes some transformers modal key-map items to avoid conflicts with navigation operations
"use_transform_navigation",
)
def __init__(
@ -129,7 +127,6 @@ class Params:
v3d_tilde_action='VIEW',
v3d_alt_mmb_drag_action='RELATIVE',
experimental=None,
use_transform_navigation=False,
):
from sys import platform
self.apple = (platform == 'darwin')
@ -228,7 +225,6 @@ class Params:
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_maybe_tweak_event = {"type": self.tool_mouse, "value": self.tool_maybe_tweak_value}
self.use_transform_navigation = use_transform_navigation
self.experimental = experimental
@ -1608,16 +1604,13 @@ def km_view3d(params):
# Transform.
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
op_tool_optional(
("transform.translate", {"type": 'G', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
(op_tool_cycle, "builtin.move"), params),
op_tool_optional(
("transform.rotate", {"type": 'R', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.rotate", {"type": 'R', "value": 'PRESS'}, None),
(op_tool_cycle, "builtin.rotate"), params),
op_tool_optional(
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.resize", {"type": 'S', "value": 'PRESS'}, None),
(op_tool_cycle, "builtin.scale"), params),
op_tool_optional(
("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),
# Extrude and move selected points
op_tool_optional(
("gpencil.extrude_move", {"type": 'E', "value": 'PRESS'},
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
("gpencil.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
(op_tool_cycle, "builtin.extrude"), params),
# Delete
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_object_apply", {"type": 'A', "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},
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
("object.duplicate_move_linked", {"type": 'D', "value": 'PRESS', "alt": True},
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
("object.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
("object.duplicate_move_linked", {"type": 'D', "value": 'PRESS', "alt": True}, None),
("object.join", {"type": 'J', "value": 'PRESS', "ctrl": True}, None),
("wm.context_toggle", {"type": 'PERIOD', "value": 'PRESS', "ctrl": True},
{"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.draw", {"type": 'RET', "value": 'PRESS'}, None),
("paintcurve.draw", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None),
("transform.translate", {"type": 'G', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
("transform.rotate", {"type": 'R', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.rotate", {"type": 'R', "value": 'PRESS'}, None),
("transform.resize", {"type": 'S', "value": 'PRESS'}, None),
])
return keymap
@ -4793,8 +4780,7 @@ def km_curve(params):
("curve.separate", {"type": 'P', "value": 'PRESS'}, None),
("curve.split", {"type": 'Y', "value": 'PRESS'}, None),
op_tool_optional(
("curve.extrude_move", {"type": 'E', "value": 'PRESS'},
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
("curve.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
(op_tool_cycle, "builtin.extrude"), params),
("curve.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, 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},
{"properties": [("inside", True)]}),
op_tool_optional(
("view3d.edit_mesh_extrude_move_normal", {"type": 'E', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("view3d.edit_mesh_extrude_move_normal", {"type": 'E', "value": 'PRESS'}, None),
(op_tool_cycle, "builtin.extrude_region"), params),
op_menu("VIEW3D_MT_edit_mesh_extrude", {"type": 'E', "value": 'PRESS', "alt": True}),
("transform.edge_crease", {"type": 'E', "value": 'PRESS', "shift": True}, None),
@ -5421,13 +5406,11 @@ def km_mesh(params):
# No tool is available for this.
("mesh.rip_move", {"type": 'V', "value": 'PRESS', "alt": True},
{"properties": [("MESH_OT_rip", [("use_fill", True)],)]}),
("mesh.rip_edge_move", {"type": 'D', "value": 'PRESS', "alt": True},
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
("mesh.rip_edge_move", {"type": 'D', "value": 'PRESS', "alt": True}, None),
op_menu("VIEW3D_MT_edit_mesh_merge", {"type": 'M', "value": 'PRESS'}),
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.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True},
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
("mesh.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
op_menu("VIEW3D_MT_mesh_add", {"type": 'A', "value": 'PRESS', "shift": True}),
("mesh.separate", {"type": 'P', "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": 'DEL', "value": 'PRESS', "ctrl": True}, None),
op_tool_optional(
("armature.extrude_move", {"type": 'E', "value": 'PRESS'},
{"properties": [("TRANSFORM_OT_translate", [("allow_navigation", params.use_transform_navigation)])]}),
("armature.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
(op_tool_cycle, "builtin.extrude"), params),
("armature.extrude_forked", {"type": 'E', "value": 'PRESS', "shift": 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_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_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "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": True}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "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_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_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_DOWN", {"type": 'WHEELUPMOUSE', "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": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None),
("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "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),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True, "alt": params.use_transform_navigation}, None),
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY', "alt": True}, None),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True, "alt": True}, None),
("PRECISION", {"type": 'LEFT_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_idname = "view3d.edit_mesh_extrude_individual_move"
allow_navigation: BoolProperty(
name="allow_navigation",
default=False,
description="Allow navigation",
)
@classmethod
def poll(cls, context):
obj = context.active_object
@ -40,27 +34,27 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
TRANSFORM_OT_translate={
"orient_type": 'NORMAL',
"constraint_axis": (False, False, True),
"allow_navigation": self.allow_navigation,
"release_confirm": False,
},
)
elif select_mode[2] and totface > 1:
bpy.ops.mesh.extrude_faces_move(
'INVOKE_REGION_WIN',
TRANSFORM_OT_shrink_fatten={
"allow_navigation": self.allow_navigation,
"release_confirm": False,
})
elif select_mode[1] and totedge >= 1:
bpy.ops.mesh.extrude_edges_move(
'INVOKE_REGION_WIN',
TRANSFORM_OT_translate={
"allow_navigation": self.allow_navigation,
"release_confirm": False,
},
)
else:
bpy.ops.mesh.extrude_vertices_move(
'INVOKE_REGION_WIN',
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",
)
allow_navigation: BoolProperty(
name="allow_navigation",
default=False,
description="Allow navigation",
)
@classmethod
def poll(cls, context):
obj = context.active_object
return (obj is not None and obj.mode == 'EDIT')
@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
totface = mesh.total_face_sel
@ -107,7 +95,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
bpy.ops.mesh.extrude_region_shrink_fatten(
'INVOKE_REGION_WIN',
TRANSFORM_OT_shrink_fatten={
"allow_navigation": allow_navigation,
"release_confirm": False,
},
)
elif dissolve_and_intersect:
@ -119,7 +107,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
TRANSFORM_OT_translate={
"orient_type": 'NORMAL',
"constraint_axis": (False, False, True),
"allow_navigation": allow_navigation,
"release_confirm": False,
},
)
else:
@ -128,7 +116,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
TRANSFORM_OT_translate={
"orient_type": 'NORMAL',
"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.
# "constraint_axis": (True, True, False)})
"constraint_axis": (False, False, False),
"allow_navigation": allow_navigation,
"release_confirm": False,
})
else:
bpy.ops.mesh.extrude_region_move(
'INVOKE_REGION_WIN',
TRANSFORM_OT_translate={
"allow_navigation": allow_navigation,
"release_confirm": False,
},
)
@ -157,8 +145,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
return {'FINISHED'}
def execute(self, context):
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(
context, False, self.dissolve_and_intersect, self.allow_navigation)
return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False, self.dissolve_and_intersect)
def invoke(self, context, _event):
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_idname = "view3d.edit_mesh_extrude_move_shrink_fatten"
allow_navigation: BoolProperty(
name="allow_navigation",
default=False,
description="Allow navigation",
)
@classmethod
def poll(cls, context):
obj = context.active_object
return (obj is not None and obj.mode == 'EDIT')
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):
return self.execute(context)
@ -192,12 +173,6 @@ class VIEW3D_OT_edit_mesh_extrude_manifold_normal(Operator):
bl_label = "Extrude Manifold Along Normals"
bl_idname = "view3d.edit_mesh_extrude_manifold_normal"
allow_navigation: BoolProperty(
name="allow_navigation",
default=False,
description="Allow navigation",
)
@classmethod
def poll(cls, context):
obj = context.active_object
@ -212,7 +187,7 @@ class VIEW3D_OT_edit_mesh_extrude_manifold_normal(Operator):
TRANSFORM_OT_translate={
"orient_type": 'NORMAL',
"constraint_axis": (False, False, True),
"allow_navigation": self.allow_navigation,
"release_confirm": False,
},
)
return {'FINISHED'}

View File

@ -513,8 +513,6 @@ class _defs_view3d_add:
row.label(text="Orientation:")
row = layout.row()
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'
if region_is_header:

View File

@ -641,7 +641,7 @@ class VIEW3D_HT_header(Header):
icon = snap_items[elem].icon
break
else:
text = "Mix"
text = "Multi"
icon = 'NONE'
del snap_items, snap_elements
@ -1049,14 +1049,10 @@ class VIEW3D_MT_transform_base:
# TODO: get rid of the custom text strings?
def draw(self, context):
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.rotate").allow_navigation = allow_navigation
layout.operator("transform.resize", text="Scale").allow_navigation = allow_navigation
layout.operator("transform.translate").release_confirm = False
layout.operator("transform.rotate").release_confirm = False
layout.operator("transform.resize", text="Scale").release_confirm = False
layout.separator()
@ -1076,18 +1072,13 @@ class VIEW3D_MT_transform_base:
# Generic transform menu - geometry types
class VIEW3D_MT_transform(VIEW3D_MT_transform_base, Menu):
def draw(self, context):
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
# base menu
VIEW3D_MT_transform_base.draw(self, context)
# generic...
layout = self.layout
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")
elif context.mode == 'EDIT_CURVE':
layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
@ -1096,10 +1087,11 @@ class VIEW3D_MT_transform(VIEW3D_MT_transform_base, Menu):
layout.separator()
props = layout.operator("transform.translate", text="Move Texture Space")
props.texture_space = True
props.allow_navigation = allow_navigation
props.release_confirm = False
props = layout.operator("transform.resize", text="Scale Texture Space")
props.texture_space = True
props.allow_navigation = allow_navigation
props.release_confirm = False
# 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'
if is_face_mode:
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
col = row.column(align=True)
col.label(text="Face Context Menu", icon='FACESEL')
@ -4225,11 +4212,11 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
col.separator()
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",
text="Extrude Faces Along Normals").allow_navigation = allow_navigation
text="Extrude Faces Along Normals").release_confirm = False
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.poke")
@ -4281,11 +4268,6 @@ class VIEW3D_MT_edit_mesh_extrude(Menu):
def draw(self, context):
from math import pi
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
@ -4295,22 +4277,22 @@ class VIEW3D_MT_edit_mesh_extrude(Menu):
if mesh.total_face_sel:
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",
text="Extrude Faces Along Normals").allow_navigation = allow_navigation
text="Extrude Faces Along Normals").release_confirm = False
layout.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
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]):
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]:
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()
@ -4463,22 +4445,17 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
bl_idname = "VIEW3D_MT_edit_mesh_faces"
def draw(self, context):
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
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",
text="Extrude Faces Along Normals").allow_navigation = allow_navigation
text="Extrude Faces Along Normals").release_confirm = False
layout.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
layout.separator()

View File

@ -27,7 +27,7 @@ extern "C" {
/* Blender file format 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
* 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_LOOSEEDGES,
BVHTREE_FROM_EM_VERTS,
BVHTREE_FROM_EM_LOOSEVERTS,
BVHTREE_FROM_EM_EDGES,
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->raycast_callback = mesh_looptri_spherecast;
break;
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
case BVHTREE_FROM_EM_EDGES:
case BVHTREE_FROM_EM_LOOPTRI:
case BVHTREE_MAX_ITEM:
@ -639,7 +639,7 @@ static void bvhtree_from_editmesh_setup_data(BVHTree *tree,
r_data->em = em;
switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
r_data->nearest_callback = nullptr;
r_data->raycast_callback = editmesh_verts_spherecast;
break;
@ -754,7 +754,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
bvhtree_balance(tree, false);
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;
@ -1223,7 +1223,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
0.0f, tree_type, 6, positions, corner_verts.data(), looptris, {}, -1);
break;
}
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
case BVHTREE_FROM_EM_EDGES:
case BVHTREE_FROM_EM_LOOPTRI:
case BVHTREE_MAX_ITEM:
@ -1253,6 +1253,25 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
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,
BMEditMesh *em,
const int tree_type,
@ -1275,9 +1294,13 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
}
switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS:
data->tree = bvhtree_from_editmesh_verts_create_tree(0.0f, tree_type, 6, em, {}, -1);
case BVHTREE_FROM_EM_LOOSEVERTS: {
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;
}
case BVHTREE_FROM_EM_EDGES:
data->tree = bvhtree_from_editmesh_edges_create_tree(0.0f, tree_type, 6, em, {}, -1);
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)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->toolsettings->snap_node_mode == SCE_SNAP_MODE_NODE_X) {
scene->toolsettings->snap_node_mode = SCE_SNAP_MODE_GRID;
if (scene->toolsettings->snap_node_mode == SCE_SNAP_TO_NODE_X) {
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)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
/* Set default values for new members. */
scene->toolsettings->snap_mode_tools = SCE_SNAP_MODE_GEOM;
scene->toolsettings->plane_axis = 2;
}
}

View File

@ -10,6 +10,7 @@
#include "CLG_log.h"
#include "DNA_defaults.h"
#include "DNA_lightprobe_types.h"
#include "DNA_modifier_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)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
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)
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
}
@ -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.
*

View File

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

View File

@ -280,7 +280,7 @@ static int gizmo_move_modal(bContext *C,
CTX_data_ensure_evaluated_depsgraph(C),
region,
CTX_wm_view3d(C),
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE),
(SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE),
&(const struct SnapObjectParams){
.snap_target_select = SCE_SNAP_TARGET_ALL,
.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);
}
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);
}
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);
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 -1;
@ -373,6 +388,15 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt)
INT_MAX);
RNA_def_property_int_array_funcs_runtime(
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)

View File

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

View File

@ -307,7 +307,8 @@ typedef enum {
} eV3DSnapCursor;
typedef struct V3DSnapCursorData {
eSnapMode snap_elem;
eSnapMode type_source;
eSnapMode type_target;
float loc[3];
float nor[3];
float obmat[4][4];
@ -348,13 +349,14 @@ void ED_view3d_cursor_snap_data_update(V3DSnapCursorState *state,
int y);
V3DSnapCursorData *ED_view3d_cursor_snap_data_get(void);
struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(struct Scene *scene);
void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d,
const float loc_prev[3],
const float loc_curr[3],
const float normal[3],
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],
eSnapMode snap_elem_type);
const uchar color_point[4]);
/* 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 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. */
zero_v3(center);

View File

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

View File

@ -25,12 +25,14 @@
#include "GPU_immediate.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_transform_snap_object_context.h"
#include "ED_view3d.h"
#include "UI_interface_icons.h"
#include "UI_resources.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);
}
void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
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)
static void cursor_x_draw(uint pos, float size)
{
if (!loc_prev && !loc_curr) {
return;
}
immBegin(GPU_PRIM_LINES, 4);
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];
copy_m4_m4(view_inv, rv3d->viewinv);
static void cursor_point_draw(uint attr_pos,
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.
* This prevents a drawing overlaps the other. */
float radius = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
#if 1
GPU_matrix_push();
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) {
immUniformColor4ubv(color_point);
imm_drawcircball(loc_curr, ED_view3d_pixel_size(rv3d, loc_curr) * radius, view_inv, pos);
float size_b = 1.0f;
switch (snap_type) {
case SCE_SNAP_TO_POINT:
imm_draw_circle_wire_3d(attr_pos, 0.0f, 0.0f, 1.0f, 24);
/* draw normal if needed */
if (normal) {
immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, loc_curr);
immVertex3f(pos, loc_curr[0] + normal[0], loc_curr[1] + normal[1], loc_curr[2] + normal[2]);
immBegin(GPU_PRIM_LINES, 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_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) {
/* Draw an "X" indicating where the previous snap point is.
* This is useful for indicating perpendicular snap. */
if (false && icon_id != ICON_NONE) {
float icon_size = 0.1f * size;
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];
/* 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);
float x_size = 0.8f * size;
mul_v3_v3fl(vx, view_inv[0], 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(v4, v2);
add_v3_v3(v1, loc_prev);
add_v3_v3(v2, loc_prev);
add_v3_v3(v3, loc_prev);
add_v3_v3(v4, loc_prev);
add_v3_v3(v1, loc);
add_v3_v3(v2, loc);
add_v3_v3(v3, loc);
add_v3_v3(v4, loc);
immUniformColor4ubv(color_line);
immBegin(GPU_PRIM_LINES, 4);
immVertex3fv(pos, v3);
immVertex3fv(pos, v1);
immVertex3fv(pos, v4);
immVertex3fv(pos, v2);
immBegin(GPU_PRIM_LINES, 8);
immVertex3fv(attr_pos, v1);
immVertex3fv(attr_pos, v2);
immVertex3fv(attr_pos, v2);
immVertex3fv(attr_pos, v3);
immVertex3fv(attr_pos, v3);
immVertex3fv(attr_pos, v4);
immVertex3fv(attr_pos, v4);
immVertex3fv(attr_pos, v1);
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. */
immUnbindProgram();
@ -447,12 +646,14 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
immUniformColor4ubv(color_line);
immBegin(GPU_PRIM_LINES, 2);
immVertex3fv(pos, loc_prev);
immVertex3fv(pos, loc_curr);
immVertex3fv(pos, source_loc);
immVertex3fv(pos, target_loc);
immEnd();
}
}
GPU_line_smooth(false);
GPU_blend(GPU_BLEND_NONE);
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)
{
return tool_settings->snap_mode_tools == SCE_SNAP_MODE_NONE ? tool_settings->snap_mode :
tool_settings->snap_mode_tools;
eSnapMode snap_mode = tool_settings->snap_mode & SCE_SNAP_TO_GEOM;
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)
@ -597,7 +801,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
const bool calc_plane_omat = v3d_cursor_snap_calc_plane();
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);
int snap_elem_index[3] = {-1, -1, -1};
int index = -1;
@ -610,10 +814,10 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
if (use_surface_nor || use_surface_co) {
v3d_cursor_snap_context_ensure(scene);
data_intern->snap_elem_hidden = SCE_SNAP_MODE_NONE;
if (calc_plane_omat && !(snap_elements & SCE_SNAP_MODE_FACE)) {
data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE;
snap_elements |= SCE_SNAP_MODE_FACE;
data_intern->snap_elem_hidden = SCE_SNAP_TO_NONE;
if (calc_plane_omat && !(snap_elements & SCE_SNAP_TO_FACE)) {
data_intern->snap_elem_hidden = SCE_SNAP_TO_FACE;
snap_elements |= SCE_SNAP_TO_FACE;
}
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)) {
snap_data->is_enabled = false;
if (!calc_plane_omat) {
snap_data->snap_elem = SCE_SNAP_MODE_NONE;
snap_data->type_target = SCE_SNAP_TO_NONE;
return;
}
snap_elements = data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE;
snap_elements = data_intern->snap_elem_hidden = SCE_SNAP_TO_FACE;
}
}
#endif
if (snap_elements & SCE_SNAP_MODE_GEOM) {
if (snap_elements & SCE_SNAP_TO_GEOM) {
float prev_co[3] = {0.0f};
if (state->prevpoint) {
copy_v3_v3(prev_co, state->prevpoint);
}
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) ?
@ -684,7 +888,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
if (calc_plane_omat) {
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) {
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. */
float ray_dir[3];
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");
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) {
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;
if (snap_elem == SCE_SNAP_MODE_NONE) {
if (snap_elem == SCE_SNAP_TO_NONE) {
RegionView3D *rv3d = region->regiondata;
const float *plane_normal = omat[tool_settings->plane_axis];
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);
}
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);
}
}
else if (snap_elem == SCE_SNAP_MODE_VERTEX) {
else if (snap_elem & SCE_SNAP_TO_VERTEX) {
snap_elem_index[0] = index;
}
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;
}
else if (snap_elem == SCE_SNAP_MODE_FACE) {
else if (snap_elem == SCE_SNAP_TO_FACE) {
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->nor, no);
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;
if (snap_data->snap_elem == SCE_SNAP_MODE_NONE && !draw_plane) {
if (snap_data->type_target == SCE_SNAP_TO_NONE && !draw_plane) {
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);
}
if (snap_data->snap_elem != SCE_SNAP_MODE_NONE && (state->draw_point || state->draw_box)) {
const float *prev_point = (snap_data->snap_elem & SCE_SNAP_MODE_EDGE_PERPENDICULAR) ?
if (snap_data->type_target != SCE_SNAP_TO_NONE && (state->draw_point || state->draw_box)) {
const float *source_loc = (snap_data->type_target & SCE_SNAP_TO_EDGE_PERPENDICULAR) ?
state->prevpoint :
NULL;
GPU_line_smooth(false);
GPU_line_width(1.0f);
ED_view3d_cursor_snap_draw_util(rv3d,
prev_point,
source_loc,
snap_data->loc,
NULL,
snap_data->type_source,
snap_data->type_target,
state->color_line,
state->color_point,
snap_data->snap_elem);
state->color_point);
}
if (state->draw_box) {

View File

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

View File

@ -153,7 +153,8 @@ struct RulerInfo {
struct {
wmGizmo *gizmo;
PropertyRNA *prop_prevpoint;
PropertyRNA *prop_snap_source;
PropertyRNA *prop_snap_source_type;
} snap_data;
};
@ -168,6 +169,7 @@ struct RulerItem {
int flag;
int raycast_dir; /* RULER_DIRECTION_* */
eSnapMode snap_type[3];
};
struct RulerInteraction {
@ -314,7 +316,7 @@ static void ruler_state_set(RulerInfo *ruler_info, int state)
if (state == RULER_STATE_NORMAL) {
WM_gizmo_set_flag(ruler_info->snap_data.gizmo, WM_GIZMO_DRAW_VALUE, false);
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) {
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) {
RulerInteraction *inter = static_cast<RulerInteraction *>(ruler_item->gz.interaction_data);
float3 &co = ruler_item->co[inter->co_index];
eSnapMode *snap_source_type = &ruler_item->snap_type[inter->co_index];
/* restore the initial depth */
co = inter->drag_start_co;
view3d_ruler_item_project(ruler_info, co, mval);
@ -376,7 +379,7 @@ static bool view3d_ruler_item_mousemove(const bContext *C,
depsgraph,
ruler_info->region,
v3d,
SCE_SNAP_MODE_FACE,
SCE_SNAP_TO_FACE,
&snap_object_params,
nullptr,
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);
if (do_snap) {
float3 *prev_point = nullptr;
eSnapMode snap_type;
BLI_assert(ED_gizmotypes_snap_3d_is_enabled(snap_gizmo));
if (inter->co_index != 1) {
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
prev_point = &ruler_item->co[1];
snap_type = ruler_item->snap_type[1];
}
else if (inter->co_index == 0) {
prev_point = &ruler_item->co[2];
snap_type = ruler_item->snap_type[2];
}
else {
prev_point = &ruler_item->co[0];
snap_type = ruler_item->snap_type[0];
}
}
if (prev_point != nullptr) {
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
@ -1154,22 +1163,29 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
{
/* Set Snap prev point. */
float3 *prev_point;
eSnapMode snap_type;
if (ruler_item_pick->flag & RULERITEM_USE_ANGLE) {
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) {
prev_point = &ruler_item_pick->co[2];
snap_type = ruler_item_pick->snap_type[2];
}
else {
prev_point = &ruler_item_pick->co[0];
snap_type = ruler_item_pick->snap_type[2];
}
if (prev_point) {
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 {
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 (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);
}
/* 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->region = region;
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;
}
@ -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);
copy_v3_v3(inter->drag_start_co, ruler_item->co[inter->co_index]);
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);
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]);
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) {
*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->snap_to = tool_settings->snap_mode_tools;
if (ipd->snap_to == SCE_SNAP_MODE_NONE) {
ipd->snap_to = tool_settings->snap_mode;
ipd->snap_to = tool_settings->snap_mode & SCE_SNAP_TO_GEOM;
if (ipd->snap_to == SCE_SNAP_TO_NONE) {
ipd->snap_to = SCE_SNAP_TO_GEOM;
}
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 */
}
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(
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 */
}
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(
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) {
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;
}
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"))) {
RNA_property_enum_set(op->ptr, prop, t->tsnap.mode);
RNA_boolean_set(
op->ptr, "use_snap_project", (t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST) != 0);
op->ptr, "use_snap_project", (t->tsnap.mode & SCE_SNAP_INDIVIDUAL_PROJECT) != 0);
RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_operation);
eSnapTargetOP target = t->tsnap.target_operation;

View File

@ -302,7 +302,8 @@ typedef struct TransSnap {
short face_nearest_steps;
eTSnap status;
/* Snapped Element Type (currently for objects only). */
eSnapMode snapElem;
eSnapMode source_type;
eSnapMode target_type;
/** snapping from this point (in global-space). */
float snap_source[3];
/** 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 (validSnap(t)) {
is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0;
is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0;
is_snap_to_edge = (t->tsnap.target_type & SCE_SNAP_TO_EDGE) != 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;
}
else if (t->tsnap.snapElem & SCE_SNAP_MODE_GRID) {
else if (t->tsnap.target_type & SCE_SNAP_TO_GRID) {
is_snap_to_point = true;
}
}

View File

@ -154,8 +154,7 @@ static void node_snap_grid_apply(TransInfo *t)
using namespace blender;
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;
}

View File

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

View File

@ -204,7 +204,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
#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. */
if (t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) {
if (t->tsnap.mode & SCE_SNAP_TO_INCREMENT) {
const float radius_snap = 0.1f;
const float snap_hack = (t->snap[0] * bend_data->warp_init_dist) / radius_snap;
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;
}
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];
sub_v3_v3v3(co_dir, co_dest[side_index], co_orig);
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);
}
else {

View File

@ -75,6 +75,11 @@ static void snapsource_confirm(TransInfo *t)
getSnapPoint(t, t->tsnap.snap_source);
t->tsnap.snap_source_fn = NULL;
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;
struct SnapSouceCustomData *customdata = t->custom.mode.data;
@ -110,7 +115,7 @@ static void snapsource_confirm(TransInfo *t)
transform_input_reset(t, mval);
/* Remote individual snap projection since this mode does not use the new `snap_source`. */
t->tsnap.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)
@ -152,6 +157,7 @@ static void snapsource_transform_fn(TransInfo *t, const int UNUSED(mval[2]))
BLI_assert(t->modifiers & MOD_EDIT_SNAP_SOURCE);
t->tsnap.snap_target_fn(t, NULL);
getSnapPoint(t, t->tsnap.snap_source);
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;
customdata->snap_mode_confirm = t->tsnap.mode;
t->tsnap.mode &= ~(SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_FACE_RAYCAST |
SCE_SNAP_MODE_FACE_NEAREST);
t->tsnap.mode &= ~(SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_INDIVIDUAL_PROJECT |
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. */
t->tsnap.mode &= ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID);
t->tsnap.mode |= SCE_SNAP_MODE_GEOM;
t->tsnap.mode &= ~(SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID);
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;
}
}

View File

@ -384,7 +384,7 @@ static void translate_snap_grid_apply(TransInfo *t,
float in[3];
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);
}
else {
@ -403,7 +403,7 @@ static bool translate_snap_grid(TransInfo *t, float *val)
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. */
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);
t->tsnap.snapElem = SCE_SNAP_MODE_GRID;
t->tsnap.target_type = SCE_SNAP_TO_GRID;
return true;
}
@ -627,7 +627,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
/* Test for mixed snap with grid. */
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);
}
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);
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];
sub_v3_v3v3(co_dir, co_curr_3d, co_orig_3d);
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);
}
else {

View File

@ -700,7 +700,7 @@ void Transform_Properties(wmOperatorType *ot, int flags)
prop = RNA_def_enum(ot->srna,
"snap_elements",
rna_enum_snap_element_items,
SCE_SNAP_MODE_INCREMENT,
SCE_SNAP_TO_INCREMENT,
"Snap to Elements",
"");
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);
}
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) {
prop = RNA_def_boolean(ot->srna,
"use_automerge_and_split",
@ -836,7 +827,7 @@ static void TRANSFORM_OT_translate(wmOperatorType *ot)
Transform_Properties(ot,
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_VIEW3D_NAVIGATION | P_POST_TRANSFORM);
P_POST_TRANSFORM);
}
static void TRANSFORM_OT_resize(wmOperatorType *ot)
@ -875,7 +866,7 @@ static void TRANSFORM_OT_resize(wmOperatorType *ot)
Transform_Properties(ot,
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)
@ -952,7 +943,7 @@ static void TRANSFORM_OT_rotate(wmOperatorType *ot)
Transform_Properties(ot,
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)
@ -1091,7 +1082,7 @@ static void TRANSFORM_OT_shrink_fatten(wmOperatorType *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)
@ -1197,7 +1188,7 @@ static void TRANSFORM_OT_edge_slide(wmOperatorType *ot)
"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");
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)
@ -1232,7 +1223,7 @@ static void TRANSFORM_OT_vert_slide(wmOperatorType *ot)
"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");
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)
@ -1380,8 +1371,7 @@ static void TRANSFORM_OT_transform(wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR |
P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION |
P_POST_TRANSFORM);
P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER | P_POST_TRANSFORM);
}
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;
}
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));
if (!(draw_source || draw_target)) {
@ -197,9 +199,9 @@ void drawSnapping(const bContext *C, TransInfo *t)
}
if (t->spacetype == SPACE_VIEW3D) {
const float *loc_cur = nullptr;
const float *loc_prev = nullptr;
const float *normal = nullptr;
const float *source_loc = nullptr;
const float *target_loc = nullptr;
const float *target_normal = nullptr;
GPU_depth_test(GPU_DEPTH_NONE);
@ -233,19 +235,25 @@ void drawSnapping(const bContext *C, TransInfo *t)
/* draw normal if needed */
if (usingSnappingNormal(t) && validSnappingNormal(t)) {
normal = t->tsnap.snapNormal;
target_normal = t->tsnap.snapNormal;
}
if (draw_source) {
loc_prev = t->tsnap.snap_source;
source_loc = t->tsnap.snap_source;
}
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(
rv3d, loc_prev, loc_cur, normal, col, activeCol, t->tsnap.snapElem);
ED_view3d_cursor_snap_draw_util(rv3d,
source_loc,
target_loc,
target_normal,
t->tsnap.source_type,
t->tsnap.target_type,
col,
activeCol);
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
@ -371,7 +379,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td
t->depsgraph,
t->region,
static_cast<const View3D *>(t->view),
SCE_SNAP_MODE_FACE,
SCE_SNAP_TO_FACE,
&snap_object_params,
nullptr,
mval_fl,
@ -379,7 +387,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td
nullptr,
loc,
no);
if (hit != SCE_SNAP_MODE_FACE) {
if (hit != SCE_SNAP_TO_FACE) {
return false;
}
@ -436,7 +444,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td
t->depsgraph,
t->region,
static_cast<const View3D *>(t->view),
SCE_SNAP_MODE_FACE_NEAREST,
SCE_SNAP_INDIVIDUAL_NEAREST,
&snap_object_params,
init_loc,
nullptr,
@ -445,7 +453,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td
snap_loc,
snap_no);
if (hit != SCE_SNAP_MODE_FACE_NEAREST) {
if (hit != SCE_SNAP_INDIVIDUAL_NEAREST) {
return;
}
@ -454,7 +462,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td
mul_m3_v3(td->smtx, 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)
@ -463,7 +471,7 @@ bool transform_snap_project_individual_is_active(const TransInfo *t)
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)
@ -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
* fallback to face nearest ray-cast does not hit. */
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);
}
if (!hit && t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST) {
if (!hit && t->tsnap.mode & SCE_SNAP_INDIVIDUAL_NEAREST) {
applyFaceNearest(t, tc, td);
}
#if 0 /* TODO: support this? */
@ -508,8 +516,8 @@ static bool transform_snap_mixed_is_active(const TransInfo *t)
}
return (t->tsnap.mode &
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_VOLUME |
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) != 0;
(SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE | SCE_SNAP_TO_VOLUME |
SCE_SNAP_TO_EDGE_MIDPOINT | SCE_SNAP_TO_EDGE_PERPENDICULAR)) != 0;
}
void transform_snap_mixed_apply(TransInfo *t, float *vec)
@ -518,7 +526,7 @@ void transform_snap_mixed_apply(TransInfo *t, float *vec)
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();
/* 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)
{
t->tsnap.status = SNAP_RESETTED;
t->tsnap.snapElem = SCE_SNAP_MODE_NONE;
t->tsnap.mode = SCE_SNAP_MODE_NONE;
t->tsnap.source_type = SCE_SNAP_TO_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.source_operation = SCE_SNAP_SOURCE_CLOSEST;
t->tsnap.last = 0;
@ -634,11 +643,11 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t)
if (t->spacetype == SPACE_IMAGE) {
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))
{
snap_mode &= ~SCE_SNAP_MODE_INCREMENT;
snap_mode |= SCE_SNAP_MODE_GRID;
snap_mode &= ~SCE_SNAP_TO_INCREMENT;
snap_mode |= SCE_SNAP_TO_GRID;
}
return snap_mode;
}
@ -649,16 +658,16 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) {
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);
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))
{
/* Special case in which snap to increments is transformed to snap to grid. */
snap_mode &= ~SCE_SNAP_MODE_INCREMENT;
snap_mode |= SCE_SNAP_MODE_GRID;
snap_mode &= ~SCE_SNAP_TO_INCREMENT;
snap_mode |= SCE_SNAP_TO_GRID;
}
return snap_mode;
}
@ -668,7 +677,7 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t)
return eSnapMode(0);
}
return SCE_SNAP_MODE_INCREMENT;
return SCE_SNAP_TO_INCREMENT;
}
static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t)
@ -757,15 +766,15 @@ static void initSnappingMode(TransInfo *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)) {
/* 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;
}
@ -839,7 +848,7 @@ void initSnapping(TransInfo *t, wmOperator *op)
RNA_property_is_set(op->ptr, prop))
{
SET_FLAG_FROM_TEST(
t->tsnap.mode, RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_MODE_FACE_RAYCAST);
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 */
@ -1093,23 +1102,23 @@ static void snap_target_view3d_fn(TransInfo *t, float * /*vec*/)
float no[3];
float mval[2];
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. */
mval[0] = t->mval[0];
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 */
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;
found = peelObjectsTransform(t, mval, use_peel, loc, no, nullptr);
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.snapElem = snap_elem;
t->tsnap.target_type = snap_elem;
}
static void snap_target_uv_fn(TransInfo *t, float * /*vec*/)
{
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;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
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*/)
{
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 dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */
char node_border;
@ -1258,32 +1267,7 @@ static void snap_source_center_fn(TransInfo *t)
TargetSnapOffset(t, nullptr);
t->tsnap.status |= SNAP_SOURCE_FOUND;
}
}
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;
t->tsnap.source_type = SCE_SNAP_TO_NONE;
}
}
@ -1374,6 +1358,35 @@ static void snap_source_closest_fn(TransInfo *t)
TargetSnapOffset(t, closest);
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)
{
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;
}
if (snap_node_mode & SCE_SNAP_MODE_NODE_Y) {
if (snap_node_mode & SCE_SNAP_TO_NODE_Y) {
flag |= NODE_TOP | NODE_BOTTOM;
}
return flag;
@ -1644,7 +1657,7 @@ static void snap_increment_apply(const TransInfo *t,
const float increment_dist,
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);
/* 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;
}
if (!(t->tsnap.mode & SCE_SNAP_MODE_INCREMENT)) {
if (!(t->tsnap.mode & SCE_SNAP_TO_INCREMENT)) {
return false;
}
@ -1710,8 +1723,7 @@ bool transform_snap_increment(const TransInfo *t, float *r_val)
float transform_snap_increment_get(const TransInfo *t)
{
if (transform_snap_is_active(t) &&
(t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))
if (transform_snap_is_active(t) && (t->tsnap.mode & (SCE_SNAP_TO_INCREMENT | SCE_SNAP_TO_GRID)))
{
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;
}
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_;
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;
eSnapMode snap_to = sctx->runtime.snap_to_flag;
int e_mode_len = ((snap_to & SCE_SNAP_MODE_EDGE) != 0) +
((snap_to & SCE_SNAP_MODE_VERTEX) != 0) +
((snap_to & SCE_SNAP_MODE_EDGE_MIDPOINT) != 0);
int e_mode_len = ((snap_to & SCE_SNAP_TO_EDGE) != 0) +
((snap_to & SCE_SNAP_TO_EDGE_ENDPOINT) != 0) +
((snap_to & SCE_SNAP_TO_EDGE_MIDPOINT) != 0);
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;
if ((range) < lambda && lambda < (1.0f - range)) {
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)) {
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];
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)) {
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. */
if (snap_to & SCE_SNAP_MODE_VERTEX) {
if (snap_to & SCE_SNAP_TO_EDGE_ENDPOINT) {
if (lambda < (range) || (1.0f - range) < lambda) {
int v_id = lambda < 0.5f ? 0 : 1;
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);
}
}
@ -432,7 +432,7 @@ static bool snap_object_is_snappable(const SnapObjectContext *sctx,
*/
static eSnapMode iter_snap_objects(SnapObjectContext *sctx, IterSnapObjsCallback sob_callback)
{
eSnapMode ret = SCE_SNAP_MODE_NONE;
eSnapMode ret = SCE_SNAP_TO_NONE;
eSnapMode tmp;
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));
if ((tmp = sob_callback(
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;
}
@ -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);
if ((tmp = sob_callback(
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;
}
@ -551,38 +551,38 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
if (ob_data == nullptr) {
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. */
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
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;
}
}
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)) {
/* 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) {
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)) {
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
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) {
copy_m4_m4(sctx->ret.obmat, obmat);
sctx->ret.ob = ob_eval;
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)
{
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
* \{ */
struct NearestWorldObjUserData {
const float *init_co;
const float *curr_co;
};
static void nearest_world_tree_co(BVHTree *tree,
BVHTree_NearestPointCallback nearest_cb,
void *treedata,
@ -718,21 +713,22 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
if (ob_data == nullptr) {
if (ob_eval->type == OB_MESH) {
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;
}
}
else {
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
}
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)) {
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;
}
@ -740,9 +736,9 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
copy_m4_m4(sctx->ret.obmat, obmat);
sctx->ret.ob = ob_eval;
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)
{
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)
{
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) {
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
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)
{
eSnapMode elem = SCE_SNAP_MODE_EDGE;
eSnapMode elem = SCE_SNAP_TO_EDGE;
if (sctx->ret.ob->type != OB_MESH) {
return elem;
@ -864,22 +860,22 @@ eSnapMode snap_object_center(SnapObjectContext *sctx,
eSnapMode snap_to_flag)
{
if (ob_eval->transflag & OB_DUPLI) {
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
/* For now only vertex supported. */
if ((snap_to_flag & SCE_SNAP_MODE_VERTEX) == 0) {
return SCE_SNAP_MODE_NONE;
if ((snap_to_flag & SCE_SNAP_TO_POINT) == 0) {
return SCE_SNAP_TO_NONE;
}
Nearest2dUserData nearest2d(
sctx, ob_eval, static_cast<const ID *>(ob_eval->data), float4x4(obmat));
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 use_hide)
{
eSnapMode retval = SCE_SNAP_MODE_NONE;
eSnapMode retval = SCE_SNAP_TO_NONE;
if (ob_data == nullptr && (ob_eval->type == OB_MESH)) {
retval = snap_object_editmesh(
@ -906,7 +902,7 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
case OB_MESH: {
if (ob_eval->dt == OB_BOUNDBOX) {
/* 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) {
retval = snap_object_mesh(
@ -1031,22 +1027,22 @@ static bool snap_object_context_runtime_init(SnapObjectContext *sctx,
ListBase *hit_list,
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) {
copy_v3_v3(sctx->runtime.curr_co, prev_co);
if (init_co) {
copy_v3_v3(sctx->runtime.init_co, init_co);
}
else {
snap_to_flag &= ~SCE_SNAP_MODE_FACE_NEAREST;
snap_to_flag &= ~SCE_SNAP_INDIVIDUAL_NEAREST;
}
}
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;
}
@ -1057,7 +1053,7 @@ static bool snap_object_context_runtime_init(SnapObjectContext *sctx,
sctx->runtime.params = *params;
sctx->runtime.params.use_occlusion_test = 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.object_index = 0;
@ -1115,7 +1111,7 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
depsgraph,
nullptr,
v3d,
SCE_SNAP_MODE_FACE,
SCE_SNAP_TO_FACE,
params,
ray_start,
ray_normal,
@ -1167,7 +1163,7 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
depsgraph,
nullptr,
v3d,
SCE_SNAP_MODE_FACE,
SCE_SNAP_TO_FACE,
params,
ray_start,
ray_normal,
@ -1246,18 +1242,18 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
float r_obmat[4][4],
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;
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. */
snap_to_flag &= ~SCE_SNAP_MODE_FACE;
snap_to_flag &= ~SCE_SNAP_TO_FACE;
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,
region,
v3d,
@ -1267,7 +1263,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
sctx->runtime.ray_start,
true))
{
snap_to_flag &= ~SCE_SNAP_MODE_FACE;
snap_to_flag &= ~SCE_SNAP_TO_FACE;
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;
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;
/* NOTE: if both face ray-cast and face nearest are enabled, first find result of nearest, then
* override with ray-cast. */
if ((snap_to_flag & SCE_SNAP_MODE_FACE_NEAREST) && !has_hit) {
if ((snap_to_flag & SCE_SNAP_INDIVIDUAL_NEAREST) && !has_hit) {
has_hit = nearestWorldObjects(sctx);
if (has_hit) {
retval = SCE_SNAP_MODE_FACE_NEAREST;
retval = SCE_SNAP_INDIVIDUAL_NEAREST;
copy_v3_v3(r_loc, sctx->ret.loc);
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);
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);
}
if (snap_to_flag & SCE_SNAP_MODE_FACE) {
retval = SCE_SNAP_MODE_FACE;
if (snap_to_flag & SCE_SNAP_TO_FACE) {
retval = SCE_SNAP_TO_FACE;
copy_v3_v3(r_loc, sctx->ret.loc);
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 |
SCE_SNAP_MODE_EDGE_PERPENDICULAR))
{
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;
}
if (snap_to_flag & (SCE_SNAP_TO_POINT | SNAP_TO_EDGE_ELEMENTS)) {
eSnapMode elem_test, elem = SCE_SNAP_TO_NONE;
/* By convention we only snap to the original elements of a curve. */
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;
}
if ((elem == SCE_SNAP_MODE_EDGE) &&
(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;
if ((elem == SCE_SNAP_TO_EDGE) && (snap_to_flag & SNAP_TO_EDGE_ELEMENTS)) {
elem = snap_edge_points(sctx, square_f(*dist_px));
}

View File

@ -10,6 +10,10 @@
#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 SnapObjectContext {
@ -118,7 +122,7 @@ class Nearest2dUserData {
bool snap_boundbox(const blender::float3 &min, const blender::float3 &max);
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);
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_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 */
struct SnapData_EditMesh {
/* Verts, Edges. */
/* Loose Verts, Edges. */
BVHTree *bvhtree[2];
bool cached[2];

View File

@ -25,9 +25,9 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
const float obmat[4][4],
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. */
return retval;
}
@ -95,16 +95,16 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
}
if (nearest2d.nearest_point.index != -2) {
retval = sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE;
if (retval == SCE_SNAP_MODE_NONE) {
retval = sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE;
if (retval == SCE_SNAP_TO_NONE) {
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;
nearest2d.nearest_point.dist_sq = sctx->ret.dist_px_sq;
if (nearest2d.snap_point(head_vec) || nearest2d.snap_point(tail_vec)) {
retval = SCE_SNAP_MODE_VERTEX;
retval = SCE_SNAP_TO_POINT;
}
else if (retval) {
nearest2d.nearest_point.dist_sq = dist_px_sq_edge;

View File

@ -23,9 +23,9 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
const float obmat[4][4],
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;
}
@ -77,10 +77,10 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
mul_m4_v3(vertex_obmat, 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;
/* Only vertex snapping mode (eg control points and handles) supported for now). */
if ((sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) == 0) {
return SCE_SNAP_MODE_NONE;
if ((sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT) == 0) {
return SCE_SNAP_TO_NONE;
}
Curve *cu = static_cast<Curve *>(ob_eval->data);
@ -41,7 +41,7 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
/* Test BoundBox */
BoundBox *bb = BKE_curve_boundbox_get(ob_eval);
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)) {
for (int u = 0; u < nu->pntsu; u++) {
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) {
if (use_obedit) {
if (nu->bezt) {
if (nu->bezt[u].hide) {
/* Skip hidden. */
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]);
}
if (use_obedit) {
if (nu->bezt) {
if (nu->bezt[u].hide) {
/* Skip hidden. */
continue;
}
else {
if (nu->bp[u].hide) {
/* Skip hidden. */
continue;
}
bool is_selected = (nu->bp[u].f1 & SELECT) != 0;
if (is_selected && skip_selected) {
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]);
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 {
/* 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);
}
if (nu->bp[u].hide) {
/* Skip hidden. */
continue;
}
bool is_selected = (nu->bp[u].f1 & SELECT) != 0;
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)
{
eSnapMode snap_mode_supported = SCE_SNAP_MODE_NONE;
eSnapMode snap_mode_supported = SCE_SNAP_TO_NONE;
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) {
snap_mode_supported |= SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
SCE_SNAP_MODE_EDGE_PERPENDICULAR;
snap_mode_supported |= SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_TO_EDGE_PERPENDICULAR;
}
if (em->bm->totvert) {
snap_mode_supported |= SCE_SNAP_MODE_VERTEX;
snap_mode_supported |= SCE_SNAP_TO_VERTEX;
}
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);
if (snap_mode_used == SCE_SNAP_MODE_NONE) {
if (snap_mode_used == SCE_SNAP_TO_NONE) {
return nullptr;
}
@ -447,7 +447,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
eSnapMode snap_to_flag,
int polygon)
{
eSnapMode elem = SCE_SNAP_MODE_NONE;
eSnapMode elem = SCE_SNAP_TO_NONE;
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
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);
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
if (snap_to_flag & SCE_SNAP_MODE_EDGE) {
elem = SCE_SNAP_MODE_EDGE;
if (snap_to_flag & SCE_SNAP_TO_EDGE) {
elem = SCE_SNAP_TO_EDGE;
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_EDGE);
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE);
do {
@ -475,7 +475,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
} while ((l_iter = l_iter->next) != l_first);
}
else {
elem = SCE_SNAP_MODE_VERTEX;
elem = SCE_SNAP_TO_EDGE_ENDPOINT;
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
do {
@ -493,7 +493,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
return elem;
}
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
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);
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,
@ -515,28 +515,32 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
const float obmat[4][4],
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));
/* Was BKE_boundbox_ray_hit_check, see: cf6ca226fa58. */
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{};
treedata.tree = sod->bvhtree[0];
if (treedata.tree == nullptr) {
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);
const int verts_num_active = BM_iter_mesh_bitmap_from_filter(
BM_VERTS_OF_MESH,
em->bm,
verts_mask,
(bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
sctx->callbacks.edit_mesh.user_data);
BM_VERTS_OF_MESH, em->bm, verts_mask, test_looseverts_fn, sctx);
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,
em,
2,
BVHTREE_FROM_EM_VERTS,
BVHTREE_FROM_EM_LOOSEVERTS,
/* WORKAROUND: avoid updating while transforming. */
G.moving ? nullptr : &sod->mesh_runtime->bvh_cache,
&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{};
treedata.tree = sod->bvhtree[1];
@ -590,9 +594,9 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
nearest.index = -1;
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_index_ensure(em->bm, BM_VERT);
BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
@ -606,7 +610,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
&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;
nearest.index = -1;
BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT);
@ -622,7 +626,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
&nearest2d);
if (nearest.index != -1) {
elem = SCE_SNAP_MODE_EDGE;
elem = SCE_SNAP_TO_EDGE;
}
else {
nearest.index = last_index;
@ -634,7 +638,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
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,
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);
if (sod == nullptr) {
@ -656,8 +660,8 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
BMEditMesh *em = sod->treedata_editmesh.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 |
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX))
if (snap_mode_used & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_TO_VERTEX))
{
elem = snapEditMesh(sod, sctx, ob_eval, em, obmat, snap_to_flag);
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++)) {
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)) {
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,
int polygon)
{
eSnapMode elem = SCE_SNAP_MODE_NONE;
eSnapMode elem = SCE_SNAP_TO_NONE;
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];
if (snap_to_flag & SCE_SNAP_MODE_EDGE) {
elem = SCE_SNAP_MODE_EDGE;
if (snap_to_flag & SCE_SNAP_TO_EDGE) {
elem = SCE_SNAP_TO_EDGE;
BLI_assert(nearest2d.edges != nullptr);
const int *poly_edges = &nearest2d.corner_edges[poly.start()];
for (int i = poly.size(); i--;) {
@ -435,7 +435,7 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
}
}
else {
elem = SCE_SNAP_MODE_VERTEX;
elem = SCE_SNAP_TO_VERTEX;
const int *poly_verts = &nearest2d.corner_verts[poly.start()];
for (int i = poly.size(); i--;) {
cb_snap_vert(&nearest2d,
@ -452,7 +452,7 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
return elem;
}
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx,
@ -463,7 +463,7 @@ eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx,
int edge)
{
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,
@ -472,12 +472,12 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
const float obmat[4][4],
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) {
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
if (me_eval->totedge == 0 && !(sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
return SCE_SNAP_MODE_NONE;
if (me_eval->totedge == 0 && !(sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT)) {
return SCE_SNAP_TO_NONE;
}
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) {
const BoundBox *bb = BKE_mesh_boundbox_get(ob_eval);
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[0] = BKE_bvhtree_from_mesh_get(&treedata_dummy, me_eval, BVHTREE_FROM_LOOSEEDGES, 2);
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);
BLI_assert(treedata_dummy.cached);
}
@ -507,10 +507,10 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
nearest.dist_sq = sctx->ret.dist_px_sq;
int last_index = nearest.index;
eSnapMode elem = SCE_SNAP_MODE_VERTEX;
eSnapMode elem = SCE_SNAP_TO_POINT;
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 */
BLI_bvhtree_find_nearest_projected(bvhtree[1],
nearest2d.pmat_local.ptr(),
@ -525,7 +525,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
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]) {
/* Snap to loose edges. */
BLI_bvhtree_find_nearest_projected(
@ -555,11 +555,11 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
}
if (last_index != nearest.index) {
elem = SCE_SNAP_MODE_EDGE;
elem = SCE_SNAP_TO_EDGE;
}
}
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]) {
/* Snap to loose edge verts. */
BLI_bvhtree_find_nearest_projected(
@ -594,23 +594,23 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
return elem;
}
return SCE_SNAP_MODE_NONE;
return SCE_SNAP_TO_NONE;
}
/** \} */
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) {
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) {
snap_mode_supported |= SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
SCE_SNAP_MODE_EDGE_PERPENDICULAR;
snap_mode_supported |= SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_TO_EDGE_PERPENDICULAR;
}
if (mesh->totvert) {
snap_mode_supported |= SCE_SNAP_MODE_VERTEX;
snap_mode_supported |= SCE_SNAP_TO_VERTEX;
}
return snap_mode_supported;
}
@ -622,13 +622,13 @@ eSnapMode snap_object_mesh(SnapObjectContext *sctx,
eSnapMode snap_to_flag,
bool use_hide)
{
eSnapMode elem = SCE_SNAP_MODE_NONE;
eSnapMode elem = SCE_SNAP_TO_NONE;
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id);
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 |
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX))
if (snap_mode_used & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_EDGE_MIDPOINT |
SCE_SNAP_TO_EDGE_PERPENDICULAR | SCE_SNAP_TO_VERTEX))
{
elem = snapMesh(sctx, ob_eval, mesh_eval, obmat, use_hide);
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)) {
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)) {
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, \
\
.transform_pivot_point = V3D_AROUND_CENTER_MEDIAN, \
.snap_mode = SCE_SNAP_MODE_INCREMENT, \
.snap_node_mode = SCE_SNAP_MODE_GRID, \
.snap_uv_mode = SCE_SNAP_MODE_INCREMENT, \
.snap_mode = SCE_SNAP_TO_GEOM, \
.snap_node_mode = SCE_SNAP_TO_GRID, \
.snap_uv_mode = SCE_SNAP_TO_INCREMENT, \
.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, \
\
.curve_paint_settings = _DNA_DEFAULTS_CurvePaintSettings, \
@ -370,7 +370,6 @@
.uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN, \
\
/* Placement */ \
.snap_mode_tools = SCE_SNAP_MODE_GEOM,\
.plane_axis = 2,\
}

View File

@ -1697,12 +1697,11 @@ typedef struct ToolSettings {
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_depth; /* #eV3DPlaceDepth. */
char plane_orient; /* #eV3DPlaceOrient. */
char plane_axis; /* X, Y or Z. */
char plane_depth; /* #eV3DPlaceDepth. */
char plane_orient; /* #eV3DPlaceOrient. */
char use_plane_axis_auto;
char _pad7[2];
char _pad7[4];
} 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 */
typedef enum eSnapSourceOP {
SCE_SNAP_SOURCE_CLOSEST = 0,
SCE_SNAP_SOURCE_CENTER = 1,
SCE_SNAP_SOURCE_MEDIAN = 2,
SCE_SNAP_SOURCE_MEDIAN = 1,
SCE_SNAP_SOURCE_CENTER = 2,
SCE_SNAP_SOURCE_ACTIVE = 3,
} eSnapSourceOP;
@ -2298,37 +2297,41 @@ ENUM_OPERATORS(eSnapTargetOP, SCE_SNAP_TARGET_NOT_NONEDITED)
/** #ToolSettings.snap_mode */
typedef enum eSnapMode {
SCE_SNAP_MODE_NONE = 0,
SCE_SNAP_TO_NONE = 0,
SCE_SNAP_MODE_VERTEX = (1 << 0),
SCE_SNAP_MODE_EDGE = (1 << 1),
SCE_SNAP_MODE_FACE = (1 << 2),
SCE_SNAP_MODE_VOLUME = (1 << 3),
SCE_SNAP_MODE_EDGE_MIDPOINT = (1 << 4),
SCE_SNAP_MODE_EDGE_PERPENDICULAR = (1 << 5),
SCE_SNAP_TO_POINT = (1 << 0),
SCE_SNAP_TO_EDGE = (1 << 1),
SCE_SNAP_TO_EDGE_ENDPOINT = (1 << 2),
SCE_SNAP_TO_EDGE_MIDPOINT = (1 << 3),
SCE_SNAP_TO_EDGE_PERPENDICULAR = (1 << 4),
SCE_SNAP_TO_FACE = (1 << 5),
SCE_SNAP_TO_VOLUME = (1 << 6),
/* For snap individual elements. */
SCE_SNAP_MODE_FACE_NEAREST = (1 << 8),
/** Project individual elements instead of whole object. */
SCE_SNAP_MODE_FACE_RAYCAST = (1 << 9),
SCE_SNAP_INDIVIDUAL_PROJECT = (1 << 7),
SCE_SNAP_INDIVIDUAL_NEAREST = (1 << 8),
/** #ToolSettings.snap_node_mode */
SCE_SNAP_MODE_NODE_X = (1 << 0),
SCE_SNAP_MODE_NODE_Y = (1 << 1),
SCE_SNAP_TO_NODE_X = (1 << 0),
SCE_SNAP_TO_NODE_Y = (1 << 1),
/** #ToolSettings.snap_mode and #ToolSettings.snap_node_mode and #ToolSettings.snap_uv_mode */
SCE_SNAP_MODE_INCREMENT = (1 << 6),
SCE_SNAP_MODE_GRID = (1 << 7),
SCE_SNAP_TO_INCREMENT = (1 << 9),
SCE_SNAP_TO_GRID = (1 << 10),
} eSnapMode;
/* Due to dependency conflicts with Cycles, header cannot directly include `BLI_utildefines.h`. */
/* TODO: move this macro to a more general place. */
#ifdef ENUM_OPERATORS
ENUM_OPERATORS(eSnapMode, SCE_SNAP_MODE_FACE_RAYCAST)
ENUM_OPERATORS(eSnapMode, SCE_SNAP_TO_GRID)
#endif
#define SCE_SNAP_MODE_GEOM \
(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_VERTEX (SCE_SNAP_TO_POINT | SCE_SNAP_TO_EDGE_ENDPOINT)
#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 */
#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 */
#define RNA_SNAP_ELEMENTS_BASE \
{SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments"}, \
{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, \
{SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges"}, \
{SCE_SNAP_MODE_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap by projecting onto faces"}, \
{SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume"}, \
{SCE_SNAP_MODE_EDGE_MIDPOINT, "EDGE_MIDPOINT", ICON_SNAP_MIDPOINT, "Edge Center", "Snap to the middle of edges"}, \
{SCE_SNAP_MODE_EDGE_PERPENDICULAR, "EDGE_PERPENDICULAR", ICON_SNAP_PERPENDICULAR, "Edge Perpendicular", "Snap to the nearest point on an edge"}
{SCE_SNAP_TO_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments"}, \
{SCE_SNAP_TO_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, \
{SCE_SNAP_TO_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges"}, \
{SCE_SNAP_TO_EDGE_MIDPOINT, "EDGE_MIDPOINT", ICON_SNAP_MIDPOINT, "Edge Center", "Snap to the middle of edges"}, \
{SCE_SNAP_TO_EDGE_PERPENDICULAR, "EDGE_PERPENDICULAR", ICON_SNAP_PERPENDICULAR, "Edge Perpendicular", "Snap to the nearest point on an edge"}, \
{SCE_SNAP_TO_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap by projecting onto faces"}, \
{SCE_SNAP_TO_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume"}
/* clang-format on */
const EnumPropertyItem rna_enum_snap_element_items[] = {
RNA_SNAP_ELEMENTS_BASE,
{SCE_SNAP_MODE_FACE_RAYCAST,
{SCE_SNAP_INDIVIDUAL_PROJECT,
"FACE_PROJECT",
ICON_SNAP_FACE,
"Face Project",
"Snap by projecting onto faces"},
{SCE_SNAP_MODE_FACE_NEAREST,
{SCE_SNAP_INDIVIDUAL_NEAREST,
"FACE_NEAREST",
ICON_SNAP_FACE_NEAREST,
"Face Nearest",
@ -189,10 +189,10 @@ static const EnumPropertyItem *rna_enum_snap_element_individual_items =
#endif
const EnumPropertyItem rna_enum_snap_node_element_items[] = {
{SCE_SNAP_MODE_GRID, "GRID", ICON_SNAP_GRID, "Grid", "Snap to grid"},
{SCE_SNAP_MODE_NODE_X, "NODE_X", ICON_NODE_SIDE, "Node X", "Snap to left/right node border"},
{SCE_SNAP_MODE_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_GRID, "GRID", ICON_SNAP_GRID, "Grid", "Snap to grid"},
{SCE_SNAP_TO_NODE_X, "NODE_X", ICON_NODE_SIDE, "Node X", "Snap to left/right node border"},
{SCE_SNAP_TO_NODE_Y, "NODE_Y", ICON_NODE_TOP, "Node Y", "Snap to top/bottom node border"},
{SCE_SNAP_TO_NODE_X | SCE_SNAP_TO_NODE_Y,
"NODE_XY",
ICON_NODE_CORNER,
"Node X / Y",
@ -202,12 +202,12 @@ const EnumPropertyItem rna_enum_snap_node_element_items[] = {
#ifndef RNA_RUNTIME
static const EnumPropertyItem snap_uv_element_items[] = {
{SCE_SNAP_MODE_INCREMENT,
{SCE_SNAP_TO_INCREMENT,
"INCREMENT",
ICON_SNAP_INCREMENT,
"Increment",
"Snap to increments of grid"},
{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"},
{SCE_SNAP_TO_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"},
{0, NULL, 0, NULL, NULL},
};
@ -678,12 +678,6 @@ static const EnumPropertyItem plane_orientation_items[] = {
{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
# include "BLI_string_utils.h"
@ -3413,6 +3407,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_funcs(
prop, "rna_ToolSettings_snap_mode_get", "rna_ToolSettings_snap_mode_set", NULL);
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
RNA_def_property_enum_default(prop, SCE_SNAP_TO_GEOM);
RNA_def_property_ui_text(prop, "Snap Element", "Type of element to snap to");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
@ -3528,7 +3523,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_snap_rotate", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, NULL, "snap_transform_mode_flag", SCE_SNAP_TRANSFORM_MODE_ROTATE);
RNA_def_property_boolean_default(prop, false);
RNA_def_property_ui_text(
prop, "Use Snap for Rotation", "Rotate is affected by the snapping settings");
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);
RNA_def_property_boolean_sdna(
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_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_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 */
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);