space_view3d_brush_menus: initial update to 2.8 series : T68350
[blender-addons-contrib.git] / mesh_border_deselect_outer.py
1 import bpy
2 import bmesh
3
4 bl_info = {
5     "name": "Border Deselect Outer",
6     "author": "CoDEmanX",
7     "version": (1, 2),
8     "blender": (2, 66, 0),
9     "location": "View3D > EditMode > Select",
10     "description": "Make a selection, then run this operator " \
11         "to border-select the desired selection intersection",
12     "warning": "",
13     "wiki_url": "http://wiki.blender.org/index.php" \
14         "?title=Extensions:2.6/Py/Scripts/Modeling/Border_Deselect_Outer",
15     "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
16     "category": "Mesh"}
17
18
19 def store_sel():
20     bm = MESH_OT_border_deselect_outer.bm
21
22     if 'select_old' in bm.loops.layers.int.keys():
23         sel = bm.loops.layers.int['select_old']
24     else:
25         sel = bm.loops.layers.int.new("select_old")
26
27     for v in bm.verts:
28         v.link_loops[0][sel] = v.select
29
30 def restore_sel(me):
31     bm = MESH_OT_border_deselect_outer.bm
32
33     sel = bm.loops.layers.int['select_old']
34
35     for v in bm.verts:
36         if not (v.select and v.link_loops[0][sel]):
37             v.select_set(False)
38
39     bm.loops.layers.int.remove(sel)
40
41     #bm.select_mode = {'VERT'}
42     #bm.select_flush_mode()
43     bm.select_flush(False)
44     me.update()
45
46
47 def changed_sel():
48     bm = MESH_OT_border_deselect_outer.bm
49
50     sel = bm.loops.layers.int['select_old']
51
52     for v in bm.verts:
53         if v.select != v.link_loops[0][sel]:
54             return True
55     return False
56
57
58 class MESH_OT_border_deselect_outer(bpy.types.Operator):
59     """Border select an existing selection and make only the intersection selected"""
60     bl_idname = "mesh.border_deselect_outer"
61     bl_label = "Border Deselect Outer"
62     bl_options = {'REGISTER'}
63
64     init = True
65     bm = None
66     mode_change = False
67
68     def modal(self, context, event):
69
70         if changed_sel() or not self.init:
71             restore_sel(context.object.data)
72             return {'FINISHED'}
73
74         elif event.type in ('RIGHTMOUSE', 'ESC'):
75             return {'CANCELLED'}
76
77         if self.init:
78             bpy.ops.view3d.select_box('INVOKE_DEFAULT', extend=False)
79             self.init = False
80
81         return {'RUNNING_MODAL'}
82         #return {'PASS_THROUGH'} # Makes no difference
83
84     @staticmethod
85     def modecheck(context):
86         return (context.area.type == 'VIEW_3D' and
87                 context.object and
88                 context.object.type == 'MESH' and
89                 context.object.mode == 'EDIT')
90
91     @classmethod
92     def poll(cls, context):
93         return cls.modecheck(context)
94
95     def invoke(self, context, event):
96         if self.__class__.modecheck(context):
97
98             MESH_OT_border_deselect_outer.bm = bmesh.from_edit_mesh(context.object.data)
99             store_sel()
100             context.window_manager.modal_handler_add(self)
101             return {'RUNNING_MODAL'}
102         else:
103             self.report({'WARNING'}, "No active editmesh!")
104             return {'CANCELLED'}
105
106 def menu_func(self, context):
107     self.layout.operator("mesh.border_deselect_outer")
108
109
110 def register():
111     bpy.utils.register_class(MESH_OT_border_deselect_outer)
112     bpy.types.VIEW3D_MT_select_edit_mesh.prepend(menu_func)
113
114 def unregister():
115     bpy.utils.unregister_class(MESH_OT_border_deselect_outer)
116     bpy.types.VIEW3D_MT_select_edit_mesh.remove(menu_func)
117
118 if __name__ == "__main__":
119     register()