1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
20 # meta-androcto, Hidesato Ikeya, zmj100, Gert De Roost, TrumanBlending, PKHG, #
21 # Oscurart, Greg, Stanislav Blinov, komi3D, BlenderLab, Paul Marshall (brikbot), #
22 # metalliandy, macouno, CoDEmanX, dustractor, Liero, lijenstina, Germano Cavalcante #
23 # Pistiwique, Jimmy Hazevoet #
26 "name": "Edit Tools 2",
27 "author": "meta-androcto",
29 "blender": (2, 78, 0),
30 "location": "View3D > Toolshelf > Tools and Specials (W-key)",
31 "description": "Extra mesh edit tools - modifying meshes and selection",
33 "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
34 "Py/Scripts/Modeling/Extra_Tools",
41 importlib
.reload(face_inset_fillet
)
42 importlib
.reload(mesh_filletplus
)
43 importlib
.reload(mesh_vertex_chamfer
)
44 importlib
.reload(mesh_mextrude_plus
)
45 importlib
.reload(mesh_offset_edges
)
46 importlib
.reload(pkhg_faces
)
47 importlib
.reload(mesh_edge_roundifier
)
48 importlib
.reload(mesh_cut_faces
)
49 importlib
.reload(split_solidify
)
50 importlib
.reload(mesh_edges_floor_plan
)
51 importlib
.reload(mesh_edges_length
)
52 importlib
.reload(random_vertices
)
53 importlib
.reload(mesh_fastloop
)
54 importlib
.reload(mesh_edgetools
)
55 importlib
.reload(mesh_pen_tool
)
56 importlib
.reload(vfe_specials
)
57 importlib
.reload(mesh_help
)
58 importlib
.reload(mesh_select_by_direction
)
59 importlib
.reload(mesh_select_by_edge_length
)
60 importlib
.reload(mesh_select_by_pi
)
61 importlib
.reload(mesh_select_by_type
)
62 importlib
.reload(mesh_select_connected_faces
)
63 importlib
.reload(mesh_index_select
)
64 importlib
.reload(mesh_selection_topokit
)
65 importlib
.reload(mesh_info_select
)
66 importlib
.reload(mesh_extrude_and_reshape
)
67 importlib
.reload(mesh_check
)
68 importlib
.reload(vertex_align
)
71 from . import face_inset_fillet
72 from . import mesh_filletplus
73 from . import mesh_vertex_chamfer
74 from . import mesh_mextrude_plus
75 from . import mesh_offset_edges
76 from . import pkhg_faces
77 from . import mesh_edge_roundifier
78 from . import mesh_cut_faces
79 from . import split_solidify
80 from . import mesh_edges_floor_plan
81 from . import mesh_edges_length
82 from . import random_vertices
83 from . import mesh_fastloop
84 from . import mesh_edgetools
85 from . import mesh_pen_tool
86 from . import vfe_specials
87 from . import mesh_help
88 from . import mesh_extrude_and_reshape
89 from . import mesh_check
90 from . import vertex_align
92 from .mesh_select_tools
import mesh_select_by_direction
93 from .mesh_select_tools
import mesh_select_by_edge_length
94 from .mesh_select_tools
import mesh_select_by_pi
95 from .mesh_select_tools
import mesh_select_by_type
96 from .mesh_select_tools
import mesh_select_connected_faces
97 from .mesh_select_tools
import mesh_index_select
98 from .mesh_select_tools
import mesh_selection_topokit
99 from .mesh_select_tools
import mesh_info_select
101 from . icons
.icons
import load_icons
104 import bpy_extras
.keyconfig_utils
105 from bpy
.types
import (
111 from bpy
.props
import (
122 # ------ MENUS ------ #
124 # Define the "Extras" menu
125 class VIEW3D_MT_edit_mesh_extras(Menu
):
126 bl_idname
= "VIEW3D_MT_edit_mesh_extras"
127 bl_label
= "Edit Tools"
129 def draw(self
, context
):
131 layout
.operator_context
= 'INVOKE_REGION_WIN'
132 mode
= context
.tool_settings
.mesh_select_mode
135 split
= layout
.split()
138 col
.label(text
="Vertex", icon
="VERTEXSEL")
141 col
.operator("mesh.vertex_chamfer", text
="Vertex Chamfer")
142 col
.operator("mesh.random_vertices", text
="Random Vertices")
145 col
.label(text
="Utilities", icon
="SCRIPTWIN")
148 col
.operator("object_ot.fastloop", text
="Fast loop")
149 col
.operator("mesh.flip_normals", text
="Normals Flip")
150 col
.operator("mesh.remove_doubles", text
="Remove Doubles")
151 col
.operator("mesh.subdivide", text
="Subdivide")
152 col
.operator("mesh.dissolve_limited", text
="Dissolve Limited")
155 split
= layout
.split()
157 col
.label(text
="Edge", icon
="EDGESEL")
160 col
.operator("mesh.fillet_plus", text
="Edge Fillet Plus")
161 col
.operator("mesh.offset_edges", text
="Offset Edges")
162 col
.operator("mesh.edge_roundifier", text
="Edge Roundify")
163 col
.operator("object.mesh_edge_length_set", text
="Set Edge Length")
164 col
.operator("mesh.edges_floor_plan")
167 col
.label(text
="Utilities", icon
="SCRIPTWIN")
170 col
.operator("object_ot.fastloop", text
="Fast loop")
171 col
.operator("mesh.flip_normals", text
="Normals Flip")
172 col
.operator("mesh.remove_doubles", text
="Remove Doubles")
174 col
.operator("mesh.subdivide", text
="Subdivide")
175 col
.operator("mesh.dissolve_limited", text
="Dissolve Limited")
178 split
= layout
.split()
180 col
.label(text
="Face", icon
="FACESEL")
183 col
.operator("object.mextrude", text
="Multi Extrude")
184 col
.operator("mesh.face_inset_fillet", text
="Face Inset Fillet")
185 col
.operator("mesh.extrude_reshape", text
="Push/Pull")
186 col
.operator("mesh.add_faces_to_object", text
="PKHG Faces")
187 col
.operator("mesh.ext_cut_faces", text
="Cut Faces")
188 col
.operator("mesh.split_solidify", text
="Split Solidify")
191 col
.label(text
="Utilities", icon
="SCRIPTWIN")
194 col
.operator("object_ot.fastloop", text
="Fast loop")
195 col
.operator("mesh.flip_normals", text
="Normals Flip")
196 col
.operator("mesh.remove_doubles", text
="Remove Doubles")
197 col
.operator("mesh.subdivide", text
="Subdivide")
198 col
.operator("mesh.dissolve_limited", text
="Dissolve Limited")
201 class EditToolsPanel(Panel
):
202 bl_label
= "Mesh Edit Tools"
203 bl_space_type
= "VIEW_3D"
204 bl_region_type
= "TOOLS"
205 bl_context
= "mesh_edit"
206 bl_category
= "Tools"
207 bl_options
= {"DEFAULT_CLOSED"}
209 def draw(self
, context
):
210 scene
= context
.scene
211 VERTDROP
= scene
.mesh_extra_tools
.UiTabDrop
[0]
212 EDGEDROP
= scene
.mesh_extra_tools
.UiTabDrop
[1]
213 FACEDROP
= scene
.mesh_extra_tools
.UiTabDrop
[2]
214 UTILSDROP
= scene
.mesh_extra_tools
.UiTabDrop
[3]
215 # Change icons depending on the bool state (compliant with the rest of the UI)
216 icon_active_0
= "TRIA_RIGHT" if not VERTDROP
else "TRIA_DOWN"
217 icon_active_1
= "TRIA_RIGHT" if not EDGEDROP
else "TRIA_DOWN"
218 icon_active_2
= "TRIA_RIGHT" if not FACEDROP
else "TRIA_DOWN"
219 icon_active_3
= "TRIA_RIGHT" if not UTILSDROP
else "TRIA_DOWN"
224 box1
= self
.layout
.box()
225 col
= box1
.column(align
=True)
226 row
= col
.row(align
=True)
227 row
.prop(scene
.mesh_extra_tools
, "UiTabDrop", text
="Vertex", index
=0, icon
=icon_active_0
)
229 row
.menu("mesh.vert_select_tools", icon
="RESTRICT_SELECT_OFF", text
="")
230 row
.menu("VIEW3D_MT_Select_Vert", icon
="VERTEXSEL", text
="")
235 row
.label(text
="Vertex Tools:", icon
="VERTEXSEL")
237 row
= layout
.split(0.8, align
=True)
238 row
.operator("mesh.vertex_chamfer", text
="Chamfer")
239 row
.operator("mesh.extra_tools_help",
240 icon
="LAYER_USED").help_ids
= "mesh_vertex_chamfer"
242 row
= layout
.split(0.8, align
=True)
243 row
.operator("mesh.random_vertices", text
="Random Vertices")
244 row
.operator("mesh.extra_tools_help",
245 icon
="LAYER_USED").help_ids
= "random_vertices"
247 # Vertex Align Properties And Menu
248 cen0
= scene
.mesh_extra_tools
.vert_align_to
251 layout
.label(text
="Vertex Align:", icon
="UV_VERTEXSEL")
253 # Draw the menu with 2 options
254 layout
.prop(scene
.mesh_extra_tools
, "vert_align_to", expand
=False)
256 row
= layout
.row(align
=True)
257 row
.operator("vertex_align.store_id", text
="Store Selected Vertex")
259 row
= layout
.split(0.8, align
=True)
260 row
.operator("vertex_align.align_original", text
="Align to Axis")
261 props
= row
.operator("mesh.extra_tools_help", icon
="LAYER_USED")
262 props
.help_ids
= "vertex_align"
263 props
.popup_size
= 400
264 elif cen0
== "coordinates":
265 layout
.prop(scene
.mesh_extra_tools
, "vert_align_use_stored", toggle
=True)
267 if scene
.mesh_extra_tools
.vert_align_use_stored
:
268 col
= layout
.column(align
=True)
269 col
.prop(scene
.mesh_extra_tools
, "vert_align_store_axis", expand
=True)
271 row
= layout
.split(0.8, align
=True)
272 row
.operator("vertex_align.coord_list_id", text
="Align Coordinates")
273 row
.operator("mesh.extra_tools_help",
274 icon
="LAYER_USED").help_ids
= "vertex_align"
277 box1
= self
.layout
.box()
278 col
= box1
.column(align
=True)
279 row
= col
.row(align
=True)
280 row
.prop(scene
.mesh_extra_tools
, "UiTabDrop", text
="Edge", index
=1, icon
=icon_active_1
)
283 row
.menu("mesh.edge_select_tools", icon
="RESTRICT_SELECT_OFF", text
="")
284 row
.menu("VIEW3D_MT_Select_Edge", icon
="EDGESEL", text
="")
289 row
.label(text
="Edge Tools:", icon
="EDGESEL")
290 row
.menu("VIEW3D_MT_edit_mesh_edgetools", icon
="GRID")
292 row
= layout
.split(0.8, align
=True)
293 row
.operator("mesh.fillet_plus", text
="Fillet plus")
295 props
= row
.operator("mesh.extra_tools_help", icon
="LAYER_USED")
296 props
.help_ids
= "mesh_filletplus"
297 props
.popup_size
= 400
299 row
= layout
.split(0.8, align
=True)
300 row
.operator("mesh.offset_edges", text
="Offset Edges")
301 row
.operator("mesh.extra_tools_help",
302 icon
="LAYER_USED").help_ids
= "mesh_offset_edges"
304 row
= layout
.split(0.8, align
=True)
305 row
.operator("mesh.edge_roundifier", text
="Roundify")
306 row
.operator("mesh.extra_tools_help",
307 icon
="LAYER_USED").help_ids
= "mesh_edge_roundifier"
309 row
= layout
.split(0.8, align
=True)
310 row
.operator("object.mesh_edge_length_set", text
="Set Edge Length")
311 row
.operator("mesh.extra_tools_help",
312 icon
="LAYER_USED").help_ids
= "mesh_edges_length"
314 row
= layout
.split(0.8, align
=True)
315 row
.operator("mesh.edges_floor_plan")
317 props
= row
.operator("mesh.extra_tools_help", icon
="LAYER_USED")
318 props
.help_ids
= "mesh_edges_floor_plan"
319 props
.popup_size
= 400
322 box1
= self
.layout
.box()
323 col
= box1
.column(align
=True)
324 row
= col
.row(align
=True)
325 row
.prop(scene
.mesh_extra_tools
, "UiTabDrop", text
="Face", index
=2, icon
=icon_active_2
)
328 row
.menu("mesh.face_select_tools", icon
="RESTRICT_SELECT_OFF", text
="")
329 row
.menu("VIEW3D_MT_Select_Face", icon
="FACESEL", text
="")
334 row
.label(text
="Face Tools:", icon
="FACESEL")
336 row
= layout
.split(0.8, align
=True)
337 row
.operator("object.mextrude", text
="Multi Extrude")
338 row
.operator("mesh.extra_tools_help",
339 icon
="LAYER_USED").help_ids
= "mesh_mextrude_plus"
341 row
= layout
.split(0.8, align
=True)
342 row
.operator("mesh.extrude_reshape", text
="Push/Pull")
343 row
.operator("mesh.extra_tools_help",
344 icon
="LAYER_USED").help_ids
= "mesh_extrude_and_reshape"
346 row
= layout
.split(0.8, align
=True)
347 row
.operator("mesh.face_inset_fillet", text
="Inset Fillet")
348 row
.operator("mesh.extra_tools_help",
349 icon
="LAYER_USED").help_ids
= "face_inset_fillet"
351 row
= layout
.split(0.8, align
=True)
352 row
.operator("mesh.ext_cut_faces", text
="Cut Faces")
353 row
.operator("mesh.extra_tools_help",
354 icon
="LAYER_USED").help_ids
= "mesh_cut_faces"
356 row
= layout
.split(0.8, align
=True)
357 row
.operator("mesh.split_solidify", text
="Split Solidify")
358 row
.operator("mesh.extra_tools_help",
359 icon
="LAYER_USED").help_ids
= "split_solidify"
361 row
= layout
.split(0.8, align
=True)
362 row
.operator("mesh.add_faces_to_object", "Shape Extrude")
363 row
.operator("mesh.extra_tools_help",
364 icon
="LAYER_USED").help_ids
= "pkhg_faces"
367 box1
= self
.layout
.box()
368 col
= box1
.column(align
=True)
369 row
= col
.row(align
=True)
370 row
.prop(scene
.mesh_extra_tools
, "UiTabDrop", text
="Utils", index
=3, icon
=icon_active_3
)
373 row
.menu("mesh.utils specials", icon
="SOLO_OFF", text
="")
374 row
.menu("VIEW3D_MT_Edit_MultiMET", icon
="LOOPSEL", text
="")
379 row
.label(text
="Utilities:")
382 row
= layout
.split(0.8, align
=True)
383 row
.operator("object_ot.fastloop", text
="Fast Loop")
385 props
= row
.operator("mesh.extra_tools_help", icon
="LAYER_USED")
386 props
.help_ids
= "mesh_fastloop"
387 props
.popup_size
= 400
389 col
= layout
.column(align
=True)
390 col
.operator("mesh.flip_normals", text
="Normals Flip")
391 col
.operator("mesh.remove_doubles", text
="Remove Doubles")
392 col
.operator("mesh.subdivide", text
="Subdivide")
393 col
.operator("mesh.dissolve_limited", text
="Dissolve Limited")
395 row
= layout
.row(align
=True)
396 row
.operator("mesh.select_vert_edge_face_index",
397 icon
="VERTEXSEL", text
="Select By Index").select_type
= 'VERT'
402 tris
= icons
.get("triangles")
403 ngons
= icons
.get("ngons")
405 mesh_check
= context
.window_manager
.mesh_check
406 icon_active_4
= "TRIA_RIGHT" if not mesh_check
.mesh_check_use
else "TRIA_DOWN"
409 row
= layout
.split(0.8, align
=True)
410 row
.prop(mesh_check
, "mesh_check_use", toggle
=True, icon
=icon_active_4
)
411 row
.operator("mesh.extra_tools_help", icon
="LAYER_USED").help_ids
= "mesh_check"
413 if mesh_check
.mesh_check_use
:
416 row
= layout
.row(align
=True)
417 row
.operator("object.face_type_select", text
="Tris",
418 icon_value
=tris
.icon_id
).face_type
= 'tris'
419 row
.operator("object.face_type_select", text
="Ngons",
420 icon_value
=ngons
.icon_id
).face_type
= 'ngons'
423 row
.prop(mesh_check
, "display_faces", text
="Display Faces")
425 if mesh_check
.display_faces
:
426 col
= layout
.column(align
=True)
427 col
.prop(mesh_check
, "edge_width")
428 col
.prop(mesh_check
, "face_opacity")
431 row
.label(text
="Custom Colors:", icon
="COLOR")
433 col
= layout
.column().split(percentage
=0.1, align
=True)
434 col
.label(text
="", icon_value
=tris
.icon_id
)
435 col
.prop(mesh_check
, "custom_tri_color", text
="")
437 col
= layout
.column().split(percentage
=0.1, align
=True)
438 col
.label(text
="", icon_value
=ngons
.icon_id
)
439 col
.prop(mesh_check
, "custom_ngons_color", text
="")
443 row
= layout
.row(align
=True)
445 obj_data
= getattr(context
.active_object
, "data", None)
447 row
.prop(obj_data
, "show_extra_indices",
448 icon
="LINENUMBERS_ON", toggle
=True)
450 if context
.mode
== 'EDIT_MESH' and not context
.space_data
.use_occlude_geometry
:
451 row
.prop(mesh_check
, "finer_lines_behind_use", icon
="ORTHO")
454 # ********** Edit Multiselect **********
455 class VIEW3D_MT_Edit_MultiMET(Menu
):
456 bl_label
= "Multi Select"
457 bl_description
= "Multi Select Modes"
459 def draw(self
, context
):
461 layout
.operator_context
= 'INVOKE_REGION_WIN'
463 prop
= layout
.operator("wm.context_set_value",
464 text
="Vertex Select",
466 prop
.value
= "(True, False, False)"
467 prop
.data_path
= "tool_settings.mesh_select_mode"
469 prop
= layout
.operator("wm.context_set_value",
472 prop
.value
= "(False, True, False)"
473 prop
.data_path
= "tool_settings.mesh_select_mode"
475 prop
= layout
.operator("wm.context_set_value",
478 prop
.value
= "(False, False, True)"
479 prop
.data_path
= "tool_settings.mesh_select_mode"
483 prop
= layout
.operator("wm.context_set_value",
484 text
="Vertex and Edge Select",
486 prop
.value
= "(True, True, False)"
487 prop
.data_path
= "tool_settings.mesh_select_mode"
489 prop
= layout
.operator("wm.context_set_value",
490 text
="Vertex and Face Select",
492 prop
.value
= "(True, False, True)"
493 prop
.data_path
= "tool_settings.mesh_select_mode"
495 prop
= layout
.operator("wm.context_set_value",
496 text
="Edge and Face Select",
498 prop
.value
= "(False, True, True)"
499 prop
.data_path
= "tool_settings.mesh_select_mode"
501 prop
= layout
.operator("wm.context_set_value",
502 text
="Vertex, Edge and Face Select",
504 prop
.value
= "(True, True, True)"
505 prop
.data_path
= "tool_settings.mesh_select_mode"
509 class VIEW3D_MT_Select_Vert(Menu
):
510 bl_label
= "Select Vert"
511 bl_description
= "Vertex Selection Modes"
513 def draw(self
, context
):
515 layout
.operator_context
= 'INVOKE_REGION_WIN'
517 prop
= layout
.operator("wm.context_set_value",
518 text
="Vertex Select",
520 prop
.value
= "(True, False, False)"
521 prop
.data_path
= "tool_settings.mesh_select_mode"
523 prop
= layout
.operator("wm.context_set_value",
524 text
="Vertex and Edge Select",
526 prop
.value
= "(True, True, False)"
527 prop
.data_path
= "tool_settings.mesh_select_mode"
529 prop
= layout
.operator("wm.context_set_value",
530 text
="Vertex and Face Select",
532 prop
.value
= "(True, False, True)"
533 prop
.data_path
= "tool_settings.mesh_select_mode"
536 class VIEW3D_MT_Select_Edge(Menu
):
537 bl_label
= "Select Edge"
538 bl_description
= "Edge Selection Modes"
540 def draw(self
, context
):
542 layout
.operator_context
= 'INVOKE_REGION_WIN'
544 prop
= layout
.operator("wm.context_set_value",
547 prop
.value
= "(False, True, False)"
548 prop
.data_path
= "tool_settings.mesh_select_mode"
550 prop
= layout
.operator("wm.context_set_value",
551 text
="Vertex and Edge Select",
553 prop
.value
= "(True, True, False)"
554 prop
.data_path
= "tool_settings.mesh_select_mode"
556 prop
= layout
.operator("wm.context_set_value",
557 text
="Edge and Face Select",
559 prop
.value
= "(False, True, True)"
560 prop
.data_path
= "tool_settings.mesh_select_mode"
563 class VIEW3D_MT_Select_Face(Menu
):
564 bl_label
= "Select Face"
565 bl_description
= "Face Selection Modes"
567 def draw(self
, context
):
569 layout
.operator_context
= 'INVOKE_REGION_WIN'
571 prop
= layout
.operator("wm.context_set_value",
574 prop
.value
= "(False, False, True)"
575 prop
.data_path
= "tool_settings.mesh_select_mode"
577 prop
= layout
.operator("wm.context_set_value",
578 text
="Vertex and Face Select",
580 prop
.value
= "(True, False, True)"
581 prop
.data_path
= "tool_settings.mesh_select_mode"
583 prop
= layout
.operator("wm.context_set_value",
584 text
="Edge and Face Select",
586 prop
.value
= "(False, True, True)"
587 prop
.data_path
= "tool_settings.mesh_select_mode"
590 class VIEW3D_MT_selectface_edit_mesh_add(Menu
):
591 bl_label
= "Select by Face"
592 bl_idname
= "mesh.face_select_tools"
593 bl_description
= "Face Selection Tools"
595 def draw(self
, context
):
597 layout
.operator_context
= 'INVOKE_REGION_WIN'
599 layout
.label(text
="Face Selection Tools", icon
="RESTRICT_SELECT_OFF")
602 layout
.operator("mesh.select_all").action
= 'TOGGLE'
603 layout
.operator("mesh.select_all", text
="Inverse").action
= 'INVERT'
604 layout
.operator("mesh.ext_deselect_boundary", text
="Deselect Boundary")
607 layout
.operator("data.facetype_select", text
="Triangles").face_type
= "3"
608 layout
.operator("data.facetype_select", text
="Quads").face_type
= "4"
609 layout
.operator("data.facetype_select", text
="Ngons").face_type
= "5"
612 layout
.operator("mesh.select_vert_edge_face_index",
613 text
="By Face Index").select_type
= 'FACE'
614 layout
.operator("mesh.select_by_direction", text
="By Direction")
615 layout
.operator("mesh.select_by_pi", text
="By Pi or e")
616 layout
.operator("mesh.select_connected_faces", text
="By Connected Faces")
617 layout
.operator("mesh.conway", text
="By Conway's game of life")
620 layout
.operator("mesh.e2e_efe", text
="Neighbors by Face")
621 layout
.operator("mesh.f2f_fvnef", text
="Neighbors by Vert not Edge")
624 class VIEW3D_MT_selectedge_edit_mesh_add(Menu
):
625 bl_label
= "Select by Edge"
626 bl_idname
= "mesh.edge_select_tools"
627 bl_description
= "Edge Selection Tools"
629 def draw(self
, context
):
631 layout
.operator_context
= 'INVOKE_REGION_WIN'
633 layout
.label(text
="Edge Selection Tools", icon
="RESTRICT_SELECT_OFF")
636 layout
.operator("mesh.select_all").action
= 'TOGGLE'
637 layout
.operator("mesh.select_all", text
="Inverse").action
= 'INVERT'
640 layout
.operator("mesh.select_vert_edge_face_index",
641 text
="By Edge Index").select_type
= 'EDGE'
642 layout
.operator("mesh.select_by_direction", text
="By Direction")
643 layout
.operator("mesh.select_by_pi", text
="By Pi or e")
644 layout
.operator("mesh.select_by_edge_length", text
="By Edge Length")
647 layout
.operator("mesh.e2e_eve", text
="Neighbors by Vertex")
648 layout
.operator("mesh.e2e_evfe", text
="Neighbors by Vertex and Face")
649 layout
.operator("mesh.e2e_efnve", text
="Lateral Neighbors")
650 layout
.operator("mesh.e2e_evnfe", text
="Longitudinal Edges")
653 class VIEW3D_MT_selectvert_edit_mesh_add(Menu
):
654 bl_label
= "Select by Vert"
655 bl_idname
= "mesh.vert_select_tools"
656 bl_description
= "Vertex Selection Tools"
658 def draw(self
, context
):
660 layout
.operator_context
= 'INVOKE_REGION_WIN'
662 layout
.label(text
="Vertex Selection Tools", icon
="RESTRICT_SELECT_OFF")
665 layout
.operator("mesh.select_all").action
= 'TOGGLE'
666 layout
.operator("mesh.select_all", text
="Inverse").action
= 'INVERT'
669 layout
.operator("mesh.select_vert_edge_face_index",
670 text
="By Vert Index").select_type
= 'VERT'
671 layout
.operator("mesh.select_by_direction", text
="By Direction")
672 layout
.operator("mesh.select_by_pi", text
="By Pi or e")
675 layout
.operator("mesh.v2v_by_edge", text
="Neighbors by Edge")
676 layout
.operator("mesh.e2e_eve", text
="Neighbors by Vertex")
677 layout
.operator("mesh.e2e_efe", text
="Neighbors by Face")
678 layout
.operator("mesh.v2v_facewise", text
="Neighbors by Face - Edge")
681 class VIEW3D_MT_utils_specials(Menu
):
682 bl_label
= "Specials Menu"
683 bl_idname
= "mesh.utils specials"
684 bl_description
= "Utils Quick Specials"
686 def draw(self
, context
):
688 layout
.operator_context
= 'INVOKE_REGION_WIN'
690 layout
.label(text
="Fast Specials")
693 layout
.menu("VIEW3D_MT_edit_mesh_clean")
696 layout
.operator("mesh.subdivide", text
="Subdivide").smoothness
= 0.0
697 layout
.operator("mesh.merge", text
="Merge...")
698 layout
.operator("mesh.remove_doubles")
699 layout
.operator("mesh.inset")
700 layout
.operator("mesh.bevel", text
="Bevel")
701 layout
.operator("mesh.bridge_edge_loops")
704 layout
.operator("mesh.normals_make_consistent",
705 text
="Recalculate Outside").inside
= False
706 layout
.operator("mesh.normals_make_consistent",
707 text
="Recalculate Inside").inside
= True
708 layout
.operator("mesh.flip_normals")
711 # Define the "Extras" Menu append
712 class VIEW3D_MT_edit_mesh_all(Menu
):
713 bl_idname
= "VIEW3D_MT_edit_mesh_all"
714 bl_label
= "Mesh Edit Tools"
716 def draw(self
, context
):
719 layout
.menu("VIEW3D_MT_edit_mesh_extras")
720 layout
.menu("VIEW3D_MT_edit_mesh_edgetools")
723 def menu_func(self
, context
):
724 self
.layout
.menu("VIEW3D_MT_edit_mesh_extras")
725 self
.layout
.menu("VIEW3D_MT_edit_mesh_edgetools")
728 # Define "Select" Menu append
729 def menu_select(self
, context
):
730 if context
.tool_settings
.mesh_select_mode
[2]:
731 self
.layout
.menu("mesh.face_select_tools", icon
="FACESEL")
732 if context
.tool_settings
.mesh_select_mode
[1]:
733 self
.layout
.menu("mesh.edge_select_tools", icon
="EDGESEL")
734 if context
.tool_settings
.mesh_select_mode
[0]:
735 self
.layout
.menu("mesh.vert_select_tools", icon
="VERTEXSEL")
739 class MeshExtraToolsSceneProps(PropertyGroup
):
740 # Define the UI drop down prop
741 UiTabDrop
= BoolVectorProperty(
743 description
="Expand/Collapse UI elements",
744 default
=(False,) * 4,
748 vert_align_store_axis
= FloatVectorProperty(
749 name
="Define Custom Coordinates",
750 description
="Store the values of coordinates, for repeated use\n"
751 "as a starting point",
752 default
=(0.0, 0.0, 0.0),
753 min=-100.0, max=100.0,
758 vert_align_use_stored
= BoolProperty(
759 name
="Use Stored Coordinates",
760 description
="Use starting point coordinates for alignment",
763 vert_align_to
= EnumProperty(
764 items
=(('vertex', "Original vertex",
765 "Use the stored vertex coordinates for aligning"),
766 ('coordinates', "Custom coordinates",
767 "Use defined custom coordinates for aligning")),
771 vert_align_axis
= BoolVectorProperty(
773 description
="Align to a specific Axis",
774 default
=(True, False, False),
778 mesh_info_show
= BoolProperty(
779 name
="Show Face Info",
780 description
="Display the Object's Face Count information\n"
781 "Note: it can have some performance impact on dense meshes\n"
782 "Leave it closed if not needed or set the Delay to a higher value",
785 mesh_info_delay
= FloatProperty(
787 description
="Set the Update time Delay in seconds\n"
788 "Set to zero to update with the UI refresh\n"
789 "Higher values will sometimes need to hover over the cursor",
799 class mesh_extra_tools_pref(AddonPreferences
):
802 show_info
= BoolProperty(
805 description
="Some general information about the add-on",
807 show_shortcuts
= BoolProperty(
810 description
="List of the shortcuts used for the included various tools",
813 def draw(self
, context
):
817 box
.prop(self
, "show_info", icon
="INFO")
819 box
.label(text
="Collection of various extra Mesh Edit Functions",
821 box
.label("The majority of the tools can be found in"
822 "Mesh Edit Mode Toolshelf or W key Specials Menu",
824 box
.label("The Pen tool is a separate Panel in the Toolshelf",
826 box
.label("The Face Extrude tool is only available in Object Mode "
827 "as a separate panel in the Toolshelf",
829 box
.label("Face Info / Select is a separate Panel located in Properties > Data Editor",
832 box
.prop(self
, "show_shortcuts", icon
="KEYINGSET")
833 if self
.show_shortcuts
:
835 col
.label(text
="Double Right Click in Edit mode in the 3D Viewport",
837 col
.label("Used for quick access to the Vertex, Edge and Face context menus",
840 col
.label(text
="W-key in Edit Mode in the 3D Viewport",
842 col
.label("Tools are grouped into menus prepended to the Specials Menu",
845 col
.label(text
="Ctrl+D in Edit Mode in the 3D Viewport",
847 col
.label("Used by the Pen Tool to start drawing. When activated:",
849 col
.label("Shift + Mouse Move is used to draw along the X axis",
851 col
.label("Alt + Mouse Move is used to draw along the Y axis",
854 col
.label(text
="Note: when using Fast Loop operator, press Esc twice to finish",
859 mesh_pen_tool
.register()
860 vfe_specials
.register()
861 mesh_extrude_and_reshape
.register()
862 mesh_check
.register()
864 bpy
.utils
.register_module(__name__
)
866 # Register Scene Properties
867 bpy
.types
.Scene
.mesh_extra_tools
= PointerProperty(
868 type=MeshExtraToolsSceneProps
870 # Used in mesh_selection_topokit to store cache selection data
871 bpy
.types
.Object
.tkkey
= IntVectorProperty(size
=4)
873 # Add "Extras" menu to the "W-key Specials" menu
874 bpy
.types
.VIEW3D_MT_edit_mesh_specials
.prepend(menu_func
)
875 bpy
.types
.VIEW3D_MT_select_edit_mesh
.prepend(menu_select
)
878 bpy
.types
.VIEW3D_MT_Select_Edit_Mesh
.prepend(menu_select
)
884 mesh_pen_tool
.unregister()
885 vfe_specials
.unregister()
886 mesh_extrude_and_reshape
.unregister()
887 mesh_check
.unregister()
889 del bpy
.types
.Scene
.mesh_extra_tools
890 del bpy
.types
.Object
.tkkey
892 bpy
.utils
.unregister_module(__name__
)
894 # Remove "Extras" menu from the "" menu.
895 bpy
.types
.VIEW3D_MT_edit_mesh_specials
.remove(menu_func
)
896 bpy
.types
.VIEW3D_MT_select_edit_mesh
.remove(menu_select
)
899 bpy
.types
.VIEW3D_MT_Select_Edit_Mesh
.remove(menu_select
)
904 if __name__
== "__main__":