123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- # ##### 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
- from bpy.props import (
- BoolProperty,
- EnumProperty,
- )
- class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
- """Extrude each individual face separately along local normals"""
- bl_label = "Extrude Individual and Move"
- bl_idname = "view3d.edit_mesh_extrude_individual_move"
- @classmethod
- def poll(cls, context):
- obj = context.active_object
- return (obj is not None and obj.mode == 'EDIT')
- 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
- # totvert = mesh.total_vert_sel
- if select_mode[2] and totface == 1:
- bpy.ops.mesh.extrude_region_move(
- 'INVOKE_REGION_WIN',
- TRANSFORM_OT_translate={
- "orient_type": 'NORMAL',
- "constraint_axis": (False, False, True),
- }
- )
- 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')
- # ignore return from operators above because they are 'RUNNING_MODAL',
- # and cause this one not to be freed. [#24671]
- return {'FINISHED'}
- def invoke(self, context, _event):
- return self.execute(context)
- class VIEW3D_OT_edit_mesh_extrude_move(Operator):
- """Extrude region together along the average normal"""
- bl_label = "Extrude and Move on Normals"
- bl_idname = "view3d.edit_mesh_extrude_move_normal"
- @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):
- mesh = context.object.data
- totface = mesh.total_face_sel
- totedge = mesh.total_edge_sel
- # totvert = mesh.total_vert_sel
- if totface >= 1:
- if use_vert_normals:
- bpy.ops.mesh.extrude_region_shrink_fatten(
- 'INVOKE_REGION_WIN',
- TRANSFORM_OT_shrink_fatten={},
- )
- else:
- bpy.ops.mesh.extrude_region_move(
- 'INVOKE_REGION_WIN',
- TRANSFORM_OT_translate={
- "orient_type": 'NORMAL',
- "constraint_axis": (False, False, True),
- },
- )
- elif totedge == 1:
- bpy.ops.mesh.extrude_region_move(
- 'INVOKE_REGION_WIN',
- TRANSFORM_OT_translate={
- # Don't set the constraint axis since users will expect MMB
- # to use the user setting, see: T61637
- # "orient_type": 'NORMAL',
- # Not a popular choice, too restrictive for retopo.
- # "constraint_axis": (True, True, False)})
- "constraint_axis": (False, False, False),
- })
- else:
- bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
- # ignore return from operators above because they are 'RUNNING_MODAL',
- # and cause this one not to be freed. [#24671]
- return {'FINISHED'}
- 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):
- """Extrude region together along local normals"""
- bl_label = "Extrude and Move on Individual Normals"
- bl_idname = "view3d.edit_mesh_extrude_move_shrink_fatten"
- @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)
- def invoke(self, context, _event):
- return self.execute(context)
- class VIEW3D_OT_transform_gizmo_set(Operator):
- """Set the current transform gizmo"""
- bl_label = "Transform Gizmo Set"
- bl_options = {'REGISTER', 'UNDO'}
- bl_idname = "view3d.transform_gizmo_set"
- extend: BoolProperty(
- default=False,
- )
- type: EnumProperty(
- items=(
- ('TRANSLATE', "Move", ""),
- ('ROTATE', "Rotate", ""),
- ('SCALE', "Scale", ""),
- ),
- options={'ENUM_FLAG'},
- )
- @classmethod
- def poll(cls, context):
- return context.area.type == 'VIEW_3D'
- def execute(self, context):
- space_data = context.space_data
- space_data.show_gizmo = True
- attrs = ("show_gizmo_object_translate", "show_gizmo_object_rotate", "show_gizmo_object_scale")
- attr_active = tuple(
- attrs[('TRANSLATE', 'ROTATE', 'SCALE').index(t)]
- for t in self.type
- )
- if self.extend:
- for attr in attrs:
- if attr in attr_active:
- setattr(space_data, attr, True)
- else:
- for attr in attrs:
- setattr(space_data, attr, attr in attr_active)
- return {'FINISHED'}
- def invoke(self, context, event):
- if not self.properties.is_property_set("extend"):
- self.extend = event.shift
- return self.execute(context)
- classes = (
- VIEW3D_OT_edit_mesh_extrude_individual_move,
- VIEW3D_OT_edit_mesh_extrude_move,
- VIEW3D_OT_edit_mesh_extrude_shrink_fatten,
- VIEW3D_OT_transform_gizmo_set,
- )
|