Cleanup: style
[blender.git] / release / scripts / startup / bl_operators / view3d.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8-80 compliant>
20
21 import bpy
22 from bpy.types import Operator
23 from bpy.props import BoolProperty
24
25
26 class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
27     """Extrude individual elements and move"""
28     bl_label = "Extrude Individual and Move"
29     bl_idname = "view3d.edit_mesh_extrude_individual_move"
30
31     @classmethod
32     def poll(cls, context):
33         obj = context.active_object
34         return (obj is not None and obj.mode == 'EDIT')
35
36     def execute(self, context):
37         mesh = context.object.data
38         select_mode = context.tool_settings.mesh_select_mode
39
40         totface = mesh.total_face_sel
41         totedge = mesh.total_edge_sel
42         # totvert = mesh.total_vert_sel
43
44         if select_mode[2] and totface == 1:
45             bpy.ops.mesh.extrude_region_move(
46                 'INVOKE_REGION_WIN',
47                 TRANSFORM_OT_translate={
48                     "constraint_orientation": 'NORMAL',
49                     "constraint_axis": (False, False, True),
50                 }
51             )
52         elif select_mode[2] and totface > 1:
53             bpy.ops.mesh.extrude_faces_move('INVOKE_REGION_WIN')
54         elif select_mode[1] and totedge >= 1:
55             bpy.ops.mesh.extrude_edges_move('INVOKE_REGION_WIN')
56         else:
57             bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN')
58
59         # ignore return from operators above because they are 'RUNNING_MODAL',
60         # and cause this one not to be freed. [#24671]
61         return {'FINISHED'}
62
63     def invoke(self, context, event):
64         return self.execute(context)
65
66
67 class VIEW3D_OT_edit_mesh_extrude_move(Operator):
68     """Extrude and move along normals"""
69     bl_label = "Extrude and Move on Normals"
70     bl_idname = "view3d.edit_mesh_extrude_move_normal"
71
72     @classmethod
73     def poll(cls, context):
74         obj = context.active_object
75         return (obj is not None and obj.mode == 'EDIT')
76
77     @staticmethod
78     def extrude_region(context, use_vert_normals):
79         mesh = context.object.data
80
81         totface = mesh.total_face_sel
82         totedge = mesh.total_edge_sel
83         # totvert = mesh.total_vert_sel
84
85         if totface >= 1:
86             if use_vert_normals:
87                 bpy.ops.mesh.extrude_region_shrink_fatten(
88                     'INVOKE_REGION_WIN',
89                     TRANSFORM_OT_shrink_fatten={},
90                 )
91             else:
92                 bpy.ops.mesh.extrude_region_move(
93                     'INVOKE_REGION_WIN',
94                     TRANSFORM_OT_translate={
95                         "constraint_orientation": 'NORMAL',
96                         "constraint_axis": (False, False, True),
97                     },
98                 )
99
100         elif totedge == 1:
101             bpy.ops.mesh.extrude_region_move(
102                 'INVOKE_REGION_WIN',
103                 TRANSFORM_OT_translate={
104                     "constraint_orientation": 'NORMAL',
105                     # not a popular choice, too restrictive for retopo.
106                     # "constraint_axis": (True, True, False)})
107                     "constraint_axis": (False, False, False),
108                 })
109         else:
110             bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
111
112         # ignore return from operators above because they are 'RUNNING_MODAL',
113         # and cause this one not to be freed. [#24671]
114         return {'FINISHED'}
115
116     def execute(self, context):
117         return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False)
118
119     def invoke(self, context, event):
120         return self.execute(context)
121
122
123 class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator):
124     """Extrude and move along individual normals"""
125     bl_label = "Extrude and Move on Individual Normals"
126     bl_idname = "view3d.edit_mesh_extrude_move_shrink_fatten"
127
128     @classmethod
129     def poll(cls, context):
130         obj = context.active_object
131         return (obj is not None and obj.mode == 'EDIT')
132
133     def execute(self, context):
134         return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True)
135
136     def invoke(self, context, event):
137         return self.execute(context)
138
139
140 class VIEW3D_OT_select_or_deselect_all(Operator):
141     """Select element under the mouse, deselect everything is there's nothing under the mouse"""
142     bl_label = "Select or Deselect All"
143     bl_idname = "view3d.select_or_deselect_all"
144
145     extend: BoolProperty(
146         name="Extend",
147         description="Extend selection instead of deselecting everything first",
148         default=False,
149         options={'SKIP_SAVE'},
150     )
151
152     toggle: BoolProperty(
153         name="Toggle",
154         description="Toggle the selection",
155         default=False,
156         options={'SKIP_SAVE'},
157     )
158
159     deselect: BoolProperty(
160         name="Deselect",
161         description="Remove from selection",
162         default=False,
163         options={'SKIP_SAVE'},
164     )
165
166     center: BoolProperty(
167         name="Center",
168         description="Use the object center when selecting, in editmode used to extend object selection",
169         default=False,
170         options={'SKIP_SAVE'},
171     )
172
173     enumerate: BoolProperty(
174         name="Enumerate",
175         description="List objects under the mouse (object mode only)",
176         default=False,
177         options={'SKIP_SAVE'},
178     )
179
180     object: BoolProperty(
181         name="Object",
182         description="Use object selection (editmode only)",
183         default=False,
184         options={'SKIP_SAVE'},
185     )
186
187     def invoke(self, context, event):
188         retval = bpy.ops.view3d.select(
189             'INVOKE_DEFAULT',
190             True,  # undo push
191             extend=self.extend,
192             deselect=self.deselect,
193             toggle=self.toggle,
194             center=self.center,
195             enumerate=self.enumerate,
196             object=self.object,
197         )
198
199         # Finished means something was selected.
200         if 'FINISHED' in retval:
201             return retval
202         if self.extend or self.toggle or self.deselect:
203             return retval
204
205         active_object = context.active_object
206         if active_object:
207             if active_object.mode == 'OBJECT':
208                 select_all = bpy.ops.object.select_all
209             elif active_object.mode == 'EDIT':
210                 if active_object.type == 'MESH':
211                     select_all = bpy.ops.mesh.select_all
212                 elif active_object.type == 'CURVE':
213                     select_all = bpy.ops.curve.select_all
214                 elif active_object.type == 'SURFACE':
215                     select_all = bpy.ops.curve.select_all
216                 elif active_object.type == 'LATTICE':
217                     select_all = bpy.ops.lattice.select_all
218                 elif active_object.type == 'META':
219                     select_all = bpy.ops.mball.select_all
220                 elif active_object.type == 'ARMATURE':
221                     select_all = bpy.ops.armature.select_all
222                 else:
223                     return retval
224             elif active_object.mode == 'POSE':
225                 select_all = bpy.ops.pose.select_all
226             elif active_object.mode == 'PARTICLE_EDIT':
227                 select_all = bpy.ops.particle.select_all
228             else:
229                 # Don nothing in paint and sculpt modes.
230                 return retval
231         else:
232             select_all = bpy.ops.object.select_all
233
234         return select_all('INVOKE_DEFAULT', True, action='DESELECT')
235
236
237 classes = (
238     VIEW3D_OT_edit_mesh_extrude_individual_move,
239     VIEW3D_OT_edit_mesh_extrude_move,
240     VIEW3D_OT_edit_mesh_extrude_shrink_fatten,
241     VIEW3D_OT_select_or_deselect_all,
242 )