| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  | # ##### BEGIN GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | #  modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | #  as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | #  of the License, or (at your option) any later version. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | #  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | #  GNU General Public License for more details. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | #  along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  | #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # ##### END GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # <pep8-80 compliant> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import bpy | 
					
						
							|  |  |  | from bpy.types import Operator | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | from bpy.props import BoolProperty | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator): | 
					
						
							| 
									
										
										
										
											2017-04-14 20:01:43 +10:00
										 |  |  |     """Extrude individual elements and move""" | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |     bl_label = "Extrude Individual and Move" | 
					
						
							|  |  |  |     bl_idname = "view3d.edit_mesh_extrude_individual_move" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 13:14:17 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							|  |  |  |         obj = context.active_object | 
					
						
							| 
									
										
										
										
											2013-12-22 07:59:24 +11:00
										 |  |  |         return (obj is not None and obj.mode == 'EDIT') | 
					
						
							| 
									
										
										
										
											2013-11-01 13:14:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         mesh = context.object.data | 
					
						
							|  |  |  |         select_mode = context.tool_settings.mesh_select_mode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         totface = mesh.total_face_sel | 
					
						
							|  |  |  |         totedge = mesh.total_edge_sel | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |         # totvert = mesh.total_vert_sel | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if select_mode[2] and totface == 1: | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |             bpy.ops.mesh.extrude_region_move( | 
					
						
							|  |  |  |                 'INVOKE_REGION_WIN', | 
					
						
							|  |  |  |                 TRANSFORM_OT_translate={ | 
					
						
							|  |  |  |                     "constraint_orientation": 'NORMAL', | 
					
						
							|  |  |  |                     "constraint_axis": (False, False, True), | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         elif select_mode[2] and totface > 1: | 
					
						
							|  |  |  |             bpy.ops.mesh.extrude_faces_move('INVOKE_REGION_WIN') | 
					
						
							|  |  |  |         elif select_mode[1] and totedge >= 1: | 
					
						
							|  |  |  |             bpy.ops.mesh.extrude_edges_move('INVOKE_REGION_WIN') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-26 15:39:15 +00:00
										 |  |  |         # ignore return from operators above because they are 'RUNNING_MODAL', | 
					
						
							|  |  |  |         # and cause this one not to be freed. [#24671] | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, context, event): | 
					
						
							|  |  |  |         return self.execute(context) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class VIEW3D_OT_edit_mesh_extrude_move(Operator): | 
					
						
							| 
									
										
										
										
											2017-04-14 20:01:43 +10:00
										 |  |  |     """Extrude and move along normals""" | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |     bl_label = "Extrude and Move on Normals" | 
					
						
							|  |  |  |     bl_idname = "view3d.edit_mesh_extrude_move_normal" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 13:14:17 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							|  |  |  |         obj = context.active_object | 
					
						
							| 
									
										
										
										
											2013-12-22 07:59:24 +11:00
										 |  |  |         return (obj is not None and obj.mode == 'EDIT') | 
					
						
							| 
									
										
										
										
											2013-11-01 13:14:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 18:30:49 +00:00
										 |  |  |     @staticmethod | 
					
						
							|  |  |  |     def extrude_region(context, use_vert_normals): | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         mesh = context.object.data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         totface = mesh.total_face_sel | 
					
						
							|  |  |  |         totedge = mesh.total_edge_sel | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |         # totvert = mesh.total_vert_sel | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if totface >= 1: | 
					
						
							| 
									
										
										
										
											2013-10-15 18:30:49 +00:00
										 |  |  |             if use_vert_normals: | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |                 bpy.ops.mesh.extrude_region_shrink_fatten( | 
					
						
							|  |  |  |                     'INVOKE_REGION_WIN', | 
					
						
							|  |  |  |                     TRANSFORM_OT_shrink_fatten={}, | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2013-10-15 18:30:49 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |                 bpy.ops.mesh.extrude_region_move( | 
					
						
							|  |  |  |                     'INVOKE_REGION_WIN', | 
					
						
							| 
									
										
										
										
											2011-09-26 15:39:15 +00:00
										 |  |  |                     TRANSFORM_OT_translate={ | 
					
						
							|  |  |  |                         "constraint_orientation": 'NORMAL', | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |                         "constraint_axis": (False, False, True), | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         elif totedge == 1: | 
					
						
							|  |  |  |             bpy.ops.mesh.extrude_region_move( | 
					
						
							|  |  |  |                 'INVOKE_REGION_WIN', | 
					
						
							|  |  |  |                 TRANSFORM_OT_translate={ | 
					
						
							|  |  |  |                     "constraint_orientation": 'NORMAL', | 
					
						
							|  |  |  |                     # not a popular choice, too restrictive for retopo. | 
					
						
							|  |  |  |                     # "constraint_axis": (True, True, False)}) | 
					
						
							|  |  |  |                     "constraint_axis": (False, False, False), | 
					
						
							|  |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-26 15:39:15 +00:00
										 |  |  |         # ignore return from operators above because they are 'RUNNING_MODAL', | 
					
						
							|  |  |  |         # and cause this one not to be freed. [#24671] | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 18:30:49 +00:00
										 |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, context, event): | 
					
						
							|  |  |  |         return self.execute(context) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator): | 
					
						
							| 
									
										
										
										
											2017-04-14 20:01:43 +10:00
										 |  |  |     """Extrude and move along individual normals""" | 
					
						
							| 
									
										
										
										
											2013-10-15 18:30:49 +00:00
										 |  |  |     bl_label = "Extrude and Move on Individual Normals" | 
					
						
							|  |  |  |     bl_idname = "view3d.edit_mesh_extrude_move_shrink_fatten" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 13:14:17 +00:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							|  |  |  |         obj = context.active_object | 
					
						
							| 
									
										
										
										
											2013-12-22 07:59:24 +11:00
										 |  |  |         return (obj is not None and obj.mode == 'EDIT') | 
					
						
							| 
									
										
										
										
											2013-11-01 13:14:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-15 18:30:49 +00:00
										 |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |     def invoke(self, context, event): | 
					
						
							| 
									
										
										
										
											2011-09-22 20:37:22 +00:00
										 |  |  |         return self.execute(context) | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class VIEW3D_OT_select_or_deselect_all(Operator): | 
					
						
							| 
									
										
										
										
											2017-04-14 20:01:43 +10:00
										 |  |  |     """Select element under the mouse, deselect everything is there's nothing under the mouse""" | 
					
						
							| 
									
										
										
										
											2013-04-29 14:09:19 +00:00
										 |  |  |     bl_label = "Select or Deselect All" | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  |     bl_idname = "view3d.select_or_deselect_all" | 
					
						
							| 
									
										
										
										
											2013-06-10 10:45:25 +00:00
										 |  |  |     bl_options = {'UNDO'} | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     extend = BoolProperty( | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |         name="Extend", | 
					
						
							|  |  |  |         description="Extend selection instead of deselecting everything first", | 
					
						
							|  |  |  |         default=False, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     toggle = BoolProperty( | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |         name="Toggle", | 
					
						
							|  |  |  |         description="Toggle the selection", | 
					
						
							|  |  |  |         default=False, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     deselect = BoolProperty( | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |         name="Deselect", | 
					
						
							|  |  |  |         description="Remove from selection", | 
					
						
							|  |  |  |         default=False, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     center = BoolProperty( | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |         name="Center", | 
					
						
							|  |  |  |         description="Use the object center when selecting, in editmode used to extend object selection", | 
					
						
							|  |  |  |         default=False, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     enumerate = BoolProperty( | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |         name="Enumerate", | 
					
						
							|  |  |  |         description="List objects under the mouse (object mode only)", | 
					
						
							|  |  |  |         default=False, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     object = BoolProperty( | 
					
						
							| 
									
										
										
										
											2018-06-26 19:41:37 +02:00
										 |  |  |         name="Object", | 
					
						
							|  |  |  |         description="Use object selection (editmode only)", | 
					
						
							|  |  |  |         default=False, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 14:00:57 +06:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							|  |  |  |         active_object = context.active_object | 
					
						
							|  |  |  |         if active_object: | 
					
						
							|  |  |  |             return active_object.mode in {'EDIT', 'OBJECT', 'POSE'} | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  |     def invoke(self, context, event): | 
					
						
							|  |  |  |         x = event.mouse_region_x | 
					
						
							|  |  |  |         y = event.mouse_region_y | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-27 03:05:19 +00:00
										 |  |  |         if self.extend is False and self.toggle is False and self.deselect is False: | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  |             active_object = context.active_object | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if active_object: | 
					
						
							|  |  |  |                 if active_object.mode == 'EDIT': | 
					
						
							|  |  |  |                     if active_object.type == 'MESH': | 
					
						
							|  |  |  |                         bpy.ops.mesh.select_all(action='DESELECT') | 
					
						
							|  |  |  |                     elif active_object.type == 'CURVE': | 
					
						
							|  |  |  |                         bpy.ops.curve.select_all(action='DESELECT') | 
					
						
							|  |  |  |                     elif active_object.type == 'SURFACE': | 
					
						
							|  |  |  |                         bpy.ops.curve.select_all(action='DESELECT') | 
					
						
							|  |  |  |                     elif active_object.type == 'LATTICE': | 
					
						
							|  |  |  |                         bpy.ops.lattice.select_all(action='DESELECT') | 
					
						
							|  |  |  |                     elif active_object.type == 'META': | 
					
						
							|  |  |  |                         bpy.ops.mball.select_all(action='DESELECT') | 
					
						
							|  |  |  |                     elif active_object.type == 'ARMATURE': | 
					
						
							|  |  |  |                         bpy.ops.armature.select_all(action='DESELECT') | 
					
						
							| 
									
										
										
										
											2013-05-10 20:49:16 +00:00
										 |  |  |                 elif active_object.mode == 'POSE': | 
					
						
							|  |  |  |                     bpy.ops.pose.select_all(action='DESELECT') | 
					
						
							|  |  |  |                 elif active_object.mode == 'PARTICLE_EDIT': | 
					
						
							|  |  |  |                     bpy.ops.particle.select_all(action='DESELECT') | 
					
						
							| 
									
										
										
										
											2013-04-22 14:56:41 +00:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     bpy.ops.object.select_all(action='DESELECT') | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 bpy.ops.object.select_all(action='DESELECT') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return bpy.ops.view3d.select(extend=self.extend, | 
					
						
							|  |  |  |                                      deselect=self.deselect, | 
					
						
							|  |  |  |                                      toggle=self.toggle, | 
					
						
							|  |  |  |                                      center=self.center, | 
					
						
							|  |  |  |                                      enumerate=self.enumerate, | 
					
						
							|  |  |  |                                      object=self.object, | 
					
						
							|  |  |  |                                      location=(x, y)) | 
					
						
							| 
									
										
										
										
											2017-03-18 20:03:24 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | classes = ( | 
					
						
							|  |  |  |     VIEW3D_OT_edit_mesh_extrude_individual_move, | 
					
						
							|  |  |  |     VIEW3D_OT_edit_mesh_extrude_move, | 
					
						
							|  |  |  |     VIEW3D_OT_edit_mesh_extrude_shrink_fatten, | 
					
						
							|  |  |  |     VIEW3D_OT_select_or_deselect_all, | 
					
						
							| 
									
										
										
										
											2017-04-14 20:01:43 +10:00
										 |  |  | ) |