forked from bookyakuno/Blender-Scramble-Addon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVIEW3D_MT_edit_mesh_delete.py
169 lines (147 loc) · 5.27 KB
/
VIEW3D_MT_edit_mesh_delete.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# 「3Dビュー」エリア > メッシュの「編集」モード > 「削除」メニュー (Xキー)
# "3D View" Area > "Edit" Mode with Mesh > "Delete" Menu (X Key)
import bpy
import bmesh
from bpy.props import *
################
# オペレーター #
################
class DeleteBySelectMode(bpy.types.Operator):
bl_idname = "mesh.delete_by_select_mode"
bl_label = "Delete Based on Select Mode"
bl_description = "Delete selected vertices / edges / faces in the specific way based on current mesh select mode"
bl_options = {'REGISTER', 'UNDO'}
use_current : BoolProperty(name="Registered", default=False, options={'HIDDEN'})
vertex_items = [
("delete(type='VERT')","Delete","Delete selected vertices",1),
("dissolve_verts()"," Dissolve","Dissolve vertices, merge edges and faces",2),
("remove_doubles()","Remove Doubles","Merge vertices based on their proximity",3)
]
vertex_mode : EnumProperty(name="Method on Vertex Mode", items=vertex_items)
edge_items = [
("delete(type='EDGE')","Delete","Delete selected edges",1),
("dissolve_edges()"," Dissolve","Dissolve edges, merging faces",2),
("edge_collapse()","Collapse","Collapse each edge to one vertex",3),
("delete_edgeloop()","Delete Loop","Delete an edge loop by merging the faces on each side",4)
]
edge_mode : EnumProperty(name="Method on Edge Mode", items=edge_items)
face_items = [
("delete(type='FACE')","Delete","Delete selected faces",1),
("dissolve_faces()"," Dissolve","Dissolve faces",2),
("delete(type='ONLY_FACE')","Only Faces","Delete selected faces keeping their vertices and edges",3)
]
face_mode : EnumProperty(name="Method on Face Mode", items=face_items)
def __init__(self):
for p in ['use_current','vertex_mode','edge_mode','face_mode',]:
exec(f"self.{p} = bpy.context.scene.scramble_dl_prop.{p}")
def invoke(self, context, event):
if not self.use_current:
return context.window_manager.invoke_props_dialog(self, width=330)
else:
return self.execute(context)
def draw(self, context):
for p in ['vertex_mode','edge_mode','face_mode',]:
box = self.layout.box()
row = box.split(factor=0.6).row()
row.alignment = 'LEFT'
target = p.split("_")[0]
row.label(text=target.capitalize(), icon =f"{target.upper()}SEL")
row.label(text="Delete Method")
row = box.row(align=True)
row.prop(self, p, expand=True)
def execute(self, context):
if not self.use_current:
self.use_current = True
mode = context.tool_settings.mesh_select_mode[:]
if (mode[0]):
exec(f"bpy.ops.mesh.{self.vertex_mode}")
elif (mode[1]):
exec(f"bpy.ops.mesh.{self.edge_mode}")
elif (mode[2]):
exec(f"bpy.ops.mesh.{self.face_mode}")
for p in ['use_current','vertex_mode','edge_mode','face_mode',]:
if eval(f"bpy.context.scene.scramble_dl_prop.{p} != self.{p}"):
exec(f"bpy.context.scene.scramble_dl_prop.{p} = self.{p}")
return {'FINISHED'}
class DeleteHideMesh(bpy.types.Operator):
bl_idname = "mesh.delete_hide_mesh"
bl_label = "Delete Hidden Vertices"
bl_description = "Delete all hidden vertices of active object"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
if context.active_object:
if not context.active_object.type == "MESH":
return False
return True
def execute(self, context):
me = context.active_object.data
bm = bmesh.from_edit_mesh(me)
for face in bm.faces[:]:
if (face.hide):
bm.faces.remove(face)
for edge in bm.edges[:]:
if (edge.hide):
bm.edges.remove(edge)
for vert in bm.verts[:]:
if (vert.hide):
bm.verts.remove(vert)
bmesh.update_edit_mesh(me)
return {'FINISHED'}
class ScrambleDeletePropGroup(bpy.types.PropertyGroup):
use_current : bpy.props.BoolProperty(
name="Use current setting",
description="",
default=False
)
vertex_mode : bpy.props.StringProperty(
name="Delete method on vertex mode",
description="",
default="delete(type='VERT')"
)
edge_mode : bpy.props.StringProperty(
name="Delete method on edge mode",
description="",
default="delete(type='EDGE')"
)
face_mode : bpy.props.StringProperty(
name="Delete method on face mode",
description="",
default="delete(type='FACE')"
)
################
# クラスの登録 #
################
classes = [
DeleteBySelectMode,
DeleteHideMesh,
ScrambleDeletePropGroup
]
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.scramble_dl_prop = bpy.props.PointerProperty(type=ScrambleDeletePropGroup)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.Scene.scramble_dl_prop
################
# メニュー追加 #
################
# メニューのオン/オフの判定
def IsMenuEnable(self_id):
for id in bpy.context.preferences.addons[__name__.partition('.')[0]].preferences.disabled_menu.split(','):
if (id == self_id):
return False
else:
return True
# メニューを登録する関数
def menu(self, context):
if (IsMenuEnable(__name__.split('.')[-1])):
self.layout.separator()
self.layout.operator(DeleteBySelectMode.bl_idname, icon="PLUGIN")
self.layout.operator(DeleteHideMesh.bl_idname, icon="PLUGIN")
self.layout.operator('mesh.dissolve_mode')
if (context.preferences.addons[__name__.partition('.')[0]].preferences.use_disabled_menu):
self.layout.separator()
self.layout.operator('wm.toggle_menu_enable', icon='CANCEL').id = __name__.split('.')[-1]