diff --git a/mesh_snap_utilities_line/__init__.py b/mesh_snap_utilities_line/__init__.py index 1080cd9b645e6afa2b6b6bbef74d1d781c70eb41..7db590129f85d9441cb0d48d0876fc92ac7c68a8 100644 --- a/mesh_snap_utilities_line/__init__.py +++ b/mesh_snap_utilities_line/__init__.py @@ -22,7 +22,7 @@ bl_info = { "name": "Snap_Utilities_Line", "author": "Germano Cavalcante", - "version": (5, 9, 6), + "version": (5, 9, 8), "blender": (2, 80, 0), "location": "View3D > TOOLS > Line Tool", "description": "Extends Blender Snap controls", @@ -35,11 +35,13 @@ if "bpy" in locals(): importlib.reload(widgets) importlib.reload(preferences) importlib.reload(op_line) + importlib.reload(keys) else: from . import navigation_ops from . import widgets from . import preferences from . import op_line + from . import keys import bpy from bpy.utils.toolsystem import ToolDef @@ -65,7 +67,8 @@ def tool_line(): icons_dir = os.path.join(os.path.dirname(__file__), "icons") return dict( - text="Make Line", + idname="snap_utilities.line", + label="Make Line", description=( "Make Lines\n" "Connect them to split faces" @@ -73,7 +76,7 @@ def tool_line(): icon=os.path.join(icons_dir, "ops.mesh.snap_utilities_line"), widget="MESH_GGT_snap_point", #operator="mesh.snap_utilities_line", - keymap="3D View Tool: Edit Mesh, Make Line", + keymap=keys.km_tool_snap_utilities_line, draw_settings=draw_settings, ) @@ -81,16 +84,6 @@ def tool_line(): # ----------------------------------------------------------------------------- # Tool Registraion -def km_3d_view_snap_tools(tool_mouse = 'LEFTMOUSE'): - return [( - tool_line.keymap[0], - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("mesh.snap_utilities_line", {"type": tool_mouse, "value": 'CLICK'}, - {"properties": [("wait_for_input", False)]}), - ]}, - )] - def get_tool_list(space_type, context_mode): from bl_ui.space_toolsystem_common import ToolSelectPanelHelper @@ -102,23 +95,12 @@ def register_snap_tools(): tools = get_tool_list('VIEW_3D', 'EDIT_MESH') for index, tool in enumerate(tools, 1): - if isinstance(tool, ToolDef) and tool.text == "Measure": + if isinstance(tool, ToolDef) and tool.label == "Measure": break tools[:index] += None, tool_line - del tools, index - - keyconfigs = bpy.context.window_manager.keyconfigs - kc_defaultconf = keyconfigs.get("blender") - kc_addonconf = keyconfigs.get("blender addon") - - keyconfig_data = km_3d_view_snap_tools() - - # TODO: find the user defined tool_mouse. - from bl_keymap_utils.io import keyconfig_init_from_data - keyconfig_init_from_data(kc_defaultconf, keyconfig_data) - keyconfig_init_from_data(kc_addonconf, keyconfig_data) + del tools def unregister_snap_tools(): @@ -128,16 +110,35 @@ def unregister_snap_tools(): tools.pop(index) tools.remove(tool_line) - del tools, index + del tools + del index + + +def register_keymaps(): + keyconfigs = bpy.context.window_manager.keyconfigs + kc_defaultconf = keyconfigs.default + kc_addonconf = keyconfigs.addon + + # TODO: find the user defined tool_mouse. + from bl_keymap_utils.io import keyconfig_init_from_data + keyconfig_init_from_data(kc_defaultconf, keys.generate_empty_snap_utilities_tools_keymaps()) + keyconfig_init_from_data(kc_addonconf, keys.generate_snap_utilities_keymaps()) + + #snap_modalkeymap = kc_addonconf.keymaps.find(keys.km_snap_utilities_modal_keymap) + #snap_modalkeymap.assign("MESH_OT_snap_utilities_line") + +def unregister_keymaps(): keyconfigs = bpy.context.window_manager.keyconfigs defaultmap = keyconfigs.get("blender").keymaps addonmap = keyconfigs.get("blender addon").keymaps - for keyconfig_data in km_3d_view_snap_tools(): + for keyconfig_data in keys.generate_snap_utilities_keymaps(): km_name, km_args, km_content = keyconfig_data - addonmap.remove(addonmap.find(km_name, **km_args)) + + for keyconfig_data in keys.generate_empty_snap_utilities_tools_keymaps(): + km_name, km_args, km_content = keyconfig_data defaultmap.remove(defaultmap.find(km_name, **km_args)) @@ -158,9 +159,11 @@ def register(): bpy.utils.register_class(cls) register_snap_tools() + register_keymaps() def unregister(): + unregister_keymaps() unregister_snap_tools() for cls in reversed(classes): diff --git a/mesh_snap_utilities_line/common_classes.py b/mesh_snap_utilities_line/common_classes.py index c36216e08f5616b70a4167070e0fb33d0adddaef..8b4333828bdd8ebd129f3d6c70d8085d05f56471 100644 --- a/mesh_snap_utilities_line/common_classes.py +++ b/mesh_snap_utilities_line/common_classes.py @@ -26,6 +26,17 @@ from .common_utilities import ( class SnapNavigation(): + __slots__ = ( + 'use_ndof', + '_rotate', + '_move', + '_zoom', + '_ndof_all', + '_ndof_orbit', + '_ndof_orbit_zoom', + '_ndof_pan') + + @staticmethod def debug_key(key): for member in dir(key): @@ -93,10 +104,13 @@ class SnapNavigation(): for key in self._zoom: if evkey == key[0:3]: - if snap_location and key[3]: - bpy.ops.view3d.zoom_custom_target('INVOKE_DEFAULT', delta=key[3], target=snap_location) + if key[3]: + if snap_location: + bpy.ops.view3d.zoom_custom_target('INVOKE_DEFAULT', delta=key[3], target=snap_location) + else: + bpy.ops.view3d.zoom('INVOKE_DEFAULT', delta=key[3]) else: - bpy.ops.view3d.zoom('INVOKE_DEFAULT', delta=key[3]) + bpy.ops.view3d.zoom('INVOKE_DEFAULT') return True if self.use_ndof: @@ -118,6 +132,13 @@ class SnapNavigation(): class CharMap: + __slots__ = ( + 'unit_system', + 'uinfo', + 'length_entered', + 'length_entered_value', + 'line_pos') + ascii = { ".", ",", "-", "+", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", @@ -194,16 +215,26 @@ class CharMap: class SnapUtilities: -# __slots__ = ( -# "sctx", -# "draw_cache", -# "outer_verts", -# "snap_face", -# "snap_to_grid", -# "unit_system", -# "rd", -# "incremental", -# ) + """ + __slots__ = ( + "sctx", + "draw_cache", + "outer_verts", + "unit_system", + "rd", + "obj", + "bm", + "geom", + "type", + "location", + "preferences", + "normal", + "snap_vert", + "snap_edge", + "snap_face", + "incremental", + ) + """ constrain_keys = { 'X': Vector((1,0,0)), @@ -327,7 +358,6 @@ class SnapUtilities: else: #init these variables to avoid errors self.obj = context.active_object - self.bm = None self.geom = None self.type = 'OUT' self.location = Vector() diff --git a/mesh_snap_utilities_line/common_utilities.py b/mesh_snap_utilities_line/common_utilities.py index a6ecbdc98dd6c5af1f1608fccf6c23d77201799a..c62968d59a95d7e3143f23cb0752d0d1d7a0ccf4 100644 --- a/mesh_snap_utilities_line/common_utilities.py +++ b/mesh_snap_utilities_line/common_utilities.py @@ -148,16 +148,35 @@ def get_snap_bm_geom(sctx, main_snap_obj, mcursor): return r_snp_obj, r_loc, r_elem, r_elem_co, r_view_vector, r_orig, r_bm, r_bm_geom -class SnapCache: - snp_obj = None - edge = None +class SnapCache(object): + __slots__ = 'edge', 'face' - vmid = None - vperp = None - v2dmid = None - v2dperp = None + class Edge: + __slots__ = 'snp_obj', 'elem', 'vmid', 'vperp', 'v2dmid', 'v2dperp', 'is_increment' - is_increment = False + def __init__(self): + self.snp_obj = None + self.elem = None + self.vmid = None + self.vperp = None + self.v2dmid = None + self.v2dperp = None + self.is_increment = False + + class Face: + __slots__ = 'bm_face', 'vmid', 'v2dmid' + + def __init__(self): + self.bm_face = None + + def __init__(self): + self.edge = self.Edge() + self.face = self.Face() + + def clear(self): + self.edge.snp_obj = self.face.bm_face = None + +_snap_cache = SnapCache() def snap_utilities( @@ -171,7 +190,7 @@ def snap_utilities( is_increment = False r_loc = None - r_type = None + r_type = 'OUT' r_len = 0.0 if not snp_obj: @@ -183,71 +202,89 @@ def snap_utilities( t_loc = constrain r_loc = t_loc[0] else: - r_type = 'OUT' r_loc = out_Location(sctx.rv3d, orig, view_vector) elif len(elem) == 1: r_type = 'VERT' + if constrain: r_loc = intersect_point_line(loc, constrain[0], constrain[1])[0] else: r_loc = loc elif len(elem) == 2: - if SnapCache.snp_obj is not snp_obj or not (elem == SnapCache.edge).all(): - SnapCache.snp_obj = snp_obj - SnapCache.edge = elem + r_type = 'EDGE' + + if _snap_cache.edge.snp_obj is not snp_obj or not (elem == _snap_cache.edge.elem).all(): + _snap_cache.edge.snp_obj = snp_obj + _snap_cache.edge.elem = elem v0 = elem_co[0] v1 = elem_co[1] - SnapCache.vmid = 0.5 * (v0 + v1) - SnapCache.v2dmid = location_3d_to_region_2d(sctx.region, sctx.rv3d, SnapCache.vmid) + _snap_cache.edge.vmid = 0.5 * (v0 + v1) + _snap_cache.edge.v2dmid = location_3d_to_region_2d( + sctx.region, sctx.rv3d, _snap_cache.edge.vmid) if previous_vert and (not bm_geom or previous_vert not in bm_geom.verts): pvert_co = main_snap_obj.mat @ previous_vert.co perp_point = intersect_point_line(pvert_co, v0, v1) - SnapCache.vperp = perp_point[0] + _snap_cache.edge.vperp = perp_point[0] #factor = point_perpendicular[1] - SnapCache.v2dperp = location_3d_to_region_2d(sctx.region, sctx.rv3d, perp_point[0]) - SnapCache.is_increment = False + _snap_cache.edge.v2dperp = location_3d_to_region_2d(sctx.region, sctx.rv3d, perp_point[0]) + _snap_cache.edge.is_increment = False else: - SnapCache.is_increment = True + _snap_cache.edge.is_increment = True - #else: SnapCache.v2dperp = None + #else: _snap_cache.edge.v2dperp = None if constrain: t_loc = intersect_line_line(constrain[0], constrain[1], elem_co[0], elem_co[1]) - if t_loc is None: is_increment = True end = orig + view_vector t_loc = intersect_line_line(constrain[0], constrain[1], orig, end) r_loc = t_loc[0] - elif SnapCache.v2dperp and\ - abs(SnapCache.v2dperp[0] - mcursor[0]) < 10 and abs(SnapCache.v2dperp[1] - mcursor[1]) < 10: + elif _snap_cache.edge.v2dperp and\ + abs(_snap_cache.edge.v2dperp[0] - mcursor[0]) < 10 and abs(_snap_cache.edge.v2dperp[1] - mcursor[1]) < 10: r_type = 'PERPENDICULAR' - r_loc = SnapCache.vperp + r_loc = _snap_cache.edge.vperp - elif abs(SnapCache.v2dmid[0] - mcursor[0]) < 10 and abs(SnapCache.v2dmid[1] - mcursor[1]) < 10: - r_type = 'CENTER' - r_loc = SnapCache.vmid + elif abs(_snap_cache.edge.v2dmid[0] - mcursor[0]) < 10 and abs(_snap_cache.edge.v2dmid[1] - mcursor[1]) < 10: + r_type = 'CENTER' + r_loc = _snap_cache.edge.vmid else: - is_increment = SnapCache.is_increment - - r_type = 'EDGE' - r_loc = loc + r_loc = loc + is_increment = _snap_cache.edge.is_increment elif len(elem) == 3: r_type = 'FACE' +# vmid = v2dmid = None +# if bm_geom and _snap_cache.face is not bm_geom: +# _snap_cache.face.bm_face = bm_geom +# vmid = _snap_cache.face.vmid = bm_geom.calc_center_median() +# v2dmid = _snap_cache.face.v2dmid = location_3d_to_region_2d( +# sctx.region, sctx.rv3d, _snap_cache.face.vmid) + if constrain: is_increment = False +# elem_world_co = [snp_obj.mat @ co for co in elem_co] +# ray_dir = constrain[1] - constrain[0] +# r_loc = intersect_ray_tri(*elem_world_co, ray_dir, constrain[0], False) +# if r_loc is None: +# r_loc = intersect_ray_tri(*elem_world_co, -ray_dir, constrain[0], False) +# if r_loc is None: r_loc = intersect_point_line(loc, constrain[0], constrain[1])[0] + +# elif v2dmid and abs(v2dmid[0] - mcursor[0]) < 10 and abs(v2dmid[1] - mcursor[1]) < 10: +# r_type = 'CENTER' +# r_loc = vmid + else: - is_increment = True r_loc = loc + is_increment = True if previous_vert: pv_co = main_snap_obj.mat @ previous_vert.co @@ -260,4 +297,4 @@ def snap_utilities( return snp_obj, loc, r_loc, r_type, bm, bm_geom, r_len -snap_utilities.edge_cache = SnapCache +snap_utilities.cache = _snap_cache diff --git a/mesh_snap_utilities_line/drawing_utilities.py b/mesh_snap_utilities_line/drawing_utilities.py index 92faceccb9f696bd8d77de5f2606127334acb326..0ce679c6ad0102ba4c6af9565ceb20569057e269 100644 --- a/mesh_snap_utilities_line/drawing_utilities.py +++ b/mesh_snap_utilities_line/drawing_utilities.py @@ -20,6 +20,24 @@ from mathutils import Vector class SnapDrawn(): + __slots__ = ( + 'out_color', + 'face_color', + 'edge_color', + 'vert_color', + 'center_color', + 'perpendicular_color', + 'constrain_shift_color', + 'axis_x_color', + 'axis_y_color', + 'axis_z_color', + '_format_pos', + '_format_pos_and_color', + '_program_unif_col', + '_program_smooth_col', + '_batch_point', + ) + def __init__(self, out_color, face_color, edge_color, vert_color, center_color, perpendicular_color, constrain_shift_color, diff --git a/mesh_snap_utilities_line/keys.py b/mesh_snap_utilities_line/keys.py new file mode 100644 index 0000000000000000000000000000000000000000..29523966e5b82460c8a98b605a52be69e1abd53a --- /dev/null +++ b/mesh_snap_utilities_line/keys.py @@ -0,0 +1,99 @@ + +#km_snap_utilities_modal_keymap = "Snap Utilities Modal Map" + +km_tool_snap_utilities_line = "3D View Tool: Edit Mesh, Make Line" + +def km_mesh_snap_utilities_operators(): + return ( + "Mesh", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": [ + ("mesh.snap_utilities_line", {"type": 'K', "value": 'PRESS'}, + {"properties": [("wait_for_input", True)], + "active":False}), + ]}, + ) + +""" +def km_snap_utilities_modal_map(): + items = [] + modal_enum = [] + keymap = ( + km_snap_utilities_modal_keymap, + {"space_type": 'EMPTY', "region_type": 'WINDOW', "modal": True, "modal_enum": modal_enum}, + {"items": items}, + ) + + modal_enum.extend([ + ("ADD_CUT", "ADD_CUT", ""), + ("CANCEL", "CANCEL", ""), + ("CONFIRM", "CONFIRM", ""), + ("IGNORE_SNAP_ON", "IGNORE_SNAP_ON", ""), + ("IGNORE_SNAP_OFF", "IGNORE_SNAP_OFF", ""), + ]) + + items.extend([ + ("ADD_CUT", {"type": 'LEFTMOUSE', "value": 'ANY', "any": True}, None), + ("CANCEL", {"type": 'ESC', "value": 'PRESS', "any": True}, None), + ("CANCEL", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK', "any": True}, None), + ("CANCEL", {"type": 'RIGHTMOUSE', "value": 'PRESS', "any": True}, None), + ("CONFIRM", {"type": 'RET', "value": 'PRESS', "any": True}, None), + ("CONFIRM", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "any": True}, None), + ("CONFIRM", {"type": 'SPACE', "value": 'PRESS', "any": True}, None), + ("IGNORE_SNAP_ON", {"type": 'LEFT_SHIFT', "value": 'PRESS', "any": True}, None), + ("IGNORE_SNAP_OFF", {"type": 'LEFT_SHIFT', "value": 'RELEASE', "any": True}, None), + ("IGNORE_SNAP_ON", {"type": 'RIGHT_SHIFT', "value": 'PRESS', "any": True}, None), + ("IGNORE_SNAP_OFF", {"type": 'RIGHT_SHIFT', "value": 'RELEASE', "any": True}, None), + ]) + + return keymap +""" + +def km_3d_view_tool_snap_utilities_line(tool_mouse): + return ( + km_tool_snap_utilities_line, + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ + ("mesh.snap_utilities_line", {"type": tool_mouse, "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ]}, + ) + +def km_view3d_empty(km_name): + return ( + km_name, + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": []}, + ) + +# ------------------------------------------------------------------------------ +# Full Configuration + +def generate_empty_snap_utilities_tools_keymaps(): + return [ + #km_view3d_empty(km_snap_utilities_modal_keymap), + + km_view3d_empty(km_tool_snap_utilities_line), + ] + +def generate_snap_utilities_global_keymaps(tool_mouse = 'LEFTMOUSE'): + return [ + km_mesh_snap_utilities_operators(), + ] + +def generate_snap_utilities_tools_keymaps(tool_mouse = 'LEFTMOUSE'): + return [ + # Tool System. + km_3d_view_tool_snap_utilities_line(tool_mouse), + ] + +def generate_snap_utilities_keymaps(tool_mouse = 'LEFTMOUSE'): + return [ + km_mesh_snap_utilities_operators(), + + # Modal maps. + #km_snap_utilities_modal_map(), + + # Tool System. + km_3d_view_tool_snap_utilities_line(tool_mouse), + ] diff --git a/mesh_snap_utilities_line/navigation_ops.py b/mesh_snap_utilities_line/navigation_ops.py index 21eecc1909c53bcb5d6361c3d91ceda42b9edde3..f08364d8d9140f7b23f422ed96cbd56d2af3d7f3 100644 --- a/mesh_snap_utilities_line/navigation_ops.py +++ b/mesh_snap_utilities_line/navigation_ops.py @@ -23,6 +23,8 @@ class VIEW3D_OT_rotate_custom_pivot(bpy.types.Operator): bl_label = "Rotate the view" bl_options = {'BLOCKING', 'GRAB_CURSOR'} + __slots__ = 'rv3d', 'init_coord', 'pos1', 'view_rot' + pivot: bpy.props.FloatVectorProperty("Pivot", subtype='XYZ') g_up_axis: bpy.props.FloatVectorProperty("up_axis", default=(0.0, 0.0, 1.0), subtype='XYZ') sensitivity: bpy.props.FloatProperty("sensitivity", default=0.007) @@ -64,6 +66,8 @@ class VIEW3D_OT_zoom_custom_target(bpy.types.Operator): bl_label = "Zoom the view" bl_options = {'BLOCKING', 'GRAB_CURSOR'} + __slots__ = 'rv3d', 'init_dist', 'delta', 'init_loc' + target: bpy.props.FloatVectorProperty("target", subtype='XYZ') delta: bpy.props.IntProperty("delta", default=0) step_factor = 0.333 diff --git a/mesh_snap_utilities_line/op_line.py b/mesh_snap_utilities_line/op_line.py index e25eb9e69de57f96a774d2a588bbe665c9ea64b5..7af0c684050ed176b671e67b011dd87cd93c2100 100644 --- a/mesh_snap_utilities_line/op_line.py +++ b/mesh_snap_utilities_line/op_line.py @@ -273,7 +273,7 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator): if self.rv3d.view_matrix != self.rotMat: self.rotMat = self.rv3d.view_matrix.copy() self.bool_update = True - snap_utilities.edge_cache.snp_obj = None # hack for snap edge elemens update + snap_utilities.cache.clear() else: self.bool_update = False @@ -329,13 +329,13 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator): else: if event.shift: if isinstance(self.geom, bmesh.types.BMEdge): + mat = self.main_snap_obj.mat + verts_co = [mat @ v.co for v in self.geom.verts] if is_making_lines: loc = self.list_verts_co[-1] - self.vector_constrain = (loc, loc + self.geom.verts[1].co - - self.geom.verts[0].co, event.type) + self.vector_constrain = (loc, loc + verts_co[1] - verts_co[0], event.type) else: - self.vector_constrain = [self.main_snap_obj.mat @ v.co for - v in self.geom.verts] + [event.type] + self.vector_constrain = verts_co + [event.type] else: if is_making_lines: loc = self.list_verts_co[-1] @@ -378,7 +378,7 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator): self._exit(context) return {'FINISHED'} else: - snap_utilities.edge_cache.snp_obj = None # hack for snap edge elemens update + snap_utilities.cache.clear() self.vector_constrain = None self.list_edges = [] self.list_verts = [] diff --git a/mesh_snap_utilities_line/preferences.py b/mesh_snap_utilities_line/preferences.py index 7361284e6afcbc15be3e767726ad44a1232421e1..11b91dc4b85dad3c41cf508d70cf156340d62857 100644 --- a/mesh_snap_utilities_line/preferences.py +++ b/mesh_snap_utilities_line/preferences.py @@ -16,6 +16,7 @@ # ##### END GPL LICENSE BLOCK ##### import bpy + from bpy.props import ( EnumProperty, StringProperty, @@ -25,6 +26,10 @@ from bpy.props import ( FloatProperty, ) +from bpy.app.translations import contexts as i18n_contexts + +import rna_keymap_ui + class SnapUtilitiesPreferences(bpy.types.AddonPreferences): # this must match the addon name, use '__package__' @@ -67,38 +72,47 @@ class SnapUtilitiesPreferences(bpy.types.AddonPreferences): step=1, precision=3) - out_color: FloatVectorProperty(name="OUT", default=(0.0, 0.0, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1) - face_color: FloatVectorProperty(name="FACE", default=(1.0, 0.8, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1) - edge_color: FloatVectorProperty(name="EDGE", default=(0.0, 0.8, 1.0, 0.5), size=4, subtype="COLOR", min=0, max=1) - vert_color: FloatVectorProperty(name="VERT", default=(1.0, 0.5, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1) - center_color: FloatVectorProperty(name="CENTER", default=(1.0, 0.0, 1.0, 1.0), size=4, subtype="COLOR", min=0, max=1) - perpendicular_color: FloatVectorProperty(name="PERPENDICULAR", default=(0.1, 0.5, 0.5, 1.0), size=4, subtype="COLOR", min=0, max=1) - constrain_shift_color: FloatVectorProperty(name="SHIFT CONSTRAIN", default=(0.8, 0.5, 0.4, 1.0), size=4, subtype="COLOR", min=0, max=1) + out_color: FloatVectorProperty(name="Floor", default=(0.0, 0.0, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1) + face_color: FloatVectorProperty(name="Face Highlighted", default=(1.0, 0.8, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1) + edge_color: FloatVectorProperty(name="Edge Highlighted", default=(0.0, 0.8, 1.0, 0.5), size=4, subtype="COLOR", min=0, max=1) + vert_color: FloatVectorProperty(name="Vertex Highlighted", default=(1.0, 0.5, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1) + center_color: FloatVectorProperty(name="Middle of the Edge", default=(1.0, 0.0, 1.0, 1.0), size=4, subtype="COLOR", min=0, max=1) + perpendicular_color: FloatVectorProperty(name="Perpendicular Point", default=(0.1, 0.5, 0.5, 1.0), size=4, subtype="COLOR", min=0, max=1) + constrain_shift_color: FloatVectorProperty(name="Shift Constrain", default=(0.8, 0.5, 0.4, 1.0), size=4, subtype="COLOR", min=0, max=1) + + # hidden + tabs: EnumProperty( + name="Tabs", + items = [ + ("GENERAL", "General", ""), + ("KEYMAPS", "Keymaps", ""), + ("COLORS", "Colors", ""), + ], + default="GENERAL") def draw(self, context): layout = self.layout - layout.label(text="Snap Colors:") - split = layout.split() - - col = split.column() - col.prop(self, "out_color") - col.prop(self, "constrain_shift_color") - col = split.column() - col.prop(self, "face_color") - col = split.column() - col.prop(self, "edge_color") - col = split.column() - col.prop(self, "vert_color") - col = split.column() - col.prop(self, "center_color") - col = split.column() - col.prop(self, "perpendicular_color") - + # TAB BAR row = layout.row() + row.prop(self, "tabs", expand=True) + + box = layout.box() + + if self.tabs == "GENERAL": + self.draw_general(box) + if self.tabs == "COLORS": + self.draw_snap_utilities_colors(box) + + elif self.tabs == "KEYMAPS": + self.draw_snap_utilities_keymaps(context, box) + + def draw_general(self, layout): + row = layout.row() col = row.column() - #col.label(text="Snap Items:") + + col.label(text="Snap Properties:") col.prop(self, "incremental") col.prop(self, "increments_grid") if self.increments_grid: @@ -111,3 +125,55 @@ class SnapUtilitiesPreferences(bpy.types.AddonPreferences): col.label(text="Line Tool:") col.prop(self, "intersect") col.prop(self, "create_face") + + def draw_snap_utilities_colors(self, layout): + layout.use_property_split = True + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + + flow.prop(self, "out_color") + flow.prop(self, "constrain_shift_color") + flow.prop(self, "face_color") + flow.prop(self, "edge_color") + flow.prop(self, "vert_color") + flow.prop(self, "center_color") + flow.prop(self, "perpendicular_color") + + def draw_snap_utilities_keymaps(self, context, layout): + from .keys import ( + generate_snap_utilities_global_keymaps, + generate_snap_utilities_tools_keymaps, + ) + + wm = context.window_manager + #kc = wm.keyconfigs.addon + kc = wm.keyconfigs.user + + layout.label(text="Global:") + + for km_name, km_args, km_content in generate_snap_utilities_global_keymaps(): + km = kc.keymaps.get(km_name) + if km: + self.draw_snap_utilities_km(kc, km, layout) + + layout.label(text="Tools:") + + for km_name, km_args, km_content in generate_snap_utilities_tools_keymaps(): + km = kc.keymaps.get(km_name) + if km: + self.draw_snap_utilities_km(kc, km, layout) + + @staticmethod + def draw_snap_utilities_km(kc, km, layout): + layout.context_pointer_set("keymap", km) + + row = layout.row() + row.prop(km, "show_expanded_items", text="", emboss=False) + row.label(text=km.name, text_ctxt=i18n_contexts.id_windowmanager) + + if km.show_expanded_items: + col = layout.column() + + for kmi in km.keymap_items: + if "snap_utilities" in kmi.idname: + rna_keymap_ui.draw_kmi(["ADDON", "USER", "DEFAULT"], kc, km, kmi, col, 0) diff --git a/mesh_snap_utilities_line/snap_context_l/__init__.py b/mesh_snap_utilities_line/snap_context_l/__init__.py index 32b8bf74bb5bcae5d3f693da089e137f57b0324c..7fa1521595bd2c4715a9311f31581443b2c0cef8 100644 --- a/mesh_snap_utilities_line/snap_context_l/__init__.py +++ b/mesh_snap_utilities_line/snap_context_l/__init__.py @@ -198,6 +198,27 @@ class SnapContext(): :type space: :class:`bpy.types.SpaceView3D` """ + __slots__ = ( + '_dist_px', + '_dist_px_sq', + '_offscreen', + '_offset_cur', + '_snap_buffer', + '_snap_mode', + 'depsgraph', + 'depth_range', + 'drawn_count', + 'freed', + 'last_ray', + 'mval', + 'proj_mat', + 'region', + 'rv3d', + 'snap_objects', + 'threshold', + 'winsize', + ) + def __init__(self, depsgraph, region, space): #print('Render:', bgl.glGetString(bgl.GL_RENDERER)) #print('OpenGL Version:', bgl.glGetString(bgl.GL_VERSION)) @@ -208,7 +229,8 @@ class SnapContext(): self._offset_cur = 1 # Starts with index 1 self.proj_mat = None - self.mval = Vector((0, 0)) + self.mval = Vector((0.0, 0.0)) + self.last_ray = Vector((1.0, 0.0, 0.0)) self._snap_mode = VERT | EDGE | FACE self.set_pixel_dist(12) diff --git a/mesh_snap_utilities_line/widgets.py b/mesh_snap_utilities_line/widgets.py index ad0ee2834d11653d9410fd6db1442c118e91de8b..3060d74e0615cd89455105efd89dbab4903afd37 100644 --- a/mesh_snap_utilities_line/widgets.py +++ b/mesh_snap_utilities_line/widgets.py @@ -30,7 +30,9 @@ from .drawing_utilities import SnapDrawn # return False -class SnapWidgetCommon(SnapUtilities): +class SnapWidgetCommon(SnapUtilities, bpy.types.Gizmo): +# __slots__ = ('inited', 'mode', 'last_mval', 'depsgraph') + snap_to_update = False def handler(self, scene): @@ -71,17 +73,18 @@ class SnapWidgetCommon(SnapUtilities): SnapUtilities.snapwidgets.append(self) def end_snapwidget(self): - SnapUtilities.snapwidgets.remove(self) + if self in SnapUtilities.snapwidgets: + SnapUtilities.snapwidgets.remove(self) - #from .snap_context_l import global_snap_context_get - #sctx = global_snap_context_get(None, None, None) + #from .snap_context_l import global_snap_context_get + #sctx = global_snap_context_get(None, None, None) - sctx = object.__getattribute__(self, 'sctx') - if sctx and not SnapUtilities.snapwidgets: - sctx.clear_snap_objects() + sctx = object.__getattribute__(self, 'sctx') + if sctx and not SnapUtilities.snapwidgets: + sctx.clear_snap_objects() - handler = object.__getattribute__(self, 'handler') - bpy.app.handlers.depsgraph_update_post.remove(handler) + handler = object.__getattribute__(self, 'handler') + bpy.app.handlers.depsgraph_update_post.remove(handler) def update_snap(self, context, mval): if self.last_mval == mval: @@ -109,7 +112,7 @@ class SnapWidgetCommon(SnapUtilities): self.sctx.set_snap_mode( self.snap_vert, self.snap_edge, self.snap_face) - snap_utilities.edge_cache.snp_obj = None # hack for snap edge elemens update + snap_utilities.cache.clear() self.snap_obj, prev_loc, self.location, self.type, self.bm, self.geom, len = snap_utilities( self.sctx, None, @@ -118,9 +121,11 @@ class SnapWidgetCommon(SnapUtilities): ) -class SnapPointWidget(SnapWidgetCommon, bpy.types.Gizmo): +class SnapPointWidget(SnapWidgetCommon): bl_idname = "VIEW3D_GT_snap_point" + __slots__ = () + def test_select(self, context, mval): if not self.inited: self.init_snapwidget(context) @@ -138,6 +143,7 @@ class SnapPointWidget(SnapWidgetCommon, bpy.types.Gizmo): def setup(self): self.init_delayed() + def context_mode_check(context, widget_group): workspace = context.workspace mode = workspace.tools_mode @@ -150,7 +156,7 @@ def context_mode_check(context, widget_group): return True -class SnapWidgetGroupCommon: +class SnapWidgetGroupCommon(bpy.types.GizmoGroup): bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' bl_options = {'3D'} @@ -167,7 +173,7 @@ class SnapWidgetGroupCommon: object.__getattribute__(self.widget, 'end_snapwidget')() -class SnapPointWidgetGroup(SnapWidgetGroupCommon, bpy.types.GizmoGroup): +class SnapPointWidgetGroup(SnapWidgetGroupCommon): bl_idname = "MESH_GGT_snap_point" bl_label = "Draw Snap Point"