1+ import bpy
2+
3+ from ..utils .math import (
4+ cross ,
5+ length
6+ )
7+
8+
9+ class MESH_OT_delete_vertical_faces (bpy .types .Operator ):
10+ bl_idname = 'mesh.delete_vertical_faces'
11+ bl_label = 'Delete Vertical Faces'
12+ bl_options = {'REGISTER' , 'UNDO' }
13+
14+ apply_rotation : bpy .props .BoolProperty (name = 'Apply rotation' , default = False )
15+
16+ @classmethod
17+ def poll (cls , context ):
18+ return context .object .type == 'MESH'
19+
20+ def invoke (self , context , event ):
21+ return context .window_manager .invoke_props_dialog (self , width = 300 )
22+
23+ def execute (self , context ):
24+ up_vector = [0. , 0. , 1. ]
25+
26+ bpy .ops .object .mode_set (mode = 'EDIT' )
27+ bpy .ops .mesh .select_mode (use_extend = False , use_expand = False , type = 'FACE' )
28+ bpy .ops .object .mode_set (mode = 'OBJECT' )
29+
30+ # Apply rotation if requested
31+ if self .apply_rotation :
32+ bpy .ops .object .transform_apply (location = False , rotation = True , scale = False )
33+
34+ # Mesh faces
35+ faces = [f for f in context .object .data .polygons ]
36+
37+ # Selecting vertical faces
38+ for f in faces :
39+ normal_x_up = cross (f .normal , up_vector )
40+ # If the norm of cross profuct is 1., then the face is vertical
41+ if (length (normal_x_up ) == 1. ):
42+ f .select = True
43+ else :
44+ f .select = False
45+
46+ # Deleting selected faces
47+ bpy .ops .object .mode_set (mode = 'EDIT' )
48+ bpy .ops .mesh .delete (type = 'FACE' )
49+ bpy .ops .object .mode_set (mode = 'OBJECT' )
50+ return {'FINISHED' }
51+
52+ def draw (self , context ):
53+ layout = self .layout
54+ layout .label (text = 'It will delete vertical face in the local space.' , icon = 'INFO' )
55+ layout .label (text = 'If your object has a transformation of its rotation,' )
56+ layout .label (text = 'You may want to apply it first' )
57+ layout .prop (self , 'apply_rotation' )
0 commit comments