From 9e99e90f08c985cb764ecb3a7bba6ff534d4d874 Mon Sep 17 00:00:00 2001
From: meta-androcto <meta.androcto1@gmail.com>
Date: Fri, 24 May 2019 16:03:30 +1000
Subject: [PATCH] mesh_extra_tools: move to contrib: T63750

---
 mesh_extra_tools/__init__.py                  |  905 --------
 mesh_extra_tools/face_inset_fillet.py         |  335 ---
 mesh_extra_tools/icons/icons.py               |   34 -
 mesh_extra_tools/icons/ngon.png               |  Bin 6747 -> 0 bytes
 mesh_extra_tools/icons/triangle.png           |  Bin 4153 -> 0 bytes
 mesh_extra_tools/mesh_check.py                |  370 ----
 mesh_extra_tools/mesh_cut_faces.py            |  266 ---
 mesh_extra_tools/mesh_edge_roundifier.py      | 1380 ------------
 mesh_extra_tools/mesh_edges_floor_plan.py     |  384 ----
 mesh_extra_tools/mesh_edges_length.py         |  341 ---
 mesh_extra_tools/mesh_edgetools.py            | 1878 -----------------
 mesh_extra_tools/mesh_extrude_and_reshape.py  |  378 ----
 mesh_extra_tools/mesh_fastloop.py             |  112 -
 mesh_extra_tools/mesh_filletplus.py           |  412 ----
 mesh_extra_tools/mesh_help.py                 |  244 ---
 mesh_extra_tools/mesh_mextrude_plus.py        |  370 ----
 mesh_extra_tools/mesh_offset_edges.py         |  823 --------
 mesh_extra_tools/mesh_pen_tool.py             |  568 -----
 .../mesh_select_tools/__init__.py             |   70 -
 .../mesh_select_tools/mesh_index_select.py    |  168 --
 .../mesh_select_tools/mesh_info_select.py     |  111 -
 .../mesh_select_by_direction.py               |  208 --
 .../mesh_select_by_edge_length.py             |  234 --
 .../mesh_select_tools/mesh_select_by_pi.py    |  196 --
 .../mesh_select_tools/mesh_select_by_type.py  |   75 -
 .../mesh_select_connected_faces.py            |  134 --
 .../mesh_selection_topokit.py                 |  632 ------
 mesh_extra_tools/mesh_vertex_chamfer.py       |  161 --
 mesh_extra_tools/pkhg_faces.py                |  835 --------
 mesh_extra_tools/random_vertices.py           |  140 --
 mesh_extra_tools/split_solidify.py            |  203 --
 mesh_extra_tools/vertex_align.py              |  301 ---
 mesh_extra_tools/vfe_specials.py              |   95 -
 33 files changed, 12363 deletions(-)
 delete mode 100644 mesh_extra_tools/__init__.py
 delete mode 100644 mesh_extra_tools/face_inset_fillet.py
 delete mode 100644 mesh_extra_tools/icons/icons.py
 delete mode 100644 mesh_extra_tools/icons/ngon.png
 delete mode 100644 mesh_extra_tools/icons/triangle.png
 delete mode 100644 mesh_extra_tools/mesh_check.py
 delete mode 100644 mesh_extra_tools/mesh_cut_faces.py
 delete mode 100644 mesh_extra_tools/mesh_edge_roundifier.py
 delete mode 100644 mesh_extra_tools/mesh_edges_floor_plan.py
 delete mode 100644 mesh_extra_tools/mesh_edges_length.py
 delete mode 100644 mesh_extra_tools/mesh_edgetools.py
 delete mode 100644 mesh_extra_tools/mesh_extrude_and_reshape.py
 delete mode 100644 mesh_extra_tools/mesh_fastloop.py
 delete mode 100644 mesh_extra_tools/mesh_filletplus.py
 delete mode 100644 mesh_extra_tools/mesh_help.py
 delete mode 100644 mesh_extra_tools/mesh_mextrude_plus.py
 delete mode 100644 mesh_extra_tools/mesh_offset_edges.py
 delete mode 100644 mesh_extra_tools/mesh_pen_tool.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/__init__.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/mesh_index_select.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/mesh_info_select.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/mesh_select_by_direction.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/mesh_select_by_edge_length.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/mesh_select_by_pi.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/mesh_select_by_type.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/mesh_select_connected_faces.py
 delete mode 100644 mesh_extra_tools/mesh_select_tools/mesh_selection_topokit.py
 delete mode 100644 mesh_extra_tools/mesh_vertex_chamfer.py
 delete mode 100644 mesh_extra_tools/pkhg_faces.py
 delete mode 100644 mesh_extra_tools/random_vertices.py
 delete mode 100644 mesh_extra_tools/split_solidify.py
 delete mode 100644 mesh_extra_tools/vertex_align.py
 delete mode 100644 mesh_extra_tools/vfe_specials.py

diff --git a/mesh_extra_tools/__init__.py b/mesh_extra_tools/__init__.py
deleted file mode 100644
index 669d22f00..000000000
--- a/mesh_extra_tools/__init__.py
+++ /dev/null
@@ -1,905 +0,0 @@
-# ##### 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 #####
-
-# Contributed to by:
-# meta-androcto,  Hidesato Ikeya, zmj100, Gert De Roost, TrumanBlending, PKHG, #
-# Oscurart, Greg, Stanislav Blinov, komi3D, BlenderLab, Paul Marshall (brikbot), #
-# metalliandy, macouno, CoDEmanX, dustractor, Liero, lijenstina, Germano Cavalcante #
-# Pistiwique, Jimmy Hazevoet #
-
-bl_info = {
-    "name": "Edit Tools 2",
-    "author": "meta-androcto",
-    "version": (0, 3, 4),
-    "blender": (2, 78, 0),
-    "location": "View3D > Toolshelf > Tools and Specials (W-key)",
-    "description": "Extra mesh edit tools - modifying meshes and selection",
-    "warning": "",
-    "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
-                "Py/Scripts/Modeling/Extra_Tools",
-    "category": "Mesh"}
-
-
-# Import From Files
-if "bpy" in locals():
-    import importlib
-    importlib.reload(face_inset_fillet)
-    importlib.reload(mesh_filletplus)
-    importlib.reload(mesh_vertex_chamfer)
-    importlib.reload(mesh_mextrude_plus)
-    importlib.reload(mesh_offset_edges)
-    importlib.reload(pkhg_faces)
-    importlib.reload(mesh_edge_roundifier)
-    importlib.reload(mesh_cut_faces)
-    importlib.reload(split_solidify)
-    importlib.reload(mesh_edges_floor_plan)
-    importlib.reload(mesh_edges_length)
-    importlib.reload(random_vertices)
-    importlib.reload(mesh_fastloop)
-    importlib.reload(mesh_edgetools)
-    importlib.reload(mesh_pen_tool)
-    importlib.reload(vfe_context_menu)
-    importlib.reload(mesh_help)
-    importlib.reload(mesh_select_by_direction)
-    importlib.reload(mesh_select_by_edge_length)
-    importlib.reload(mesh_select_by_pi)
-    importlib.reload(mesh_select_by_type)
-    importlib.reload(mesh_select_connected_faces)
-    importlib.reload(mesh_index_select)
-    importlib.reload(mesh_selection_topokit)
-    importlib.reload(mesh_info_select)
-    importlib.reload(mesh_extrude_and_reshape)
-    importlib.reload(mesh_check)
-    importlib.reload(vertex_align)
-
-else:
-    from . import face_inset_fillet
-    from . import mesh_filletplus
-    from . import mesh_vertex_chamfer
-    from . import mesh_mextrude_plus
-    from . import mesh_offset_edges
-    from . import pkhg_faces
-    from . import mesh_edge_roundifier
-    from . import mesh_cut_faces
-    from . import split_solidify
-    from . import mesh_edges_floor_plan
-    from . import mesh_edges_length
-    from . import random_vertices
-    from . import mesh_fastloop
-    from . import mesh_edgetools
-    from . import mesh_pen_tool
-    from . import vfe_context_menu
-    from . import mesh_help
-    from . import mesh_extrude_and_reshape
-    from . import mesh_check
-    from . import vertex_align
-
-    from .mesh_select_tools import mesh_select_by_direction
-    from .mesh_select_tools import mesh_select_by_edge_length
-    from .mesh_select_tools import mesh_select_by_pi
-    from .mesh_select_tools import mesh_select_by_type
-    from .mesh_select_tools import mesh_select_connected_faces
-    from .mesh_select_tools import mesh_index_select
-    from .mesh_select_tools import mesh_selection_topokit
-    from .mesh_select_tools import mesh_info_select
-
-    from . icons.icons import load_icons
-
-import bpy
-import bpy_extras.keyconfig_utils
-from bpy.types import (
-        Menu,
-        Panel,
-        PropertyGroup,
-        AddonPreferences,
-        )
-from bpy.props import (
-        BoolProperty,
-        BoolVectorProperty,
-        EnumProperty,
-        FloatProperty,
-        FloatVectorProperty,
-        IntVectorProperty,
-        PointerProperty,
-        )
-
-
-# ------ MENUS ------ #
-
-# Define the "Extras" menu
-class VIEW3D_MT_edit_mesh_extras(Menu):
-    bl_idname = "VIEW3D_MT_edit_mesh_extras"
-    bl_label = "Edit Tools"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-        mode = context.tool_settings.mesh_select_mode
-
-        if mode[0]:
-            split = layout.split()
-            col = split.column()
-
-            col.label(text="Vertex", icon="VERTEXSEL")
-            col.separator()
-
-            col.operator("mesh.vertex_chamfer", text="Vertex Chamfer")
-            col.operator("mesh.random_vertices", text="Random Vertices")
-
-            col = split.column()
-            col.label(text="Utilities", icon="SCRIPTWIN")
-            col.separator()
-
-            col.operator("object_ot.fastloop", text="Fast loop")
-            col.operator("mesh.flip_normals", text="Normals Flip")
-            col.operator("mesh.remove_doubles", text="Remove Doubles")
-            col.operator("mesh.subdivide", text="Subdivide")
-            col.operator("mesh.dissolve_limited", text="Dissolve Limited")
-
-        elif mode[1]:
-            split = layout.split()
-            col = split.column()
-            col.label(text="Edge", icon="EDGESEL")
-            col.separator()
-
-            col.operator("mesh.fillet_plus", text="Edge Fillet Plus")
-            col.operator("mesh.offset_edges", text="Offset Edges")
-            col.operator("mesh.edge_roundifier", text="Edge Roundify")
-            col.operator("object.mesh_edge_length_set", text="Set Edge Length")
-            col.operator("mesh.edges_floor_plan")
-
-            col = split.column()
-            col.label(text="Utilities", icon="SCRIPTWIN")
-            col.separator()
-
-            col.operator("object_ot.fastloop", text="Fast loop")
-            col.operator("mesh.flip_normals", text="Normals Flip")
-            col.operator("mesh.remove_doubles", text="Remove Doubles")
-
-            col.operator("mesh.subdivide", text="Subdivide")
-            col.operator("mesh.dissolve_limited", text="Dissolve Limited")
-
-        elif mode[2]:
-            split = layout.split()
-            col = split.column()
-            col.label(text="Face", icon="FACESEL")
-            col.separator()
-
-            col.operator("object.mextrude", text="Multi Extrude")
-            col.operator("mesh.face_inset_fillet", text="Face Inset Fillet")
-            col.operator("mesh.extrude_reshape", text="Push/Pull")
-            col.operator("mesh.add_faces_to_object", text="PKHG Faces")
-            col.operator("mesh.ext_cut_faces", text="Cut Faces")
-            col.operator("mesh.split_solidify", text="Split Solidify")
-
-            col = split.column()
-            col.label(text="Utilities", icon="SCRIPTWIN")
-            col.separator()
-
-            col.operator("object_ot.fastloop", text="Fast loop")
-            col.operator("mesh.flip_normals", text="Normals Flip")
-            col.operator("mesh.remove_doubles", text="Remove Doubles")
-            col.operator("mesh.subdivide", text="Subdivide")
-            col.operator("mesh.dissolve_limited", text="Dissolve Limited")
-
-
-class EditToolsPanel(Panel):
-    bl_label = "Mesh Edit Tools"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_context = "mesh_edit"
-    bl_category = "Tools"
-    bl_options = {"DEFAULT_CLOSED"}
-
-    def draw(self, context):
-        scene = context.scene
-        VERTDROP = scene.mesh_extra_tools.UiTabDrop[0]
-        EDGEDROP = scene.mesh_extra_tools.UiTabDrop[1]
-        FACEDROP = scene.mesh_extra_tools.UiTabDrop[2]
-        UTILSDROP = scene.mesh_extra_tools.UiTabDrop[3]
-        # Change icons depending on the bool state (compliant with the rest of the UI)
-        icon_active_0 = "TRIA_RIGHT" if not VERTDROP else "TRIA_DOWN"
-        icon_active_1 = "TRIA_RIGHT" if not EDGEDROP else "TRIA_DOWN"
-        icon_active_2 = "TRIA_RIGHT" if not FACEDROP else "TRIA_DOWN"
-        icon_active_3 = "TRIA_RIGHT" if not UTILSDROP else "TRIA_DOWN"
-
-        layout = self.layout
-
-        # Vert options
-        box1 = self.layout.box()
-        col = box1.column(align=True)
-        row = col.row(align=True)
-        row.prop(scene.mesh_extra_tools, "UiTabDrop", text="Vertex", index=0, icon=icon_active_0)
-        if not VERTDROP:
-            row.menu("mesh.vert_select_tools", icon="RESTRICT_SELECT_OFF", text="")
-            row.menu("VIEW3D_MT_Select_Vert", icon="VERTEXSEL", text="")
-        else:
-            layout = self.layout
-
-            row = layout.row()
-            row.label(text="Vertex Tools:", icon="VERTEXSEL")
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.vertex_chamfer", text="Chamfer")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "mesh_vertex_chamfer"
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.random_vertices", text="Random Vertices")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "random_vertices"
-
-            # Vertex Align Properties And Menu
-            cen0 = scene.mesh_extra_tools.vert_align_to
-
-            layout = self.layout
-            layout.label(text="Vertex Align:", icon="UV_VERTEXSEL")
-
-            # Draw the menu with 2 options
-            layout.prop(scene.mesh_extra_tools, "vert_align_to", expand=False)
-            if cen0 == 'vertex':
-                row = layout.row(align=True)
-                row.operator("vertex_align.store_id", text="Store Selected Vertex")
-
-                row = layout.split(0.8, align=True)
-                row.operator("vertex_align.align_original", text="Align to Axis")
-                props = row.operator("mesh.extra_tools_help", icon="LAYER_USED")
-                props.help_ids = "vertex_align"
-                props.popup_size = 400
-            elif cen0 == "coordinates":
-                layout.prop(scene.mesh_extra_tools, "vert_align_use_stored", toggle=True)
-
-                if scene.mesh_extra_tools.vert_align_use_stored:
-                    col = layout.column(align=True)
-                    col.prop(scene.mesh_extra_tools, "vert_align_store_axis", expand=True)
-
-                row = layout.split(0.8, align=True)
-                row.operator("vertex_align.coord_list_id", text="Align Coordinates")
-                row.operator("mesh.extra_tools_help",
-                            icon="LAYER_USED").help_ids = "vertex_align"
-
-        # Edge options
-        box1 = self.layout.box()
-        col = box1.column(align=True)
-        row = col.row(align=True)
-        row.prop(scene.mesh_extra_tools, "UiTabDrop", text="Edge", index=1, icon=icon_active_1)
-
-        if not EDGEDROP:
-            row.menu("mesh.edge_select_tools", icon="RESTRICT_SELECT_OFF", text="")
-            row.menu("VIEW3D_MT_Select_Edge", icon="EDGESEL", text="")
-        else:
-            layout = self.layout
-
-            row = layout.row()
-            row.label(text="Edge Tools:", icon="EDGESEL")
-            row.menu("VIEW3D_MT_edit_mesh_edgetools", icon="GRID")
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.fillet_plus", text="Fillet plus")
-
-            props = row.operator("mesh.extra_tools_help", icon="LAYER_USED")
-            props.help_ids = "mesh_filletplus"
-            props.popup_size = 400
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.offset_edges", text="Offset Edges")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "mesh_offset_edges"
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.edge_roundifier", text="Roundify")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "mesh_edge_roundifier"
-
-            row = layout.split(0.8, align=True)
-            row.operator("object.mesh_edge_length_set", text="Set Edge Length")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "mesh_edges_length"
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.edges_floor_plan")
-
-            props = row.operator("mesh.extra_tools_help", icon="LAYER_USED")
-            props.help_ids = "mesh_edges_floor_plan"
-            props.popup_size = 400
-
-        # Face options
-        box1 = self.layout.box()
-        col = box1.column(align=True)
-        row = col.row(align=True)
-        row.prop(scene.mesh_extra_tools, "UiTabDrop", text="Face", index=2, icon=icon_active_2)
-
-        if not FACEDROP:
-            row.menu("mesh.face_select_tools", icon="RESTRICT_SELECT_OFF", text="")
-            row.menu("VIEW3D_MT_Select_Face", icon="FACESEL", text="")
-        else:
-            layout = self.layout
-
-            row = layout.row()
-            row.label(text="Face Tools:", icon="FACESEL")
-
-            row = layout.split(0.8, align=True)
-            row.operator("object.mextrude", text="Multi Extrude")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "mesh_mextrude_plus"
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.extrude_reshape", text="Push/Pull")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "mesh_extrude_and_reshape"
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.face_inset_fillet", text="Inset Fillet")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "face_inset_fillet"
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.ext_cut_faces", text="Cut Faces")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "mesh_cut_faces"
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.split_solidify", text="Split Solidify")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "split_solidify"
-
-            row = layout.split(0.8, align=True)
-            row.operator("mesh.add_faces_to_object", "Shape Extrude")
-            row.operator("mesh.extra_tools_help",
-                        icon="LAYER_USED").help_ids = "pkhg_faces"
-
-        # Utils options
-        box1 = self.layout.box()
-        col = box1.column(align=True)
-        row = col.row(align=True)
-        row.prop(scene.mesh_extra_tools, "UiTabDrop", text="Utils", index=3, icon=icon_active_3)
-
-        if not UTILSDROP:
-            row.menu("mesh.utils specials", icon="SOLO_OFF", text="")
-            row.menu("VIEW3D_MT_Edit_MultiMET", icon="LOOPSEL", text="")
-        else:
-            layout = self.layout
-
-            row = layout.row()
-            row.label(text="Utilities:")
-
-            row = layout.row()
-            row = layout.split(0.8, align=True)
-            row.operator("object_ot.fastloop", text="Fast Loop")
-
-            props = row.operator("mesh.extra_tools_help", icon="LAYER_USED")
-            props.help_ids = "mesh_fastloop"
-            props.popup_size = 400
-
-            col = layout.column(align=True)
-            col.operator("mesh.flip_normals", text="Normals Flip")
-            col.operator("mesh.remove_doubles", text="Remove Doubles")
-            col.operator("mesh.subdivide", text="Subdivide")
-            col.operator("mesh.dissolve_limited", text="Dissolve Limited")
-
-            row = layout.row(align=True)
-            row.operator("mesh.select_vert_edge_face_index",
-                          icon="VERTEXSEL", text="Select By Index").select_type = 'VERT'
-
-            # Mesh Check
-            layout = self.layout
-            icons = load_icons()
-            tris = icons.get("triangles")
-            ngons = icons.get("ngons")
-
-            mesh_check = context.window_manager.mesh_check
-            icon_active_4 = "TRIA_RIGHT" if not mesh_check.mesh_check_use else "TRIA_DOWN"
-
-            row = layout.row()
-            row = layout.split(0.8, align=True)
-            row.prop(mesh_check, "mesh_check_use", toggle=True, icon=icon_active_4)
-            row.operator("mesh.extra_tools_help", icon="LAYER_USED").help_ids = "mesh_check"
-
-            if mesh_check.mesh_check_use:
-                layout = self.layout
-
-                row = layout.row(align=True)
-                row.operator("object.face_type_select", text="Tris",
-                             icon_value=tris.icon_id).face_type = 'tris'
-                row.operator("object.face_type_select", text="Ngons",
-                             icon_value=ngons.icon_id).face_type = 'ngons'
-
-                row = layout.row()
-                row.prop(mesh_check, "display_faces", text="Display Faces")
-
-                if mesh_check.display_faces:
-                    col = layout.column(align=True)
-                    col.prop(mesh_check, "edge_width")
-                    col.prop(mesh_check, "face_opacity")
-
-                    row = layout.row()
-                    row.label(text="Custom Colors:", icon="COLOR")
-
-                    col = layout.column().split(factor=0.1, align=True)
-                    col.label(text="", icon_value=tris.icon_id)
-                    col.prop(mesh_check, "custom_tri_color", text="")
-
-                    col = layout.column().split(factor=0.1, align=True)
-                    col.label(text="", icon_value=ngons.icon_id)
-                    col.prop(mesh_check, "custom_ngons_color", text="")
-
-                    layout.separator()
-
-                    row = layout.row(align=True)
-                    if bpy.app.debug:
-                        obj_data = getattr(context.active_object, "data", None)
-                        if obj_data:
-                            row.prop(obj_data, "show_extra_indices",
-                                     icon="LINENUMBERS_ON", toggle=True)
-
-                    if context.mode == 'EDIT_MESH' and not context.space_data.use_occlude_geometry:
-                        row.prop(mesh_check, "finer_lines_behind_use", icon="ORTHO")
-
-
-# ********** Edit Multiselect **********
-class VIEW3D_MT_Edit_MultiMET(Menu):
-    bl_label = "Multi Select"
-    bl_description = "Multi Select Modes"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex Select",
-                               icon='VERTEXSEL')
-        prop.value = "(True, False, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Edge Select",
-                               icon='EDGESEL')
-        prop.value = "(False, True, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Face Select",
-                               icon='FACESEL')
-        prop.value = "(False, False, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        layout.separator()
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex and Edge Select",
-                               icon='EDITMODE_HLT')
-        prop.value = "(True, True, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex and Face Select",
-                               icon='ORTHO')
-        prop.value = "(True, False, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Edge and Face Select",
-                               icon='SNAP_FACE')
-        prop.value = "(False, True, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex, Edge and Face Select",
-                               icon='SNAP_VOLUME')
-        prop.value = "(True, True, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-
-# Select Tools
-class VIEW3D_MT_Select_Vert(Menu):
-    bl_label = "Select Vert"
-    bl_description = "Vertex Selection Modes"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex Select",
-                               icon='VERTEXSEL')
-        prop.value = "(True, False, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex and Edge Select",
-                               icon='EDITMODE_HLT')
-        prop.value = "(True, True, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex and Face Select",
-                               icon='ORTHO')
-        prop.value = "(True, False, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-
-class VIEW3D_MT_Select_Edge(Menu):
-    bl_label = "Select Edge"
-    bl_description = "Edge Selection Modes"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Edge Select",
-                               icon='EDGESEL')
-        prop.value = "(False, True, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex and Edge Select",
-                               icon='EDITMODE_HLT')
-        prop.value = "(True, True, False)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Edge and Face Select",
-                               icon='SNAP_FACE')
-        prop.value = "(False, True, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-
-class VIEW3D_MT_Select_Face(Menu):
-    bl_label = "Select Face"
-    bl_description = "Face Selection Modes"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Face Select",
-                               icon='FACESEL')
-        prop.value = "(False, False, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Vertex and Face Select",
-                               icon='ORTHO')
-        prop.value = "(True, False, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-        prop = layout.operator("wm.context_set_value",
-                               text="Edge and Face Select",
-                               icon='SNAP_FACE')
-        prop.value = "(False, True, True)"
-        prop.data_path = "tool_settings.mesh_select_mode"
-
-
-class VIEW3D_MT_selectface_edit_mesh_add(Menu):
-    bl_label = "Select by Face"
-    bl_idname = "mesh.face_select_tools"
-    bl_description = "Face Selection Tools"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.label(text="Face Selection Tools", icon="RESTRICT_SELECT_OFF")
-        layout.separator()
-
-        layout.operator("mesh.select_all").action = 'TOGGLE'
-        layout.operator("mesh.select_all", text="Inverse").action = 'INVERT'
-        layout.operator("mesh.ext_deselect_boundary", text="Deselect Boundary")
-        layout.separator()
-
-        layout.operator("data.facetype_select", text="Triangles").face_type = "3"
-        layout.operator("data.facetype_select", text="Quads").face_type = "4"
-        layout.operator("data.facetype_select", text="Ngons").face_type = "5"
-        layout.separator()
-
-        layout.operator("mesh.select_vert_edge_face_index",
-                        text="By Face Index").select_type = 'FACE'
-        layout.operator("mesh.select_by_direction", text="By Direction")
-        layout.operator("mesh.select_by_pi", text="By Pi or e")
-        layout.operator("mesh.select_connected_faces", text="By Connected Faces")
-        layout.operator("mesh.conway", text="By Conway's game of life")
-        layout.separator()
-
-        layout.operator("mesh.e2e_efe", text="Neighbors by Face")
-        layout.operator("mesh.f2f_fvnef", text="Neighbors by Vert not Edge")
-
-
-class VIEW3D_MT_selectedge_edit_mesh_add(Menu):
-    bl_label = "Select by Edge"
-    bl_idname = "mesh.edge_select_tools"
-    bl_description = "Edge Selection Tools"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.label(text="Edge Selection Tools", icon="RESTRICT_SELECT_OFF")
-        layout.separator()
-
-        layout.operator("mesh.select_all").action = 'TOGGLE'
-        layout.operator("mesh.select_all", text="Inverse").action = 'INVERT'
-        layout.separator()
-
-        layout.operator("mesh.select_vert_edge_face_index",
-                        text="By Edge Index").select_type = 'EDGE'
-        layout.operator("mesh.select_by_direction", text="By Direction")
-        layout.operator("mesh.select_by_pi", text="By Pi or e")
-        layout.operator("mesh.select_by_edge_length", text="By Edge Length")
-        layout.separator()
-
-        layout.operator("mesh.e2e_eve", text="Neighbors by Vertex")
-        layout.operator("mesh.e2e_evfe", text="Neighbors by Vertex and Face")
-        layout.operator("mesh.e2e_efnve", text="Lateral Neighbors")
-        layout.operator("mesh.e2e_evnfe", text="Longitudinal Edges")
-
-
-class VIEW3D_MT_selectvert_edit_mesh_add(Menu):
-    bl_label = "Select by Vert"
-    bl_idname = "mesh.vert_select_tools"
-    bl_description = "Vertex Selection Tools"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.label(text="Vertex Selection Tools", icon="RESTRICT_SELECT_OFF")
-        layout.separator()
-
-        layout.operator("mesh.select_all").action = 'TOGGLE'
-        layout.operator("mesh.select_all", text="Inverse").action = 'INVERT'
-        layout.separator()
-
-        layout.operator("mesh.select_vert_edge_face_index",
-                        text="By Vert Index").select_type = 'VERT'
-        layout.operator("mesh.select_by_direction", text="By Direction")
-        layout.operator("mesh.select_by_pi", text="By Pi or e")
-        layout.separator()
-
-        layout.operator("mesh.v2v_by_edge", text="Neighbors by Edge")
-        layout.operator("mesh.e2e_eve", text="Neighbors by Vertex")
-        layout.operator("mesh.e2e_efe", text="Neighbors by Face")
-        layout.operator("mesh.v2v_facewise", text="Neighbors by Face - Edge")
-
-
-class VIEW3D_MT_utils_context_menu(Menu):
-    bl_label = "Specials Menu"
-    bl_idname = "mesh.utils specials"
-    bl_description = "Utils Quick Specials"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.label(text="Fast Specials")
-        layout.separator()
-
-        layout.menu("VIEW3D_MT_edit_mesh_clean")
-        layout.separator()
-
-        layout.operator("mesh.subdivide", text="Subdivide").smoothness = 0.0
-        layout.operator("mesh.merge", text="Merge...")
-        layout.operator("mesh.remove_doubles")
-        layout.operator("mesh.inset")
-        layout.operator("mesh.bevel", text="Bevel")
-        layout.operator("mesh.bridge_edge_loops")
-        layout.separator()
-
-        layout.operator("mesh.normals_make_consistent",
-                        text="Recalculate Outside").inside = False
-        layout.operator("mesh.normals_make_consistent",
-                        text="Recalculate Inside").inside = True
-        layout.operator("mesh.flip_normals")
-
-
-# Define the "Extras" Menu append
-class VIEW3D_MT_edit_mesh_all(Menu):
-    bl_idname = "VIEW3D_MT_edit_mesh_all"
-    bl_label = "Mesh Edit Tools"
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.menu("VIEW3D_MT_edit_mesh_extras")
-        layout.menu("VIEW3D_MT_edit_mesh_edgetools")
-
-
-def menu_func(self, context):
-    self.layout.menu("VIEW3D_MT_edit_mesh_extras")
-    self.layout.menu("VIEW3D_MT_edit_mesh_edgetools")
-
-
-# Define "Select" Menu append
-def menu_select(self, context):
-    if context.tool_settings.mesh_select_mode[2]:
-        self.layout.menu("mesh.face_select_tools", icon="FACESEL")
-    if context.tool_settings.mesh_select_mode[1]:
-        self.layout.menu("mesh.edge_select_tools", icon="EDGESEL")
-    if context.tool_settings.mesh_select_mode[0]:
-        self.layout.menu("mesh.vert_select_tools", icon="VERTEXSEL")
-
-
-# Scene Properties
-class MeshExtraToolsSceneProps(PropertyGroup):
-    # Define the UI drop down prop
-    UiTabDrop = BoolVectorProperty(
-            name="Tab",
-            description="Expand/Collapse UI elements",
-            default=(False,) * 4,
-            size=4,
-            )
-    # Vertex align
-    vert_align_store_axis: FloatVectorProperty(
-            name="Define Custom Coordinates",
-            description="Store the values of coordinates, for repeated use\n"
-                        "as a starting point",
-            default=(0.0, 0.0, 0.0),
-            min=-100.0, max=100.0,
-            step=1, size=3,
-            subtype='XYZ',
-            precision=3
-            )
-    vert_align_use_stored: BoolProperty(
-            name="Use Stored Coordinates",
-            description="Use starting point coordinates for alignment",
-            default=False
-            )
-    vert_align_to: EnumProperty(
-            items=(('vertex', "Original vertex",
-                    "Use the stored vertex coordinates for aligning"),
-                   ('coordinates', "Custom coordinates",
-                    "Use defined custom coordinates for aligning")),
-            name="Align to",
-            default='vertex'
-            )
-    vert_align_axis = BoolVectorProperty(
-            name="Axis",
-            description="Align to a specific Axis",
-            default=(True, False, False),
-            size=3,
-            )
-    # Mesh Info select
-    mesh_info_show: BoolProperty(
-            name="Show Face Info",
-            description="Display the Object's Face Count information\n"
-                        "Note: it can have some performance impact on dense meshes\n"
-                        "Leave it closed if not needed or set the Delay to a higher value",
-            default=False
-            )
-    mesh_info_delay: FloatProperty(
-            name="Delay",
-            description="Set the Update time Delay in seconds\n"
-                        "Set to zero to update with the UI refresh\n"
-                        "Higher values will sometimes need to hover over the cursor",
-            default=2.0,
-            min=0.0, max=20.0,
-            step=100,
-            subtype='TIME',
-            precision=1
-            )
-
-
-# Add-on Preferences
-class mesh_extra_tools_pref(AddonPreferences):
-    bl_idname = __name__
-
-    show_info: BoolProperty(
-            name="Info",
-            default=False,
-            description="Some general information about the add-on",
-            )
-    show_shortcuts: BoolProperty(
-            name="Hot Keys",
-            default=False,
-            description="List of the shortcuts used for the included various tools",
-            )
-
-    def draw(self, context):
-        layout = self.layout
-        box = layout.box()
-
-        box.prop(self, "show_info", icon="INFO")
-        if self.show_info:
-            box.label(text="Collection of various extra Mesh Edit Functions",
-                      icon="LAYER_ACTIVE")
-            box.label(text="The majority of the tools can be found in"
-                      "Mesh Edit Mode Toolshelf or W key Specials Menu",
-                      icon="LAYER_USED")
-            box.label(text="The Pen tool is a separate Panel in the Toolshelf",
-                      icon="LAYER_USED")
-            box.label(text="The Face Extrude tool is only available in Object Mode "
-                      "as a separate panel in the Toolshelf",
-                      icon="LAYER_USED")
-            box.label(text="Face Info / Select is a separate Panel located in Properties > Data Editor",
-                      icon="LAYER_USED")
-
-        box.prop(self, "show_shortcuts", icon="KEYINGSET")
-        if self.show_shortcuts:
-            col = box.column()
-            col.label(text="Double Right Click in Edit mode in the 3D Viewport",
-                      icon="LAYER_ACTIVE")
-            col.label(text="Used for quick access to the Vertex, Edge and Face context menus",
-                      icon="LAYER_USED")
-            col.separator()
-            col.label(text="W-key in Edit Mode in the 3D Viewport",
-                      icon="LAYER_ACTIVE")
-            col.label(text="Tools are grouped into menus prepended to the Specials Menu",
-                      icon="LAYER_USED")
-            col.separator()
-            col.label(text="Ctrl+D in Edit Mode in the 3D Viewport",
-                      icon="LAYER_ACTIVE")
-            col.label(text="Used by the Pen Tool to start drawing. When activated:",
-                      icon="LAYER_USED")
-            col.label(text="Shift + Mouse Move is used to draw along the X axis",
-                      icon="LAYER_USED")
-            col.label(text="Alt + Mouse Move is used to draw along the Y axis",
-                      icon="LAYER_USED")
-            col.separator()
-            col.label(text="Note: when using Fast Loop operator, press Esc twice to finish",
-                      icon="LAYER_ACTIVE")
-
-
-def register():
-    mesh_pen_tool.register()
-    vfe_context_menu.register()
-    mesh_extrude_and_reshape.register()
-    mesh_check.register()
-
-    bpy.utils.register_module(__name__)
-
-    # Register Scene Properties
-    bpy.types.Scene.mesh_extra_tools = PointerProperty(
-                                            type=MeshExtraToolsSceneProps
-                                            )
-    # Used in mesh_selection_topokit to store cache selection data
-    bpy.types.Object.tkkey = IntVectorProperty(size=4)
-
-    # Add "Extras" menu to the "W-key Specials" menu
-    bpy.types.VIEW3D_MT_edit_mesh_context_menu.prepend(menu_func)
-    bpy.types.VIEW3D_MT_select_edit_mesh.prepend(menu_select)
-
-    try:
-        bpy.types.VIEW3D_MT_Select_Edit_Mesh.prepend(menu_select)
-    except:
-        pass
-
-
-def unregister():
-    mesh_pen_tool.unregister()
-    vfe_context_menu.unregister()
-    mesh_extrude_and_reshape.unregister()
-    mesh_check.unregister()
-
-    del bpy.types.Scene.mesh_extra_tools
-    del bpy.types.Object.tkkey
-
-    bpy.utils.unregister_module(__name__)
-
-    # Remove "Extras" menu from the "" menu.
-    bpy.types.VIEW3D_MT_edit_mesh_context_menu.remove(menu_func)
-    bpy.types.VIEW3D_MT_select_edit_mesh.remove(menu_select)
-
-    try:
-        bpy.types.VIEW3D_MT_Select_Edit_Mesh.remove(menu_select)
-    except:
-        pass
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/face_inset_fillet.py b/mesh_extra_tools/face_inset_fillet.py
deleted file mode 100644
index 8af709c18..000000000
--- a/mesh_extra_tools/face_inset_fillet.py
+++ /dev/null
@@ -1,335 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# ##### 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 #####
-
-# based completely on addon by zmj100
-# added some distance limits to prevent overlap - max12345
-
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from bpy.props import (
-        FloatProperty,
-        IntProperty,
-        BoolProperty,
-        EnumProperty,
-        )
-from math import (
-        sin, cos, tan,
-        degrees, radians,
-        )
-from mathutils import Matrix
-
-
-def edit_mode_out():
-    bpy.ops.object.mode_set(mode='OBJECT')
-
-
-def edit_mode_in():
-    bpy.ops.object.mode_set(mode='EDIT')
-
-
-def angle_rotation(rp, q, axis, angle):
-    # returns the vector made by the rotation of the vector q
-    # rp by angle around axis and then adds rp
-
-    return (Matrix.Rotation(angle, 3, axis) * (q - rp)) + rp
-
-
-def face_inset_fillet(bme, face_index_list, inset_amount, distance,
-                      number_of_sides, out, radius, type_enum, kp):
-    list_del = []
-
-    for faceindex in face_index_list:
-
-        bme.faces.ensure_lookup_table()
-        # loops through the faces...
-        f = bme.faces[faceindex]
-        f.select_set(False)
-        list_del.append(f)
-        f.normal_update()
-        vertex_index_list = [v.index for v in f.verts]
-        dict_0 = {}
-        orientation_vertex_list = []
-        n = len(vertex_index_list)
-        for i in range(n):
-            # loops through the vertices
-            dict_0[i] = []
-            bme.verts.ensure_lookup_table()
-            p = (bme.verts[vertex_index_list[i]].co).copy()
-            p1 = (bme.verts[vertex_index_list[(i - 1) % n]].co).copy()
-            p2 = (bme.verts[vertex_index_list[(i + 1) % n]].co).copy()
-            # copies some vert coordinates, always the 3 around i
-            dict_0[i].append(bme.verts[vertex_index_list[i]])
-            # appends the bmesh vert of the appropriate index to the dict
-            vec1 = p - p1
-            vec2 = p - p2
-            # vectors for the other corner points to the cornerpoint
-            # corresponding to i / p
-            angle = vec1.angle(vec2)
-
-            adj = inset_amount / tan(angle * 0.5)
-            h = (adj ** 2 + inset_amount ** 2) ** 0.5
-            if round(degrees(angle)) == 180 or round(degrees(angle)) == 0.0:
-                # if the corner is a straight line...
-                # I think this creates some new points...
-                if out is True:
-                    val = ((f.normal).normalized() * inset_amount)
-                else:
-                    val = -((f.normal).normalized() * inset_amount)
-                p6 = angle_rotation(p, p + val, vec1, radians(90))
-            else:
-                # if the corner is an actual corner
-                val = ((f.normal).normalized() * h)
-                if out is True:
-                    # this -(p - (vec2.normalized() * adj))) is just the freaking axis afaik...
-                    p6 = angle_rotation(
-                                p, p + val,
-                                -(p - (vec2.normalized() * adj)),
-                                -radians(90)
-                                )
-                else:
-                    p6 = angle_rotation(
-                                p, p - val,
-                                ((p - (vec1.normalized() * adj)) - (p - (vec2.normalized() * adj))),
-                                -radians(90)
-                                )
-
-                orientation_vertex_list.append(p6)
-
-        new_inner_face = []
-        orientation_vertex_list_length = len(orientation_vertex_list)
-        ovll = orientation_vertex_list_length
-
-        for j in range(ovll):
-            q = orientation_vertex_list[j]
-            q1 = orientation_vertex_list[(j - 1) % ovll]
-            q2 = orientation_vertex_list[(j + 1) % ovll]
-            # again, these are just vectors between somewhat displaced corner vertices
-            vec1_ = q - q1
-            vec2_ = q - q2
-            ang_ = vec1_.angle(vec2_)
-
-            # the angle between them
-            if round(degrees(ang_)) == 180 or round(degrees(ang_)) == 0.0:
-                # again... if it's really a line...
-                v = bme.verts.new(q)
-                new_inner_face.append(v)
-                dict_0[j].append(v)
-            else:
-                # s.a.
-                if radius is False:
-                    h_ = distance * (1 / cos(ang_ * 0.5))
-                    d = distance
-                elif radius is True:
-                    h_ = distance / sin(ang_ * 0.5)
-                    d = distance / tan(ang_ * 0.5)
-                # max(d) is vec1_.magnitude * 0.5
-                # or vec2_.magnitude * 0.5 respectively
-
-                # only functional difference v
-                if d > vec1_.magnitude * 0.5:
-                    d = vec1_.magnitude * 0.5
-
-                if d > vec2_.magnitude * 0.5:
-                    d = vec2_.magnitude * 0.5
-                # only functional difference ^
-
-                q3 = q - (vec1_.normalized() * d)
-                q4 = q - (vec2_.normalized() * d)
-                # these are new verts somewhat offset from the corners
-                rp_ = q - ((q - ((q3 + q4) * 0.5)).normalized() * h_)
-                # reference point inside the curvature
-                axis_ = vec1_.cross(vec2_)
-                # this should really be just the face normal
-                vec3_ = rp_ - q3
-                vec4_ = rp_ - q4
-                rot_ang = vec3_.angle(vec4_)
-                cornerverts = []
-
-                for o in range(number_of_sides + 1):
-                    # this calculates the actual new vertices
-                    q5 = angle_rotation(rp_, q4, axis_, rot_ang * o / number_of_sides)
-                    v = bme.verts.new(q5)
-
-                    # creates new bmesh vertices from it
-                    bme.verts.index_update()
-
-                    dict_0[j].append(v)
-                    cornerverts.append(v)
-
-                cornerverts.reverse()
-                new_inner_face.extend(cornerverts)
-
-        if out is False:
-            f = bme.faces.new(new_inner_face)
-            f.select_set(True)
-        elif out is True and kp is True:
-            f = bme.faces.new(new_inner_face)
-            f.select_set(True)
-
-        n2_ = len(dict_0)
-        # these are the new side faces, those that don't depend on cornertype
-        for o in range(n2_):
-            list_a = dict_0[o]
-            list_b = dict_0[(o + 1) % n2_]
-            bme.faces.new([list_a[0], list_b[0], list_b[-1], list_a[1]])
-            bme.faces.index_update()
-        # cornertype 1 - ngon faces
-        if type_enum == 'opt0':
-            for k in dict_0:
-                if len(dict_0[k]) > 2:
-                    bme.faces.new(dict_0[k])
-                    bme.faces.index_update()
-        # cornertype 2 - triangulated faces
-        if type_enum == 'opt1':
-            for k_ in dict_0:
-                q_ = dict_0[k_][0]
-                dict_0[k_].pop(0)
-                n3_ = len(dict_0[k_])
-                for kk in range(n3_ - 1):
-                    bme.faces.new([dict_0[k_][kk], dict_0[k_][(kk + 1) % n3_], q_])
-                    bme.faces.index_update()
-
-    del_ = [bme.faces.remove(f) for f in list_del]
-
-    if del_:
-        del del_
-
-
-# Operator
-
-class MESH_OT_face_inset_fillet(Operator):
-    bl_idname = "mesh.face_inset_fillet"
-    bl_label = "Face Inset Fillet"
-    bl_description = ("Inset selected and Fillet (make round) the corners \n"
-                     "of the newly created Faces")
-    bl_options = {"REGISTER", "UNDO"}
-
-    # inset amount
-    inset_amount: FloatProperty(
-            name="Inset amount",
-            description="Define the size of the Inset relative to the selection",
-            default=0.04,
-            min=0, max=100.0,
-            step=1,
-            precision=3
-            )
-    # number of sides
-    number_of_sides: IntProperty(
-            name="Number of sides",
-            description="Define the roundness of the corners by specifying\n"
-                        "the subdivision count",
-            default=4,
-            min=1, max=100,
-            step=1
-            )
-    distance: FloatProperty(
-            name="",
-            description="Use distance or radius for corners' size calculation",
-            default=0.04,
-            min=0.00001, max=100.0,
-            step=1,
-            precision=3
-            )
-    out: BoolProperty(
-            name="Outside",
-            description="Inset the Faces outwards in relation to the selection\n"
-                        "Note: depending on the geometry, can give unsatisfactory results",
-            default=False
-            )
-    radius: BoolProperty(
-            name="Radius",
-            description="Use radius for corners' size calculation",
-            default=False
-            )
-    type_enum: EnumProperty(
-            items=(('opt0', "N-gon", "N-gon corners - Keep the corner Faces uncut"),
-                   ('opt1', "Triangle", "Triangulate corners")),
-            name="Corner Type",
-            default="opt0"
-            )
-    kp: BoolProperty(
-            name="Keep faces",
-            description="Do not delete the inside Faces\n"
-                        "Only available if the Out option is checked",
-            default=False
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.label(text="Corner Type:")
-
-        row = layout.row()
-        row.prop(self, "type_enum", text="")
-
-        row = layout.row(align=True)
-        row.prop(self, "out")
-
-        if self.out is True:
-            row.prop(self, "kp")
-
-        row = layout.row()
-        row.prop(self, "inset_amount")
-
-        row = layout.row()
-        row.prop(self, "number_of_sides")
-
-        row = layout.row()
-        row.prop(self, "radius")
-
-        row = layout.row()
-        dist_rad = "Radius" if self.radius else "Distance"
-        row.prop(self, "distance", text=dist_rad)
-
-    def execute(self, context):
-        # this really just prepares everything for the main function
-        inset_amount = self.inset_amount
-        number_of_sides = self.number_of_sides
-        distance = self.distance
-        out = self.out
-        radius = self.radius
-        type_enum = self.type_enum
-        kp = self.kp
-
-        edit_mode_out()
-        ob_act = context.active_object
-        bme = bmesh.new()
-        bme.from_mesh(ob_act.data)
-        # this
-        face_index_list = [f.index for f in bme.faces if f.select and f.is_valid]
-
-        if len(face_index_list) == 0:
-            self.report({'WARNING'},
-                        "No suitable Face selection found. Operation cancelled")
-            edit_mode_in()
-
-            return {'CANCELLED'}
-
-        elif len(face_index_list) != 0:
-            face_inset_fillet(bme, face_index_list,
-                              inset_amount, distance, number_of_sides,
-                              out, radius, type_enum, kp)
-
-        bme.to_mesh(ob_act.data)
-        edit_mode_in()
-
-        return {'FINISHED'}
diff --git a/mesh_extra_tools/icons/icons.py b/mesh_extra_tools/icons/icons.py
deleted file mode 100644
index d98c8c063..000000000
--- a/mesh_extra_tools/icons/icons.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import os
-import bpy
-import bpy.utils.previews
-
-mesh_check_icon_collections = {}
-mesh_check_icons_loaded = False
-
-
-def load_icons():
-    global mesh_check_icon_collections
-    global mesh_check_icons_loaded
-
-    if mesh_check_icons_loaded:
-        return mesh_check_icon_collections["main"]
-
-    custom_icons = bpy.utils.previews.new()
-
-    icons_dir = os.path.join(os.path.dirname(__file__))
-
-    custom_icons.load("ngons", os.path.join(icons_dir, "ngon.png"), 'IMAGE')
-    custom_icons.load("triangles", os.path.join(icons_dir, "triangle.png"), 'IMAGE')
-
-    mesh_check_icon_collections["main"] = custom_icons
-    mesh_check_icons_loaded = True
-
-    return mesh_check_icon_collections["main"]
-
-
-def clear_icons():
-    global mesh_check_icons_loaded
-    for icon in mesh_check_icon_collections.values():
-        bpy.utils.previews.remove(icon)
-    mesh_check_icon_collections.clear()
-    mesh_check_icons_loaded = False
diff --git a/mesh_extra_tools/icons/ngon.png b/mesh_extra_tools/icons/ngon.png
deleted file mode 100644
index b1a79b981a9fbfec54e4c487a45957869df6e4e5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 6747
zcmeAS@N?(olHy`uVBq!ia0y~yU}OMc4mJh`hM1xiX$%ZfN}eu`Ar*7p-mPB~=Q{Ji
zM}2eNOerUhZqW_1Hh1U<F}VkM9OjqZbz@2tccEaw71px9jSKX;yF5A+yBc1v7Y*Bd
zf@@LJp9#84yYK3i`Ev-gu(2gcO;df7@^;##w`RPVvu4kJmiB+f&Zj}|_U`>&JHL3|
z%<r{!oQhFa?=SB=Z&Uv4%p6IBV-m?dhUkRIdxp0RJ$&MSY!VWG&A&Zs)xE`%{TCBi
z6F7D};AfF3;49!NP${r5nDlRQVS@Gs)(WW#j*MBW<X+oET-MZPU_QfIZ&Sd#LCB(_
zZ~x!Y1l@w<;H&i$`p!N%$aR3B=%7B+KF*ph^SV>tvt)K~?^w6;)!Dzt(mo}zCLGxD
z;J?%k)*1SDzG!@CUA8J;Jny>3CME-gOU`@WGsfrqTwKQzlgiJ_-YnX{_@HUNe@(&m
zHH-UW_~%>>`I_NAKRxQw`#%>niVrg1aV(!Z|4U@~lJjP)o0$Ukt!Eb3s(IJ?a<lKj
z9IgNZ@jpfnw!aYlRQTY{vQ^i$YxljJEZX3-w7u>;^Ks4gO`H}N<+!GuT*mNpm&D(5
z{Dy7aTbm8`ZWMHAjQPOb@LwhG<=KN`4{Uuy-(TZ9a;CSJ;nbE%HCFaVBEquR6Q7;q
za+rDUB3}ZR<*}4+hnF$5dgg!I%O<l(_Ox9YQ~q{yj?+oX4WH(C)y<Vp@>vejag58M
zvhNaK0-NRWv}Fmb3v4WH|J)8gw{fOs1f#}z!CQ=H6rSHWBeI5J%5#Ia3~3XJbJDoN
z7*1_=wr-GoA~SntlW4=IJ*#97@D%l(^*PAp;286voiRP@xM8z#aL+P<Fb1xNP4Qke
zzt3y78ws=9%uh09-7vRdruX{4b;3Wio{GFFd|-WKa?4xOhdq&uCuVT(V|vFpO{4wN
z>g5gnrlGQ1m<@xqpQ@j_P<SxjL*~=;TR#<#{j2%4c?Qo-4h3VqAI%-lf5oqn>Dpr5
z`JL;{CB7qj4stoT#e6U=&@bpI)6uQu+_7L~mbIUSa2SKpgud(lq#vX`aJZWhWzH7E
z`)9+-thW(u^F$d^^?tM-DgGOtas1Lo_Xh7-tL`n6Jz=n!X~7BBda)1Ok3#Pr&d~mF
za@i{Rt9&UDk&FQou6@gA*w?f6NDuRU)^%HLneT39x?m{&C-BJDzrkCQPoBAa#Flw|
z2D_0@+u!B>%VR#sv(Gzh^*_Xqah`X*`!Z!SrWX!TxBs(02)?yZ<dNQkqT9w7?6etl
zix19sk@>{`>Q-HJoRS~sysLaE6CxQiJfm*^kAC1*a{XI5<LAc8;y<<34S^37K6a$#
z^Xy>zvG1*9M!PL@hGW$2|GFP+ORWFjJz(9iol%_eJ7eRGjo(bC)xF*K<^De1zxQ@q
zcNAN(3;pM-pZ(9T*Fc()!#lj}zs%jOe`AkWeu)kKn<O<?=9u*IA9;-1{J#fZWBsrB
z$e8Es#RFjv^xtX~MTRl7ERn9xQ{ek;>K=Ap==<&cIyYBv|I2t(&86<S&D#C(f$yEw
zY;V|<7{eG?mYgf(-w<KgQ~03$fN5@NU&xa@m3`Y6L_RSSk{9R_+nJccy1-xWhrdAk
zadz#tjlC8&ao3Nw?|d*_c)8`Q&!4V$UY--Lbu7R}o59vA`?o!#-9njDRY}k9-+J1<
z>jA&ISYv8z-8+#w&X}}nwyNaS47LRa_0`_Jxcuf%@`3P%&AZ?IVR&hL-p?@O+;Mxy
zJB}+X|7uO^Wq5Xg)!wP*L^<=W)7ARI&ksn8Cg0F5-B;bPSoE+2^E%ack`m!Pi#5U+
z(oVMRF_!+O8Mtx{!x<+v{=H>_)^*qT_g-?oIDf(J^aYpO7pZP$GGLDW_Uh~goo+rR
zZHCJmdiDQGe(4QtKE!oEB<J<&IYQgq_>Hw0ChvH_uXZkeEC136_cwo-3lq|+CO&_D
zpy+A9J2gA^%2><3oEvrxM_B8*3UlK(f9_`t7rg$BebHy;CHALp9<iVOEachaBeu+C
zO2I~7lpD5e`=9!Vb<VBq-{L&K7$sgdOsT$j-?%{b!`;OD#s*hd71qA}&t&0kIc1?0
zllEfeOLD4m-gaB6+1j=-?066^p#S7T-NL7vmaQ`7zZ)=_kKr%pFa4m{OCevCy9`%I
z?qZrSZFwHszK(yl{;?je<0-RJ`y2P=JI^1E9lN$Xy;jE?%2;qv-r2|OEc3HBN<FnH
zC4pV)Vo#@wB)_<FL4-m4&(Z_;7w_MeAD-x|JbCq{GRF9<Rlm}^3`^1;aDx)P`va$^
z0c=^h`*kJXO8zkYaMSU=vB8Dk3^5<P8=hZ$`zQIpRGu5R>Y~-&O70N4Ys)Oobbh&v
zR0OjnlSlUNc-3`p&wsV4@hscvDsQwiB$dDL{DE?|!t)0Xh%$)(nRuk~Nzl`PcP#r1
zbh3ZvdRDXLG3tf!r80l~c~<PHg$r*8W5L1oD(l|LFOxVHu>S3K)ycNZw>zuZu4x@p
z$Wq_}xzGC1t$k{{AMJ9Lj9vRr`GI!xhV%tL+8gwKBsbn)eEa9|#@P***L>ct{`c-Y
zw?DhD&FQZf{84*q?;=rKkOQ|faElzi;S_Uk^VYw7OKq9$pZC5#Yw||T?zv{!d54Lt
z2UzPl3UmM0JPnXjEc^HNR3VS5_@BfhN*kOkr~K}yW-HS=ZkT@5m+{iBH^nc?{&jBs
z%OCmt`s9D_>|6fLYy8~#oJVAP`hppPAeTxN*zU^ytuG}1rSho68M~MdrXLv>KHF2n
z|AF_xvY>A~B7qE-Zv9)&uw3TU`Htd!cTW}0(A@DrTwp$D>?#>A=9rK}^BUi9H*nX9
ze(-;>?(KV(b#MPi8L}CB>;2&FtY+g2<Vm*v5bhhgKCmZo|0Z1qy&pf1Z2hY}#ksP}
z;tBt$!WotY2g8qOHh$alC+yL@#=xf*%ceYab`bwlcw}qs*>m=MHPRM`t?DZ;m6x%7
zw7xQ@Ki=_<alxD<p3A55SROR}=lQ_=<@z`Kn;~D>j!N_hi2n(C^jq;(HQTzJRlm%R
zO59VL%{1ZKw|cHQ%VkbQJ*vx(z9+4adH#Ux0k5Y4atwBJPtR-AS;nCEBe?VZ+w8J`
zfe*Y7w6FclKkv)jx*0!Yv(FtruRPDVU{w-N^~yd_NL=sCUJlALCZT_ul6aOW>-`Y!
zNO#V9FS$eR$F^tl8uxKKNbQoJ`Ok9B534uRzMQ}I@?U}857#4G|9<~2?L0pxx1J+)
zOZo%DNAnub2LDa^rC4c^|7BxyXS#PD<F+r>Q)d)2dYmp!XM8U3JlI(FfrZ;0k&gl!
z(jM`@Y_gxeV_W@;82k7OevkgW{VkGga4P1*bK(2i7w;HvXx@>YP}-F#xS{LDaT(+L
z5nHGJxbsT!!Nr|==I3@X?0CS>x{lS(`MvsUGY5zNCDYYAL(MggCmK!o#`A~k!o2DC
zIYYkedt54BAYI@beAPPbv-G!UhD-i`v^(a;Z}#$<QIY>&x=d~VOr5*F1-2h+C+o=d
zeNR;XIIlJOySdVgjSM>;+-J4nnWG>+dzS8z`M-M06x8DND%@pwGu}x~_{3Bg`g;HJ
z-~7wgmgxPs+?X!Wb8bJI#YL<AH|I}LRu?K>R-(>ue#t(YrJCFhRUY51OZ3l8G2p6U
zv^ak4+u59@F_!H!tRvq&oZsAf;C;~iy6){hjF+mf`Y+fm8h%Lak+;pZZTVHxzVX~)
zPT4uVp07;!{F<7}mSXu*j5{9itDpPn{r=B(X7%Xj=6}5`ON<Pcdu?N=u=x6M@3*_P
z-?bA0(-lwN_Pmq+x1mfStze07()_Z6|Fu8XP7Mk_tY&uq@6RLuH<oifXo_e2)9n-x
zG*5-^=knS|nLhh3ow{NB;=SaH<L$Fn)v;U>QOGsl6KT5SUN7@~CcA{W_qXUiy}{mL
z8GdAEeee#;uRr&mXRzawSugH?-i$fjEVOoR?i<6{%vDwX!B?*{rVABsFgY&#`_Db5
zf{AfDw$Z*Zx9feZ1&rqey_@TC=IEsumI8-ewO{|w_}SV#r-vz=(LQfgl(krL!9nI4
zxgT-{@#eE4rJ4UdVG#dQdEoD@i)SvWJ*xg)e}V7FjM|+K`qk$d2b`MM*x$z>f2A*J
zTAuQ{x6#kdBfWN38X1Ore>hnAWdFPU%{#XJUr?rS?2Z2|;}17ItJzG>@3}GGRr$%^
zYnOu${9f~U_N66rYUK^vi%XwyRQ5CEZQEKKylTpB%lGReO`P5@|6QW^{6^2r-Z{lT
z76>NHE)y}nu}ZeVu=bQ?`}SS||5GPJ&ux@6mbQHUVVdBld#7f6j-O|^d15hNz8quR
zrM@Jo=;EDrCuhVhl{r@`_2Cl7N1Kl_Yp?PhkWk$D?31(d0k=;w%brBd=$W}%rnr)O
zL!nCS-Ko*7w^(gf$+j3e$*Ddo@w;XgYHRn=>Vxi+(j5nLi}yY{F(YPa%(<6;8w!)=
z_djP`GF{@`rJjsQozcEMk}Bo`#n$ZQzI#H<e}+7Ged00Cm&p6sX+D}ke$PKN=T5nC
zz0s3Z;qIO4y>2d(_b}X9CDUw}yL0M{$FtVWuMz#Z&z$)#OGfPUy}cFvk$j5<l8-FC
z^Ut8__WSqB-#+fW7s7B!FnT(}`7-g#ano<lu1~wLRAzt7!^QJi^=^Kb*t`7>?+iYZ
z9|m{D8_P@oR36KCX?1<RYTvr@_rJM=<M?icd=-1ZvuiHjAJ_KzsXfc|ivQX@=()1|
ze$uVi2ZOinVA#=?7sftq$Ae<KxhH1qTPhQO>7aYB(C>Gw!GE93H^^md_~El)<*V5Z
z-x<m;y-Qmt_&`~ATfPsU-J!Z)vGb30)_%414ZXi*|KiW-q8`ClXU|@>ucd<XQ0|uR
z?;3oW&n(E+KE7Sx_p?sl(0HTDmHBGyZ~og?t}a=BBk7SV$MWx&j+uO8c%QM#>UnTi
z&&y8kI>it6d%lLftF!UjqmiCmwLaaiN~+5w)b?J;*UJa^tA749p20px`_3}MofhIZ
z&+&g~UbbrfyQQC<{})dzJ+c33%4G)Q6-$b%#W(VQTeF^N!aTiiq6b9gaQ_o{Xx1Az
zwdfY7`R=@B>VGyXel+=H&Xns@rm(?lhi~$hwNC$-?(O?M&xJ9f`;T2?KiBs39<!Ho
z<Xj&p%-_fD5PWra!`HvtHurD7wDsvR5&fs1A`hKi=U=;CKS)|=$#TZejZ+WhN-a)R
zHC(RR`NeW2(*`yP;jHYYwQMsS73ZE#K4N#>d?M3?b9VO?E?!g7j`_gda@%BCux5KW
zhxu;DSLb+6+Mc|0xq<aS(L=M|m$!<N^t^>$XHQ~HFfG(xuQHo$#wE|^ALNqag%!gX
zX05u%XQOsCZqp@J{k>&bKI%d5yzI}^>3lU6ytH1`%b%H#Z5rqHOrP*+g2fS&GUO-g
zF|3|wZ+u`G<Fb%TJFWX3e2}lIk*!eE`=Q<t%sTrH<DR`MvtB;uKDOl;t37`OuSLj)
zo9eSy+4*kR8|J4raUPotmyT%O<r&*_UAKL1uDPGJl)>hL(`++dgQc0u=|_K0`ys+`
zfb~Dm$0G`ww;PnJY`+|sp|@0ca~!J}m)Y)(D_>1!z0G{fdQL#qicJDH7a#A*y!`S+
zSzSir5B|5J4Q9(2zjbZUbd}zD%WZyEIv2x(rg}LG#|<aX9<csierBWLte6iB^(<nX
zX1|?+uc~ux+a5mq`DAbYNU@7&Te*&XN#@)%S3XMWpYv|k17XZ(4747-{NHko%OUvc
z><01H*|z>WY?GIGK7Y}@Qh)2Bvw{o<nh(7V)%!8I<+h2N%c-+oJ0f4&eNoF5Z!mkN
zXU1!=GfUY#diH<k)2s_tzDjQlZ<)O{v*F~_lDvJBeg$OTl4ET6Bk)W@{LjZjxl)&>
zPnmq2!~FKE5AwS-8FG0N-$)fso^4jN>FPuKl3<2;N_mearkrQ=$y-ufWW4eHmQ`Pw
zCX~JN<WKc0IOxs4z2~LpDc6&+>lygVHoo54Ey!@g<N(h$rS|_9Vi_xBZfM<E=F9A(
zx1_jGd*k^n>n1Zzxc69m=gE{wNA-SylI$~;rwg9k6lciZW%YZ}YC(nre|5KHUS?Rl
zwpS)+@p_+?r<pDY@c)>Sa+zVVuN8Z_z;7>gD{Y3CA@MIW4+x3>nRqBy%2-?T`;z#;
z_{&c@Z^ZU7IMihrH~BL6%<EUU-)<%S&-pv+gTM!+56yC=61I3ezxVox-KCj+pv;hb
zAnIY7fB8Xg`2!hedV<b*%7^SW`#SMli7gYuPhP&y4WWl}r8e8I?%1ima`IXG$(bSz
zr3dsLn!P=eaM|?boZGH%r02fc!(bA+SNf;@isFOvN_UnS27B#%)-pSG`Y*TTCT<K0
z_E#(gX0y$Bw?^sNoF(Vl|1St<xW=^jQ0}d)hL>F>>w1;`7u1A>fFgQ#!`DM+^@<P5
ztK3;;m_Ml~XJ*0X*TM5&%(=$F@TA=ak~cT6pL!%_@)Dyz?01<quuX{jyd|?Cb9PBz
zui}2!x@%WJ=2$oK9y+_O;Gn)h-en1fpuDvLd1cP8xV22&85HclL^9}z=Utw`dAie5
z%`^80|1Z`AQ-#0JCi^n`L@z1M=HJM_B2bsXH#Fb<-;2dl^(tPPMj1Z|^7FJ$sk8aY
zXnISTVM6`ij|oqvXZA$8ozeB2yYH9vR2i-VSq{Jc7|&*t$h>4}+V|;$`~!x!3=A<J
z{27*WneAk*sGhFAdd9)0P4n6Ju*qoMcr)2IbiUe+IR7FE#)dzWFE~%Ek37ty-=6cF
z{ps@m!bO@4{97(8+pCnbWXnYF+$VqLq#Cj^6dbf~e)IFy?FQvtR`GXv)WrXAe9%&;
ze0Am6vQ_?KIqTDR_Aofqd0aU*(KqeKoW7jr?LKY)CxkO@$ZR-y@c`d{#l@No4cz}K
zQ}QG4^6c5%9UXS|LE%B>KY|e|H{NjjhR)Zx5f@)1#n|xYLWbZcaq}4uH?rJ3$1lnI
zUvWRvg<}^^n6b``+d9$uCeMGx%}f_UzN$TNeVF$4nZjl5mv<@+pH`S{(qcH-eCVz0
z(<Xb*9lpj7g3igP-dR(U_g(im(}iO)Czmm%t-Ez%=9*{!CnPdvtojxCK=ff+u2jM^
zFRS!8&z*CpzTt9EvJJ7i##%q8V0N0r(iqFI9XH>!{hyG}n324qB#t|G*1;=o>r%}B
zwAXMS2tML#GwF?G!%W?mF*kkAynK@q$#ChM?MubWoO(YNx862kR(sm<Brl|az4&hL
ztW-vi9H|5op0gk1Kj|^_3&+2lnsS+8v;8H@O}syw^N*%PGhC|vb18k9ZrQ>8-aCAa
z6@v0S=6N!1uzGH+xk;D7Q+oNbTP6p5miOKXu>V=Ewo|;Jt>VCPP_h2f<M}bZB))X*
z*Gv=qzE0g|QP|1-&*Pz)@53NJkNsBr)V@z%xmk~)^NT<hi$(Yj-{5`46W{Yk^8a7h
z!}LMp!>)qaWg#<ePA~D><9Funn$&oPS*zrjuW^}I@8bSv@X*Y6VUV7Oyuxm?r+L>l
z=`(bGaqFtQVRB&4!<ZyLk5grz&!;Q}<;=W?X1S&Zd?uW0y?bQN**HN^*?0GV@}aYO
zrQoco>2s=a>7lcBlZwo$T}2vPsys@;)n@R#&?7MuLXLcpKc&Tx-53ZiDV7u`i2Q87
zwpMc)D1UQD=-+u`B>u<oQ0^?JCGYFNS#zD(!Wm2xJowi>W7clHZSpk2^9-ZsQJ((`
z_kgoz^w!J+A13{KcYMPAUH4Wkf@e*=a&Xp6(W`xax^?#52}N5ZTtypPsya#q3Nm-G
z-{Wcg5*zRJ=bfsk>7Vv9dF=Cgx8!~feNvv6%b3TKr=7^Xe5SSdpT+~}4cQDY&7Hn8
zxSNFTjoooKOf(#n<NovQm^Q0ka);Os{p-y#XYVY@-gllokKvY;#J0>;zs^j%mFK(i
z@IABm%{Edy#CP1E$2&#8w*9;C{>x_mt>^w-y}xow6vGmE7Qd%94>-m5eEIufnexls
z)lGSQjjxr|kBWvf#C&MKbocNysfuH)^*-+N(_5Cje<S&*{6_2jC3keZ0$C5R+V@*r
zdG%@D{=<#!Z;vi4TJru?;-m8GQy+I+c6-@=d9Bte28Qhl|DRpUk#TN}e`hf3i?dVm
zm2FdIEIz8SjA6$EeHOdr5{DuWly=R}PkV0lsC?<uV$JaGfFni;QTzY$F9_mGH80Sf
z@Ya>zIge!r(}lRboCoGl-7tU26vemCFTVdHApCmuEyo#eLXXV(yRb;+_td`}3VS#G
zjBk*Al<Boe_Q&Nr@w|EuB@Yy>`8@lROxvH+ZjZb)7@lXaC;0SlI)8V~a)wOL=k<)y
z&E~4NIQQs2e|@k>o>AwR)qc(EiYMaD^|Zb-CH(&2`*PE{hj+Le?mo))nqJEHJdUC7
z0^fldcByj@?-XaS-gJA4-fNk2dl~jD1Go9D+KcrWqPH>|Ec1_iUhs}Jp}UOX*cVNR
zk|j_joAnrcL-+IKT<SYKLoV0La?aW{+zy+ftQnH4rqsTh7QpZ?63R{k<&k?FHY;V@
z4U4~|oC4>XNvpRq8>IDhow&Iso_*dK*8c(<yexafJHx$h&uplaQoJWwxTZ)Zd)BIR
z|8y8Mp8Gg7tZw+e_<Pj{xd)q;t;!8mO4j>vx}n}#e|x!5@m7wdK8$M9SnS>2bV#ks
zS+y(hSB|mwOY2=hFCTwrkUw4fGJjJN7lT9a)z=qhM&G>`@^vlO{Oqa;`&Qo;wfpsI
z%HpFMs~8weLjTr2h?cE;a`(Vf*}8cX3oSqHetl|tP@dS*8SM?fy|%Bv!+0kDrSh@H
z?8e!%R;~W6+N&aNbKrV|bjJJkyBY<a!B_X^t^6A%8VyR@-Hp`~_J6OH{_t|ys_Puv
zvqg412xqis72`7hYgBk{{@<$qC0(<be5U<-bl+R%U9NCOk@yGR2Y0XiWOx6ici;C<
zo~quf8*XQIexG*d=fV$y2U1?LEj%xL{iV3^_D9<~cjW(mKYP_Q4HdOuy&tUyrZ*JN
zylwjV@d39-cFpq7>mHxa;q_shafY>CWrL7KZ-vI=MPJ@m9{Il6e0jY+`x?E>o5xNR
z9+dahVR`@fY~`kQ^XDgp58PU|YIEK8{o?=mw?+I7^H-=+Wnf@n@O1TaS?83{1OQ2w
B<6!^*

diff --git a/mesh_extra_tools/icons/triangle.png b/mesh_extra_tools/icons/triangle.png
deleted file mode 100644
index 05f3a8db8650f03143a26010e79885a4ed2787b8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4153
zcmeAS@N?(olHy`uVBq!ia0y~yU}OMc4mJh`hM1xiX$%Yk44y8IAr*7p-pya3d$scT
z$M-TWE-ptpPON2#<}oxoJO7eYpywh}MZ>TDXI7`^Y!UsmNH=5Wol~wZO(LGEVV=Pz
z6Sm#xc{%$?{XvmiQJQKibU6)=sk!v9>=fN8C@47b^xS<jK32UeonQRzUi!Sq?6WoY
z1qbb)uc<t@uiEzc%$wE!*;G6y;Y6w-OZ6NcXG{CBefv_+z{kM8YF7B=(4`_d48|AC
z=CH;v#&FJIpR?uY^nGkLoHh(L5m#;O-D<s#vl%4j9u7U=d*J=Lok#c^qgT!P-M-q(
zawDTp!0iIN0_lQ_4&HWbZ&qi?$!FN69%3_4%stFjp#34-vHgd1LVaklMMiD!88!pK
zzpZ=o8K<+#ze;@YInH1XoAd#eExgN_|8vf<zN9#xQEy#VoYcz-u1ynnF}(G=U10Me
z_t@<}UylDOtIrWV!xpe_z2Tjs`$A)`$Van&7Fm#xdsv?N|BM|y_A9ggX%_NEP3Bz?
zkbAiEfPTgAyEQ9i814mM-7{|o-`a!04Mnm3zs~Z<@?KxA=k&UeNh9EPfz}7_2T!hS
z{SwDow|P~iWvOCRudu_+bxQNk^2h3iFV%Bey_s>!%TrfabtWYH-fCRV(E3vU-(M*U
z#Zukl70eaW#hFh(VhNbnKk5Fn_I1npm+3jJ-pDxR`Q4S=H{8x`&195zsH{^iWxRc2
zr<ra7v&MNzBndyy*aK!o>wLLyFr1qF*}b3`!u(v1q=s*aUV^mc^<}I%3{NY~kPLc!
z;NTTkodN+LUcFx41qPvK6(8(g`8wjk?%G_f4&DVm-<RqoG|FUO;>%%3{T2RT=M~qS
zPcpH-T0OiA974~|F4_L))KTABFh7RhN$mNZ_7_=!jX4ZYcQIP%l?s-a-kGqAW9@N=
z2~1zN|Na;M=_G3fbH)7a!utKf4m0;T+0B;U6}4~DE{?V5I2Rb?9zOo^9rKLE-K%H0
z2a7L!dXs_c(*1wG-4Cz_UEkEYyn(;^_lKeiu7GL!liojTU$;$vnV!?>VkQlj+XY;A
z*B<cmjy=uCcj>Oyo2ge?Gt&JSp8gQ}nP2xJ>rc=tr7be*4NO~jpEKF3^<V!xy^!Na
zLg;6oS58}O)f<fd=o-$h&;OsEas1-dHD@dtQ`Y7FaDK3`Vd;EEyBq&M_cs<Z_Z3!#
zrvJQ{`Zb3^GF!Tjy^d>+?1n$;t7g@|?=RN;kk5F$LhMJby~Y%Mf5uN`wuZC+AKY$c
z@9_V;p!^HV+3(T=md#->x@tCu@z0!x`ON>+?&d#T{OR|tw#_e>^*&~|ySMs4_3ByT
z>~Z1D1xzQdujSeQlkuHJ*=Oc2|KIjCJf7?GeY1wMAA@9;bRB<1(?jVm-6i>#Ds#IZ
z&vW^nws>Lw$5M$O9-*J@nb)t5En+(1bDN<+-LT&L_x4+V82<jhEnjel_rbY;>A`L}
z3_pJ|6*wN)<<In8=VR&jFY(q}xL?$nr5*`x=-I-nekt~cb@79x{LJEEUyFAB%{~0{
zz<0@i;zzhk#989yD`MB4<W$iAEm`-O`OfY)&)8q=|8}pz>YU0m5$Eh8rV}m+XRc?L
z>@N-9l^=h5LwlZ-W#)sb9{$rE!VY$elJ@1rmVRdba$or4r@0>!B{wprEa?Ba%PQgJ
z^TyldAOCLup3U?2)xY$xB(sJizh<nrZk~2O`s$vI@65m7m;RXP_##g1%g^aE>KR|U
z9<8yBx>}RIz57eH&92`?_YVHpz;lB^=vDH*JkE$;0tI&)UdOthiS5XHDbK8$#O$H1
z_3ZWQ(6hnLy4Ti!{krhl?IS-n9I25sn0R2u`spv@zFAv5S(JM?vqYbJp4F3G67tig
z2s>B>8pfOR@BPX6%QRoEDz=B;`xM&*hua0LA5MZ2#yhTv@4Dq*k4xNA|9#v=`Ljqu
zO7hVfS3|p;s5uPB%)QQpi#$HO>?mh~OY(8Bu+<!fW2RXU;lrE>Dl3!rEs~Ho<Mm@u
z_K^H6di2MJ%ngh^%B5fxT+cNfHpGBcgqf)~R74&DnXx9vkD;-s`)5~DO~lSQ3`wb?
zV0}e58JbdLz)Yr_3`|cTOrxI*j-9Z2rrq^1@##iJo;3?*tk*c!E_#H`V2={SV6k{M
znSe~g_`n{1?RMb<8@jr{CR^q(Fl$<XHL`vXNnltCcE3)&AH!h{h<QJYnQkn7Fk}7q
zP}B3gd)}?M)pmc;Z=05niIPQ3H};;Gv3`-cy~BTF3HfQ7>J70oqQGAI^ps`8GR<Qk
zf9S-UHGK6o1zREcNhE<cxF2kD-5iE%#md5cKf8ov<jax|?3(<XWy7MKV883=`!TGZ
z?Fum}i8;bC;mq~oCz78<pO$e{_BVe_)ZWCXqiOLhJHF2_KJeH4()bIXj<v5nz@AmP
zxd&{zTn>Y`!87fikBOZ(8KxP(28YMe=cgO2Ir@H9`G<b~bl|nv(p-zF?~0j@wW~g0
z*|7P<jP;TEbq)Uv4eWFTr4N|({FLhbnAlmtwShHx-?7x12q`~?Xya$uF2~xJK4jU@
zU>Kh%A#Y}<-f$F@+RH!ZudUBfx+j!db3<$nLto;V@Tg<$y{9=7CO??5Ui!`->(}y&
zrJ1Ig+2t@wAGoNLyl<c6hIb*g!jBKTJ=Anq-~aO$>xT3POVwpRi>eyfy<xb!a>mC*
z3&xx><-_@PGb+x6PdV^ogRO*oS&J~kv6`o+er%}lV~|bWXOvPCvFD~aL-M{&=`|4x
zB0;QA=`|5+BL9Cla<s<Q==hBF8h?|2dK|d4xu1V_F0;Y2)fUIvS!d)jE0{fd{j#An
zeQmu@FTeB+op?5rXRCdVwe#k$6K*h!XEn0Rso0#&aI8l3{ErQcXJ3gNn6W<7z%Iw4
zcs4`N&shwQ54Rc5=2S3v_L_IseJQoSJuCY8e`_Az-&!5^F|l|S!=j{p?+QNmudhGz
zo+F|v>|^5Q86bUXj}MpSe*)QXIko1-JKueb31_Zfk(A%YJ=u=c;90g@4}bLiE9wl%
z`_c~l*znc2jLG0xc3cmC^!X`Z!6QF5eD&GHDDl}e`dItgj3V9xGuHn!vdbx*{JYWM
zS@yLa{^+wyq#6w4UrEYuTjFWT(DPI1So_)}BYkG6&r8qt@JFAUqQ;QCucYN;;^~<#
z%p5&GtE7_md6kK`%-Q9uX1C@?FhlabEwYafZ!>S@RM2|%y3V}*=db;Te=|>;=TZ}K
z5#;o!wvUO?+O<pu&%CXT>~gY?`Y{}<$rL@-t{e7*CE?8Uu+*9xNv>uL52Sj2UV5eU
z`0zT;2=kc2<qUr{z8ClWyd>51`0%~xTVEm`v22h}-nV7hgC86IGQMup$^sebY+&~$
zcd0MP$m>1))zOB$2WIH=p7~+Gl?f8dIM!a;r6H8OPvpRl4NM@fa+$sUvEhw0!?7C8
z3wItL-c%=fVTOKh;<=BBJN+5Tlg><UVm;pO8oNi%WgG8;{+L}R37N_Jws?fp+*oRP
zygjv&E8)!apc%<E5#X4Yx-0Ye@Fq|s2YD5D^PesRx#{E?T|1rCpy*zG;(V5N?}Ia)
zYaSimG?SqzdEd9)Kew*=w^Qij&3|tm9p045An|$Wo-;~zI^Ce4oU+*RNc&SGMv2c$
z-<(mj)A<Pspdz!cKQ_pK;$h0#mB-sva~Y1+tQ45s%kO;+Y@*cXr3=5DU%J=vw0bYU
zw<V*?u^QJs^P`Qg*)LZUm!GzT@e3o*v6_`86F(+8w@=hjy~<Kxe5_`r!NHG-f{iNH
zQh!q&lJ|vdT6wg6DJaziZCoZMZ<fVu@XTA-aORH<7yTG}eqNg5qiUCPhV#G-ecxjt
zj}E)dWa#;MNyJytE@ur`@SMn_!-qhL&Lnl|@%C0fhT1O|!<+k(&rF}h-N*kstE494
zi{=5-13wvGOMPBC$K`1IT>pZah#Q&>hVio|2R%Nl1lBCQ^jLeV4=CpPyn6V%XMt>a
zGett)tODd7<M5E08w$%Aat{|CkSuwweV^f;{gGYAf2{Ge*K)jFAX*TA;F3S{^-Hl5
zH5*rz%lmB#W6qF1$F`0^kNq5@pZd3^N6MjR<yqG0^RCMM!T(^=0cRPuIHo!_8x~MY
zeD^CQZ}WzK+yBhJbW~~X?pKXv4+TCXPOb}?wC&;F1N|K*_uV*UTr!jC|Asdu8?NNP
zty}Vwv%vguUY)@+Z&t1z{@dqvmQ;UH|2yyQ#cje4w+oCu=swtV_xd)m<b5G)4*b}V
zYRglzZ&hXKYW*8UOfSxVp09BC8GG`+kPRTYST>uB@1M4cnKk^&?e)J9`@s9?41Hh6
zkeVBt&MnMl;<lgsxi7e3+rzsD>MzIM^glU6-`6Rj=7v@rQ{DbmKd(OfUvY)yg4rAn
z8;4(K^Uq9IQ#P>65nayA|E2m*N3uWTJ2pF$D9>)!d+oknsroAW<Da&_`1V84-H-8B
z+vgYOeg{{#yu0gn=}JxW4Rdzg*UF)HpNi+yO+GYTShRSJcSHO#J*Qb4^qIw->$xtN
z)o@+9w>;)jhTXmQKb5aD$n0ENxl?SxtM@lPXSeYiPMEU(dP8~cg}KGMe=e=G<lK?M
z{G;TRmx}7gm%I<wTnY8?dbEZ&X;QW7)BN*n1!=FeR8$L}vAwigt)sa%*u0^6<?0Dj
zjvVAQNROYjlG%(Qb01&MfmeZtCaFEV$@`!hEc@N8!M!nDNL(p1W<5iH-WPL$3X4+H
zNp4>YLW^Il?PtEf_w97AS+jO8JkPu$>mT=WhD<%Vci;a6PE0Uon6LCrZT{&U%sVs-
zd4pP_8(s@vFPM?Hp85D4@ddd*q&}o4hi^H_ec*k_R&iBR+uXyNCEsuO{QNn4|N5+d
zf7aGpe%t;xo~ge#`n=$J=I~uVO+)_{|MuGTyo#&;;@gkPeOU~lXJ;RH{@}&#_MRuV
zRy}Ly?9=XDR^PY$#DhPgA9mLD%YW?q{CCwe)d$8s-^CstKCo}qvv@bFc~e6E$J}@S
zen<W=;{)Tr_w05}Tf1*@?hWQU>~q8;Ze$;j4=w$4Tg`KEw)8rte=~3RoKtT+ANKW8
z{EO(gkMH+COg>=i*lNoj^Wxd{n6Kyma=-lM)KcBhpS$&E;%v@@&D$O-Jur)?>3%4>
zm*<b^hw|g|`aO!TxPSi7TA+NG<%^A9dDPy=tbdnEF*w|2C@?LMEnsxt-<}|Op7}e|
z_R6L4Rm=aS9;!Vc9$~xYyTAwL2YwH%L-*b>*S*VNmM!hatjDa!er{oP?B^-I@t@f4
zwziAEc-Q?eA@uVVtK*ZNt;qesP{8_ubJyRk>=ucar|)svzQ2ym#^w9FeN!**y_Ut$
zy@gkuA)R48lfM4#MwPc~<{$89^<#@$^XkcVsp-gl?J3>=+57eumBt9Zz0SbEz~JfX
K=d#Wzp$PyJ{@G0c

diff --git a/mesh_extra_tools/mesh_check.py b/mesh_extra_tools/mesh_check.py
deleted file mode 100644
index 2acfe184b..000000000
--- a/mesh_extra_tools/mesh_check.py
+++ /dev/null
@@ -1,370 +0,0 @@
-# gpl author: Pistiwique
-
-bl_info = {
-    "name": "Mesh Check BGL edition",
-    "description": "Display the triangles and ngons of the mesh",
-    "author": "Pistiwique",
-    "version": (1, 0, 1),
-    "blender": (2, 75, 0),
-    "location": "3D View(s) > Properties > Shading",
-    "category": "3D View"
-    }
-
-import bpy
-import bmesh
-from bgl import (
-        glBegin,
-        glLineWidth,
-        glColor4f,
-        glVertex3f,
-        glEnd,
-        GL_LINES,
-        glEnable,
-        glDisable,
-        GL_DEPTH_TEST,
-        GL_BLEND,
-        GL_POLYGON
-        )
-from mathutils.geometry import tessellate_polygon as tessellate
-from bpy.types import (
-        Operator,
-        PropertyGroup,
-        )
-from bpy.props import (
-        BoolProperty,
-        EnumProperty,
-        FloatProperty,
-        FloatVectorProperty,
-        PointerProperty,
-        )
-
-# -- Globals -- #
-mesh_check_handle = []
-draw_enabled = [False]
-edge_width = [1.0]
-face_opacity = [0.2]
-edges_tri_color = [(1.0, 1.0, 0.0, 1)]
-faces_tri_color = [(1.0, 1.0, 0.0, face_opacity[0])]
-edges_ngons_color = [(1.0, 0.0, 0.0, 1.0)]
-faces_ngons_color = [(1.0, 0.0, 0.0, face_opacity[0])]
-bm_old = [None]
-finer_lines = [False]
-
-
-def draw_poly(points):
-    for i in range(len(points)):
-        glVertex3f(points[i][0], points[i][1], points[i][2])
-
-
-def mesh_check_draw_callback():
-    obj = bpy.context.object
-    if obj and obj.type == 'MESH':
-        if draw_enabled[0]:
-            mesh = obj.data
-            matrix_world = obj.matrix_world
-
-            glLineWidth(edge_width[0])
-
-            if bpy.context.mode == 'EDIT_MESH':
-                use_occlude = True
-
-                if bm_old[0] is None or not bm_old[0].is_valid:
-                    bm = bm_old[0] = bmesh.from_edit_mesh(mesh)
-                else:
-                    bm = bm_old[0]
-
-                no_depth = not bpy.context.space_data.use_occlude_geometry
-
-                if no_depth:
-                    glDisable(GL_DEPTH_TEST)
-
-                    use_occlude = False
-
-                    if finer_lines[0]:
-                        glLineWidth(edge_width[0] / 4.0)
-                        use_occlude = True
-
-                    for face in bm.faces:
-                        if len([verts for verts in face.verts]) == 3:
-                            faces = [matrix_world * vert.co for vert in face.verts]
-                            glColor4f(*faces_tri_color[0])
-                            glEnable(GL_BLEND)
-                            glBegin(GL_POLYGON)
-                            draw_poly(faces)
-                            glEnd()
-
-                            for edge in face.edges:
-                                if edge.is_valid:
-                                    edges = [matrix_world * vert.co for vert in edge.verts]
-                                    glColor4f(*edges_tri_color[0])
-                                    glBegin(GL_LINES)
-                                    draw_poly(edges)
-                                    glEnd()
-
-                        elif len([verts for verts in face.verts]) > 4:
-                            new_faces = []
-                            faces = []
-                            coords = [v.co for v in face.verts]
-                            indices = [v.index for v in face.verts]
-                            for pol in tessellate([coords]):
-                                new_faces.append([indices[i] for i in pol])
-
-                            for f in new_faces:
-                                faces.append(
-                                        [((matrix_world * bm.verts[i].co)[0] + face.normal.x * 0.001,
-                                        (matrix_world * bm.verts[i].co)[1] + face.normal.y * 0.001,
-                                        (matrix_world * bm.verts[i].co)[2] + face.normal.z * 0.001)
-                                        for i in f]
-                                        )
-
-                            for f in faces:
-                                glColor4f(*faces_ngons_color[0])
-                                glEnable(GL_BLEND)
-                                glBegin(GL_POLYGON)
-                                draw_poly(f)
-                                glEnd()
-
-                            for edge in face.edges:
-                                if edge.is_valid:
-                                    edges = [matrix_world * vert.co for vert in edge.verts]
-                                    glColor4f(*edges_ngons_color[0])
-                                    glBegin(GL_LINES)
-                                    draw_poly(edges)
-                                    glEnd()
-
-                    glDisable(GL_BLEND)
-                    glColor4f(0.0, 0.0, 0.0, 1.0)
-                    glLineWidth(edge_width[0])
-                    glEnable(GL_DEPTH_TEST)
-
-                if use_occlude:
-
-                    for face in bm.faces:
-                        if len([verts for verts in face.verts]) == 3:
-                            faces = []
-                            for vert in face.verts:
-                                vert_face = matrix_world * vert.co
-                                faces.append(
-                                        (vert_face[0] + face.normal.x * 0.001,
-                                        vert_face[1] + face.normal.y * 0.001,
-                                        vert_face[2] + face.normal.z * 0.001)
-                                        )
-
-                            glColor4f(*faces_tri_color[0])
-                            glEnable(GL_BLEND)
-                            glBegin(GL_POLYGON)
-                            draw_poly(faces)
-                            glEnd()
-
-                            for edge in face.edges:
-                                if edge.is_valid:
-                                    edges = []
-                                    for vert in edge.verts:
-                                        vert_edge = matrix_world * vert.co
-                                        edges.append(
-                                            (vert_edge[0] + face.normal.x * 0.001,
-                                            vert_edge[1] + face.normal.y * 0.001,
-                                            vert_edge[2] + face.normal.z * 0.001)
-                                            )
-                                    glColor4f(*edges_tri_color[0])
-                                    glBegin(GL_LINES)
-                                    draw_poly(edges)
-                                    glEnd()
-
-                        elif len([verts for verts in face.verts]) > 4:
-                            new_faces = []
-                            faces = []
-                            coords = [v.co for v in face.verts]
-                            indices = [v.index for v in face.verts]
-                            for pol in tessellate([coords]):
-                                new_faces.append([indices[i] for i in pol])
-
-                            for f in new_faces:
-                                faces.append([
-                                        ((matrix_world * bm.verts[i].co)[0] + face.normal.x * 0.001,
-                                         (matrix_world * bm.verts[i].co)[1] + face.normal.y * 0.001,
-                                         (matrix_world * bm.verts[i].co)[2] + face.normal.z * 0.001)
-                                        for i in f]
-                                        )
-
-                            for f in faces:
-                                glColor4f(*faces_ngons_color[0])
-                                glEnable(GL_BLEND)
-                                glBegin(GL_POLYGON)
-                                draw_poly(f)
-                                glEnd()
-
-                            for edge in face.edges:
-                                if edge.is_valid:
-                                    edges = []
-                                    for vert in edge.verts:
-                                        vert_edge = matrix_world * vert.co
-                                        edges.append(
-                                                (vert_edge[0] + face.normal.x * 0.001,
-                                                vert_edge[1] + face.normal.y * 0.001,
-                                                vert_edge[2] + face.normal.z * 0.001)
-                                                )
-                                    glColor4f(*edges_ngons_color[0])
-                                    glBegin(GL_LINES)
-                                    draw_poly(edges)
-                                    glEnd()
-
-                    glDisable(GL_BLEND)
-                    glColor4f(0.0, 0.0, 0.0, 1.0)
-
-
-def updateBGLData(self, context):
-    if self.mesh_check_use and self.display_faces:
-        bpy.ops.object.mode_set(mode='EDIT')
-        draw_enabled[0] = True
-        edge_width[0] = self.edge_width
-        finer_lines[0] = self.finer_lines_behind_use
-        face_opacity[0] = self.face_opacity
-        edges_tri_color[0] = (
-                self.custom_tri_color[0],
-                self.custom_tri_color[1],
-                self.custom_tri_color[2],
-                1)
-        faces_tri_color[0] = (
-                self.custom_tri_color[0],
-                self.custom_tri_color[1],
-                self.custom_tri_color[2],
-                self.face_opacity
-                )
-        edges_ngons_color[0] = (
-                self.custom_ngons_color[0],
-                self.custom_ngons_color[1],
-                self.custom_ngons_color[2],
-                1)
-        faces_ngons_color[0] = (
-                self.custom_ngons_color[0],
-                self.custom_ngons_color[1],
-                self.custom_ngons_color[2],
-                self.face_opacity
-                )
-        return
-
-    draw_enabled[0] = False
-
-
-class FaceTypeSelect(Operator):
-    bl_idname = "object.face_type_select"
-    bl_label = "Face type select"
-    bl_description = "Select Triangles and / or Ngons on the Active Object"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    face_type: EnumProperty(
-            name="Face Type",
-            items=(('tris', "Tris", "Colorize Triangles in the Mesh"),
-                   ('ngons', "Ngons", "Colorize Ngons in the Mesh")),
-            default='ngons'
-            )
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None and context.active_object.type == 'MESH'
-
-    def execute(self, context):
-        bpy.ops.object.mode_set(mode='EDIT')
-        bpy.ops.mesh.select_all(action='DESELECT')
-        context.tool_settings.mesh_select_mode = (False, False, True)
-
-        if self.face_type == "tris":
-            bpy.ops.mesh.select_face_by_sides(number=3, type='EQUAL')
-        else:
-            bpy.ops.mesh.select_face_by_sides(number=4, type='GREATER')
-
-        return {'FINISHED'}
-
-
-class MeshCheckCollectionGroup(PropertyGroup):
-    mesh_check_use: BoolProperty(
-            name="Mesh Check",
-            description="Display Mesh Check options",
-            default=False,
-            update=updateBGLData
-            )
-    display_faces: BoolProperty(
-            name="Display Faces",
-            description="Use BGL to display Ngons and Tris of the mesh",
-            default=False,
-            update=updateBGLData
-            )
-    edge_width: FloatProperty(
-            name="Width",
-            description="Drawn Edges width in pixels",
-            min=1.0,
-            max=10.0,
-            default=3.0,
-            subtype='PIXEL',
-            update=updateBGLData
-            )
-    finer_lines_behind_use: BoolProperty(
-            name="Finer Lines behind",
-            description="Display partially hidden edges finer in non-occlude mode",
-            default=True,
-            update=updateBGLData
-            )
-    custom_tri_color: FloatVectorProperty(
-            name="Tri Color",
-            description="Custom color for the Triangles",
-            min=0.0,
-            max=1.0,
-            default=(1.0, 1.0, 0.0),
-            size=3,
-            subtype='COLOR',
-            update=updateBGLData
-            )
-    custom_ngons_color: FloatVectorProperty(
-            name="Ngons Color",
-            description="Custom color for the Ngons",
-            min=0.0,
-            max=1.0,
-            default=(1.0, 0.0, 0.0),
-            size=3,
-            subtype='COLOR',
-            update=updateBGLData
-            )
-    face_opacity: FloatProperty(
-            name="Face Opacity",
-            description="Opacity of the color for the face",
-            min=0.0,
-            max=1.0,
-            default=0.2,
-            subtype='FACTOR',
-            update=updateBGLData
-            )
-
-
-# Register
-classes = (
-    FaceTypeSelect,
-    MeshCheckCollectionGroup,
-    )
-
-
-def register():
-    for cls in classes:
-        bpy.utils.register_class(cls)
-
-    bpy.types.WindowManager.mesh_check = PointerProperty(
-                                                type=MeshCheckCollectionGroup
-                                                )
-    if mesh_check_handle:
-        bpy.types.SpaceView3D.draw_handler_remove(mesh_check_handle[0], 'WINDOW')
-    mesh_check_handle[:] = [bpy.types.SpaceView3D.draw_handler_add(mesh_check_draw_callback,
-                            (), 'WINDOW', 'POST_VIEW')]
-
-
-def unregister():
-    del bpy.types.WindowManager.mesh_check
-    if mesh_check_handle:
-        bpy.types.SpaceView3D.draw_handler_remove(mesh_check_handle[0], 'WINDOW')
-        mesh_check_handle[:] = []
-
-    for cls in classes:
-        bpy.utils.unregister_class(cls)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_cut_faces.py b/mesh_extra_tools/mesh_cut_faces.py
deleted file mode 100644
index 1522b1597..000000000
--- a/mesh_extra_tools/mesh_cut_faces.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# gpl author: Stanislav Blinov
-
-bl_info = {
-    "name": "Cut Faces",
-    "author": "Stanislav Blinov",
-    "version": (1, 0, 0),
-    "blender": (2, 72, 0),
-    "description": "Cut Faces and Deselect Boundary operators",
-    "category": "Mesh", }
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from bpy.props import (
-        BoolProperty,
-        IntProperty,
-        EnumProperty,
-        )
-
-
-def bmesh_from_object(object):
-    mesh = object.data
-    if object.mode == 'EDIT':
-        bm = bmesh.from_edit_mesh(mesh)
-    else:
-        bm = bmesh.new()
-        bm.from_mesh(mesh)
-    return bm
-
-
-def bmesh_release(bm, object):
-    mesh = object.data
-    bm.select_flush_mode()
-    if object.mode == 'EDIT':
-        bmesh.update_edit_mesh(mesh, True)
-    else:
-        bm.to_mesh(mesh)
-        bm.free()
-
-
-def calc_face(face, keep_caps=True):
-
-    assert face.tag
-
-    def radial_loops(loop):
-        next = loop.link_loop_radial_next
-        while next != loop:
-            result, next = next, next.link_loop_radial_next
-            yield result
-
-    result = []
-
-    face.tag = False
-    selected = []
-    to_select = []
-    for loop in face.loops:
-        self_selected = False
-        # Iterate over selected adjacent faces
-        for radial_loop in filter(lambda l: l.face.select, radial_loops(loop)):
-            # Tag the edge if no other face done so already
-            if not loop.edge.tag:
-                loop.edge.tag = True
-                self_selected = True
-
-            adjacent_face = radial_loop.face
-            # Only walk adjacent face if current face tagged the edge
-            if adjacent_face.tag and self_selected:
-                result += calc_face(adjacent_face, keep_caps)
-
-        if loop.edge.tag:
-            (selected, to_select)[self_selected].append(loop)
-
-    for loop in to_select:
-        result.append(loop.edge)
-        selected.append(loop)
-
-    # Select opposite edge in quads
-    if keep_caps and len(selected) == 1 and len(face.verts) == 4:
-        result.append(selected[0].link_loop_next.link_loop_next.edge)
-
-    return result
-
-
-def get_edge_rings(bm, keep_caps=True):
-
-    def tag_face(face):
-        if face.select:
-            face.tag = True
-            for edge in face.edges:
-                edge.tag = False
-        return face.select
-
-    # fetch selected faces while setting up tags
-    selected_faces = [f for f in bm.faces if tag_face(f)]
-
-    edges = []
-
-    try:
-        # generate a list of edges to select:
-        # traversing only tagged faces, since calc_face can walk and untag islands
-        for face in filter(lambda f: f.tag, selected_faces):
-            edges += calc_face(face, keep_caps)
-    finally:
-        # housekeeping: clear tags
-        for face in selected_faces:
-            face.tag = False
-            for edge in face.edges:
-                edge.tag = False
-
-    return edges
-
-
-class MESH_xOT_deselect_boundary(Operator):
-    bl_idname = "mesh.ext_deselect_boundary"
-    bl_label = "Deselect Boundary"
-    bl_description = ("Deselect boundary edges of selected faces\n"
-                      "Note: if all Faces are selected there is no boundary,\n"
-                      "so the tool will not have results")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    keep_cap_edges: BoolProperty(
-                        name="Keep Cap Edges",
-                        description="Keep quad strip cap edges selected",
-                        default=False
-                        )
-
-    @classmethod
-    def poll(cls, context):
-        active_object = context.active_object
-        return active_object and active_object.type == 'MESH' and active_object.mode == 'EDIT'
-
-    def execute(self, context):
-        object = context.active_object
-        bm = bmesh_from_object(object)
-
-        try:
-            edges = get_edge_rings(bm, keep_caps=self.keep_cap_edges)
-            if not edges:
-                self.report({'WARNING'}, "No suitable Face selection found. Operation cancelled")
-                return {'CANCELLED'}
-
-            bpy.ops.mesh.select_all(action='DESELECT')
-            bm.select_mode = {'EDGE'}
-
-            for edge in edges:
-                edge.select = True
-            context.tool_settings.mesh_select_mode[:] = False, True, False
-
-        finally:
-            bmesh_release(bm, object)
-
-        return {'FINISHED'}
-
-
-class MESH_xOT_cut_faces(Operator):
-    bl_idname = "mesh.ext_cut_faces"
-    bl_label = "Cut Faces"
-    bl_description = "Cut selected faces, connected through their adjacent edges"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    # from bmesh_operators.h
-    SUBD_INNERVERT = 0
-    SUBD_PATH = 1
-    SUBD_FAN = 2
-    SUBD_STRAIGHT_CUT = 3
-
-    num_cuts: IntProperty(
-            name="Number of Cuts",
-            default=1,
-            min=1,
-            max=100,
-            subtype='UNSIGNED'
-            )
-    use_single_edge: BoolProperty(
-            name="Quad/Tri Mode",
-            description="Cut boundary faces",
-            default=False
-            )
-    corner_type: EnumProperty(
-            items=[('SUBD_INNERVERT', "Inner Vert", ""),
-                   ('SUBD_PATH', "Path", ""),
-                   ('SUBD_FAN', "Fan", ""),
-                   ('SUBD_STRAIGHT_CUT', "Straight Cut", ""),
-                   ],
-            name="Quad Corner Type",
-            description="How to subdivide quad corners",
-            default='SUBD_STRAIGHT_CUT'
-            )
-    use_grid_fill: BoolProperty(
-            name="Use Grid Fill",
-            description="Fill fully enclosed faces with a grid",
-            default=True
-            )
-
-    @classmethod
-    def poll(cls, context):
-        active_object = context.active_object
-        return active_object and active_object.type == 'MESH' and active_object.mode == 'EDIT'
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.label(text="Number of Cuts:")
-        layout.prop(self, "num_cuts", text="")
-
-        layout.prop(self, "use_single_edge")
-        layout.prop(self, "use_grid_fill")
-
-        layout.label(text="Quad Corner Type:")
-        layout.prop(self, "corner_type", text="")
-
-    def cut_edges(self, context):
-        object = context.active_object
-        bm = bmesh_from_object(object)
-
-        try:
-            edges = get_edge_rings(bm, keep_caps=True)
-            if not edges:
-                self.report({'WARNING'},
-                            "No suitable Face selection found. Operation cancelled")
-                return False
-
-            result = bmesh.ops.subdivide_edges(
-                            bm,
-                            edges=edges,
-                            cuts=int(self.num_cuts),
-                            use_grid_fill=bool(self.use_grid_fill),
-                            use_single_edge=bool(self.use_single_edge),
-                            quad_corner_type=eval("self." + self.corner_type)
-                            )
-            bpy.ops.mesh.select_all(action='DESELECT')
-            bm.select_mode = {'EDGE'}
-
-            inner = result['geom_inner']
-            for edge in filter(lambda e: isinstance(e, bmesh.types.BMEdge), inner):
-                edge.select = True
-
-        finally:
-            bmesh_release(bm, object)
-
-        return True
-
-    def execute(self, context):
-
-        if not self.cut_edges(context):
-            return {'CANCELLED'}
-
-        context.tool_settings.mesh_select_mode[:] = False, True, False
-        # Try to select all possible loops
-        bpy.ops.mesh.loop_multi_select(ring=False)
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(MESH_xOT_deselect_boundary)
-    bpy.utils.register_class(MESH_xOT_cut_faces)
-
-
-def unregister():
-    bpy.utils.unregister_class(MESH_xOT_deselect_boundary)
-    bpy.utils.unregister_class(MESH_xOT_cut_faces)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_edge_roundifier.py b/mesh_extra_tools/mesh_edge_roundifier.py
deleted file mode 100644
index f216b1dbe..000000000
--- a/mesh_extra_tools/mesh_edge_roundifier.py
+++ /dev/null
@@ -1,1380 +0,0 @@
-# ##### 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 #####
-
-bl_info = {
-    "name": "Edge Roundifier",
-    "category": "Mesh",
-    "author": "Piotr Komisarczyk (komi3D), PKHG",
-    "version": (1, 0, 1),
-    "blender": (2, 73, 0),
-    "location": "SPACE > Edge Roundifier or CTRL-E > "
-                "Edge Roundifier or Tools > Addons > Edge Roundifier",
-    "description": "Mesh editing script allowing edge rounding",
-    "wiki_url": "",
-    "category": "Mesh"
-}
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        EnumProperty,
-        IntProperty,
-        )
-from math import (
-        sqrt, acos, pi,
-        radians, degrees, sin,
-        )
-from mathutils import (
-        Vector, Euler,
-        Quaternion,
-        )
-
-# CONSTANTS
-two_pi = 2 * pi
-XY = "XY"
-XZ = "XZ"
-YZ = "YZ"
-SPIN_END_THRESHOLD = 0.001
-LINE_TOLERANCE = 0.0001
-d_XABS_YABS = False
-d_Edge_Info = False
-d_Plane = False
-d_Radius_Angle = False
-d_Roots = False
-d_RefObject = False
-d_LineAB = False
-d_Selected_edges = False
-d_Rotate_Around_Spin_Center = False
-
-# Enable debug prints
-DEBUG = False
-
-
-# for debugging PKHG #
-def debugPrintNew(debugs, *text):
-    if DEBUG and debugs:
-        tmp = [el for el in text]
-        for row in tmp:
-            print(row)
-
-
-# Geometry and math calculation methods #
-
-class CalculationHelper:
-
-    def __init__(self):
-        """
-        Constructor
-        """
-    def getLineCoefficientsPerpendicularToVectorInPoint(self, point, vector, plane):
-        x, y, z = point
-        xVector, yVector, zVector = vector
-        destinationPoint = (x + yVector, y - xVector, z)
-        if plane == 'YZ':
-            destinationPoint = (x, y + zVector, z - yVector)
-        if plane == 'XZ':
-            destinationPoint = (x + zVector, y, z - xVector)
-        return self.getCoefficientsForLineThrough2Points(point, destinationPoint, plane)
-
-    def getQuadraticRoots(self, coef):
-        if len(coef) != 3:
-            return None  # Replaced NaN with None
-        else:
-            a, b, c = coef
-            delta = b ** 2 - 4 * a * c
-            if delta == 0:
-                x = -b / (2 * a)
-                return (x, x)
-            elif delta < 0:
-                return None
-            else:
-                x1 = (-b - sqrt(delta)) / (2 * a)
-                x2 = (-b + sqrt(delta)) / (2 * a)
-                return (x1, x2)
-
-    def getCoefficientsForLineThrough2Points(self, point1, point2, plane):
-        x1, y1, z1 = point1
-        x2, y2, z2 = point2
-
-        # mapping x1,x2, y1,y2 to proper values based on plane
-        if plane == YZ:
-            x1 = y1
-            x2 = y2
-            y1 = z1
-            y2 = z2
-        if plane == XZ:
-            y1 = z1
-            y2 = z2
-
-        # Further calculations the same as for XY plane
-        xabs = abs(x2 - x1)
-        yabs = abs(y2 - y1)
-        debugPrintNew(d_XABS_YABS, "XABS = " + str(xabs) + " YABS = " + str(yabs))
-
-        if xabs <= LINE_TOLERANCE:
-            return None  # this means line x = edgeCenterX
-        if yabs <= LINE_TOLERANCE:
-            A = 0
-            B = y1
-            return A, B
-        A = (y2 - y1) / (x2 - x1)
-        B = y1 - (A * x1)
-        return (A, B)
-
-    def getLineCircleIntersections(self, lineAB, circleMidPoint, radius):
-        # (x - a)**2 + (y - b)**2 = r**2 - circle equation
-        # y = A*x + B - line equation
-        # f * x**2 + g * x + h = 0 - quadratic equation
-        A, B = lineAB
-        a, b = circleMidPoint
-        f = 1 + (A ** 2)
-        g = -2 * a + 2 * A * B - 2 * A * b
-        h = (B ** 2) - 2 * b * B - (radius ** 2) + (a ** 2) + (b ** 2)
-        coef = [f, g, h]
-        roots = self.getQuadraticRoots(coef)
-        if roots is not None:
-            x1 = roots[0]
-            x2 = roots[1]
-            point1 = [x1, A * x1 + B]
-            point2 = [x2, A * x2 + B]
-            return [point1, point2]
-        else:
-            return None
-
-    def getLineCircleIntersectionsWhenXPerpendicular(self, edgeCenter,
-                                                     circleMidPoint, radius, plane):
-        # (x - a)**2 + (y - b)**2 = r**2 - circle equation
-        # x = xValue - line equation
-        # f * x**2 + g * x + h = 0 - quadratic equation
-        xValue = edgeCenter[0]
-        if plane == YZ:
-            xValue = edgeCenter[1]
-        if plane == XZ:
-            xValue = edgeCenter[0]
-
-        a, b = circleMidPoint
-        f = 1
-        g = -2 * b
-        h = (a ** 2) + (b ** 2) + (xValue ** 2) - 2 * a * xValue - (radius ** 2)
-        coef = [f, g, h]
-        roots = self.getQuadraticRoots(coef)
-        if roots is not None:
-            y1 = roots[0]
-            y2 = roots[1]
-            point1 = [xValue, y1]
-            point2 = [xValue, y2]
-            return [point1, point2]
-        else:
-            return None
-
-    # point1 is the point near 90 deg angle
-    def getAngle(self, point1, point2, point3):
-        distance1 = (Vector(point1) - Vector(point2)).length
-        distance2 = (Vector(point2) - Vector(point3)).length
-        cos = distance1 / distance2
-
-        if abs(cos) > 1:  # prevents Domain Error
-            cos = round(cos)
-
-        alpha = acos(cos)
-        return (alpha, degrees(alpha))
-
-    # get two of three coordinates used for further calculation of spin center
-    # PKHG>nice if rescriction to these 3 types or planes is to be done
-    # komi3D> from 0.0.2 there is a restriction. In future I would like Edge
-    # komi3D> Roundifier to work on Normal and View coordinate systems
-    def getCircleMidPointOnPlane(self, V1, plane):
-        X = V1[0]
-        Y = V1[1]
-        if plane == 'XZ':
-            X = V1[0]
-            Y = V1[2]
-        elif plane == 'YZ':
-            X = V1[1]
-            Y = V1[2]
-        return [X, Y]
-
-    def getEdgeReference(self, edge, edgeCenter, plane):
-        vert1 = edge.verts[1].co
-        V = vert1 - edgeCenter
-        orthoVector = Vector((V[1], -V[0], V[2]))
-        if plane == 'XZ':
-            orthoVector = Vector((V[2], V[1], -V[0]))
-        elif plane == 'YZ':
-            orthoVector = Vector((V[0], V[2], -V[1]))
-        refPoint = edgeCenter + orthoVector
-        return refPoint
-
-
-# Selection Methods #
-
-class SelectionHelper:
-
-    def selectVertexInMesh(self, mesh, vertex):
-        bpy.ops.object.mode_set(mode="OBJECT")
-        for v in mesh.vertices:
-            if v.co == vertex:
-                v.select = True
-                break
-
-        bpy.ops.object.mode_set(mode="EDIT")
-
-    def getSelectedVertex(self, mesh):
-        bpy.ops.object.mode_set(mode="OBJECT")
-        for v in mesh.vertices:
-            if v.select is True:
-                bpy.ops.object.mode_set(mode="EDIT")
-                return v
-
-        bpy.ops.object.mode_set(mode="EDIT")
-        return None
-
-    def refreshMesh(self, bm, mesh):
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bm.to_mesh(mesh)
-        bpy.ops.object.mode_set(mode='EDIT')
-
-
-# Operator
-
-class EdgeRoundifier(Operator):
-    bl_idname = "mesh.edge_roundifier"
-    bl_label = "Edge Roundifier"
-    bl_description = "Mesh modeling tool for building arcs on selected Edges"
-    bl_options = {'REGISTER', 'UNDO', 'PRESET'}
-
-    threshold = 0.0005
-    obj = None
-
-    edgeScaleFactor: FloatProperty(
-            name="",
-            description="Set the Factor of scaling",
-            default=1.0,
-            min=0.00001, max=100000.0,
-            step=0.5,
-            precision=5
-            )
-    r: FloatProperty(
-            name="",
-            description="User Defined arc steepness by a Radius\n"
-                        "Enabled only if Entry mode is set to Radius\n",
-            default=1,
-            min=0.00001, max=1000.0,
-            step=0.1,
-            precision=3
-            )
-    a: FloatProperty(
-            name="",
-            description="User defined arc steepness calculated from an Angle\n"
-                        "Enabled only if Entry mode is set to Angle and\n"
-                        "Angle presets is set Other",
-            default=180.0,
-            min=0.1, max=180.0,
-            step=0.5,
-            precision=1
-            )
-    n: IntProperty(
-            name="",
-            description="Arc subdivision level",
-            default=4,
-            min=1, max=100,
-            step=1
-            )
-    flip: BoolProperty(
-            name="Flip",
-            description="If True, flip the side of the selected edges where the arcs are drawn",
-            default=False
-            )
-    invertAngle: BoolProperty(
-            name="Invert",
-            description="If True, uses an inverted angle to draw the arc (360 degrees - angle)",
-            default=False
-            )
-    fullCircles: BoolProperty(
-            name="Circles",
-            description="If True, uses an angle of 360 degrees to draw the arcs",
-            default=False
-            )
-    bothSides: BoolProperty(
-            name="Both sides",
-            description="If True, draw arcs on both sides of the selected edges",
-            default=False
-            )
-    drawArcCenters: BoolProperty(
-            name="Centers",
-            description="If True, draws a vertex for each spin center",
-            default=False
-            )
-    removeEdges: BoolProperty(
-            name="Edges",
-            description="If True removes the Original selected edges",
-            default=False
-            )
-    removeScaledEdges: BoolProperty(
-            name="Scaled edges",
-            description="If True removes the Scaled edges (not part of the arcs)",
-            default=False
-            )
-    connectArcWithEdge: BoolProperty(
-            name="Arc - Edge",
-            description="Connect Arcs to Edges",
-            default=False
-            )
-    connectArcs: BoolProperty(
-            name="Arcs",
-            description="Connect subsequent Arcs",
-            default=False
-            )
-    connectScaledAndBase: BoolProperty(
-            name="Scaled - Base Edge",
-            description="Connect Scaled to Base Edge",
-            default=False
-            )
-    connectArcsFlip: BoolProperty(
-            name="Flip Arcs",
-            description="Flip the connection of subsequent Arcs",
-            default=False
-            )
-    connectArcWithEdgeFlip: BoolProperty(
-            name="Flip Arc - Edge",
-            description="Flip the connection of the Arcs to Edges",
-            default=False
-            )
-    axisAngle: FloatProperty(
-            name="",
-            description="Rotate Arc around the perpendicular axis",
-            default=0.0,
-            min=-180.0, max=180.0,
-            step=0.5,
-            precision=1
-            )
-    edgeAngle: FloatProperty(
-            name="",
-            description="Rotate Arc around the Edge (Edge acts like as the axis)",
-            default=0.0,
-            min=-180.0, max=180.0,
-            step=0.5,
-            precision=1
-            )
-    offset: FloatProperty(
-            name="",
-            description="Offset Arc perpendicular the Edge",
-            default=0.0,
-            min=-1000000.0, max=1000000.0,
-            step=0.1,
-            precision=5
-            )
-    offset2: FloatProperty(
-            name="",
-            description="Offset Arc in parallel to the Edge",
-            default=0.0,
-            min=-1000000.0, max=1000000.0,
-            step=0.1,
-            precision=5
-            )
-    ellipticFactor: FloatProperty(
-            name="",
-            description="Make Arc elliptic",
-            default=0.0,
-            min=-1000000.0, max=1000000.0,
-            step=0.1,
-            precision=5
-            )
-    workModeItems = [("Normal", "Normal", ""), ("Reset", "Reset", "")]
-    workMode: EnumProperty(
-            items=workModeItems,
-            name="",
-            default='Normal',
-            description="Normal work with the current given parameters set by the user\n"
-                        "Reset - changes back the parameters to their default values"
-            )
-    entryModeItems = [("Radius", "Radius", ""), ("Angle", "Angle", "")]
-    entryMode: EnumProperty(
-            items=entryModeItems,
-            name="",
-            default='Angle',
-            description="Entry mode switch between Angle and Radius\n"
-                        "If Angle is selected, arc radius is calculated from it"
-            )
-    rotateCenterItems = [
-            ("Spin", "Spin", ""), ("V1", "V1", ""),
-            ("Edge", "Edge", ""), ("V2", "V2", "")
-            ]
-    rotateCenter: EnumProperty(
-            items=rotateCenterItems,
-            name="",
-            default='Edge',
-            description="Rotate center for spin axis rotate"
-            )
-    arcModeItems = [("FullEdgeArc", "Full", "Full"), ('HalfEdgeArc', "Half", "Half")]
-    arcMode: EnumProperty(
-            items=arcModeItems,
-            name="",
-            default='FullEdgeArc',
-            description="Arc mode - switch between Full and Half arcs"
-            )
-    angleItems = [
-            ('Other', "Other", "User defined angle"), ('180', "180", "HemiCircle (2 sides)"),
-            ('120', "120", "TriangleCircle (3 sides)"), ('90', "90", "QuadCircle (4 sides)"),
-            ('72', "72", "PentagonCircle (5 sides)"), ('60', "60", "HexagonCircle (6 sides)"),
-            ('45', "45", "OctagonCircle (8 sides)"), ('30', "30", "DodecagonCircle (12 sides)")
-            ]
-    angleEnum: EnumProperty(
-            items=angleItems,
-            name="",
-            default='180',
-            description="Presets prepare standard angles and calculate proper ray"
-            )
-    refItems = [('ORG', "Origin", "Use Origin Location"), ('CUR', "3D Cursor", "Use 3DCursor Location"),
-                ('EDG', "Edge", "Use Individual Edge Reference")]
-    referenceLocation: EnumProperty(
-            items=refItems,
-            name="",
-            default='ORG',
-            description="Reference location used to calculate initial centers of drawn arcs"
-            )
-    planeItems = [
-            (XY, "XY", "XY Plane (Z=0)"),
-            (YZ, "YZ", "YZ Plane (X=0)"),
-            (XZ, "XZ", "XZ Plane (Y=0)")
-            ]
-    planeEnum: EnumProperty(
-            items=planeItems,
-            name="",
-            default='XY',
-            description="Plane used to calculate spin plane of drawn arcs"
-            )
-    edgeScaleCenterItems = [
-            ('V1', "V1", "v1 - First Edge's Vertex"),
-            ('CENTER', "Center", "Center of the Edge"),
-            ('V2', "V2", "v2 - Second Edge's Vertex")
-            ]
-    edgeScaleCenterEnum: EnumProperty(
-            items=edgeScaleCenterItems,
-            name="Edge scale center",
-            default='CENTER',
-            description="Center used for scaling the initial edge"
-            )
-
-    calc = CalculationHelper()
-    sel = SelectionHelper()
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH' and
-                obj.mode == 'EDIT')
-
-    def prepareMesh(self, context):
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bpy.ops.object.mode_set(mode='EDIT')
-
-        mesh = context.view_layer.objects.active.data
-        bm = bmesh.new()
-        bm.from_mesh(mesh)
-
-        edges = [ele for ele in bm.edges if ele.select]
-        return edges, mesh, bm
-
-    def prepareParameters(self):
-        parameters = {"a": "a"}
-        parameters["arcMode"] = self.arcMode
-        parameters["edgeScaleFactor"] = self.edgeScaleFactor
-        parameters["edgeScaleCenterEnum"] = self.edgeScaleCenterEnum
-        parameters["plane"] = self.planeEnum
-        parameters["radius"] = self.r
-        parameters["angle"] = self.a
-        parameters["segments"] = self.n
-        parameters["fullCircles"] = self.fullCircles
-        parameters["invertAngle"] = self.invertAngle
-        parameters["bothSides"] = self.bothSides
-        parameters["angleEnum"] = self.angleEnum
-        parameters["entryMode"] = self.entryMode
-        parameters["workMode"] = self.workMode
-        parameters["refObject"] = self.referenceLocation
-        parameters["flip"] = self.flip
-        parameters["drawArcCenters"] = self.drawArcCenters
-        parameters["removeEdges"] = self.removeEdges
-        parameters["removeScaledEdges"] = self.removeScaledEdges
-        parameters["connectArcWithEdge"] = self.connectArcWithEdge
-        parameters["connectScaledAndBase"] = self.connectScaledAndBase
-        parameters["connectArcs"] = self.connectArcs
-        parameters["connectArcsFlip"] = self.connectArcsFlip
-        parameters["connectArcWithEdgeFlip"] = self.connectArcWithEdgeFlip
-        parameters["axisAngle"] = self.axisAngle
-        parameters["edgeAngle"] = self.edgeAngle
-        parameters["offset"] = self.offset
-        parameters["offset2"] = self.offset2
-        parameters["ellipticFactor"] = self.ellipticFactor
-        parameters["rotateCenter"] = self.rotateCenter
-        return parameters
-
-    def draw(self, context):
-        layout = self.layout
-        box = layout.box()
-        uiPercentage = 0.333
-
-        self.addEnumParameterToUI(box, False, uiPercentage, 'Mode:', 'workMode')
-        self.addEnumParameterToUI(box, False, uiPercentage, 'Plane:', 'planeEnum')
-        self.addEnumParameterToUI(box, False, uiPercentage, 'Reference:', 'referenceLocation')
-
-        box = layout.box()
-        self.addEnumParameterToUI(box, False, uiPercentage, 'Scale base:', 'edgeScaleCenterEnum')
-        self.addParameterToUI(box, False, uiPercentage, 'Scale factor:', 'edgeScaleFactor')
-
-        box = layout.box()
-        self.addEnumParameterToUI(box, False, uiPercentage, 'Entry mode:', 'entryMode')
-
-        row = box.row(align=False)
-        row.prop(self, 'angleEnum', expand=True, text="Angle presets")
-
-        disable_a = bool(self.entryMode == 'Angle' and self.angleEnum == 'Other')
-        disable_r = bool(self.entryMode == 'Radius')
-
-        self.addParameterToUI(box, False, uiPercentage, 'Angle:', 'a', disable_a)
-        self.addParameterToUI(box, False, uiPercentage, 'Radius:', 'r', disable_r)
-        self.addParameterToUI(box, False, uiPercentage, 'Segments:', 'n')
-
-        box = layout.box()
-        self.addCheckboxToUI(box, True, 'Options:', 'flip', 'invertAngle')
-        self.addCheckboxToUI(box, True, '', 'bothSides', 'fullCircles')
-        self.addCheckboxToUI(box, True, '', 'drawArcCenters')
-
-        box = layout.box()
-        self.addCheckboxToUI(box, True, 'Remove:', 'removeEdges', 'removeScaledEdges')
-
-        box = layout.box()
-        self.addCheckboxToUI(box, True, 'Connect:', 'connectArcs', 'connectArcsFlip')
-        self.addCheckboxToUI(box, True, '', 'connectArcWithEdge', 'connectArcWithEdgeFlip')
-        self.addCheckboxToUI(box, True, '', 'connectScaledAndBase')
-
-        box = layout.box()
-        self.addParameterToUI(box, False, uiPercentage, 'Orhto offset:', 'offset')
-        self.addParameterToUI(box, False, uiPercentage, 'Parallel offset:', 'offset2')
-
-        box = layout.box()
-        self.addParameterToUI(box, False, uiPercentage, 'Edge rotate :', 'edgeAngle')
-        self.addEnumParameterToUI(box, False, uiPercentage, 'Axis rotate center:', 'rotateCenter')
-        self.addParameterToUI(box, False, uiPercentage, 'Axis rotate:', 'axisAngle')
-
-        box = layout.box()
-        self.addParameterToUI(box, False, uiPercentage, 'Elliptic factor:', 'ellipticFactor')
-
-    def addParameterToUI(self, layout, alignment, percent, label, properties, disable=True):
-        row = layout.row(align=alignment)
-        split = row.split(factor=percent)
-        col = split.column()
-
-        col.label(label)
-        col2 = split.column()
-        row = col2.row(align=alignment)
-        row.enabled = disable
-        row.prop(self, properties)
-
-    def addCheckboxToUI(self, layout, alignment, label, property1, property2=None):
-        if label not in (""):
-            row = layout.row()
-            row.label(label)
-        row2 = layout.row(align=alignment)
-        if property2:
-            split = row2.split(factor=0.5)
-            split.prop(self, property1, toggle=True)
-            split.prop(self, property2, toggle=True)
-        else:
-            row2.prop(self, property1, toggle=True)
-            layout.separator()
-
-    def addEnumParameterToUI(self, layout, alignment, percent, label, properties):
-        row = layout.row(align=alignment)
-        split = row.split(factor=percent)
-        col = split.column()
-
-        col.label(label)
-        col2 = split.column()
-        row = col2.row(align=alignment)
-        row.prop(self, properties, expand=True, text="a")
-
-    def execute(self, context):
-
-        edges, mesh, bm = self.prepareMesh(context)
-        parameters = self.prepareParameters()
-
-        self.resetValues(parameters["workMode"])
-
-        self.obj = context.view_layer.objects.active
-        scaledEdges = self.scaleDuplicatedEdges(bm, edges, parameters)
-
-        if len(scaledEdges) > 0:
-            self.roundifyEdges(scaledEdges, parameters, bm, mesh)
-
-            if parameters["connectScaledAndBase"]:
-                self.connectScaledEdgesWithBaseEdge(scaledEdges, edges, bm, mesh)
-
-            self.sel.refreshMesh(bm, mesh)
-            self.selectEdgesAfterRoundifier(context, scaledEdges)
-        else:
-            debugPrintNew(True, "No edges selected!")
-
-        if parameters["removeEdges"]:
-            bmesh.ops.delete(bm, geom=edges, context=2)
-
-        if parameters["removeScaledEdges"] and self.edgeScaleFactor != 1.0:
-            bmesh.ops.delete(bm, geom=scaledEdges, context=2)
-
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bm.to_mesh(mesh)
-        bpy.ops.object.mode_set(mode='EDIT')
-        bpy.ops.mesh.select_all(action='SELECT')
-        bpy.ops.mesh.remove_doubles()
-
-        bm.free()
-
-        return {'FINISHED'}
-
-    def resetValues(self, workMode):
-        if workMode == "Reset":
-            self.setAllParamsToDefaults()
-
-    def setAllParamsToDefaults(self):
-        try:
-            self.edgeScaleFactor = 1.0
-            self.r = 1
-            self.a = 180.0
-            self.n = 4
-            self.flip = False
-            self.invertAngle = False
-            self.fullCircles = False
-            self.bothSides = False
-            self.drawArcCenters = False
-            self.removeEdges = False
-            self.removeScaledEdges = False
-
-            self.connectArcWithEdge = False
-            self.connectArcs = False
-            self.connectScaledAndBase = False
-            self.connectArcsFlip = False
-            self.connectArcWithEdgeFlip = False
-
-            self.axisAngle = 0.0
-            self.edgeAngle = 0.0
-            self.offset = 0.0
-            self.offset2 = 0.0
-            self.ellipticFactor = 0.0
-
-            self.workMode = 'Normal'
-            self.entryMode = 'Angle'
-            self.angleEnum = '180'
-            self.referenceLocation = 'ORG'
-            self.planeEnum = 'XY'
-            self.edgeScaleCenterEnum = 'CENTER'
-            self.rotateCenter = 'Edge'
-
-            self.report({'INFO'}, "The parameters have been reset to default values")
-        except Exception as e:
-            self.report({'WARNING'}, "The parameters could not be reset")
-            debugPrintNew(True, "\n[setAllParamsToDefaults]\n parameter reset error\n" + e)
-
-    def scaleDuplicatedEdges(self, bm, edges, parameters):
-        scaleCenter = parameters["edgeScaleCenterEnum"]
-        factor = parameters["edgeScaleFactor"]
-        # this code is based on Zeffi's answer to my question
-        duplicateEdges = []
-        if factor == 1:
-            duplicateEdges = edges
-        else:
-            for e in edges:
-                v1 = e.verts[0].co
-                v2 = e.verts[1].co
-                origin = None
-                if scaleCenter == 'CENTER':
-                    origin = (v1 + v2) * 0.5
-                elif scaleCenter == 'V1':
-                    origin = v1
-                elif scaleCenter == 'V2':
-                    origin = v2
-
-                bmv1 = bm.verts.new(((v1 - origin) * factor) + origin)
-                bmv2 = bm.verts.new(((v2 - origin) * factor) + origin)
-                bme = bm.edges.new([bmv1, bmv2])
-                duplicateEdges.append(bme)
-        return duplicateEdges
-
-    def roundifyEdges(self, edges, parameters, bm, mesh):
-        arcs = []
-        for e in edges:
-            arcVerts = self.roundify(e, parameters, bm, mesh)
-            arcs.append(arcVerts)
-
-        if parameters["connectArcs"]:
-            self.connectArcsTogether(arcs, bm, mesh, parameters)
-
-    def getNormalizedEdgeVector(self, edge):
-        V1 = edge.verts[0].co
-        V2 = edge.verts[1].co
-        edgeVector = V2 - V1
-        normEdge = edgeVector.normalized()
-        return normEdge
-
-    def getEdgePerpendicularVector(self, edge, plane):
-        normEdge = self.getNormalizedEdgeVector(edge)
-
-        edgePerpendicularVector = Vector((normEdge[1], -normEdge[0], 0))
-        if plane == YZ:
-            edgePerpendicularVector = Vector((0, normEdge[2], -normEdge[1]))
-        if plane == XZ:
-            edgePerpendicularVector = Vector((normEdge[2], 0, -normEdge[0]))
-        return edgePerpendicularVector
-
-    def getEdgeInfo(self, edge):
-        V1 = edge.verts[0].co
-        V2 = edge.verts[1].co
-        edgeVector = V2 - V1
-        edgeLength = edgeVector.length
-        edgeCenter = (V2 + V1) * 0.5
-        return V1, V2, edgeVector, edgeLength, edgeCenter
-
-    def roundify(self, edge, parameters, bm, mesh):
-        V1, V2, edgeVector, edgeLength, edgeCenter = self.getEdgeInfo(edge)
-        if self.skipThisEdge(V1, V2, parameters["plane"]):
-            return
-
-        roundifyParams = None
-        arcVerts = None
-        roundifyParams = self.calculateRoundifyParams(edge, parameters, bm, mesh)
-        if roundifyParams is None:
-            return
-
-        arcVerts = self.spinAndPostprocess(edge, parameters, bm, mesh, edgeCenter, roundifyParams)
-        return arcVerts
-
-    def spinAndPostprocess(self, edge, parameters, bm, mesh, edgeCenter, roundifyParams):
-        spinnedVerts, roundifyParamsUpdated = self.drawSpin(
-                                                edge, edgeCenter,
-                                                roundifyParams,
-                                                parameters, bm, mesh
-                                                )
-        postProcessedArcVerts = self.arcPostprocessing(
-                                                edge, parameters, bm, mesh,
-                                                roundifyParamsUpdated,
-                                                spinnedVerts, edgeCenter
-                                                )
-        return postProcessedArcVerts
-
-    def rotateArcAroundEdge(self, bm, mesh, arcVerts, parameters):
-        angle = parameters["edgeAngle"]
-        if angle != 0:
-            self.arc_rotator(arcVerts, angle, parameters)
-
-    # arc_rotator method was created by PKHG, I (komi3D) adjusted it to fit the rest
-    def arc_rotator(self, arcVerts, extra_rotation, parameters):
-        bpy.ops.object.mode_set(mode='OBJECT')
-        old_location = self.obj.location.copy()
-        bpy.ops.transform.translate(
-            value=-old_location,
-            constraint_axis=(False, False, False),
-            orient_type='GLOBAL',
-            mirror=False,
-            use_proportional_edit=False,
-        )
-        bpy.ops.object.mode_set(mode='EDIT')
-        adjust_matrix = self.obj.matrix_parent_inverse
-        bm = bmesh.from_edit_mesh(self.obj.data)
-        lastVert = len(arcVerts) - 1
-        if parameters["drawArcCenters"]:
-            lastVert = lastVert - 1  # center gets added as last vert of arc
-        v0_old = adjust_matrix * arcVerts[0].co.copy()
-
-        # PKHG>INFO move if necessary v0 to origin such that the axis gos through origin and v1
-        if v0_old != Vector((0, 0, 0)):
-            for i, ele in enumerate(arcVerts):
-                arcVerts[i].co += - v0_old
-
-        axis = arcVerts[0].co - arcVerts[lastVert].co
-        a_mat = Quaternion(axis, radians(extra_rotation)).normalized().to_matrix()
-
-        for ele in arcVerts:
-            ele.co = a_mat * ele.co
-
-        # PKHG>INFO move back if needed
-        if v0_old != Vector((0, 0, 0)):
-            for i, ele in enumerate(arcVerts):
-                arcVerts[i].co += + v0_old
-
-        bpy.ops.object.mode_set(mode='OBJECT')
-        # PKHG>INFO move origin object back print("old location = " , old_location)
-        bpy.ops.transform.translate(
-            value=old_location,
-            constraint_axis=(False, False, False),
-            orient_type='GLOBAL',
-            mirror=False,
-            use_proportional_edit=False,
-        )
-        bpy.ops.object.mode_set(mode='EDIT')
-
-    def makeElliptic(self, bm, mesh, arcVertices, parameters):
-        if parameters["ellipticFactor"] != 0:  # if 0 then nothing has to be done
-            lastVert = len(arcVertices) - 1
-            if parameters["drawArcCenters"]:
-                lastVert = lastVert - 1  # center gets added as last vert of arc
-            v0co = arcVertices[0].co
-            v1co = arcVertices[lastVert].co
-
-            for vertex in arcVertices:  # range(len(res_list)):
-                # PKHg>INFO compute the base on the edge  of the height-vector
-                top = vertex.co  # res_list[nr].co
-                t = 0
-                if v1co - v0co != 0:
-                    t = (v1co - v0co).dot(top - v0co) / (v1co - v0co).length ** 2
-                h_bottom = v0co + t * (v1co - v0co)
-                height = (h_bottom - top)
-                vertex.co = top + parameters["ellipticFactor"] * height
-
-        return arcVertices
-
-    def arcPostprocessing(self, edge, parameters, bm, mesh, roundifyParams, spinnedVerts, edgeCenter):
-        [chosenSpinCenter, otherSpinCenter, spinAxis, angle, steps, refObjectLocation] = roundifyParams
-        rotatedVerts = []
-        if parameters["rotateCenter"] == 'Edge':
-            rotatedVerts = self.rotateArcAroundSpinAxis(
-                                bm, mesh, spinnedVerts, parameters, edgeCenter
-                                )
-        elif parameters["rotateCenter"] == 'Spin':
-            rotatedVerts = self.rotateArcAroundSpinAxis(
-                                bm, mesh, spinnedVerts, parameters, chosenSpinCenter
-                                )
-        elif parameters["rotateCenter"] == 'V1':
-            rotatedVerts = self.rotateArcAroundSpinAxis(
-                                bm, mesh, spinnedVerts, parameters, edge.verts[0].co
-                                )
-        elif parameters["rotateCenter"] == 'V2':
-            rotatedVerts = self.rotateArcAroundSpinAxis(
-                                bm, mesh, spinnedVerts, parameters, edge.verts[1].co
-                                )
-
-        offsetVerts = self.offsetArcPerpendicular(
-                                bm, mesh, rotatedVerts, edge, parameters
-                                )
-        offsetVerts2 = self.offsetArcParallel(
-                                bm, mesh, offsetVerts, edge, parameters
-                                )
-        ellipticVerts = self.makeElliptic(
-                                bm, mesh, offsetVerts2, parameters
-                                )
-        self.rotateArcAroundEdge(bm, mesh, ellipticVerts, parameters)
-
-        if parameters["connectArcWithEdge"]:
-            self.connectArcTogetherWithEdge(
-                                edge, offsetVerts2, bm, mesh, parameters
-                                )
-        return offsetVerts2
-
-    def connectArcTogetherWithEdge(self, edge, arcVertices, bm, mesh, parameters):
-        lastVert = len(arcVertices) - 1
-        if parameters["drawArcCenters"]:
-            lastVert = lastVert - 1  # center gets added as last vert of arc
-        edgeV1 = edge.verts[0].co
-        edgeV2 = edge.verts[1].co
-        arcV1 = arcVertices[0].co
-        arcV2 = arcVertices[lastVert].co
-
-        bmv1 = bm.verts.new(edgeV1)
-        bmv2 = bm.verts.new(arcV1)
-
-        bmv3 = bm.verts.new(edgeV2)
-        bmv4 = bm.verts.new(arcV2)
-
-        if parameters["connectArcWithEdgeFlip"] is False:
-            bme = bm.edges.new([bmv1, bmv2])
-            bme2 = bm.edges.new([bmv3, bmv4])
-        else:
-            bme = bm.edges.new([bmv1, bmv4])
-            bme2 = bm.edges.new([bmv3, bmv2])
-        self.sel.refreshMesh(bm, mesh)
-
-    def connectScaledEdgesWithBaseEdge(self, scaledEdges, baseEdges, bm, mesh):
-        for i in range(0, len(scaledEdges)):
-            scaledEdgeV1 = scaledEdges[i].verts[0].co
-            baseEdgeV1 = baseEdges[i].verts[0].co
-            scaledEdgeV2 = scaledEdges[i].verts[1].co
-            baseEdgeV2 = baseEdges[i].verts[1].co
-
-            bmv1 = bm.verts.new(baseEdgeV1)
-            bmv2 = bm.verts.new(scaledEdgeV1)
-            bme = bm.edges.new([bmv1, bmv2])
-
-            bmv3 = bm.verts.new(scaledEdgeV2)
-            bmv4 = bm.verts.new(baseEdgeV2)
-            bme = bm.edges.new([bmv3, bmv4])
-        self.sel.refreshMesh(bm, mesh)
-
-    def connectArcsTogether(self, arcs, bm, mesh, parameters):
-        for i in range(0, len(arcs) - 1):
-            # in case on XZ or YZ there are no arcs drawn
-            if arcs[i] is None or arcs[i + 1] is None:
-                return
-
-            lastVert = len(arcs[i]) - 1
-            if parameters["drawArcCenters"]:
-                lastVert = lastVert - 1  # center gets added as last vert of arc
-            # take last vert of arc i and first vert of arc i+1
-
-            V1 = arcs[i][lastVert].co
-            V2 = arcs[i + 1][0].co
-
-            if parameters["connectArcsFlip"]:
-                V1 = arcs[i][0].co
-                V2 = arcs[i + 1][lastVert].co
-
-            bmv1 = bm.verts.new(V1)
-            bmv2 = bm.verts.new(V2)
-            bme = bm.edges.new([bmv1, bmv2])
-
-        # connect last arc and first one
-        lastArcId = len(arcs) - 1
-        lastVertIdOfLastArc = len(arcs[lastArcId]) - 1
-        if parameters["drawArcCenters"]:
-            # center gets added as last vert of arc
-            lastVertIdOfLastArc = lastVertIdOfLastArc - 1
-
-        V1 = arcs[lastArcId][lastVertIdOfLastArc].co
-        V2 = arcs[0][0].co
-        if parameters["connectArcsFlip"]:
-            V1 = arcs[lastArcId][0].co
-            V2 = arcs[0][lastVertIdOfLastArc].co
-
-        bmv1 = bm.verts.new(V1)
-        bmv2 = bm.verts.new(V2)
-        bme = bm.edges.new([bmv1, bmv2])
-
-        self.sel.refreshMesh(bm, mesh)
-
-    def offsetArcPerpendicular(self, bm, mesh, Verts, edge, parameters):
-        perpendicularVector = self.getEdgePerpendicularVector(edge, parameters["plane"])
-        offset = parameters["offset"]
-        translation = offset * perpendicularVector
-
-        try:
-            bmesh.ops.translate(bm, verts=Verts, vec=translation)
-        except ValueError:
-            print("[Edge Roundifier]: Perpendicular translate value error - "
-                  "multiple vertices in list - try unchecking 'Centers'")
-
-        indexes = [v.index for v in Verts]
-        self.sel.refreshMesh(bm, mesh)
-        offsetVertices = [bm.verts[i] for i in indexes]
-        return offsetVertices
-
-    def offsetArcParallel(self, bm, mesh, Verts, edge, parameters):
-        edgeVector = self.getNormalizedEdgeVector(edge)
-        offset = parameters["offset2"]
-        translation = offset * edgeVector
-
-        try:
-            bmesh.ops.translate(bm, verts=Verts, vec=translation)
-        except ValueError:
-            print("[Edge Roundifier]: Parallel translate value error - "
-                  "multiple vertices in list - try unchecking 'Centers'")
-
-        indexes = [v.index for v in Verts]
-        self.sel.refreshMesh(bm, mesh)
-        offsetVertices = [bm.verts[i] for i in indexes]
-        return offsetVertices
-
-    def skipThisEdge(self, V1, V2, plane):
-        # Check If It is possible to spin selected verts on this plane if not exit roundifier
-        if(plane == XY):
-            if (V1[0] == V2[0] and V1[1] == V2[1]):
-                return True
-        elif(plane == YZ):
-            if (V1[1] == V2[1] and V1[2] == V2[2]):
-                return True
-        elif(plane == XZ):
-            if (V1[0] == V2[0] and V1[2] == V2[2]):
-                return True
-        return False
-
-    def calculateRoundifyParams(self, edge, parameters, bm, mesh):
-        # Because all data from mesh is in local coordinates
-        # and spin operator works on global coordinates
-        # We first need to translate all input data by vector equal
-        # to origin position and then perform calculations
-        # At least that is my understanding :) <komi3D>
-
-        # V1 V2 stores Local Coordinates
-        V1, V2, edgeVector, edgeLength, edgeCenter = self.getEdgeInfo(edge)
-
-        debugPrintNew(d_Plane, "PLANE: " + parameters["plane"])
-        lineAB = self.calc.getLineCoefficientsPerpendicularToVectorInPoint(
-                                                edgeCenter, edgeVector,
-                                                parameters["plane"]
-                                                )
-        circleMidPoint = V1
-        circleMidPointOnPlane = self.calc.getCircleMidPointOnPlane(
-                                                V1, parameters["plane"]
-                                                )
-        radius = parameters["radius"]
-
-        angle = 0
-        if (parameters["entryMode"] == 'Angle'):
-            if (parameters["angleEnum"] != 'Other'):
-                radius, angle = self.CalculateRadiusAndAngleForAnglePresets(
-                                                parameters["angleEnum"], radius,
-                                                angle, edgeLength
-                                                )
-            else:
-                radius, angle = self.CalculateRadiusAndAngle(edgeLength)
-        debugPrintNew(d_Radius_Angle, "RADIUS = " + str(radius) + "  ANGLE = " + str(angle))
-        roots = None
-        if angle != pi:  # mode other than 180
-            if lineAB is None:
-                roots = self.calc.getLineCircleIntersectionsWhenXPerpendicular(
-                                                edgeCenter, circleMidPointOnPlane,
-                                                radius, parameters["plane"]
-                                                )
-            else:
-                roots = self.calc.getLineCircleIntersections(
-                                                lineAB, circleMidPointOnPlane, radius
-                                                )
-
-            if roots is None:
-                debugPrintNew(True,
-                             "[Edge Roundifier]: No centers were found. Change radius to higher value")
-                return None
-            roots = self.addMissingCoordinate(roots, V1, parameters["plane"])  # adds X, Y or Z coordinate
-        else:
-            roots = [edgeCenter, edgeCenter]
-        debugPrintNew(d_Roots, "roots=" + str(roots))
-
-        refObjectLocation = None
-        objectLocation = bpy.context.active_object.location  # Origin Location
-
-        if parameters["refObject"] == "ORG":
-            refObjectLocation = [0, 0, 0]
-        elif parameters["refObject"] == "CUR":
-            refObjectLocation = bpy.context.scene.cursor.location - objectLocation
-        else:
-            refObjectLocation = self.calc.getEdgeReference(edge, edgeCenter, parameters["plane"])
-
-        debugPrintNew(d_RefObject, parameters["refObject"], refObjectLocation)
-        chosenSpinCenter, otherSpinCenter = self.getSpinCenterClosestToRefCenter(
-                                                            refObjectLocation, roots
-                                                            )
-
-        if (parameters["entryMode"] == "Radius"):
-            halfAngle = self.calc.getAngle(edgeCenter, chosenSpinCenter, circleMidPoint)
-            angle = 2 * halfAngle[0]  # in radians
-            self.a = degrees(angle)   # in degrees
-
-        spinAxis = self.getSpinAxis(parameters["plane"])
-        steps = parameters["segments"]
-        angle = -angle  # rotate clockwise by default
-
-        return [chosenSpinCenter, otherSpinCenter, spinAxis, angle, steps, refObjectLocation]
-
-    def drawSpin(self, edge, edgeCenter, roundifyParams, parameters, bm, mesh):
-        [chosenSpinCenter, otherSpinCenter, spinAxis, angle, steps, refObjectLocation] = roundifyParams
-
-        v0org, v1org = (edge.verts[0], edge.verts[1])
-
-        if parameters["flip"]:
-            angle = -angle
-            spinCenterTemp = chosenSpinCenter
-            chosenSpinCenter = otherSpinCenter
-            otherSpinCenter = spinCenterTemp
-
-        if(parameters["invertAngle"]):
-            if angle < 0:
-                angle = two_pi + angle
-            elif angle > 0:
-                angle = -two_pi + angle
-            else:
-                angle = two_pi
-
-        if(parameters["fullCircles"]):
-            angle = two_pi
-
-        v0 = bm.verts.new(v0org.co)
-
-        result = bmesh.ops.spin(
-                        bm, geom=[v0], cent=chosenSpinCenter, axis=spinAxis,
-                        angle=angle, steps=steps, use_duplicate=False
-                        )
-
-        # it seems there is something wrong with last index of this spin
-        # I need to calculate the last index manually here
-        vertsLength = len(bm.verts)
-        bm.verts.ensure_lookup_table()
-        lastVertIndex = bm.verts[vertsLength - 1].index
-        lastSpinVertIndices = self.getLastSpinVertIndices(steps, lastVertIndex)
-
-        self.sel.refreshMesh(bm, mesh)
-
-        alternativeLastSpinVertIndices = []
-        bothSpinVertices = []
-        spinVertices = []
-        alternate = False
-
-        if ((angle == pi or angle == -pi) and not parameters["bothSides"]):
-
-            midVertexIndex = lastVertIndex - round(steps / 2)
-            bm.verts.ensure_lookup_table()
-            midVert = bm.verts[midVertexIndex].co
-
-            midVertexDistance = (Vector(refObjectLocation) - Vector(midVert)).length
-            midEdgeDistance = (Vector(refObjectLocation) - Vector(edgeCenter)).length
-
-            if ((parameters["invertAngle"]) or (parameters["flip"])):
-                if (midVertexDistance > midEdgeDistance):
-                    alternativeLastSpinVertIndices = self.alternateSpin(
-                                                        bm, mesh, angle, chosenSpinCenter,
-                                                        spinAxis, steps, v0, v1org, lastSpinVertIndices
-                                                        )
-            else:
-                if (midVertexDistance < midEdgeDistance):
-                    alternativeLastSpinVertIndices = self.alternateSpin(
-                                                        bm, mesh, angle, chosenSpinCenter,
-                                                        spinAxis, steps, v0, v1org, lastSpinVertIndices
-                                                        )
-        elif (angle != two_pi):  # to allow full circles
-            if (result['geom_last'][0].co - v1org.co).length > SPIN_END_THRESHOLD:
-                alternativeLastSpinVertIndices = self.alternateSpin(
-                                                        bm, mesh, angle, chosenSpinCenter,
-                                                        spinAxis, steps, v0, v1org, lastSpinVertIndices
-                                                        )
-                alternate = True
-
-        self.sel.refreshMesh(bm, mesh)
-        if alternativeLastSpinVertIndices != []:
-            lastSpinVertIndices = alternativeLastSpinVertIndices
-
-        if lastSpinVertIndices.stop <= len(bm.verts):  # make sure arc was added to bmesh
-            spinVertices = [bm.verts[i] for i in lastSpinVertIndices]
-            if alternativeLastSpinVertIndices != []:
-                spinVertices = spinVertices + [v0]
-            else:
-                spinVertices = [v0] + spinVertices
-
-        if (parameters["bothSides"]):
-            # do some more testing here!!!
-            if (angle == pi or angle == -pi):
-                alternativeLastSpinVertIndices = self.alternateSpinNoDelete(
-                                                        bm, mesh, -angle, chosenSpinCenter,
-                                                        spinAxis, steps, v0, v1org, []
-                                                        )
-            elif alternate:
-                alternativeLastSpinVertIndices = self.alternateSpinNoDelete(
-                                                        bm, mesh, angle, otherSpinCenter,
-                                                        spinAxis, steps, v0, v1org, []
-                                                        )
-            elif not alternate:
-                alternativeLastSpinVertIndices = self.alternateSpinNoDelete(
-                                                        bm, mesh, -angle, otherSpinCenter,
-                                                        spinAxis, steps, v0, v1org, []
-                                                        )
-            bothSpinVertices = [bm.verts[i] for i in lastSpinVertIndices]
-            alternativeSpinVertices = [bm.verts[i] for i in alternativeLastSpinVertIndices]
-            bothSpinVertices = [v0] + bothSpinVertices + alternativeSpinVertices
-            spinVertices = bothSpinVertices
-
-        if (parameters["fullCircles"]):
-            v1 = bm.verts.new(v1org.co)
-            spinVertices = spinVertices + [v1]
-
-        if (parameters['drawArcCenters']):
-            centerVert = bm.verts.new(chosenSpinCenter)
-            spinVertices.append(centerVert)
-
-        return spinVertices, [chosenSpinCenter, otherSpinCenter, spinAxis, angle, steps, refObjectLocation]
-
-    def deleteSpinVertices(self, bm, mesh, lastSpinVertIndices):
-        verticesForDeletion = []
-        bm.verts.ensure_lookup_table()
-        for i in lastSpinVertIndices:
-            vi = bm.verts[i]
-            vi.select = True
-            debugPrintNew(True, str(i) + ") " + str(vi))
-            verticesForDeletion.append(vi)
-
-        bmesh.ops.delete(bm, geom=verticesForDeletion, context=1)
-        bmesh.update_edit_mesh(mesh, True)
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bpy.ops.object.mode_set(mode='EDIT')
-
-    def alternateSpinNoDelete(self, bm, mesh, angle, chosenSpinCenter,
-                              spinAxis, steps, v0, v1org, lastSpinVertIndices):
-        v0prim = v0
-
-        result2 = bmesh.ops.spin(bm, geom=[v0prim], cent=chosenSpinCenter, axis=spinAxis,
-                                 angle=angle, steps=steps, use_duplicate=False)
-        vertsLength = len(bm.verts)
-        bm.verts.ensure_lookup_table()
-        lastVertIndex2 = bm.verts[vertsLength - 1].index
-
-        lastSpinVertIndices2 = self.getLastSpinVertIndices(steps, lastVertIndex2)
-        return lastSpinVertIndices2
-
-    def alternateSpin(self, bm, mesh, angle, chosenSpinCenter,
-                      spinAxis, steps, v0, v1org, lastSpinVertIndices):
-
-        self.deleteSpinVertices(bm, mesh, lastSpinVertIndices)
-        v0prim = v0
-
-        result2 = bmesh.ops.spin(
-                        bm, geom=[v0prim], cent=chosenSpinCenter, axis=spinAxis,
-                        angle=-angle, steps=steps, use_duplicate=False
-                        )
-        # it seems there is something wrong with last index of this spin
-        # I need to calculate the last index manually here
-        vertsLength = len(bm.verts)
-        bm.verts.ensure_lookup_table()
-        lastVertIndex2 = bm.verts[vertsLength - 1].index
-
-        lastSpinVertIndices2 = self.getLastSpinVertIndices(steps, lastVertIndex2)
-        # second spin also does not hit the v1org
-        if (result2['geom_last'][0].co - v1org.co).length > SPIN_END_THRESHOLD:
-
-            self.deleteSpinVertices(bm, mesh, lastSpinVertIndices2)
-            self.deleteSpinVertices(bm, mesh, range(v0.index, v0.index + 1))
-            return []
-        else:
-            return lastSpinVertIndices2
-
-    def getLastSpinVertIndices(self, steps, lastVertIndex):
-        arcfirstVertexIndex = lastVertIndex - steps + 1
-        lastSpinVertIndices = range(arcfirstVertexIndex, lastVertIndex + 1)
-        return lastSpinVertIndices
-
-    def rotateArcAroundSpinAxis(self, bm, mesh, vertices, parameters, edgeCenter):
-        axisAngle = parameters["axisAngle"]
-        plane = parameters["plane"]
-        # compensate rotation center
-        objectLocation = bpy.context.active_object.location
-        center = objectLocation + edgeCenter
-
-        rot = Euler((0.0, 0.0, radians(axisAngle)), 'XYZ').to_matrix()
-        if plane == YZ:
-            rot = Euler((radians(axisAngle), 0.0, 0.0), 'XYZ').to_matrix()
-        if plane == XZ:
-            rot = Euler((0.0, radians(axisAngle), 0.0), 'XYZ').to_matrix()
-
-        indexes = [v.index for v in vertices]
-
-        bmesh.ops.rotate(
-            bm,
-            cent=center,
-            matrix=rot,
-            verts=vertices,
-            space=bpy.context.edit_object.matrix_world
-        )
-        self.sel.refreshMesh(bm, mesh)
-        bm.verts.ensure_lookup_table()
-        rotatedVertices = [bm.verts[i] for i in indexes]
-
-        return rotatedVertices
-
-    def CalculateRadiusAndAngle(self, edgeLength):
-        degAngle = self.a
-        angle = radians(degAngle)
-        self.r = radius = edgeLength / (2 * sin(angle / 2))
-        return radius, angle
-
-    def CalculateRadiusAndAngleForAnglePresets(self, angleEnum, initR, initA, edgeLength):
-        radius = initR
-        angle = initA
-        try:
-            # Note - define an integer string in the angleEnum
-            angle_convert = int(angleEnum)
-            self.a = angle_convert
-        except:
-            self.a = 180  # fallback
-            debugPrintNew(True,
-                          "CalculateRadiusAndAngleForAnglePresets problem with int conversion")
-
-        return self.CalculateRadiusAndAngle(edgeLength)
-
-    def getSpinCenterClosestToRefCenter(self, objLocation, roots):
-        root0Distance = (Vector(objLocation) - Vector(roots[0])).length
-        root1Distance = (Vector(objLocation) - Vector(roots[1])).length
-
-        chosenId = 0
-        rejectedId = 1
-        if (root0Distance > root1Distance):
-            chosenId = 1
-            rejectedId = 0
-        return roots[chosenId], roots[rejectedId]
-
-    def addMissingCoordinate(self, roots, startVertex, plane):
-        if roots is not None:
-            a, b = roots[0]
-            c, d = roots[1]
-            if plane == XY:
-                roots[0] = Vector((a, b, startVertex[2]))
-                roots[1] = Vector((c, d, startVertex[2]))
-            if plane == YZ:
-                roots[0] = Vector((startVertex[0], a, b))
-                roots[1] = Vector((startVertex[0], c, d))
-            if plane == XZ:
-                roots[0] = Vector((a, startVertex[1], b))
-                roots[1] = Vector((c, startVertex[1], d))
-        return roots
-
-    def selectEdgesAfterRoundifier(self, context, edges):
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bpy.ops.object.mode_set(mode='EDIT')
-        mesh = context.view_layer.objects.active.data
-        bmnew = bmesh.new()
-        bmnew.from_mesh(mesh)
-
-        self.deselectEdges(bmnew)
-        for selectedEdge in edges:
-            for e in bmnew.edges:
-                if (e.verts[0].co - selectedEdge.verts[0].co).length <= self.threshold \
-                   and (e.verts[1].co - selectedEdge.verts[1].co).length <= self.threshold:
-                    e.select_set(True)
-
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bmnew.to_mesh(mesh)
-        bmnew.free()
-        bpy.ops.object.mode_set(mode='EDIT')
-
-    def deselectEdges(self, bm):
-        for edge in bm.edges:
-            edge.select_set(False)
-
-    def getSpinAxis(self, plane):
-        axis = (0, 0, 1)
-        if plane == YZ:
-            axis = (1, 0, 0)
-        if plane == XZ:
-            axis = (0, 1, 0)
-        return axis
-
-
-def register():
-    bpy.utils.register_class(EdgeRoundifier)
-
-
-def unregister():
-    bpy.utils.unregister_class(EdgeRoundifier)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_edges_floor_plan.py b/mesh_extra_tools/mesh_edges_floor_plan.py
deleted file mode 100644
index 1804c79aa..000000000
--- a/mesh_extra_tools/mesh_edges_floor_plan.py
+++ /dev/null
@@ -1,384 +0,0 @@
-# ##### 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; version 2
-#  of the License.
-#
-#  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 #####
-
-# based upon the functionality of Mesh to wall by luxuy_BlenderCN
-# thanks to meta-androcto
-
-bl_info = {
-    "name": "Edge Floor Plan",
-    "author": "lijenstina",
-    "version": (0, 2),
-    "blender": (2, 78, 0),
-    "location": "View3D > EditMode > Mesh",
-    "description": "Make a Floor Plan from Edges",
-    "wiki_url": "",
-    "category": "Mesh"}
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from bpy.props import (
-        BoolProperty,
-        EnumProperty,
-        FloatProperty,
-        FloatVectorProperty,
-        IntProperty,
-        )
-
-
-# Handle error notifications
-def error_handlers(self, error, reports="ERROR"):
-    if self and reports:
-        self.report({'WARNING'}, reports + " (See Console for more info)")
-
-    print("\n[mesh.edges_floor_plan]\nError: {}\n".format(error))
-
-
-class MESH_OT_edges_floor_plan(Operator):
-    bl_idname = "mesh.edges_floor_plan"
-    bl_label = "Edges Floor Plan"
-    bl_description = "Top View, Extrude Flat Along Edges"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    wid: FloatProperty(
-            name="Wall width:",
-            description="Set the width of the generated walls\n",
-            default=0.1,
-            min=0.001, max=30000
-            )
-    depth: FloatProperty(
-            name="Inner height:",
-            description="Set the height of the inner wall edges",
-            default=0.0,
-            min=0, max=10
-            )
-    connect_ends: BoolProperty(
-            name="Connect Ends",
-            description="Connect the ends of the boundary Edge loops",
-            default=False
-            )
-    repeat_cleanup: IntProperty(
-            name="Recursive Prepare",
-            description="Number of times that the preparation phase runs\n"
-                        "at the start of the script\n"
-                        "If parts of the mesh are not modified, increase this value",
-            min=1, max=20,
-            default=1
-            )
-    fill_items = [
-            ('EDGE_NET', "Edge Net",
-             "Edge Net Method for mesh preparation - Initial Fill\n"
-             "The filled in faces will be Inset individually\n"
-             "Supports simple 3D objects"),
-            ('SINGLE_FACE', "Single Face",
-             "Single Face Method for mesh preparation - Initial Fill\n"
-             "The produced face will be Triangulated before Inset Region\n"
-             "Good for edges forming a circle, avoid 3D objects"),
-            ('SOLIDIFY', "Solidify",
-             "Extrude and Solidify Method\n"
-             "Useful for complex meshes, however works best on flat surfaces\n"
-             "as the extrude direction has to be defined")
-            ]
-    fill_type: EnumProperty(
-            name="Fill Type",
-            items=fill_items,
-            description="Choose the method for creating geometry",
-            default='SOLIDIFY'
-            )
-    keep_faces: BoolProperty(
-            name="Keep Faces",
-            description="Keep or not the fill faces\n"
-                        "Can depend on Remove Ngons state",
-            default=False
-            )
-    tri_faces: BoolProperty(
-            name="Triangulate Faces",
-            description="Triangulate the created fill faces\n"
-                        "Sometimes can lead to unsatisfactory results",
-            default=False
-            )
-    initial_extrude: FloatVectorProperty(
-            name="Initial Extrude",
-            description="",
-            default=(0.0, 0.0, 0.1),
-            min=-20.0, max=20.0,
-            subtype='XYZ',
-            precision=3,
-            size=3
-            )
-    remove_ngons: BoolProperty(
-            name="Remove Ngons",
-            description="Keep or not the Ngon Faces\n"
-                        "Note about limitations:\n"
-                        "Sometimes the kept Faces could be Ngons\n"
-                        "Removing the Ngons can lead to no geometry created",
-            default=True
-            )
-    offset: FloatProperty(
-            name="Wall Offset:",
-            description="Set the offset for the Solidify modifier",
-            default=0.0,
-            min=-1.0, max=1.0
-            )
-    only_rim: BoolProperty(
-            name="Rim Only",
-            description="Solidify Fill Rim only option",
-            default=False
-            )
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return (ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def check_edge(self, context):
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bpy.ops.object.mode_set(mode='EDIT')
-        obj = bpy.context.object
-        me_check = obj.data
-        if len(me_check.edges) < 1:
-            return False
-
-        return True
-
-    @staticmethod
-    def ensure(bm):
-        if bm:
-            bm.verts.ensure_lookup_table()
-            bm.edges.ensure_lookup_table()
-            bm.faces.ensure_lookup_table()
-
-    def solidify_mod(self, context, ob, wid, offset, only_rim):
-        try:
-            mods = ob.modifiers.new(
-                        name="_Mesh_Solidify_Wall", type='SOLIDIFY'
-                        )
-            mods.thickness = wid
-            mods.use_quality_normals = True
-            mods.offset = offset
-            mods.use_even_offset = True
-            mods.use_rim = True
-            mods.use_rim_only = only_rim
-            mods.show_on_cage = True
-
-            bpy.ops.object.modifier_apply(
-                        modifier="_Mesh_Solidify_Wall"
-                        )
-        except Exception as e:
-            error_handlers(self, e,
-                           reports="Adding a Solidify Modifier failed")
-            pass
-
-    def draw(self, context):
-        layout = self.layout
-
-        box = layout.box()
-        box.label(text="Choose Method:", icon="SCRIPTWIN")
-        box.prop(self, "fill_type")
-
-        col = box.column(align=True)
-
-        if self.fill_type == 'EDGE_NET':
-            col.prop(self, "repeat_cleanup")
-            col.prop(self, "remove_ngons", toggle=True)
-
-        elif self.fill_type == 'SOLIDIFY':
-            col.prop(self, "offset", slider=True)
-            col.prop(self, "initial_extrude")
-
-        else:
-            col.prop(self, "remove_ngons", toggle=True)
-            col.prop(self, "tri_faces", toggle=True)
-
-        box = layout.box()
-        box.label(text="Settings:", icon="MOD_BUILD")
-
-        col = box.column(align=True)
-        col.prop(self, "wid")
-
-        if self.fill_type != 'SOLIDIFY':
-            col.prop(self, "depth")
-            col.prop(self, "connect_ends", toggle=True)
-            col.prop(self, "keep_faces", toggle=True)
-        else:
-            col.prop(self, "only_rim", toggle=True)
-
-    def execute(self, context):
-        if not self.check_edge(context):
-            self.report({'WARNING'},
-                        "Operation Cancelled. Needs a Mesh with at least one edge")
-            return {'CANCELLED'}
-
-        wid = self.wid * 0.1
-        depth = self.depth * 0.1
-        offset = self.offset * 0.1
-        store_selection_mode = context.tool_settings.mesh_select_mode
-        # Note: the remove_doubles called after bmesh creation would make
-        # blender crash with certain meshes - keep it in mind for the future
-        bpy.ops.mesh.remove_doubles(threshold=0.003)
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bpy.ops.object.mode_set(mode='EDIT')
-        ob = bpy.context.object
-
-        me = ob.data
-        bm = bmesh.from_edit_mesh(me)
-
-        bmesh.ops.delete(bm, geom=bm.faces, context=3)
-        self.ensure(bm)
-        context.tool_settings.mesh_select_mode = (False, True, False)
-        original_edges = [edge.index for edge in bm.edges]
-        original_verts = [vert.index for vert in bm.verts]
-        self.ensure(bm)
-        bpy.ops.mesh.select_all(action='DESELECT')
-
-        if self.fill_type == 'EDGE_NET':
-            for i in range(self.repeat_cleanup):
-                bmesh.ops.edgenet_prepare(bm, edges=bm.edges)
-                self.ensure(bm)
-            bmesh.ops.edgenet_fill(bm, edges=bm.edges, mat_nr=0, use_smooth=True, sides=0)
-            self.ensure(bm)
-            if self.remove_ngons:
-                ngons = [face for face in bm.faces if len(face.edges) > 4]
-                self.ensure(bm)
-                bmesh.ops.delete(bm, geom=ngons, context=5)  # 5 - delete faces
-                del ngons
-                self.ensure(bm)
-
-        elif self.fill_type == 'SOLIDIFY':
-            for vert in bm.verts:
-                vert.normal_update()
-            self.ensure(bm)
-            bmesh.ops.extrude_edge_only(
-                    bm, edges=bm.edges, use_select_history=False
-                    )
-            self.ensure(bm)
-            verts_extrude = [vert for vert in bm.verts if vert.index in original_verts]
-            self.ensure(bm)
-            bmesh.ops.translate(
-                bm,
-                verts=verts_extrude,
-                vec=(self.initial_extrude)
-                )
-            self.ensure(bm)
-            del verts_extrude
-            self.ensure(bm)
-
-            for edge in bm.edges:
-                if edge.is_boundary:
-                    edge.select = True
-
-            bm = bmesh.update_edit_mesh(ob.data, 1, 1)
-
-            bpy.ops.object.mode_set(mode='OBJECT')
-            self.solidify_mod(context, ob, wid, offset, self.only_rim)
-
-            bpy.ops.object.mode_set(mode='EDIT')
-
-            context.tool_settings.mesh_select_mode = store_selection_mode
-
-            return {'FINISHED'}
-
-        else:
-            bm.faces.new(bm.verts)
-            self.ensure(bm)
-
-            if self.tri_faces:
-                bmesh.ops.triangle_fill(
-                        bm, use_beauty=True, use_dissolve=False, edges=bm.edges
-                        )
-                self.ensure(bm)
-
-        if self.remove_ngons and self.fill_type != 'EDGE_NET':
-            ngons = [face for face in bm.faces if len(face.edges) > 4]
-            self.ensure(bm)
-            bmesh.ops.delete(bm, geom=ngons, context=5)  # 5 - delete faces
-            del ngons
-            self.ensure(bm)
-
-        del_boundary = [edge for edge in bm.edges if edge.index not in original_edges]
-        self.ensure(bm)
-
-        del original_edges
-        self.ensure(bm)
-
-        if self.fill_type == 'EDGE_NET':
-            extrude_inner = bmesh.ops.inset_individual(
-                    bm, faces=bm.faces, thickness=wid, depth=depth,
-                    use_even_offset=True, use_interpolate=False,
-                    use_relative_offset=False
-                    )
-        else:
-            extrude_inner = bmesh.ops.inset_region(
-                    bm, faces=bm.faces, faces_exclude=[], use_boundary=True,
-                    use_even_offset=True, use_interpolate=False,
-                    use_relative_offset=False, use_edge_rail=False,
-                    thickness=wid, depth=depth, use_outset=False
-                    )
-        self.ensure(bm)
-
-        del_faces = [faces for faces in bm.faces if faces not in extrude_inner["faces"]]
-        self.ensure(bm)
-        del extrude_inner
-        self.ensure(bm)
-
-        if not self.keep_faces:
-            bmesh.ops.delete(bm, geom=del_faces, context=5)  # 5 delete faces
-        del del_faces
-        self.ensure(bm)
-
-        face_del = set()
-        for face in bm.faces:
-            for edge in del_boundary:
-                if isinstance(edge, bmesh.types.BMEdge):
-                    if edge in face.edges:
-                        face_del.add(face)
-        self.ensure(bm)
-        face_del = list(face_del)
-        self.ensure(bm)
-
-        del del_boundary
-        self.ensure(bm)
-
-        if not self.connect_ends:
-            bmesh.ops.delete(bm, geom=face_del, context=5)
-            self.ensure(bm)
-
-        del face_del
-        self.ensure(bm)
-
-        for edge in bm.edges:
-            if edge.is_boundary:
-                edge.select = True
-
-        bm = bmesh.update_edit_mesh(ob.data, 1, 1)
-
-        context.tool_settings.mesh_select_mode = store_selection_mode
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(MESH_OT_edges_floor_plan)
-
-
-def unregister():
-    bpy.utils.unregister_class(MESH_OT_edges_floor_plan)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_edges_length.py b/mesh_extra_tools/mesh_edges_length.py
deleted file mode 100644
index d8c3ec5f2..000000000
--- a/mesh_extra_tools/mesh_edges_length.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# gpl author: Giuseppe De Marco [BlenderLab] inspired by NirenYang
-
-bl_info = {
-    "name": "Set edges length",
-    "description": "Edges length",
-    "author": "Giuseppe De Marco [BlenderLab] inspired by NirenYang",
-    "version": (0, 1, 0),
-    "blender": (2, 71, 0),
-    "location": "Toolbar > Tools > Mesh Tools: set Length(Shit+Alt+E)",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh",
-    }
-
-import bpy
-import bmesh
-from mathutils import Vector
-from bpy.types import Operator
-from bpy.props import (
-        FloatProperty,
-        EnumProperty,
-        )
-
-# GLOBALS
-edge_length_debug = False
-_error_message = "Please select at least one edge to fill select history"
-_error_message_2 = "Edges with shared vertices are not allowed. Please, use scale instead"
-
-# Note : Refactor - removed all the operators apart from LengthSet
-#        and merged the other ones as options of length (lijenstina)
-
-
-def get_edge_vector(edge):
-    verts = (edge.verts[0].co, edge.verts[1].co)
-    vector = verts[1] - verts[0]
-
-    return vector
-
-
-def get_selected(bmesh_obj, geometry_type):
-    # geometry type should be edges, verts or faces
-    selected = []
-
-    for i in getattr(bmesh_obj, geometry_type):
-        if i.select:
-            selected.append(i)
-    return tuple(selected)
-
-
-def get_center_vector(verts):
-    # verts = [Vector((x,y,z)), Vector((x,y,z))]
-
-    center_vector = Vector((((verts[1][0] + verts[0][0]) / 2.),
-                           ((verts[1][1] + verts[0][1]) / 2.),
-                           ((verts[1][2] + verts[0][2]) / 2.)))
-    return center_vector
-
-
-class LengthSet(Operator):
-    bl_idname = "object.mesh_edge_length_set"
-    bl_label = "Set edge length"
-    bl_description = ("Change one selected edge length by a specified target,\n"
-                      "existing length and different modes\n"
-                      "Note: works only with Edges that not share a vertex")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    old_length: FloatProperty(
-            name="Original length",
-            options={'HIDDEN'},
-            )
-    set_length_type: EnumProperty(
-            items=[
-                ('manual', "Manual",
-                 "Input manually the desired Target Length"),
-                ('existing', "Existing Length",
-                 "Use existing geometry Edges' characteristics"),
-            ],
-            name="Set Type of Input",
-            )
-    target_length: FloatProperty(
-            name="Target Length",
-            description="Input a value for an Edges Length target",
-            default=1.00,
-            unit='LENGTH',
-            precision=5
-            )
-    existing_length: EnumProperty(
-            items=[
-                ('min', "Shortest",
-                 "Set all to shortest Edge of selection"),
-                ('max', "Longest",
-                 "Set all to the longest Edge of selection"),
-                ('average', "Average",
-                 "Set all to the average Edge length of selection"),
-                ('active', "Active",
-                 "Set all to the active Edge's one\n"
-                 "Needs a selection to be done in Edge Select mode"),
-            ],
-            name="Existing length"
-            )
-    mode: EnumProperty(
-            items=[
-                ('fixed', "Fixed", "Fixed"),
-                ('increment', "Increment", "Increment"),
-                ('decrement', "Decrement", "Decrement"),
-            ],
-            name="Mode"
-            )
-    behaviour: EnumProperty(
-            items=[
-                ('proportional', "Proportional",
-                 "Move vertex locations proportionally to the center of the Edge"),
-                ('clockwise', "Clockwise",
-                "Compute the Edges' vertex locations in a clockwise fashion"),
-                ('unclockwise', "Counterclockwise",
-                "Compute the Edges' vertex locations in a counterclockwise fashion"),
-            ],
-            name="Resize behavior"
-            )
-
-    originary_edge_length_dict = {}
-    edge_lengths = []
-    selected_edges = ()
-
-    @classmethod
-    def poll(cls, context):
-        return (context.edit_object and context.object.type == 'MESH')
-
-    def check(self, context):
-        return True
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.label(text="Original Active length is: {:.3f}".format(self.old_length))
-
-        layout.label(text="Input Mode:")
-        layout.prop(self, "set_length_type", expand=True)
-        if self.set_length_type == 'manual':
-            layout.prop(self, "target_length")
-        else:
-            layout.prop(self, "existing_length", text="")
-
-        layout.label(text="Mode:")
-        layout.prop(self, "mode", text="")
-
-        layout.label(text="Resize Behavior:")
-        layout.prop(self, "behaviour", text="")
-
-    def get_existing_edge_length(self, bm):
-        if self.existing_length != "active":
-            if self.existing_length == "min":
-                return min(self.edge_lengths)
-            if self.existing_length == "max":
-                return max(self.edge_lengths)
-            elif self.existing_length == "average":
-                return sum(self.edge_lengths) / float(len(self.selected_edges))
-        else:
-            bm.edges.ensure_lookup_table()
-            active_edge_length = None
-
-            for elem in reversed(bm.select_history):
-                if isinstance(elem, bmesh.types.BMEdge):
-                    active_edge_length = elem.calc_length()
-                    break
-            return active_edge_length
-
-        return 0.0
-
-    def invoke(self, context, event):
-        wm = context.window_managerlength
-
-        obj = context.edit_object
-        bm = bmesh.from_edit_mesh(obj.data)
-
-        bpy.ops.mesh.select_mode(type="EDGE")
-        self.selected_edges = get_selected(bm, 'edges')
-
-        if self.selected_edges:
-            vertex_set = []
-
-            for edge in self.selected_edges:
-                vector = get_edge_vector(edge)
-
-                if edge.verts[0].index not in vertex_set:
-                    vertex_set.append(edge.verts[0].index)
-                else:
-                    self.report({'ERROR_INVALID_INPUT'}, _error_message_2)
-                    return {'CANCELLED'}
-
-                if edge.verts[1].index not in vertex_set:
-                    vertex_set.append(edge.verts[1].index)
-                else:
-                    self.report({'ERROR_INVALID_INPUT'}, _error_message_2)
-                    return {'CANCELLED'}
-
-                # warning, it's a constant !
-                verts_index = ''.join((str(edge.verts[0].index), str(edge.verts[1].index)))
-                self.originary_edge_length_dict[verts_index] = vector
-                self.edge_lengths.append(vector.length)
-                self.old_length = vector.length
-        else:
-            self.report({'ERROR'}, _error_message)
-            return {'CANCELLED'}
-
-        if edge_length_debug:
-            self.report({'INFO'}, str(self.originary_edge_length_dict))
-
-        if bpy.context.scene.unit_settings.system == 'IMPERIAL':
-            # imperial to metric conversion
-            vector.length = (0.9144 * vector.length) / 3
-
-        self.target_length = vector.length
-
-        return wm.invoke_props_dialog(self)
-
-    def execute(self, context):
-
-        bpy.ops.mesh.select_mode(type="EDGE")
-        self.context = context
-
-        obj = context.edit_object
-        bm = bmesh.from_edit_mesh(obj.data)
-
-        self.selected_edges = get_selected(bm, 'edges')
-
-        if not self.selected_edges:
-            self.report({'ERROR'}, _error_message)
-            return {'CANCELLED'}
-
-        for edge in self.selected_edges:
-            vector = get_edge_vector(edge)
-            # what we should see in original length dialog field
-            self.old_length = vector.length
-
-            if self.set_length_type == 'manual':
-                vector.length = abs(self.target_length)
-            else:
-                get_lengths = self.get_existing_edge_length(bm)
-                # check for edit mode
-                if not get_lengths:
-                    self.report({'WARNING'},
-                                "Operation Cancelled. "
-                                "Active Edge could not be determined (needs selection in Edit Mode)")
-                    return {'CANCELLED'}
-
-                vector.length = get_lengths
-
-            if vector.length == 0.0:
-                self.report({'ERROR'}, "Operation cancelled. Target length is set to zero")
-                return {'CANCELLED'}
-
-            center_vector = get_center_vector((edge.verts[0].co, edge.verts[1].co))
-
-            verts_index = ''.join((str(edge.verts[0].index), str(edge.verts[1].index)))
-
-            if edge_length_debug:
-                self.report({'INFO'},
-                            ' - '.join(('vector ' + str(vector),
-                                        'originary_vector ' +
-                                        str(self.originary_edge_length_dict[verts_index])
-                                        )))
-            verts = (edge.verts[0].co, edge.verts[1].co)
-
-            if edge_length_debug:
-                self.report({'INFO'},
-                            '\n edge.verts[0].co ' + str(verts[0]) +
-                            '\n edge.verts[1].co ' + str(verts[1]) +
-                            '\n vector.length' + str(vector.length))
-
-            # the clockwise direction have v1 -> v0, unclockwise v0 -> v1
-            if self.target_length >= 0:
-                if self.behaviour == 'proportional':
-                    edge.verts[1].co = center_vector + vector / 2
-                    edge.verts[0].co = center_vector - vector / 2
-
-                    if self.mode == 'decrement':
-                        edge.verts[0].co = (center_vector + vector / 2) - \
-                                            (self.originary_edge_length_dict[verts_index] / 2)
-                        edge.verts[1].co = (center_vector - vector / 2) + \
-                                            (self.originary_edge_length_dict[verts_index] / 2)
-
-                    elif self.mode == 'increment':
-                        edge.verts[1].co = (center_vector + vector / 2) + \
-                                            self.originary_edge_length_dict[verts_index] / 2
-                        edge.verts[0].co = (center_vector - vector / 2) - \
-                                            self.originary_edge_length_dict[verts_index] / 2
-
-                elif self.behaviour == 'unclockwise':
-                    if self.mode == 'increment':
-                        edge.verts[1].co = \
-                                verts[0] + (self.originary_edge_length_dict[verts_index] + vector)
-                    elif self.mode == 'decrement':
-                        edge.verts[0].co = \
-                                verts[1] - (self.originary_edge_length_dict[verts_index] - vector)
-                    else:
-                        edge.verts[1].co = verts[0] + vector
-
-                else:
-                    # clockwise
-                    if self.mode == 'increment':
-                        edge.verts[0].co = \
-                                verts[1] - (self.originary_edge_length_dict[verts_index] + vector)
-                    elif self.mode == 'decrement':
-                        edge.verts[1].co = \
-                                verts[0] + (self.originary_edge_length_dict[verts_index] - vector)
-                    else:
-                        edge.verts[0].co = verts[1] - vector
-
-            if bpy.context.scene.unit_settings.system == 'IMPERIAL':
-                """
-                # yards to metric conversion
-                vector.length = ( 3. * vector.length ) / 0.9144
-                # metric to yards conversion
-                vector.length = ( 0.9144 * vector.length ) / 3.
-                """
-                for mvert in edge.verts:
-                    # school time: 0.9144 : 3 = X : mvert
-                    mvert.co = (0.9144 * mvert.co) / 3
-
-            if edge_length_debug:
-                self.report({'INFO'},
-                            '\n edge.verts[0].co' + str(verts[0]) +
-                            '\n edge.verts[1].co' + str(verts[1]) +
-                            '\n vector' + str(vector) + '\n v1 > v0:' + str((verts[1] >= verts[0]))
-                            )
-            bmesh.update_edit_mesh(obj.data, True)
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(LengthSet)
-
-
-def unregister():
-    bpy.utils.unregister_class(LengthSet)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_edgetools.py b/mesh_extra_tools/mesh_edgetools.py
deleted file mode 100644
index 0547e915f..000000000
--- a/mesh_extra_tools/mesh_edgetools.py
+++ /dev/null
@@ -1,1878 +0,0 @@
-#  The Blender Edgetools is to bring CAD tools to Blender.
-#  Copyright (C) 2012  Paul Marshall
-
-# ##### 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 3 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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-bl_info = {
-    "name": "EdgeTools",
-    "author": "Paul Marshall",
-    "version": (0, 9, 2),
-    "blender": (2, 68, 0),
-    "location": "View3D > Toolbar and View3D > Specials (W-key)",
-    "warning": "",
-    "description": "CAD style edge manipulation tools",
-    "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
-                "Scripts/Modeling/EdgeTools",
-    "category": "Mesh"}
-
-
-import bpy
-import bmesh
-from bpy.types import (
-        Operator,
-        Menu,
-        )
-from math import acos, pi, radians, sqrt
-from mathutils import Matrix, Vector
-from mathutils.geometry import (
-        distance_point_to_plane,
-        interpolate_bezier,
-        intersect_point_line,
-        intersect_line_line,
-        intersect_line_plane,
-        )
-from bpy.props import (
-        BoolProperty,
-        IntProperty,
-        FloatProperty,
-        EnumProperty,
-       )
-
-"""
-Blender EdgeTools
-This is a toolkit for edge manipulation based on mesh manipulation
-abilities of several CAD/CAE packages, notably CATIA's Geometric Workbench
-from which most of these tools have a functional basis.
-
-The GUI and Blender add-on structure shamelessly coded in imitation of the
-LoopTools addon.
-
-Examples:
-- "Ortho" inspired from CATIA's line creation tool which creates a line of a
-   user specified length at a user specified angle to a curve at a chosen
-   point.  The user then selects the plane the line is to be created in.
-- "Shaft" is inspired from CATIA's tool of the same name.  However, instead
-   of a curve around an axis, this will instead shaft a line, a point, or
-   a fixed radius about the selected axis.
-- "Slice" is from CATIA's ability to split a curve on a plane.  When
-   completed this be a Python equivalent with all the same basic
-   functionality, though it will sadly be a little clumsier to use due
-   to Blender's selection limitations.
-
-Notes:
-- Fillet operator and related functions removed as they didn't work
-- Buggy parts have been hidden behind ENABLE_DEBUG global (set it to True)
-   Example: Shaft with more than two edges selected
-
-Paul "BrikBot" Marshall
-Created: January 28, 2012
-Last Modified: October 6, 2012
-
-Coded in IDLE, tested in Blender 2.6.
-Search for "@todo" to quickly find sections that need work
-
-Note: lijenstina - modified this script in preparation for merging
-fixed the needless jumping to object mode for bmesh creation
-causing the crash with the Slice > Rip operator
-Removed the test operator since version 0.9.2
-added general error handling
-"""
-
-# Enable debug
-# Set to True to have the debug prints available
-ENABLE_DEBUG = False
-
-
-# Quick an dirty method for getting the sign of a number:
-def sign(number):
-    return (number > 0) - (number < 0)
-
-
-# is_parallel
-# Checks to see if two lines are parallel
-
-def is_parallel(v1, v2, v3, v4):
-    result = intersect_line_line(v1, v2, v3, v4)
-    return result is None
-
-
-# Handle error notifications
-def error_handlers(self, op_name, error, reports="ERROR", func=False):
-    if self and reports:
-        self.report({'WARNING'}, reports + " (See Console for more info)")
-
-    is_func = "Function" if func else "Operator"
-    print("\n[Mesh EdgeTools]\n{}: {}\nError: {}\n".format(is_func, op_name, error))
-
-
-def flip_edit_mode():
-    bpy.ops.object.editmode_toggle()
-    bpy.ops.object.editmode_toggle()
-
-
-# check the appropriate selection condition
-# to prevent crashes with the index out of range errors
-# pass the bEdges and bVerts based selection tables here
-# types: Edge, Vertex, All
-def is_selected_enough(self, bEdges, bVerts, edges_n=1, verts_n=0, types="Edge"):
-    check = False
-    try:
-        if bEdges and types == "Edge":
-            check = (len(bEdges) >= edges_n)
-        elif bVerts and types == "Vertex":
-            check = (len(bVerts) >= verts_n)
-        elif bEdges and bVerts and types == "All":
-            check = (len(bEdges) >= edges_n and len(bVerts) >= verts_n)
-
-        if check is False:
-            strings = "%s Vertices and / or " % verts_n if verts_n != 0 else ""
-            self.report({'WARNING'},
-                        "Needs at least " + strings + "%s Edge(s) selected. "
-                        "Operation Cancelled" % edges_n)
-            flip_edit_mode()
-
-        return check
-
-    except Exception as e:
-        error_handlers(self, "is_selected_enough", e,
-                      "No appropriate selection. Operation Cancelled", func=True)
-        return False
-
-    return False
-
-
-# is_axial
-# This is for the special case where the edge is parallel to an axis.
-# The projection onto the XY plane will fail so it will have to be handled differently
-
-def is_axial(v1, v2, error=0.000002):
-    vector = v2 - v1
-    # Don't need to store, but is easier to read:
-    vec0 = vector[0] > -error and vector[0] < error
-    vec1 = vector[1] > -error and vector[1] < error
-    vec2 = vector[2] > -error and vector[2] < error
-    if (vec0 or vec1) and vec2:
-        return 'Z'
-    elif vec0 and vec1:
-        return 'Y'
-    return None
-
-
-# is_same_co
-# For some reason "Vector = Vector" does not seem to look at the actual coordinates
-
-def is_same_co(v1, v2):
-    if len(v1) != len(v2):
-        return False
-    else:
-        for co1, co2 in zip(v1, v2):
-            if co1 != co2:
-                return False
-    return True
-
-
-def is_face_planar(face, error=0.0005):
-    for v in face.verts:
-        d = distance_point_to_plane(v.co, face.verts[0].co, face.normal)
-        if ENABLE_DEBUG:
-            print("Distance: " + str(d))
-        if d < -error or d > error:
-            return False
-    return True
-
-
-# other_joined_edges
-# Starts with an edge. Then scans for linked, selected edges and builds a
-# list with them in "order", starting at one end and moving towards the other
-
-def order_joined_edges(edge, edges=[], direction=1):
-    if len(edges) == 0:
-        edges.append(edge)
-        edges[0] = edge
-
-    if ENABLE_DEBUG:
-        print(edge, end=", ")
-        print(edges, end=", ")
-        print(direction, end="; ")
-
-    # Robustness check: direction cannot be zero
-    if direction == 0:
-        direction = 1
-
-    newList = []
-    for e in edge.verts[0].link_edges:
-        if e.select and edges.count(e) == 0:
-            if direction > 0:
-                edges.insert(0, e)
-                newList.extend(order_joined_edges(e, edges, direction + 1))
-                newList.extend(edges)
-            else:
-                edges.append(e)
-                newList.extend(edges)
-                newList.extend(order_joined_edges(e, edges, direction - 1))
-
-    # This will only matter at the first level:
-    direction = direction * -1
-
-    for e in edge.verts[1].link_edges:
-        if e.select and edges.count(e) == 0:
-            if direction > 0:
-                edges.insert(0, e)
-                newList.extend(order_joined_edges(e, edges, direction + 2))
-                newList.extend(edges)
-            else:
-                edges.append(e)
-                newList.extend(edges)
-                newList.extend(order_joined_edges(e, edges, direction))
-
-    if ENABLE_DEBUG:
-        print(newList, end=", ")
-        print(direction)
-
-    return newList
-
-
-# --------------- GEOMETRY CALCULATION METHODS --------------
-
-# distance_point_line
-# I don't know why the mathutils.geometry API does not already have this, but
-# it is trivial to code using the structures already in place. Instead of
-# returning a float, I also want to know the direction vector defining the
-# distance. Distance can be found with "Vector.length"
-
-def distance_point_line(pt, line_p1, line_p2):
-    int_co = intersect_point_line(pt, line_p1, line_p2)
-    distance_vector = int_co[0] - pt
-    return distance_vector
-
-
-# interpolate_line_line
-# This is an experiment into a cubic Hermite spline (c-spline) for connecting
-# two edges with edges that obey the general equation.
-# This will return a set of point coordinates (Vectors)
-#
-# A good, easy to read background on the mathematics can be found at:
-# http://cubic.org/docs/hermite.htm
-#
-# Right now this is . . . less than functional :P
-# @todo
-#   - C-Spline and Bezier curves do not end on p2_co as they are supposed to.
-#   - B-Spline just fails.  Epically.
-#   - Add more methods as I come across them.  Who said flexibility was bad?
-
-def interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, segments, tension=1,
-                          typ='BEZIER', include_ends=False):
-    pieces = []
-    fraction = 1 / segments
-
-    # Form: p1, tangent 1, p2, tangent 2
-    if typ == 'HERMITE':
-        poly = [[2, -3, 0, 1], [1, -2, 1, 0],
-                [-2, 3, 0, 0], [1, -1, 0, 0]]
-    elif typ == 'BEZIER':
-        poly = [[-1, 3, -3, 1], [3, -6, 3, 0],
-                [1, 0, 0, 0], [-3, 3, 0, 0]]
-        p1_dir = p1_dir + p1_co
-        p2_dir = -p2_dir + p2_co
-    elif typ == 'BSPLINE':
-        # Supposed poly matrix for a cubic b-spline:
-        # poly = [[-1, 3, -3, 1], [3, -6, 3, 0],
-        #         [-3, 0, 3, 0], [1, 4, 1, 0]]
-        # My own invention to try to get something that somewhat acts right
-        # This is semi-quadratic rather than fully cubic:
-        poly = [[0, -1, 0, 1], [1, -2, 1, 0],
-                [0, -1, 2, 0], [1, -1, 0, 0]]
-
-    if include_ends:
-        pieces.append(p1_co)
-
-    # Generate each point:
-    for i in range(segments - 1):
-        t = fraction * (i + 1)
-        if ENABLE_DEBUG:
-            print(t)
-        s = [t ** 3, t ** 2, t, 1]
-        h00 = (poly[0][0] * s[0]) + (poly[0][1] * s[1]) + (poly[0][2] * s[2]) + (poly[0][3] * s[3])
-        h01 = (poly[1][0] * s[0]) + (poly[1][1] * s[1]) + (poly[1][2] * s[2]) + (poly[1][3] * s[3])
-        h10 = (poly[2][0] * s[0]) + (poly[2][1] * s[1]) + (poly[2][2] * s[2]) + (poly[2][3] * s[3])
-        h11 = (poly[3][0] * s[0]) + (poly[3][1] * s[1]) + (poly[3][2] * s[2]) + (poly[3][3] * s[3])
-        pieces.append((h00 * p1_co) + (h01 * p1_dir) + (h10 * p2_co) + (h11 * p2_dir))
-    if include_ends:
-        pieces.append(p2_co)
-
-    # Return:
-    if len(pieces) == 0:
-        return None
-    else:
-        if ENABLE_DEBUG:
-            print(pieces)
-        return pieces
-
-
-# intersect_line_face
-
-# Calculates the coordinate of intersection of a line with a face.  It returns
-# the coordinate if one exists, otherwise None.  It can only deal with tris or
-# quads for a face. A quad does NOT have to be planar
-"""
-Quad math and theory:
-A quad may not be planar. Therefore the treated definition of the surface is
-that the surface is composed of all lines bridging two other lines defined by
-the given four points. The lines do not "cross"
-
-The two lines in 3-space can defined as:
-┌  ┐         ┌   ┐     ┌   ┐  ┌  ┐         ┌   ┐     ┌   ┐
-│x1│         │a11│     │b11│  │x2│         │a21│     │b21│
-│y1│ = (1-t1)│a12│ + t1│b12│, │y2│ = (1-t2)│a22│ + t2│b22│
-│z1│         │a13│     │b13│  │z2│         │a23│     │b23│
-└  ┘         └   ┘     └   ┘  └  ┘         └   ┘     └   ┘
-Therefore, the surface is the lines defined by every point alone the two
-lines with a same "t" value (t1 = t2). This is basically R = V1 + tQ, where
-Q = V2 - V1 therefore R = V1 + t(V2 - V1) -> R = (1 - t)V1 + tV2:
-┌   ┐            ┌                  ┐      ┌                  ┐
-│x12│            │(1-t)a11 + t * b11│      │(1-t)a21 + t * b21│
-│y12│ = (1 - t12)│(1-t)a12 + t * b12│ + t12│(1-t)a22 + t * b22│
-│z12│            │(1-t)a13 + t * b13│      │(1-t)a23 + t * b23│
-└   ┘            └                  ┘      └                  ┘
-Now, the equation of our line can be likewise defined:
-┌  ┐   ┌   ┐     ┌   ┐
-│x3│   │a31│     │b31│
-│y3│ = │a32│ + t3│b32│
-│z3│   │a33│     │b33│
-└  ┘   └   ┘     └   ┘
-Now we just have to find a valid solution for the two equations.  This should
-be our point of intersection. Therefore, x12 = x3 -> x, y12 = y3 -> y,
-z12 = z3 -> z.  Thus, to find that point we set the equation defining the
-surface as equal to the equation for the line:
-        ┌                  ┐      ┌                  ┐   ┌   ┐     ┌   ┐
-        │(1-t)a11 + t * b11│      │(1-t)a21 + t * b21│   │a31│     │b31│
-(1 - t12)│(1-t)a12 + t * b12│ + t12│(1-t)a22 + t * b22│ = │a32│ + t3│b32│
-        │(1-t)a13 + t * b13│      │(1-t)a23 + t * b23│   │a33│     │b33│
-        └                  ┘      └                  ┘   └   ┘     └   ┘
-This leaves us with three equations, three unknowns.  Solving the system by
-hand is practically impossible, but using Mathematica we are given an insane
-series of three equations (not reproduced here for the sake of space: see
-http://www.mediafire.com/file/cc6m6ba3sz2b96m/intersect_line_surface.nb and
-http://www.mediafire.com/file/0egbr5ahg14talm/intersect_line_surface2.nb for
-Mathematica computation).
-
-Additionally, the resulting series of equations may result in a div by zero
-exception if the line in question if parallel to one of the axis or if the
-quad is planar and parallel to either the XY, XZ, or YZ planes. However, the
-system is still solvable but must be dealt with a little differently to avaid
-these special cases. Because the resulting equations are a little different,
-we have to code them differently. 00Hence the special cases.
-
-Tri math and theory:
-A triangle must be planar (three points define a plane). So we just
-have to make sure that the line intersects inside the triangle.
-
-If the point is within the triangle, then the angle between the lines that
-connect the point to the each individual point of the triangle will be
-equal to 2 * PI. Otherwise, if the point is outside the triangle, then the
-sum of the angles will be less.
-"""
-# @todo
-# - Figure out how to deal with n-gons
-# How the heck is a face with 8 verts defined mathematically?
-# How do I then find the intersection point of a line with said vert?
-# How do I know if that point is "inside" all the verts?
-# I have no clue, and haven't been able to find anything on it so far
-# Maybe if someone (actually reads this and) who knows could note?
-
-
-def intersect_line_face(edge, face, is_infinite=False, error=0.000002):
-    int_co = None
-
-    # If we are dealing with a non-planar quad:
-    if len(face.verts) == 4 and not is_face_planar(face):
-        edgeA = face.edges[0]
-        edgeB = None
-        flipB = False
-
-        for i in range(len(face.edges)):
-            if face.edges[i].verts[0] not in edgeA.verts and \
-               face.edges[i].verts[1] not in edgeA.verts:
-
-                edgeB = face.edges[i]
-                break
-
-        # I haven't figured out a way to mix this in with the above. Doing so might remove a
-        # few extra instructions from having to be executed saving a few clock cycles:
-        for i in range(len(face.edges)):
-            if face.edges[i] == edgeA or face.edges[i] == edgeB:
-                continue
-            if ((edgeA.verts[0] in face.edges[i].verts and
-               edgeB.verts[1] in face.edges[i].verts) or
-               (edgeA.verts[1] in face.edges[i].verts and edgeB.verts[0] in face.edges[i].verts)):
-
-                flipB = True
-                break
-
-        # Define calculation coefficient constants:
-        # "xx1" is the x coordinate, "xx2" is the y coordinate, and "xx3" is the z coordinate
-        a11, a12, a13 = edgeA.verts[0].co[0], edgeA.verts[0].co[1], edgeA.verts[0].co[2]
-        b11, b12, b13 = edgeA.verts[1].co[0], edgeA.verts[1].co[1], edgeA.verts[1].co[2]
-
-        if flipB:
-            a21, a22, a23 = edgeB.verts[1].co[0], edgeB.verts[1].co[1], edgeB.verts[1].co[2]
-            b21, b22, b23 = edgeB.verts[0].co[0], edgeB.verts[0].co[1], edgeB.verts[0].co[2]
-        else:
-            a21, a22, a23 = edgeB.verts[0].co[0], edgeB.verts[0].co[1], edgeB.verts[0].co[2]
-            b21, b22, b23 = edgeB.verts[1].co[0], edgeB.verts[1].co[1], edgeB.verts[1].co[2]
-        a31, a32, a33 = edge.verts[0].co[0], edge.verts[0].co[1], edge.verts[0].co[2]
-        b31, b32, b33 = edge.verts[1].co[0], edge.verts[1].co[1], edge.verts[1].co[2]
-
-        # There are a bunch of duplicate "sub-calculations" inside the resulting
-        # equations for t, t12, and t3.  Calculate them once and store them to
-        # reduce computational time:
-        m01 = a13 * a22 * a31
-        m02 = a12 * a23 * a31
-        m03 = a13 * a21 * a32
-        m04 = a11 * a23 * a32
-        m05 = a12 * a21 * a33
-        m06 = a11 * a22 * a33
-        m07 = a23 * a32 * b11
-        m08 = a22 * a33 * b11
-        m09 = a23 * a31 * b12
-        m10 = a21 * a33 * b12
-        m11 = a22 * a31 * b13
-        m12 = a21 * a32 * b13
-        m13 = a13 * a32 * b21
-        m14 = a12 * a33 * b21
-        m15 = a13 * a31 * b22
-        m16 = a11 * a33 * b22
-        m17 = a12 * a31 * b23
-        m18 = a11 * a32 * b23
-        m19 = a13 * a22 * b31
-        m20 = a12 * a23 * b31
-        m21 = a13 * a32 * b31
-        m22 = a23 * a32 * b31
-        m23 = a12 * a33 * b31
-        m24 = a22 * a33 * b31
-        m25 = a23 * b12 * b31
-        m26 = a33 * b12 * b31
-        m27 = a22 * b13 * b31
-        m28 = a32 * b13 * b31
-        m29 = a13 * b22 * b31
-        m30 = a33 * b22 * b31
-        m31 = a12 * b23 * b31
-        m32 = a32 * b23 * b31
-        m33 = a13 * a21 * b32
-        m34 = a11 * a23 * b32
-        m35 = a13 * a31 * b32
-        m36 = a23 * a31 * b32
-        m37 = a11 * a33 * b32
-        m38 = a21 * a33 * b32
-        m39 = a23 * b11 * b32
-        m40 = a33 * b11 * b32
-        m41 = a21 * b13 * b32
-        m42 = a31 * b13 * b32
-        m43 = a13 * b21 * b32
-        m44 = a33 * b21 * b32
-        m45 = a11 * b23 * b32
-        m46 = a31 * b23 * b32
-        m47 = a12 * a21 * b33
-        m48 = a11 * a22 * b33
-        m49 = a12 * a31 * b33
-        m50 = a22 * a31 * b33
-        m51 = a11 * a32 * b33
-        m52 = a21 * a32 * b33
-        m53 = a22 * b11 * b33
-        m54 = a32 * b11 * b33
-        m55 = a21 * b12 * b33
-        m56 = a31 * b12 * b33
-        m57 = a12 * b21 * b33
-        m58 = a32 * b21 * b33
-        m59 = a11 * b22 * b33
-        m60 = a31 * b22 * b33
-        m61 = a33 * b12 * b21
-        m62 = a32 * b13 * b21
-        m63 = a33 * b11 * b22
-        m64 = a31 * b13 * b22
-        m65 = a32 * b11 * b23
-        m66 = a31 * b12 * b23
-        m67 = b13 * b22 * b31
-        m68 = b12 * b23 * b31
-        m69 = b13 * b21 * b32
-        m70 = b11 * b23 * b32
-        m71 = b12 * b21 * b33
-        m72 = b11 * b22 * b33
-        n01 = m01 - m02 - m03 + m04 + m05 - m06
-        n02 = -m07 + m08 + m09 - m10 - m11 + m12 + m13 - m14 - m15 + m16 + m17 - m18 - \
-              m25 + m27 + m29 - m31 + m39 - m41 - m43 + m45 - m53 + m55 + m57 - m59
-        n03 = -m19 + m20 + m33 - m34 - m47 + m48
-        n04 = m21 - m22 - m23 + m24 - m35 + m36 + m37 - m38 + m49 - m50 - m51 + m52
-        n05 = m26 - m28 - m30 + m32 - m40 + m42 + m44 - m46 + m54 - m56 - m58 + m60
-        n06 = m61 - m62 - m63 + m64 + m65 - m66 - m67 + m68 + m69 - m70 - m71 + m72
-        n07 = 2 * n01 + n02 + 2 * n03 + n04 + n05
-        n08 = n01 + n02 + n03 + n06
-
-        # Calculate t, t12, and t3:
-        t = (n07 - sqrt(pow(-n07, 2) - 4 * (n01 + n03 + n04) * n08)) / (2 * n08)
-
-        # t12 can be greatly simplified by defining it with t in it:
-        # If block used to help prevent any div by zero error.
-        t12 = 0
-
-        if a31 == b31:
-            # The line is parallel to the z-axis:
-            if a32 == b32:
-                t12 = ((a11 - a31) + (b11 - a11) * t) / ((a21 - a11) + (a11 - a21 - b11 + b21) * t)
-            # The line is parallel to the y-axis:
-            elif a33 == b33:
-                t12 = ((a11 - a31) + (b11 - a11) * t) / ((a21 - a11) + (a11 - a21 - b11 + b21) * t)
-            # The line is along the y/z-axis but is not parallel to either:
-            else:
-                t12 = -(-(a33 - b33) * (-a32 + a12 * (1 - t) + b12 * t) + (a32 - b32) *
-                        (-a33 + a13 * (1 - t) + b13 * t)) / (-(a33 - b33) *
-                        ((a22 - a12) * (1 - t) + (b22 - b12) * t) + (a32 - b32) *
-                        ((a23 - a13) * (1 - t) + (b23 - b13) * t))
-        elif a32 == b32:
-            # The line is parallel to the x-axis:
-            if a33 == b33:
-                t12 = ((a12 - a32) + (b12 - a12) * t) / ((a22 - a12) + (a12 - a22 - b12 + b22) * t)
-            # The line is along the x/z-axis but is not parallel to either:
-            else:
-                t12 = -(-(a33 - b33) * (-a31 + a11 * (1 - t) + b11 * t) + (a31 - b31) * (-a33 + a13 *
-                      (1 - t) + b13 * t)) / (-(a33 - b33) * ((a21 - a11) * (1 - t) + (b21 - b11) * t) +
-                      (a31 - b31) * ((a23 - a13) * (1 - t) + (b23 - b13) * t))
-        # The line is along the x/y-axis but is not parallel to either:
-        else:
-            t12 = -(-(a32 - b32) * (-a31 + a11 * (1 - t) + b11 * t) + (a31 - b31) * (-a32 + a12 *
-                  (1 - t) + b12 * t)) / (-(a32 - b32) * ((a21 - a11) * (1 - t) + (b21 - b11) * t) +
-                  (a31 - b31) * ((a22 - a21) * (1 - t) + (b22 - b12) * t))
-
-        # Likewise, t3 is greatly simplified by defining it in terms of t and t12:
-        # If block used to prevent a div by zero error.
-        t3 = 0
-        if a31 != b31:
-            t3 = (-a11 + a31 + (a11 - b11) * t + (a11 - a21) *
-                t12 + (a21 - a11 + b11 - b21) * t * t12) / (a31 - b31)
-        elif a32 != b32:
-            t3 = (-a12 + a32 + (a12 - b12) * t + (a12 - a22) *
-                t12 + (a22 - a12 + b12 - b22) * t * t12) / (a32 - b32)
-        elif a33 != b33:
-            t3 = (-a13 + a33 + (a13 - b13) * t + (a13 - a23) *
-                t12 + (a23 - a13 + b13 - b23) * t * t12) / (a33 - b33)
-        else:
-            if ENABLE_DEBUG:
-                print("The second edge is a zero-length edge")
-            return None
-
-        # Calculate the point of intersection:
-        x = (1 - t3) * a31 + t3 * b31
-        y = (1 - t3) * a32 + t3 * b32
-        z = (1 - t3) * a33 + t3 * b33
-        int_co = Vector((x, y, z))
-
-        if ENABLE_DEBUG:
-            print(int_co)
-
-        # If the line does not intersect the quad, we return "None":
-        if (t < -1 or t > 1 or t12 < -1 or t12 > 1) and not is_infinite:
-            int_co = None
-
-    elif len(face.verts) == 3:
-        p1, p2, p3 = face.verts[0].co, face.verts[1].co, face.verts[2].co
-        int_co = intersect_line_plane(edge.verts[0].co, edge.verts[1].co, p1, face.normal)
-
-        # Only check if the triangle is not being treated as an infinite plane:
-        # Math based from http://paulbourke.net/geometry/linefacet/
-        if int_co is not None and not is_infinite:
-            pA = p1 - int_co
-            pB = p2 - int_co
-            pC = p3 - int_co
-            # These must be unit vectors, else we risk a domain error:
-            pA.length = 1
-            pB.length = 1
-            pC.length = 1
-            aAB = acos(pA.dot(pB))
-            aBC = acos(pB.dot(pC))
-            aCA = acos(pC.dot(pA))
-            sumA = aAB + aBC + aCA
-
-            # If the point is outside the triangle:
-            if (sumA > (pi + error) and sumA < (pi - error)):
-                int_co = None
-
-    # This is the default case where we either have a planar quad or an n-gon
-    else:
-        int_co = intersect_line_plane(edge.verts[0].co, edge.verts[1].co,
-                                      face.verts[0].co, face.normal)
-    return int_co
-
-
-# project_point_plane
-# Projects a point onto a plane. Returns a tuple of the projection vector
-# and the projected coordinate
-
-def project_point_plane(pt, plane_co, plane_no):
-    if ENABLE_DEBUG:
-        print("project_point_plane was called")
-    proj_co = intersect_line_plane(pt, pt + plane_no, plane_co, plane_no)
-    proj_ve = proj_co - pt
-    if ENABLE_DEBUG:
-        print("project_point_plane: proj_co is {}\nproj_ve is {}".format(proj_co, proj_ve))
-    return (proj_ve, proj_co)
-
-
-# ------------ CHAMPHER HELPER METHODS -------------
-
-def is_planar_edge(edge, error=0.000002):
-    angle = edge.calc_face_angle()
-    return ((angle < error and angle > -error) or
-            (angle < (180 + error) and angle > (180 - error)))
-
-
-# ------------- EDGE TOOL METHODS -------------------
-
-# Extends an "edge" in two directions:
-#   - Requires two vertices to be selected. They do not have to form an edge
-#   - Extends "length" in both directions
-
-class Extend(Operator):
-    bl_idname = "mesh.edgetools_extend"
-    bl_label = "Extend"
-    bl_description = "Extend the selected edges of vertex pairs"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    di1: BoolProperty(
-            name="Forwards",
-            description="Extend the edge forwards",
-            default=True
-            )
-    di2: BoolProperty(
-            name="Backwards",
-            description="Extend the edge backwards",
-            default=False
-            )
-    length: FloatProperty(
-            name="Length",
-            description="Length to extend the edge",
-            min=0.0, max=1024.0,
-            default=1.0
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        row = layout.row(align=True)
-        row.prop(self, "di1", toggle=True)
-        row.prop(self, "di2", toggle=True)
-
-        layout.prop(self, "length")
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def invoke(self, context, event):
-        return self.execute(context)
-
-    def execute(self, context):
-        try:
-            me = context.object.data
-            bm = bmesh.from_edit_mesh(me)
-            bm.normal_update()
-
-            bEdges = bm.edges
-            bVerts = bm.verts
-
-            edges = [e for e in bEdges if e.select]
-            verts = [v for v in bVerts if v.select]
-
-            if not is_selected_enough(self, edges, 0, edges_n=1, verts_n=0, types="Edge"):
-                return {'CANCELLED'}
-
-            if len(edges) > 0:
-                for e in edges:
-                    vector = e.verts[0].co - e.verts[1].co
-                    vector.length = self.length
-
-                    if self.di1:
-                        v = bVerts.new()
-                        if (vector[0] + vector[1] + vector[2]) < 0:
-                            v.co = e.verts[1].co - vector
-                            newE = bEdges.new((e.verts[1], v))
-                            bEdges.ensure_lookup_table()
-                        else:
-                            v.co = e.verts[0].co + vector
-                            newE = bEdges.new((e.verts[0], v))
-                            bEdges.ensure_lookup_table()
-                    if self.di2:
-                        v = bVerts.new()
-                        if (vector[0] + vector[1] + vector[2]) < 0:
-                            v.co = e.verts[0].co + vector
-                            newE = bEdges.new((e.verts[0], v))
-                            bEdges.ensure_lookup_table()
-                        else:
-                            v.co = e.verts[1].co - vector
-                            newE = bEdges.new((e.verts[1], v))
-                            bEdges.ensure_lookup_table()
-            else:
-                vector = verts[0].co - verts[1].co
-                vector.length = self.length
-
-                if self.di1:
-                    v = bVerts.new()
-                    if (vector[0] + vector[1] + vector[2]) < 0:
-                        v.co = verts[1].co - vector
-                        e = bEdges.new((verts[1], v))
-                        bEdges.ensure_lookup_table()
-                    else:
-                        v.co = verts[0].co + vector
-                        e = bEdges.new((verts[0], v))
-                        bEdges.ensure_lookup_table()
-                if self.di2:
-                    v = bVerts.new()
-                    if (vector[0] + vector[1] + vector[2]) < 0:
-                        v.co = verts[0].co + vector
-                        e = bEdges.new((verts[0], v))
-                        bEdges.ensure_lookup_table()
-                    else:
-                        v.co = verts[1].co - vector
-                        e = bEdges.new((verts[1], v))
-                        bEdges.ensure_lookup_table()
-
-            bmesh.update_edit_mesh(me)
-
-        except Exception as e:
-            error_handlers(self, "mesh.edgetools_extend", e,
-                           reports="Extend Operator failed", func=False)
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-# Creates a series of edges between two edges using spline interpolation.
-# This basically just exposes existing functionality in addition to some
-# other common methods: Hermite (c-spline), Bezier, and b-spline. These
-# alternates I coded myself after some extensive research into spline theory
-#
-# @todo Figure out what's wrong with the Blender bezier interpolation
-
-class Spline(Operator):
-    bl_idname = "mesh.edgetools_spline"
-    bl_label = "Spline"
-    bl_description = "Create a spline interplopation between two edges"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    alg: EnumProperty(
-            name="Spline Algorithm",
-            items=[('Blender', "Blender", "Interpolation provided through mathutils.geometry"),
-                    ('Hermite', "C-Spline", "C-spline interpolation"),
-                    ('Bezier', "Bezier", "Bezier interpolation"),
-                    ('B-Spline', "B-Spline", "B-Spline interpolation")],
-            default='Bezier'
-            )
-    segments: IntProperty(
-            name="Segments",
-            description="Number of segments to use in the interpolation",
-            min=2, max=4096,
-            soft_max=1024,
-            default=32
-            )
-    flip1: BoolProperty(
-            name="Flip Edge",
-            description="Flip the direction of the spline on Edge 1",
-            default=False
-            )
-    flip2: BoolProperty(
-            name="Flip Edge",
-            description="Flip the direction of the spline on Edge 2",
-            default=False
-            )
-    ten1: FloatProperty(
-            name="Tension",
-            description="Tension on Edge 1",
-            min=-4096.0, max=4096.0,
-            soft_min=-8.0, soft_max=8.0,
-            default=1.0
-            )
-    ten2: FloatProperty(
-            name="Tension",
-            description="Tension on Edge 2",
-            min=-4096.0, max=4096.0,
-            soft_min=-8.0, soft_max=8.0,
-            default=1.0
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.prop(self, "alg")
-        layout.prop(self, "segments")
-
-        layout.label(text="Edge 1:")
-        split = layout.split(factor=0.8, align=True)
-        split.prop(self, "ten1")
-        split.prop(self, "flip1", text="", icon="ALIGN", toggle=True)
-
-        layout.label(text="Edge 2:")
-        split = layout.split(factor=0.8, align=True)
-        split.prop(self, "ten2")
-        split.prop(self, "flip2", text="", icon="ALIGN", toggle=True)
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def invoke(self, context, event):
-        return self.execute(context)
-
-    def execute(self, context):
-        try:
-            me = context.object.data
-            bm = bmesh.from_edit_mesh(me)
-            bm.normal_update()
-
-            bEdges = bm.edges
-            bVerts = bm.verts
-
-            seg = self.segments
-            edges = [e for e in bEdges if e.select]
-
-            if not is_selected_enough(self, edges, 0, edges_n=2, verts_n=0, types="Edge"):
-                return {'CANCELLED'}
-
-            verts = [edges[v // 2].verts[v % 2] for v in range(4)]
-
-            if self.flip1:
-                v1 = verts[1]
-                p1_co = verts[1].co
-                p1_dir = verts[1].co - verts[0].co
-            else:
-                v1 = verts[0]
-                p1_co = verts[0].co
-                p1_dir = verts[0].co - verts[1].co
-            if self.ten1 < 0:
-                p1_dir = -1 * p1_dir
-                p1_dir.length = -self.ten1
-            else:
-                p1_dir.length = self.ten1
-
-            if self.flip2:
-                v2 = verts[3]
-                p2_co = verts[3].co
-                p2_dir = verts[2].co - verts[3].co
-            else:
-                v2 = verts[2]
-                p2_co = verts[2].co
-                p2_dir = verts[3].co - verts[2].co
-            if self.ten2 < 0:
-                p2_dir = -1 * p2_dir
-                p2_dir.length = -self.ten2
-            else:
-                p2_dir.length = self.ten2
-
-            # Get the interploted coordinates:
-            if self.alg == 'Blender':
-                pieces = interpolate_bezier(
-                                p1_co, p1_dir, p2_dir, p2_co, self.segments
-                                )
-            elif self.alg == 'Hermite':
-                pieces = interpolate_line_line(
-                                p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'HERMITE'
-                                )
-            elif self.alg == 'Bezier':
-                pieces = interpolate_line_line(
-                                p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'BEZIER'
-                                )
-            elif self.alg == 'B-Spline':
-                pieces = interpolate_line_line(
-                                p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'BSPLINE'
-                                )
-
-            verts = []
-            verts.append(v1)
-            # Add vertices and set the points:
-            for i in range(seg - 1):
-                v = bVerts.new()
-                v.co = pieces[i]
-                bVerts.ensure_lookup_table()
-                verts.append(v)
-            verts.append(v2)
-            # Connect vertices:
-            for i in range(seg):
-                e = bEdges.new((verts[i], verts[i + 1]))
-                bEdges.ensure_lookup_table()
-
-            bmesh.update_edit_mesh(me)
-
-        except Exception as e:
-            error_handlers(self, "mesh.edgetools_spline", e,
-                           reports="Spline Operator failed", func=False)
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-# Creates edges normal to planes defined between each of two edges and the
-# normal or the plane defined by those two edges.
-#   - Select two edges.  The must form a plane.
-#   - On running the script, eight edges will be created.  Delete the
-#     extras that you don't need.
-#   - The length of those edges is defined by the variable "length"
-#
-# @todo Change method from a cross product to a rotation matrix to make the
-#   angle part work.
-#   --- todo completed 2/4/2012, but still needs work ---
-# @todo Figure out a way to make +/- predictable
-#   - Maybe use angle between edges and vector direction definition?
-#   --- TODO COMPLETED ON 2/9/2012 ---
-
-class Ortho(Operator):
-    bl_idname = "mesh.edgetools_ortho"
-    bl_label = "Angle Off Edge"
-    bl_description = "Creates new edges within an angle from vertices of selected edges"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    vert1: BoolProperty(
-            name="Vertice 1",
-            description="Enable edge creation for Vertice 1",
-            default=True
-            )
-    vert2: BoolProperty(
-            name="Vertice 2",
-            description="Enable edge creation for Vertice 2",
-            default=True
-            )
-    vert3: BoolProperty(
-            name="Vertice 3",
-            description="Enable edge creation for Vertice 3",
-            default=True
-            )
-    vert4: BoolProperty(
-            name="Vertice 4",
-            description="Enable edge creation for Vertice 4",
-            default=True
-            )
-    pos: BoolProperty(
-            name="Positive",
-            description="Enable creation of positive direction edges",
-            default=True
-            )
-    neg: BoolProperty(
-            name="Negative",
-            description="Enable creation of negative direction edges",
-            default=True
-            )
-    angle: FloatProperty(
-            name="Angle",
-            description="Define the angle off of the originating edge",
-            min=0.0, max=180.0,
-            default=90.0
-            )
-    length: FloatProperty(
-            name="Length",
-            description="Length of created edges",
-            min=0.0, max=1024.0,
-            default=1.0
-            )
-    # For when only one edge is selected (Possible feature to be testd):
-    plane: EnumProperty(
-            name="Plane",
-            items=[("XY", "X-Y Plane", "Use the X-Y plane as the plane of creation"),
-                   ("XZ", "X-Z Plane", "Use the X-Z plane as the plane of creation"),
-                   ("YZ", "Y-Z Plane", "Use the Y-Z plane as the plane of creation")],
-            default="XY"
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.label(text="Creation:")
-        split = layout.split()
-        col = split.column()
-
-        col.prop(self, "vert1", toggle=True)
-        col.prop(self, "vert2", toggle=True)
-
-        col = split.column()
-        col.prop(self, "vert3", toggle=True)
-        col.prop(self, "vert4", toggle=True)
-
-        layout.label(text="Direction:")
-        row = layout.row(align=False)
-        row.alignment = 'EXPAND'
-        row.prop(self, "pos")
-        row.prop(self, "neg")
-
-        layout.separator()
-
-        col = layout.column(align=True)
-        col.prop(self, "angle")
-        col.prop(self, "length")
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def invoke(self, context, event):
-        return self.execute(context)
-
-    def execute(self, context):
-        try:
-            me = context.object.data
-            bm = bmesh.from_edit_mesh(me)
-            bm.normal_update()
-
-            bVerts = bm.verts
-            bEdges = bm.edges
-            edges = [e for e in bEdges if e.select]
-            vectors = []
-
-            if not is_selected_enough(self, edges, 0, edges_n=2, verts_n=0, types="Edge"):
-                return {'CANCELLED'}
-
-            verts = [edges[0].verts[0],
-                     edges[0].verts[1],
-                     edges[1].verts[0],
-                     edges[1].verts[1]]
-
-            cos = intersect_line_line(verts[0].co, verts[1].co, verts[2].co, verts[3].co)
-
-            # If the two edges are parallel:
-            if cos is None:
-                self.report({'WARNING'},
-                            "Selected lines are parallel: results may be unpredictable")
-                vectors.append(verts[0].co - verts[1].co)
-                vectors.append(verts[0].co - verts[2].co)
-                vectors.append(vectors[0].cross(vectors[1]))
-                vectors.append(vectors[2].cross(vectors[0]))
-                vectors.append(-vectors[3])
-            else:
-                # Warn the user if they have not chosen two planar edges:
-                if not is_same_co(cos[0], cos[1]):
-                    self.report({'WARNING'},
-                                "Selected lines are not planar: results may be unpredictable")
-
-                # This makes the +/- behavior predictable:
-                if (verts[0].co - cos[0]).length < (verts[1].co - cos[0]).length:
-                    verts[0], verts[1] = verts[1], verts[0]
-                if (verts[2].co - cos[0]).length < (verts[3].co - cos[0]).length:
-                    verts[2], verts[3] = verts[3], verts[2]
-
-                vectors.append(verts[0].co - verts[1].co)
-                vectors.append(verts[2].co - verts[3].co)
-
-                # Normal of the plane formed by vector1 and vector2:
-                vectors.append(vectors[0].cross(vectors[1]))
-
-                # Possible directions:
-                vectors.append(vectors[2].cross(vectors[0]))
-                vectors.append(vectors[1].cross(vectors[2]))
-
-            # Set the length:
-            vectors[3].length = self.length
-            vectors[4].length = self.length
-
-            # Perform any additional rotations:
-            matrix = Matrix.Rotation(radians(90 + self.angle), 3, vectors[2])
-            vectors.append(matrix * -vectors[3])    # vectors[5]
-            matrix = Matrix.Rotation(radians(90 - self.angle), 3, vectors[2])
-            vectors.append(matrix * vectors[4])     # vectors[6]
-            vectors.append(matrix * vectors[3])     # vectors[7]
-            matrix = Matrix.Rotation(radians(90 + self.angle), 3, vectors[2])
-            vectors.append(matrix * -vectors[4])    # vectors[8]
-
-            # Perform extrusions and displacements:
-            # There will be a total of 8 extrusions.  One for each vert of each edge.
-            # It looks like an extrusion will add the new vert to the end of the verts
-            # list and leave the rest in the same location.
-            # -- EDIT --
-            # It looks like I might be able to do this within "bpy.data" with the ".add" function
-
-            for v in range(len(verts)):
-                vert = verts[v]
-                if ((v == 0 and self.vert1) or (v == 1 and self.vert2) or
-                   (v == 2 and self.vert3) or (v == 3 and self.vert4)):
-
-                    if self.pos:
-                        new = bVerts.new()
-                        new.co = vert.co - vectors[5 + (v // 2) + ((v % 2) * 2)]
-                        bVerts.ensure_lookup_table()
-                        bEdges.new((vert, new))
-                        bEdges.ensure_lookup_table()
-                    if self.neg:
-                        new = bVerts.new()
-                        new.co = vert.co + vectors[5 + (v // 2) + ((v % 2) * 2)]
-                        bVerts.ensure_lookup_table()
-                        bEdges.new((vert, new))
-                        bEdges.ensure_lookup_table()
-
-            bmesh.update_edit_mesh(me)
-        except Exception as e:
-            error_handlers(self, "mesh.edgetools_ortho", e,
-                           reports="Angle Off Edge Operator failed", func=False)
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-# Usage:
-# Select an edge and a point or an edge and specify the radius (default is 1 BU)
-# You can select two edges but it might be unpredictable which edge it revolves
-# around so you might have to play with the switch
-
-class Shaft(Operator):
-    bl_idname = "mesh.edgetools_shaft"
-    bl_label = "Shaft"
-    bl_description = "Create a shaft mesh around an axis"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    # Selection defaults:
-    shaftType = 0
-
-    # For tracking if the user has changed selection:
-    last_edge: IntProperty(
-            name="Last Edge",
-            description="Tracks if user has changed selected edges",
-            min=0, max=1,
-            default=0
-            )
-    last_flip = False
-
-    edge: IntProperty(
-            name="Edge",
-            description="Edge to shaft around",
-            min=0, max=1,
-            default=0
-            )
-    flip: BoolProperty(
-            name="Flip Second Edge",
-            description="Flip the perceived direction of the second edge",
-            default=False
-            )
-    radius: FloatProperty(
-            name="Radius",
-            description="Shaft Radius",
-            min=0.0, max=1024.0,
-            default=1.0
-            )
-    start: FloatProperty(
-            name="Starting Angle",
-            description="Angle to start the shaft at",
-            min=-360.0, max=360.0,
-            default=0.0
-            )
-    finish: FloatProperty(
-            name="Ending Angle",
-            description="Angle to end the shaft at",
-            min=-360.0, max=360.0,
-            default=360.0
-            )
-    segments: IntProperty(
-            name="Shaft Segments",
-            description="Number of segments to use in the shaft",
-            min=1, max=4096,
-            soft_max=512,
-            default=32
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        if self.shaftType == 0:
-            layout.prop(self, "edge")
-            layout.prop(self, "flip")
-        elif self.shaftType == 3:
-            layout.prop(self, "radius")
-
-        layout.prop(self, "segments")
-        layout.prop(self, "start")
-        layout.prop(self, "finish")
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def invoke(self, context, event):
-        # Make sure these get reset each time we run:
-        self.last_edge = 0
-        self.edge = 0
-
-        return self.execute(context)
-
-    def execute(self, context):
-        try:
-            me = context.object.data
-            bm = bmesh.from_edit_mesh(me)
-            bm.normal_update()
-
-            bFaces = bm.faces
-            bEdges = bm.edges
-            bVerts = bm.verts
-
-            active = None
-            edges, verts = [], []
-
-            # Pre-caclulated values:
-            rotRange = [radians(self.start), radians(self.finish)]
-            rads = radians((self.finish - self.start) / self.segments)
-
-            numV = self.segments + 1
-            numE = self.segments
-
-            edges = [e for e in bEdges if e.select]
-
-            # Robustness check: there should at least be one edge selected
-            if not is_selected_enough(self, edges, 0, edges_n=1, verts_n=0, types="Edge"):
-                return {'CANCELLED'}
-
-            # If two edges are selected:
-            if len(edges) == 2:
-                # default:
-                edge = [0, 1]
-                vert = [0, 1]
-
-                # By default, we want to shaft around the last selected edge (it
-                # will be the active edge). We know we are using the default if
-                # the user has not changed which edge is being shafted around (as
-                # is tracked by self.last_edge). When they are not the same, then
-                # the user has changed selection.
-                # We then need to make sure that the active object really is an edge
-                # (robustness check)
-                # Finally, if the active edge is not the initial one, we flip them
-                # and have the GUI reflect that
-                if self.last_edge == self.edge:
-                    if isinstance(bm.select_history.active, bmesh.types.BMEdge):
-                        if bm.select_history.active != edges[edge[0]]:
-                            self.last_edge, self.edge = edge[1], edge[1]
-                            edge = [edge[1], edge[0]]
-                    else:
-                        flip_edit_mode()
-                        self.report({'WARNING'},
-                                    "Active geometry is not an edge. Operation Cancelled")
-                        return {'CANCELLED'}
-                elif self.edge == 1:
-                    edge = [1, 0]
-
-                verts.append(edges[edge[0]].verts[0])
-                verts.append(edges[edge[0]].verts[1])
-
-                if self.flip:
-                    verts = [1, 0]
-
-                verts.append(edges[edge[1]].verts[vert[0]])
-                verts.append(edges[edge[1]].verts[vert[1]])
-
-                self.shaftType = 0
-            # If there is more than one edge selected:
-            # There are some issues with it ATM, so don't expose is it to normal users
-            # @todo Fix edge connection ordering issue
-            elif ENABLE_DEBUG and len(edges) > 2:
-                if isinstance(bm.select_history.active, bmesh.types.BMEdge):
-                    active = bm.select_history.active
-                    edges.remove(active)
-                    # Get all the verts:
-                    # edges = order_joined_edges(edges[0])
-                    verts = []
-                    for e in edges:
-                        if verts.count(e.verts[0]) == 0:
-                            verts.append(e.verts[0])
-                        if verts.count(e.verts[1]) == 0:
-                            verts.append(e.verts[1])
-                else:
-                    flip_edit_mode()
-                    self.report({'WARNING'},
-                                "Active geometry is not an edge. Operation Cancelled")
-                    return {'CANCELLED'}
-                self.shaftType = 1
-            else:
-                verts.append(edges[0].verts[0])
-                verts.append(edges[0].verts[1])
-
-                for v in bVerts:
-                    if v.select and verts.count(v) == 0:
-                        verts.append(v)
-                    v.select = False
-                if len(verts) == 2:
-                    self.shaftType = 3
-                else:
-                    self.shaftType = 2
-
-            # The vector denoting the axis of rotation:
-            if self.shaftType == 1:
-                axis = active.verts[1].co - active.verts[0].co
-            else:
-                axis = verts[1].co - verts[0].co
-
-            # We will need a series of rotation matrices. We could use one which
-            # would be faster but also might cause propagation of error
-            # matrices = []
-            # for i in range(numV):
-            #    matrices.append(Matrix.Rotation((rads * i) + rotRange[0], 3, axis))
-            matrices = [Matrix.Rotation((rads * i) + rotRange[0], 3, axis) for i in range(numV)]
-
-            # New vertice coordinates:
-            verts_out = []
-
-            # If two edges were selected:
-            #  - If the lines are not parallel, then it will create a cone-like shaft
-            if self.shaftType == 0:
-                for i in range(len(verts) - 2):
-                    init_vec = distance_point_line(verts[i + 2].co, verts[0].co, verts[1].co)
-                    co = init_vec + verts[i + 2].co
-                    # These will be rotated about the origin so will need to be shifted:
-                    for j in range(numV):
-                        verts_out.append(co - (matrices[j] * init_vec))
-            elif self.shaftType == 1:
-                for i in verts:
-                    init_vec = distance_point_line(i.co, active.verts[0].co, active.verts[1].co)
-                    co = init_vec + i.co
-                    # These will be rotated about the origin so will need to be shifted:
-                    for j in range(numV):
-                        verts_out.append(co - (matrices[j] * init_vec))
-            # Else if a line and a point was selected:
-            elif self.shaftType == 2:
-                init_vec = distance_point_line(verts[2].co, verts[0].co, verts[1].co)
-                # These will be rotated about the origin so will need to be shifted:
-                verts_out = [
-                    (verts[i].co - (matrices[j] * init_vec)) for i in range(2) for j in range(numV)
-                    ]
-            else:
-                # Else the above are not possible, so we will just use the edge:
-                #  - The vector defined by the edge is the normal of the plane for the shaft
-                #  - The shaft will have radius "radius"
-                if is_axial(verts[0].co, verts[1].co) is None:
-                    proj = (verts[1].co - verts[0].co)
-                    proj[2] = 0
-                    norm = proj.cross(verts[1].co - verts[0].co)
-                    vec = norm.cross(verts[1].co - verts[0].co)
-                    vec.length = self.radius
-                elif is_axial(verts[0].co, verts[1].co) == 'Z':
-                    vec = verts[0].co + Vector((0, 0, self.radius))
-                else:
-                    vec = verts[0].co + Vector((0, self.radius, 0))
-                init_vec = distance_point_line(vec, verts[0].co, verts[1].co)
-                # These will be rotated about the origin so will need to be shifted:
-                verts_out = [
-                    (verts[i].co - (matrices[j] * init_vec)) for i in range(2) for j in range(numV)
-                    ]
-
-            # We should have the coordinates for a bunch of new verts
-            # Now add the verts and build the edges and then the faces
-
-            newVerts = []
-
-            if self.shaftType == 1:
-                # Vertices:
-                for i in range(numV * len(verts)):
-                    new = bVerts.new()
-                    new.co = verts_out[i]
-                    bVerts.ensure_lookup_table()
-                    new.select = True
-                    newVerts.append(new)
-                # Edges:
-                for i in range(numE):
-                    for j in range(len(verts)):
-                        e = bEdges.new((newVerts[i + (numV * j)], newVerts[i + (numV * j) + 1]))
-                        bEdges.ensure_lookup_table()
-                        e.select = True
-                for i in range(numV):
-                    for j in range(len(verts) - 1):
-                        e = bEdges.new((newVerts[i + (numV * j)], newVerts[i + (numV * (j + 1))]))
-                        bEdges.ensure_lookup_table()
-                        e.select = True
-
-                # Faces: There is a problem with this right now
-                """
-                for i in range(len(edges)):
-                    for j in range(numE):
-                        f = bFaces.new((newVerts[i], newVerts[i + 1],
-                                       newVerts[i + (numV * j) + 1], newVerts[i + (numV * j)]))
-                        f.normal_update()
-                """
-            else:
-                # Vertices:
-                for i in range(numV * 2):
-                    new = bVerts.new()
-                    new.co = verts_out[i]
-                    new.select = True
-                    bVerts.ensure_lookup_table()
-                    newVerts.append(new)
-                # Edges:
-                for i in range(numE):
-                    e = bEdges.new((newVerts[i], newVerts[i + 1]))
-                    e.select = True
-                    bEdges.ensure_lookup_table()
-                    e = bEdges.new((newVerts[i + numV], newVerts[i + numV + 1]))
-                    e.select = True
-                    bEdges.ensure_lookup_table()
-                for i in range(numV):
-                    e = bEdges.new((newVerts[i], newVerts[i + numV]))
-                    e.select = True
-                    bEdges.ensure_lookup_table()
-                # Faces:
-                for i in range(numE):
-                    f = bFaces.new((newVerts[i], newVerts[i + 1],
-                                    newVerts[i + numV + 1], newVerts[i + numV]))
-                    bFaces.ensure_lookup_table()
-                    f.normal_update()
-
-            bmesh.update_edit_mesh(me)
-
-        except Exception as e:
-            error_handlers(self, "mesh.edgetools_shaft", e,
-                           reports="Shaft Operator failed", func=False)
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-# "Slices" edges crossing a plane defined by a face
-
-class Slice(Operator):
-    bl_idname = "mesh.edgetools_slice"
-    bl_label = "Slice"
-    bl_description = "Cut edges at the plane defined by a selected face"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    make_copy: BoolProperty(
-            name="Make Copy",
-            description="Make new vertices at intersection points instead of splitting the edge",
-            default=False
-            )
-    rip: BoolProperty(
-            name="Rip",
-            description="Split into two edges that DO NOT share an intersection vertex",
-            default=True
-            )
-    pos: BoolProperty(
-            name="Positive",
-            description="Remove the portion on the side of the face normal",
-            default=False
-            )
-    neg: BoolProperty(
-            name="Negative",
-            description="Remove the portion on the side opposite of the face normal",
-            default=False
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.prop(self, "make_copy")
-        if not self.make_copy:
-            layout.prop(self, "rip")
-            layout.label(text="Remove Side:")
-            layout.prop(self, "pos")
-            layout.prop(self, "neg")
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def invoke(self, context, event):
-        return self.execute(context)
-
-    def execute(self, context):
-        try:
-            me = context.object.data
-            bm = bmesh.from_edit_mesh(me)
-            bm.normal_update()
-
-            bVerts = bm.verts
-            bEdges = bm.edges
-            bFaces = bm.faces
-
-            face, normal = None, None
-
-            # Find the selected face. This will provide the plane to project onto:
-            #  - First check to use the active face. Allows users to just
-            #    select a bunch of faces with the last being the cutting plane
-            #  - If that fails, then use the first found selected face in the BMesh face list
-            if isinstance(bm.select_history.active, bmesh.types.BMFace):
-                face = bm.select_history.active
-                normal = bm.select_history.active.normal
-                bm.select_history.active.select = False
-            else:
-                for f in bFaces:
-                    if f.select:
-                        face = f
-                        normal = f.normal
-                        f.select = False
-                        break
-
-            # If we don't find a selected face exit:
-            if face is None:
-                flip_edit_mode()
-                self.report({'WARNING'},
-                            "Please select a face as the cutting plane. Operation Cancelled")
-                return {'CANCELLED'}
-
-            # Warn the user if they are using an n-gon might lead to some odd results
-            elif len(face.verts) > 4 and not is_face_planar(face):
-                self.report({'WARNING'},
-                            "Selected face is an N-gon.  Results may be unpredictable")
-
-            if ENABLE_DEBUG:
-                dbg = 0
-                print("Number of Edges: ", len(bEdges))
-
-            for e in bEdges:
-                if ENABLE_DEBUG:
-                    print("Looping through Edges - ", dbg)
-                    dbg = dbg + 1
-
-                # Get the end verts on the edge:
-                v1 = e.verts[0]
-                v2 = e.verts[1]
-
-                # Make sure that verts are not a part of the cutting plane:
-                if e.select and (v1 not in face.verts and v2 not in face.verts):
-                    if len(face.verts) < 5:  # Not an n-gon
-                        intersection = intersect_line_face(e, face, True)
-                    else:
-                        intersection = intersect_line_plane(v1.co, v2.co, face.verts[0].co, normal)
-
-                    if ENABLE_DEBUG:
-                        print("Intersection: ", intersection)
-
-                    # If an intersection exists find the distance of each of the end
-                    # points from the plane, with "positive" being in the direction
-                    # of the cutting plane's normal. If the points are on opposite
-                    # side of the plane, then it intersects and we need to cut it
-                    if intersection is not None:
-                        bVerts.ensure_lookup_table()
-                        bEdges.ensure_lookup_table()
-                        bFaces.ensure_lookup_table()
-
-                        d1 = distance_point_to_plane(v1.co, face.verts[0].co, normal)
-                        d2 = distance_point_to_plane(v2.co, face.verts[0].co, normal)
-                        # If they have different signs, then the edge crosses the cutting plane:
-                        if abs(d1 + d2) < abs(d1 - d2):
-                            # Make the first vertex the positive one:
-                            if d1 < d2:
-                                v2, v1 = v1, v2
-
-                            if self.make_copy:
-                                new = bVerts.new()
-                                new.co = intersection
-                                new.select = True
-                                bVerts.ensure_lookup_table()
-                            elif self.rip:
-                                if ENABLE_DEBUG:
-                                    print("Branch rip engaged")
-                                newV1 = bVerts.new()
-                                newV1.co = intersection
-                                bVerts.ensure_lookup_table()
-                                if ENABLE_DEBUG:
-                                    print("newV1 created", end='; ')
-
-                                newV2 = bVerts.new()
-                                newV2.co = intersection
-                                bVerts.ensure_lookup_table()
-
-                                if ENABLE_DEBUG:
-                                    print("newV2 created", end='; ')
-
-                                newE1 = bEdges.new((v1, newV1))
-                                newE2 = bEdges.new((v2, newV2))
-                                bEdges.ensure_lookup_table()
-
-                                if ENABLE_DEBUG:
-                                    print("new edges created", end='; ')
-
-                                if e.is_valid:
-                                    bEdges.remove(e)
-
-                                bEdges.ensure_lookup_table()
-
-                                if ENABLE_DEBUG:
-                                    print("Old edge removed.\nWe're done with this edge")
-                            else:
-                                new = list(bmesh.utils.edge_split(e, v1, 0.5))
-                                bEdges.ensure_lookup_table()
-                                new[1].co = intersection
-                                e.select = False
-                                new[0].select = False
-                                if self.pos:
-                                    bEdges.remove(new[0])
-                                if self.neg:
-                                    bEdges.remove(e)
-                                bEdges.ensure_lookup_table()
-
-            if ENABLE_DEBUG:
-                print("The Edge Loop has exited. Now to update the bmesh")
-                dbg = 0
-
-            bmesh.update_edit_mesh(me)
-
-        except Exception as e:
-            error_handlers(self, "mesh.edgetools_slice", e,
-                           reports="Slice Operator failed", func=False)
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-# This projects the selected edges onto the selected plane
-# and/or both points on the selected edge
-
-class Project(Operator):
-    bl_idname = "mesh.edgetools_project"
-    bl_label = "Project"
-    bl_description = ("Projects the selected Vertices/Edges onto a selected plane\n"
-                      "(Active is projected onto the rest)")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    make_copy: BoolProperty(
-            name="Make Copy",
-            description="Make duplicates of the vertices instead of altering them",
-            default=False
-            )
-
-    def draw(self, context):
-        layout = self.layout
-        layout.prop(self, "make_copy")
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return (ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def invoke(self, context, event):
-        return self.execute(context)
-
-    def execute(self, context):
-        try:
-            me = context.object.data
-            bm = bmesh.from_edit_mesh(me)
-            bm.normal_update()
-
-            bFaces = bm.faces
-            bVerts = bm.verts
-
-            fVerts = []
-
-            # Find the selected face.  This will provide the plane to project onto:
-            # @todo Check first for an active face
-            for f in bFaces:
-                if f.select:
-                    for v in f.verts:
-                        fVerts.append(v)
-                    normal = f.normal
-                    f.select = False
-                    break
-
-            for v in bVerts:
-                if v.select:
-                    if v in fVerts:
-                        v.select = False
-                        continue
-                    d = distance_point_to_plane(v.co, fVerts[0].co, normal)
-                    if self.make_copy:
-                        temp = v
-                        v = bVerts.new()
-                        v.co = temp.co
-                        bVerts.ensure_lookup_table()
-                    vector = normal
-                    vector.length = abs(d)
-                    v.co = v.co - (vector * sign(d))
-                    v.select = False
-
-            bmesh.update_edit_mesh(me)
-
-        except Exception as e:
-            error_handlers(self, "mesh.edgetools_project", e,
-                           reports="Project Operator failed", func=False)
-
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-# Project_End is for projecting/extending an edge to meet a plane
-# This is used be selecting a face to define the plane then all the edges
-# Then move the vertices in the edge that is closest to the
-# plane to the coordinates of the intersection of the edge and the plane
-
-class Project_End(Operator):
-    bl_idname = "mesh.edgetools_project_end"
-    bl_label = "Project (End Point)"
-    bl_description = ("Projects the vertices of the selected\n"
-                      "edges closest to a plane onto that plane")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    make_copy: BoolProperty(
-            name="Make Copy",
-            description="Make a duplicate of the vertice instead of moving it",
-            default=False
-            )
-    keep_length: BoolProperty(
-            name="Keep Edge Length",
-            description="Maintain edge lengths",
-            default=False
-            )
-    use_force: BoolProperty(
-            name="Use opposite vertices",
-            description="Force the usage of the vertices at the other end of the edge",
-            default=False
-            )
-    use_normal: BoolProperty(
-            name="Project along normal",
-            description="Use the plane's normal as the projection direction",
-            default=False
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        if not self.keep_length:
-            layout.prop(self, "use_normal")
-        layout.prop(self, "make_copy")
-        layout.prop(self, "use_force")
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def invoke(self, context, event):
-        return self.execute(context)
-
-    def execute(self, context):
-        try:
-            me = context.object.data
-            bm = bmesh.from_edit_mesh(me)
-            bm.normal_update()
-
-            bFaces = bm.faces
-            bEdges = bm.edges
-            bVerts = bm.verts
-
-            fVerts = []
-
-            # Find the selected face. This will provide the plane to project onto:
-            for f in bFaces:
-                if f.select:
-                    for v in f.verts:
-                        fVerts.append(v)
-                    normal = f.normal
-                    f.select = False
-                    break
-
-            for e in bEdges:
-                if e.select:
-                    v1 = e.verts[0]
-                    v2 = e.verts[1]
-                    if v1 in fVerts or v2 in fVerts:
-                        e.select = False
-                        continue
-                    intersection = intersect_line_plane(v1.co, v2.co, fVerts[0].co, normal)
-                    if intersection is not None:
-                        # Use abs because we don't care what side of plane we're on:
-                        d1 = distance_point_to_plane(v1.co, fVerts[0].co, normal)
-                        d2 = distance_point_to_plane(v2.co, fVerts[0].co, normal)
-                        # If d1 is closer than we use v1 as our vertice:
-                        # "xor" with 'use_force':
-                        if (abs(d1) < abs(d2)) is not self.use_force:
-                            if self.make_copy:
-                                v1 = bVerts.new()
-                                v1.co = e.verts[0].co
-                                bVerts.ensure_lookup_table()
-                                bEdges.ensure_lookup_table()
-                            if self.keep_length:
-                                v1.co = intersection
-                            elif self.use_normal:
-                                vector = normal
-                                vector.length = abs(d1)
-                                v1.co = v1.co - (vector * sign(d1))
-                            else:
-                                v1.co = intersection
-                        else:
-                            if self.make_copy:
-                                v2 = bVerts.new()
-                                v2.co = e.verts[1].co
-                                bVerts.ensure_lookup_table()
-                                bEdges.ensure_lookup_table()
-                            if self.keep_length:
-                                v2.co = intersection
-                            elif self.use_normal:
-                                vector = normal
-                                vector.length = abs(d2)
-                                v2.co = v2.co - (vector * sign(d2))
-                            else:
-                                v2.co = intersection
-                    e.select = False
-
-            bmesh.update_edit_mesh(me)
-
-        except Exception as e:
-            error_handlers(self, "mesh.edgetools_project_end", e,
-                           reports="Project (End Point) Operator failed", func=False)
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-class VIEW3D_MT_edit_mesh_edgetools(Menu):
-    bl_label = "Edge Tools"
-    bl_description = "Various tools for manipulating edges"
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.operator("mesh.edgetools_extend")
-        layout.operator("mesh.edgetools_spline")
-        layout.operator("mesh.edgetools_ortho")
-        layout.operator("mesh.edgetools_shaft")
-        layout.operator("mesh.edgetools_slice")
-        layout.separator()
-
-        layout.operator("mesh.edgetools_project")
-        layout.operator("mesh.edgetools_project_end")
-
-
-# define classes for registration
-classes = (
-    VIEW3D_MT_edit_mesh_edgetools,
-    Extend,
-    Spline,
-    Ortho,
-    Shaft,
-    Slice,
-    Project,
-    Project_End,
-    )
-
-
-# registering and menu integration
-def register():
-    for cls in classes:
-        bpy.utils.register_class(cls)
-
-
-# unregistering and removing menus
-def unregister():
-    for cls in classes:
-        bpy.utils.unregister_class(cls)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_extrude_and_reshape.py b/mesh_extra_tools/mesh_extrude_and_reshape.py
deleted file mode 100644
index ec7b969d7..000000000
--- a/mesh_extra_tools/mesh_extrude_and_reshape.py
+++ /dev/null
@@ -1,378 +0,0 @@
-# ##### 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 3
-#  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, see <http://www.gnu.org/licenses/>.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# Contact for more information about the Addon:
-# Email:    germano.costa@ig.com.br
-# Twitter:  wii_mano @mano_wii
-
-bl_info = {
-    "name": "Extrude and Reshape",
-    "author": "Germano Cavalcante",
-    "version": (0, 8, 1),
-    "blender": (2, 76, 5),
-    "location": "View3D > TOOLS > Tools > Mesh Tools > Add: > Extrude Menu (Alt + E)",
-    "description": "Extrude face and merge edge intersections "
-                   "between the mesh and the new edges",
-    "wiki_url": "http://blenderartists.org/forum/"
-                "showthread.php?376618-Addon-Push-Pull-Face",
-    "category": "Mesh"}
-
-import bpy
-import bmesh
-from mathutils.geometry import intersect_line_line
-from bpy.types import Operator
-
-
-class BVHco():
-    i = 0
-    c1x = 0.0
-    c1y = 0.0
-    c1z = 0.0
-    c2x = 0.0
-    c2y = 0.0
-    c2z = 0.0
-
-
-def edges_BVH_overlap(bm, edges, epsilon=0.0001):
-    bco = set()
-    for e in edges:
-        bvh = BVHco()
-        bvh.i = e.index
-        b1 = e.verts[0]
-        b2 = e.verts[1]
-        co1 = b1.co.x
-        co2 = b2.co.x
-        if co1 <= co2:
-            bvh.c1x = co1 - epsilon
-            bvh.c2x = co2 + epsilon
-        else:
-            bvh.c1x = co2 - epsilon
-            bvh.c2x = co1 + epsilon
-        co1 = b1.co.y
-        co2 = b2.co.y
-        if co1 <= co2:
-            bvh.c1y = co1 - epsilon
-            bvh.c2y = co2 + epsilon
-        else:
-            bvh.c1y = co2 - epsilon
-            bvh.c2y = co1 + epsilon
-        co1 = b1.co.z
-        co2 = b2.co.z
-        if co1 <= co2:
-            bvh.c1z = co1 - epsilon
-            bvh.c2z = co2 + epsilon
-        else:
-            bvh.c1z = co2 - epsilon
-            bvh.c2z = co1 + epsilon
-        bco.add(bvh)
-    del edges
-    overlap = {}
-    oget = overlap.get
-    for e1 in bm.edges:
-        by = bz = True
-        a1 = e1.verts[0]
-        a2 = e1.verts[1]
-        c1x = a1.co.x
-        c2x = a2.co.x
-        if c1x > c2x:
-            tm = c1x
-            c1x = c2x
-            c2x = tm
-        for bvh in bco:
-            if c1x <= bvh.c2x and c2x >= bvh.c1x:
-                if by:
-                    by = False
-                    c1y = a1.co.y
-                    c2y = a2.co.y
-                    if c1y > c2y:
-                        tm = c1y
-                        c1y = c2y
-                        c2y = tm
-                if c1y <= bvh.c2y and c2y >= bvh.c1y:
-                    if bz:
-                        bz = False
-                        c1z = a1.co.z
-                        c2z = a2.co.z
-                        if c1z > c2z:
-                            tm = c1z
-                            c1z = c2z
-                            c2z = tm
-                    if c1z <= bvh.c2z and c2z >= bvh.c1z:
-                        e2 = bm.edges[bvh.i]
-                        if e1 != e2:
-                            overlap[e1] = oget(e1, set()).union({e2})
-    return overlap
-
-
-def intersect_edges_edges(overlap, precision=4):
-    epsilon = .1**precision
-    fpre_min = -epsilon
-    fpre_max = 1 + epsilon
-    splits = {}
-    sp_get = splits.get
-    new_edges1 = set()
-    new_edges2 = set()
-    targetmap = {}
-    for edg1 in overlap:
-        # print("***", ed1.index, "***")
-        for edg2 in overlap[edg1]:
-            a1 = edg1.verts[0]
-            a2 = edg1.verts[1]
-            b1 = edg2.verts[0]
-            b2 = edg2.verts[1]
-
-            # test if are linked
-            if a1 in {b1, b2} or a2 in {b1, b2}:
-                # print('linked')
-                continue
-
-            aco1, aco2 = a1.co, a2.co
-            bco1, bco2 = b1.co, b2.co
-            tp = intersect_line_line(aco1, aco2, bco1, bco2)
-            if tp:
-                p1, p2 = tp
-                if (p1 - p2).to_tuple(precision) == (0, 0, 0):
-                    v = aco2 - aco1
-                    f = p1 - aco1
-                    x, y, z = abs(v.x), abs(v.y), abs(v.z)
-                    max1 = 0 if x >= y and x >= z else\
-                           1 if y >= x and y >= z else 2
-                    fac1 = f[max1] / v[max1]
-
-                    v = bco2 - bco1
-                    f = p2 - bco1
-                    x, y, z = abs(v.x), abs(v.y), abs(v.z)
-                    max2 = 0 if x >= y and x >= z else\
-                           1 if y >= x and y >= z else 2
-                    fac2 = f[max2] / v[max2]
-
-                    if fpre_min <= fac1 <= fpre_max:
-                        # print(edg1.index, 'can intersect', edg2.index)
-                        ed1 = edg1
-
-                    elif edg1 in splits:
-                        for ed1 in splits[edg1]:
-                            a1 = ed1.verts[0]
-                            a2 = ed1.verts[1]
-
-                            vco1 = a1.co
-                            vco2 = a2.co
-
-                            v = vco2 - vco1
-                            f = p1 - vco1
-                            fac1 = f[max1] / v[max1]
-                            if fpre_min <= fac1 <= fpre_max:
-                                # print(e.index, 'can intersect', edg2.index)
-                                break
-                        else:
-                            # print(edg1.index, 'really does not intersect', edg2.index)
-                            continue
-                    else:
-                        # print(edg1.index, 'not intersect', edg2.index)
-                        continue
-
-                    if fpre_min <= fac2 <= fpre_max:
-                        # print(ed1.index, 'actually intersect', edg2.index)
-                        ed2 = edg2
-
-                    elif edg2 in splits:
-                        for ed2 in splits[edg2]:
-                            b1 = ed2.verts[0]
-                            b2 = ed2.verts[1]
-
-                            vco1 = b1.co
-                            vco2 = b2.co
-
-                            v = vco2 - vco1
-                            f = p2 - vco1
-                            fac2 = f[max2] / v[max2]
-                            if fpre_min <= fac2 <= fpre_max:
-                                # print(ed1.index, 'actually intersect', e.index)
-                                break
-                        else:
-                            # print(ed1.index, 'really does not intersect', ed2.index)
-                            continue
-                    else:
-                        # print(ed1.index, 'not intersect', edg2.index)
-                        continue
-
-                    new_edges1.add(ed1)
-                    new_edges2.add(ed2)
-
-                    if abs(fac1) <= epsilon:
-                        nv1 = a1
-                    elif fac1 + epsilon >= 1:
-                        nv1 = a2
-                    else:
-                        ne1, nv1 = bmesh.utils.edge_split(ed1, a1, fac1)
-                        new_edges1.add(ne1)
-                        splits[edg1] = sp_get(edg1, set()).union({ne1})
-
-                    if abs(fac2) <= epsilon:
-                        nv2 = b1
-                    elif fac2 + epsilon >= 1:
-                        nv2 = b2
-                    else:
-                        ne2, nv2 = bmesh.utils.edge_split(ed2, b1, fac2)
-                        new_edges2.add(ne2)
-                        splits[edg2] = sp_get(edg2, set()).union({ne2})
-
-                    if nv1 != nv2:  # necessary?
-                        targetmap[nv1] = nv2
-
-    return new_edges1, new_edges2, targetmap
-
-
-class Extrude_and_Reshape(Operator):
-    bl_idname = "mesh.extrude_reshape"
-    bl_label = "Extrude and Reshape"
-    bl_description = "Push and pull face entities to sculpt 3d models"
-    bl_options = {'REGISTER', 'GRAB_CURSOR', 'BLOCKING'}
-
-    @classmethod
-    def poll(cls, context):
-        return context.mode != 'EDIT_MESH'
-
-    def modal(self, context, event):
-        if self.confirm:
-            sface = self.bm.faces.active
-            if not sface:
-                for face in self.bm.faces:
-                    if face.select is True:
-                        sface = face
-                        break
-                else:
-                    return {'FINISHED'}
-            # edges to intersect
-            edges = set()
-            [[edges.add(ed) for ed in v.link_edges] for v in sface.verts]
-
-            overlap = edges_BVH_overlap(self.bm, edges, epsilon=0.0001)
-            overlap = {k: v for k, v in overlap.items() if k not in edges}  # remove repetition
-            """
-            print([e.index for e in edges])
-            for a, b in overlap.items():
-                print(a.index, [e.index for e in b])
-            """
-            new_edges1, new_edges2, targetmap = intersect_edges_edges(overlap)
-            pos_weld = set()
-            for e in new_edges1:
-                v1, v2 = e.verts
-                if v1 in targetmap and v2 in targetmap:
-                    pos_weld.add((targetmap[v1], targetmap[v2]))
-            if targetmap:
-                bmesh.ops.weld_verts(self.bm, targetmap=targetmap)
-            """
-            print([e.is_valid for e in new_edges1])
-            print([e.is_valid for e in new_edges2])
-            sp_faces1 = set()
-            """
-            for e in pos_weld:
-                v1, v2 = e
-                lf1 = set(v1.link_faces)
-                lf2 = set(v2.link_faces)
-                rlfe = lf1.intersection(lf2)
-                for f in rlfe:
-                    try:
-                        nf = bmesh.utils.face_split(f, v1, v2)
-                        # sp_faces1.update({f, nf[0]})
-                    except:
-                        pass
-
-            # sp_faces2 = set()
-            for e in new_edges2:
-                lfe = set(e.link_faces)
-                v1, v2 = e.verts
-                lf1 = set(v1.link_faces)
-                lf2 = set(v2.link_faces)
-                rlfe = lf1.intersection(lf2)
-                for f in rlfe.difference(lfe):
-                    nf = bmesh.utils.face_split(f, v1, v2)
-                    # sp_faces2.update({f, nf[0]})
-
-            bmesh.update_edit_mesh(self.mesh, loop_triangles=True, destructive=True)
-            return {'FINISHED'}
-        if self.cancel:
-            return {'FINISHED'}
-        self.cancel = event.type in {'ESC', 'NDOF_BUTTON_ESC'}
-        self.confirm = event.type in {'LEFTMOUSE', 'RET', 'NUMPAD_ENTER'}
-        return {'PASS_THROUGH'}
-
-    def execute(self, context):
-        self.mesh = context.object.data
-        self.bm = bmesh.from_edit_mesh(self.mesh)
-        try:
-            selection = self.bm.select_history[-1]
-        except:
-            for face in self.bm.faces:
-                if face.select is True:
-                    selection = face
-                    break
-            else:
-                return {'FINISHED'}
-        if not isinstance(selection, bmesh.types.BMFace):
-            bpy.ops.mesh.extrude_region_move('INVOKE_DEFAULT')
-            return {'FINISHED'}
-        else:
-            face = selection
-            # face.select = False
-            bpy.ops.mesh.select_all(action='DESELECT')
-            geom = []
-            for edge in face.edges:
-                if abs(edge.calc_face_angle(0) - 1.5707963267948966) < 0.01:  # self.angle_tolerance:
-                    geom.append(edge)
-
-            ret_dict = bmesh.ops.extrude_discrete_faces(self.bm, faces=[face])
-
-            for face in ret_dict['faces']:
-                self.bm.faces.active = face
-                face.select = True
-                sface = face
-            dfaces = bmesh.ops.dissolve_edges(
-                        self.bm, edges=geom, use_verts=True, use_face_split=False
-                        )
-            bmesh.update_edit_mesh(self.mesh, loop_triangles=True, destructive=True)
-            bpy.ops.transform.translate(
-                        'INVOKE_DEFAULT', constraint_axis=(False, False, True),
-                        orient_type='NORMAL', release_confirm=True
-                        )
-
-        context.window_manager.modal_handler_add(self)
-
-        self.cancel = False
-        self.confirm = False
-        return {'RUNNING_MODAL'}
-
-
-def operator_draw(self, context):
-    layout = self.layout
-    col = layout.column(align=True)
-    col.operator("mesh.extrude_reshape", text="Extrude and Reshape")
-
-
-def register():
-    bpy.utils.register_class(Extrude_and_Reshape)
-    bpy.types.VIEW3D_MT_edit_mesh_extrude.append(operator_draw)
-
-
-def unregister():
-    bpy.types.VIEW3D_MT_edit_mesh_extrude.remove(operator_draw)
-    bpy.utils.unregister_class(Extrude_and_Reshape)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_fastloop.py b/mesh_extra_tools/mesh_fastloop.py
deleted file mode 100644
index b52a35077..000000000
--- a/mesh_extra_tools/mesh_fastloop.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# ##### 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 #####
-
-bl_info = {
-    "name": "Fast Loop",
-    "description": "Add loops fast",
-    "author": "Andy Davies (metalliandy)",
-    "version": (0, 1, 7),
-    "blender": (2, 56, 0),
-    "location": "Tool Shelf",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"
-    }
-
-"""
-About this script:-
-This script enables the fast creation of multiple loops on a mesh
-
-Usage:-
-1)Click the FastLoop button on the Tool Shelf to activate the tool
-2)Hover over the mesh in the general area where you would like a loop to be added
-  (shown by a highlight on the mesh)
-3)Click once to confirm the loop placement
-4)place the loop and then slide to fine tune its position
-5)Repeat 1-4 if needed
-6)Press Esc. twice to exit the tool
-
-Related Links:-
-http://blenderartists.org/forum/showthread.php?t=206989
-http://www.metalliandy.com
-
-Thanks to:-
-Bartius Crouch (Crouch) - http://sites.google.com/site/bartiuscrouch/
-Dealga McArdle (zeffii) - http://www.digitalaphasia.com
-
-Version history:-
-v0.16 - Amended script for compatibility with recent API changes
-v0.15 - Amended script meta information and button rendering code for
-        compatibility with recent API changes
-v0.14 - Modal operator
-v0.13 - Initial revision
-"""
-
-import bpy
-from bpy.types import Operator
-from bpy.props import BoolProperty
-
-
-class OBJECT_OT_FastLoop(Operator):
-    bl_idname = "object_ot.fastloop"
-    bl_label = "FastLoop"
-    bl_description = ("Create multiple edge loops in succession\n"
-                      "Runs modal until ESC is pressed twice")
-
-    active: BoolProperty(
-                name="active",
-                default=False
-                )
-
-    @classmethod
-    def poll(cls, context):
-        return bpy.ops.mesh.loopcut_slide.poll()
-
-    def modal(self, context, event):
-        if event.type == 'ESC':
-            context.area.header_text_set(None)
-            return {'CANCELLED'}
-
-        elif event.type == 'LEFTMOUSE' and event.value == 'RELEASE':
-            self.active = False
-
-        if not self.active:
-            self.active = True
-            bpy.ops.mesh.loopcut_slide('INVOKE_DEFAULT')
-            context.area.header_text_set("Press ESC twice to stop FastLoop")
-
-        return {'RUNNING_MODAL'}
-
-    def invoke(self, context, event):
-        context.window_manager.modal_handler_add(self)
-
-        return {'RUNNING_MODAL'}
-
-
-def register():
-    bpy.utils.register_module(__name__)
-    pass
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    pass
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_filletplus.py b/mesh_extra_tools/mesh_filletplus.py
deleted file mode 100644
index a54eba7b2..000000000
--- a/mesh_extra_tools/mesh_filletplus.py
+++ /dev/null
@@ -1,412 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# ##### END 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 #####
-
-bl_info = {
-    "name": "FilletPlus",
-    "author": "Gert De Roost - original by zmj100",
-    "version": (0, 4, 3),
-    "blender": (2, 61, 0),
-    "location": "View3D > Tool Shelf",
-    "description": "",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"}
-
-
-import bpy
-from bpy.props import (
-        FloatProperty,
-        IntProperty,
-        BoolProperty,
-        )
-from bpy.types import Operator
-import bmesh
-from mathutils import Matrix
-from math import (
-        cos, pi, sin,
-        degrees, tan,
-        )
-
-
-def list_clear_(l):
-    if l:
-        del l[:]
-    return l
-
-
-def get_adj_v_(list_):
-    tmp = {}
-    for i in list_:
-        try:
-            tmp[i[0]].append(i[1])
-        except KeyError:
-            tmp[i[0]] = [i[1]]
-        try:
-            tmp[i[1]].append(i[0])
-        except KeyError:
-            tmp[i[1]] = [i[0]]
-    return tmp
-
-
-class f_buf():
-    # one of the angles was not 0 or 180
-    check = False
-
-
-def fillets(list_0, startv, vertlist, face, adj, n, out, flip, radius):
-    try:
-        dict_0 = get_adj_v_(list_0)
-        list_1 = [[dict_0[i][0], i, dict_0[i][1]] for i in dict_0 if (len(dict_0[i]) == 2)][0]
-        list_3 = []
-        for elem in list_1:
-            list_3.append(bm.verts[elem])
-        list_2 = []
-
-        p_ = list_3[1]
-        p = (list_3[1].co).copy()
-        p1 = (list_3[0].co).copy()
-        p2 = (list_3[2].co).copy()
-
-        vec1 = p - p1
-        vec2 = p - p2
-
-        ang = vec1.angle(vec2, any)
-        check_angle = round(degrees(ang))
-
-        if check_angle == 180 or check_angle == 0.0:
-            return False
-        else:
-            f_buf.check = True
-
-        opp = adj
-
-        if radius is False:
-            h = adj * (1 / cos(ang * 0.5))
-            adj_ = adj
-        elif radius is True:
-            h = opp / sin(ang * 0.5)
-            adj_ = opp / tan(ang * 0.5)
-
-        p3 = p - (vec1.normalized() * adj_)
-        p4 = p - (vec2.normalized() * adj_)
-        rp = p - ((p - ((p3 + p4) * 0.5)).normalized() * h)
-
-        vec3 = rp - p3
-        vec4 = rp - p4
-
-        axis = vec1.cross(vec2)
-
-        if out is False:
-            if flip is False:
-                rot_ang = vec3.angle(vec4)
-            elif flip is True:
-                rot_ang = vec1.angle(vec2)
-        elif out is True:
-            rot_ang = (2 * pi) - vec1.angle(vec2)
-
-        for j in range(n + 1):
-            new_angle = rot_ang * j / n
-            mtrx = Matrix.Rotation(new_angle, 3, axis)
-            if out is False:
-                if flip is False:
-                    tmp = p4 - rp
-                    tmp1 = mtrx * tmp
-                    tmp2 = tmp1 + rp
-                elif flip is True:
-                    p3 = p - (vec1.normalized() * opp)
-                    tmp = p3 - p
-                    tmp1 = mtrx * tmp
-                    tmp2 = tmp1 + p
-            elif out is True:
-                p4 = p - (vec2.normalized() * opp)
-                tmp = p4 - p
-                tmp1 = mtrx * tmp
-                tmp2 = tmp1 + p
-
-            v = bm.verts.new(tmp2)
-            list_2.append(v)
-
-        if flip is True:
-            list_3[1:2] = list_2
-        else:
-            list_2.reverse()
-            list_3[1:2] = list_2
-
-        list_clear_(list_2)
-
-        n1 = len(list_3)
-
-        for t in range(n1 - 1):
-            bm.edges.new([list_3[t], list_3[(t + 1) % n1]])
-
-            v = bm.verts.new(p)
-            bm.edges.new([v, p_])
-
-        bm.edges.ensure_lookup_table()
-
-        if face is not None:
-            for l in face.loops:
-                if l.vert == list_3[0]:
-                    startl = l
-                    break
-            vertlist2 = []
-
-            if startl.link_loop_next.vert == startv:
-                l = startl.link_loop_prev
-                while len(vertlist) > 0:
-                    vertlist2.insert(0, l.vert)
-                    vertlist.pop(vertlist.index(l.vert))
-                    l = l.link_loop_prev
-            else:
-                l = startl.link_loop_next
-                while len(vertlist) > 0:
-                    vertlist2.insert(0, l.vert)
-                    vertlist.pop(vertlist.index(l.vert))
-                    l = l.link_loop_next
-
-            for v in list_3:
-                vertlist2.append(v)
-            bm.faces.new(vertlist2)
-        if startv.is_valid:
-            bm.verts.remove(startv)
-        else:
-            print("\n[Function fillets Error]\n"
-                  "Starting vertex (startv var) couldn't be removed\n")
-            return False
-        bm.verts.ensure_lookup_table()
-        bm.edges.ensure_lookup_table()
-        bm.faces.ensure_lookup_table()
-        list_3[1].select = 1
-        list_3[-2].select = 1
-        bm.edges.get([list_3[0], list_3[1]]).select = 1
-        bm.edges.get([list_3[-1], list_3[-2]]).select = 1
-        bm.verts.index_update()
-        bm.edges.index_update()
-        bm.faces.index_update()
-
-        me.update(calc_edges=True, calc_loop_triangles=True)
-        bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
-
-    except Exception as e:
-        print("\n[Function fillets Error]\n{}\n".format(e))
-        return False
-
-
-def do_filletplus(self, pair):
-    is_finished = True
-    try:
-        startv = None
-        global inaction
-        global flip
-        list_0 = [list([e.verts[0].index, e.verts[1].index]) for e in pair]
-
-        vertset = set([])
-        bm.verts.ensure_lookup_table()
-        bm.edges.ensure_lookup_table()
-        bm.faces.ensure_lookup_table()
-        vertset.add(bm.verts[list_0[0][0]])
-        vertset.add(bm.verts[list_0[0][1]])
-        vertset.add(bm.verts[list_0[1][0]])
-        vertset.add(bm.verts[list_0[1][1]])
-
-        v1, v2, v3 = vertset
-
-        if len(list_0) != 2:
-            self.report({'WARNING'}, "Two adjacent edges must be selected")
-            is_finished = False
-        else:
-            inaction = 1
-            vertlist = []
-            found = 0
-            for f in v1.link_faces:
-                if v2 in f.verts and v3 in f.verts:
-                    found = 1
-            if not found:
-                for v in [v1, v2, v3]:
-                    if v.index in list_0[0] and v.index in list_0[1]:
-                        startv = v
-                face = None
-            else:
-                for f in v1.link_faces:
-                    if v2 in f.verts and v3 in f.verts:
-                        for v in f.verts:
-                            if not(v in vertset):
-                                vertlist.append(v)
-                            if (v in vertset and v.link_loops[0].link_loop_prev.vert in vertset and
-                               v.link_loops[0].link_loop_next.vert in vertset):
-                                startv = v
-                        face = f
-            if out is True:
-                flip = False
-            if startv:
-                fills = fillets(list_0, startv, vertlist, face, adj, n, out, flip, radius)
-                if not fills:
-                    is_finished = False
-            else:
-                is_finished = False
-    except Exception as e:
-        print("\n[Function do_filletplus Error]\n{}\n".format(e))
-        is_finished = False
-    return is_finished
-
-
-def check_is_not_coplanar(bm_data):
-    from mathutils import Vector
-    check = False
-    angles, norm_angle = 0, 0
-    z_vec = Vector((0, 0, 1))
-    try:
-        bm_data.faces.ensure_lookup_table()
-
-        for f in bm_data.faces:
-            norm_angle = f.normal.angle(z_vec)
-            if angles == 0:
-                angles = norm_angle
-            if angles != norm_angle:
-                check = True
-                break
-    except Exception as e:
-        print("\n[Function check_is_not_coplanar Error]\n{}\n".format(e))
-        check = True
-    return check
-
-
-#  Operator
-
-class MESH_OT_fillet_plus(Operator):
-    bl_idname = "mesh.fillet_plus"
-    bl_label = "Fillet Plus"
-    bl_description = ("Fillet adjoining edges\n"
-                      "Note: Works on a mesh whose all faces share the same normal")
-    bl_options = {"REGISTER", "UNDO"}
-
-    adj: FloatProperty(
-            name="",
-            description="Size of the filleted corners",
-            default=0.1,
-            min=0.00001, max=100.0,
-            step=1,
-            precision=3
-            )
-    n: IntProperty(
-            name="",
-            description="Subdivision of the filleted corners",
-            default=3,
-            min=1, max=50,
-            step=1
-            )
-    out: BoolProperty(
-            name="Outside",
-            description="Fillet towards outside",
-            default=False
-            )
-    flip: BoolProperty(
-            name="Flip",
-            description="Flip the direction of the Fillet\n"
-                        "Only available if Outside option is not active",
-            default=False
-            )
-    radius: BoolProperty(
-            name="Radius",
-            description="Use radius for the size of the filleted corners",
-            default=False
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def draw(self, context):
-        layout = self.layout
-
-        if f_buf.check is False:
-            layout.label(text="Angle is equal to 0 or 180", icon="INFO")
-            layout.label(text="Can not fillet", icon="BLANK1")
-        else:
-            layout.prop(self, "radius")
-            if self.radius is True:
-                layout.label(text="Radius:")
-            elif self.radius is False:
-                layout.label(text="Distance:")
-            layout.prop(self, "adj")
-            layout.label(text="Number of sides:")
-            layout.prop(self, "n")
-
-            if self.n > 1:
-                row = layout.row(align=False)
-                row.prop(self, "out")
-                if self.out is False:
-                    row.prop(self, "flip")
-
-    def execute(self, context):
-        global inaction
-        global bm, me, adj, n, out, flip, radius
-
-        adj = self.adj
-        n = self.n
-        out = self.out
-        flip = self.flip
-        radius = self.radius
-
-        inaction = 0
-        f_buf.check = False
-
-        ob_act = context.active_object
-        try:
-            me = ob_act.data
-            bm = bmesh.from_edit_mesh(me)
-            warn_obj = bool(check_is_not_coplanar(bm))
-            if warn_obj is False:
-                tempset = set([])
-                bm.verts.ensure_lookup_table()
-                bm.edges.ensure_lookup_table()
-                bm.faces.ensure_lookup_table()
-                for v in bm.verts:
-                    if v.select and v.is_boundary:
-                        tempset.add(v)
-                for v in tempset:
-                    edgeset = set([])
-                    for e in v.link_edges:
-                        if e.select and e.is_boundary:
-                            edgeset.add(e)
-                        if len(edgeset) == 2:
-                            is_finished = do_filletplus(self, edgeset)
-                            if not is_finished:
-                                break
-
-                if inaction == 1:
-                    bpy.ops.mesh.select_all(action="DESELECT")
-                    for v in bm.verts:
-                        if len(v.link_edges) == 0:
-                            bm.verts.remove(v)
-                    bpy.ops.object.editmode_toggle()
-                    bpy.ops.object.editmode_toggle()
-                else:
-                    self.report({'WARNING'}, "Filletplus operation could not be performed")
-                    return {'CANCELLED'}
-            else:
-                self.report({'WARNING'}, "Mesh is not a coplanar surface. Operation cancelled")
-                return {'CANCELLED'}
-        except:
-            self.report({'WARNING'}, "Filletplus operation could not be performed")
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
diff --git a/mesh_extra_tools/mesh_help.py b/mesh_extra_tools/mesh_help.py
deleted file mode 100644
index 30047a8b6..000000000
--- a/mesh_extra_tools/mesh_help.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# gpl authors: lijenstina, meta-androcto
-
-# Note:  this script contains the Help Operator used by the various functions
-# Usage: add a key string to the dictionary in this file with the list of strings to pass to labels
-#        and call the operator from the add-on UI draw function by passing the help_ids parameter
-#        If the size of the pop-up if needed, define popup_size in the call by using variables
-#        Example (with using the variable props):
-#        props = layout.row("mesh.extra_tools_help")
-#        props.help_ids = "default"
-#        props.popup_size = 400
-
-
-import bpy
-from bpy.types import Operator
-from bpy.props import (
-        StringProperty,
-        IntProperty,
-        )
-
-
-class MESH_OT_extra_tools_help(Operator):
-    bl_idname = "mesh.extra_tools_help"
-    bl_label = ""
-    bl_description = "Tool Help - click to read some basic information"
-    bl_options = {'REGISTER'}
-
-    help_ids: StringProperty(
-            name="ID of the Operator to display",
-            options={'HIDDEN'},
-            default="default"
-            )
-    popup_size: IntProperty(
-            name="Size of the Help Pop-up Menu",
-            default=350,
-            min=100,
-            max=600,
-            )
-
-    def draw(self, context):
-        layout = self.layout
-        pick_help = help_custom_draw(self.help_ids)
-
-        for line_text in pick_help:
-            layout.label(line_text)
-
-    def execute(self, context):
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        return context.window_manager.invoke_popup(self, width=self.popup_size)
-
-
-def help_custom_draw(identifier="default"):
-    # A table of lists containing the help text under an index key that is the script name
-    # If several returns are needed per file, add some suffix after the script name
-    # and call them separately
-    # In case nothing is passed from the UI call, the returned list is default
-    # If undefined one is passed, it will return a warning message
-    help_text = {
-        "default": [
-                "This is a placeholder text",
-                "Please fill up the entries in the " + __name__ + " script",
-                ],
-        "random_vertices": [
-                "To use:",
-                "Make a selection or selection of Vertices",
-                "Randomize displaced positions",
-                "Note:",
-                "There is an option to use Vertex Weights for displacement",
-                "Prior to use, don't forget to assign after updating the Group Weight",
-                ],
-        "mesh_vertex_chamfer": [
-                "To use:",
-                "Make a selection or selection of vertices",
-                "Result is a triangle Chamfer, works on a single vertex",
-                "Note:",
-                "The difference to the vertex Bevel is that original geometry",
-                "(selected vertices) can optionally be kept and displaced",
-                "Limitation:",
-                "In some cases, may need to press F to fill the result",
-                ],
-        "mesh_filletplus": [
-                "To use:",
-                "Select two adjacent edges and press Fillet button",
-                "Limitation:",
-                "Works on a mesh with all faces sharing the same normal",
-                "(Flat Surface - faces have the same direction)",
-                "Planes with already round corners can produce unsatisfactory results",
-                "Only boundary edges will be evaluated",
-                ],
-        "mesh_offset_edges": [
-                "To use:",
-                "Make a selection or selection of Edges",
-                "Extrude, rotate extrusions and more",
-                "Limitation:",
-                "Operates only on separate Edge loops selections",
-                "(i.e. Edge loops that are not connected by a selected edge)",
-                ],
-        "mesh_edge_roundifier": [
-                "To use:",
-                "Select a single or multiple Edges",
-                "Make Arcs with various parameters",
-                "Reference, Rotation, Scaling, Connection and Offset",
-                "Note:",
-                "The Mode - Reset button restores the default values",
-                ],
-        "mesh_edges_length": [
-                "To use:",
-                "Select a single or multiple Edges",
-                "Change length with various parameters",
-                "Limitation:",
-                "Does not operate on edges that share a vertex",
-                "If the selection wasn't done in Edge Selection mode,",
-                "the option Active will not work (due to Blender's limitation)",
-                ],
-        "mesh_edges_floor_plan": [
-                "To use:",
-                "Starting edges will be flat extruded forming faces strips",
-                "on the inside. Similar to using Face fill inset select outer",
-                "Methods:",
-                "Edge Net: Fills the edge grid with faces then Inset",
-                "Single Face: Single Face fill (all Edges) then Inset",
-                "Solidify: Extrude along defined axis, apply a Solidify modifier",
-                "Note:",
-                "Grid Fill and Single Face sometimes need tweaking with the options",
-                "Limitation:",
-                "Depending on the input geometry, Keep Ngons sometimes needs to be",
-                "enabled to produce any results",
-                "Edge Net and Single Face depend on bmesh face fill and inset",
-                "that sometimes can fail to produce good results",
-                "Avoid using Single Face Method on Edges that define a Volume - like Suzanne",
-                "Solidify method works best for flat surfaces and complex geometry",
-                ],
-        "mesh_mextrude_plus": [
-                "To use:",
-                "Make a selection of Faces",
-                "Extrude with Rotation, Scaling, Variation,",
-                "Randomization and Offset parameters",
-                "Limitation:",
-                "Works only with selections that enclose Faces",
-                "(i.e. all Edges or Vertices of a Face selected)",
-                ],
-        "mesh_extrude_and_reshape": [
-                "To use:",
-                "Extrude Face and merge Edge intersections,",
-                "between the mesh and the new Edges",
-                "Note:",
-                "If selected Vertices don't form Face they will be",
-                "still extruded in the same direction",
-                "Limitation:",
-                "Works only with the last selected face",
-                "(or all Edges or Vertices of a Face selected)",
-                ],
-        "face_inset_fillet": [
-                "To use:",
-                "Select one or multiple faces and inset",
-                "Inset square, circle or outside",
-                "Note:",
-                "Radius: use remove doubles to tidy joins",
-                "Out: select and use normals flip before extruding",
-                "Limitation:",
-                "Using the Out option, sometimes can lead to unsatisfactory results",
-                ],
-        "mesh_cut_faces": [
-                "To use:",
-                "Make a selection or selection of Faces",
-                "Some Functions work on a plane only",
-                "Limitation:",
-                "The selection must include at least two Faces with adjacent edges",
-                "(Selections not sharing edges will not work)",
-                ],
-        "split_solidify": [
-                "To use:",
-                "Make a selection or selection of Faces",
-                "Split Faces and Extrude results",
-                "Similar to a shatter/explode effect",
-                ],
-        "mesh_fastloop": [
-                "To use:",
-                "Activate the tool and hover over the mesh in the general area",
-                "for the loop and left click once to confirm the loop placement",
-                "Slide using the mouse to fine tune its position, left click to confirm",
-                "Repeat the operations if needed for new loops",
-                "Press Esc. twice to exit the tool",
-                "Limitation:",
-                "The tool has the same limitations as Loop Cut and Slide",
-                "In the Operator Panel, only the last loop can be tweaked",
-                ],
-        "mesh_pen_tool": [
-                "To use:",
-                "Press Ctrl + D key or click Draw button",
-                "To draw along x use SHIFT + MOUSEMOVE",
-                "To draw along y use ALT + MOUSEMOVE",
-                "Press Ctrl to toggle Extrude at Cursor tool",
-                "Right click to finish drawing or",
-                "Press Esc to cancel",
-                ],
-        "pkhg_faces": [
-                "To use:",
-                "Needs a Face Selection in Edit Mode",
-                "Select an option from Face Types drop down list",
-                "Extrude, rotate extrusions and more",
-                "Toggle Edit Mode after use",
-                "Note:",
-                "After using the operator, normals could need repair,",
-                "or Removing Doubles",
-                ],
-        "vertex_align": [
-                "To use:",
-                "Select vertices that you want to align and click Align button",
-                "Options include aligning to defined Custom coordinates or",
-                "Stored vertex - (a single selected one with Store Selected Vertex)",
-                "Note:",
-                "Use Stored Coordinates - allows to save a set of coordinates",
-                "as a starting point that can be tweaked on during operation",
-                ],
-        "mesh_check": [
-                "To use:",
-                "Tris and Ngons will select Faces by corensponding type",
-                "Display faces will color the faces depending on the",
-                "defined Colors, Edges' width and Face Opacity",
-                "Note:",
-                "The Faces' type count is already included elsewhere:",
-                "In the Properties Editor > Data > Face / Info Select Panel",
-                ],
-        }
-
-    if identifier in help_text:
-        return help_text[identifier]
-
-    return ["ERROR:", "Help Operator", "Undefined call to the Dictionary"]
-
-
-# register
-def register():
-    bpy.utils.register_class(MESH_OT_extra_tools_help)
-
-
-def unregister():
-    bpy.utils.unregister_class(MESH_OT_extra_tools_help)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_mextrude_plus.py b/mesh_extra_tools/mesh_mextrude_plus.py
deleted file mode 100644
index 5fa2aa2b7..000000000
--- a/mesh_extra_tools/mesh_mextrude_plus.py
+++ /dev/null
@@ -1,370 +0,0 @@
-# ##### 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 #####
-
-# Repeats extrusion + rotation + scale for one or more faces
-# Original code by liero
-# Update by Jimmy Hazevoet 03/2017 for Blender 2.79
-# normal rotation, probability, scaled offset, object coords, initial and per step noise
-
-
-bl_info = {
-    "name": "MExtrude Plus1",
-    "author": "liero, Jimmy Hazevoet",
-    "version": (1, 3, 0),
-    "blender": (2, 77, 0),
-    "location": "View3D > Tool Shelf",
-    "description": "Repeat extrusions from faces to create organic shapes",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"}
-
-
-import bpy
-import bmesh
-import random
-from bpy.types import Operator
-from random import gauss
-from math import radians
-from mathutils import (
-        Euler, Vector,
-        )
-from bpy.props import (
-        FloatProperty,
-        IntProperty,
-        BoolProperty,
-        )
-
-
-def gloc(self, r):
-    return Vector((self.offx, self.offy, self.offz))
-
-
-def vloc(self, r):
-    random.seed(self.ran + r)
-    return self.off * (1 + gauss(0, self.var1 / 3))
-
-
-def nrot(self, n):
-    return Euler((radians(self.nrotx) * n[0],
-                  radians(self.nroty) * n[1],
-                  radians(self.nrotz) * n[2]), 'XYZ')
-
-
-def vrot(self, r):
-    random.seed(self.ran + r)
-    return Euler((radians(self.rotx) + gauss(0, self.var2 / 3),
-                  radians(self.roty) + gauss(0, self.var2 / 3),
-                  radians(self.rotz) + gauss(0, self.var2 / 3)), 'XYZ')
-
-
-def vsca(self, r):
-    random.seed(self.ran + r)
-    return self.sca * (1 + gauss(0, self.var3 / 3))
-
-
-class MExtrude(Operator):
-    bl_idname = "object.mextrude"
-    bl_label = "Multi Extrude"
-    bl_description = ("Extrude selected Faces with Rotation,\n"
-                      "Scaling, Variation, Randomization")
-    bl_options = {"REGISTER", "UNDO", "PRESET"}
-
-    off: FloatProperty(
-            name="Offset",
-            soft_min=0.001, soft_max=10,
-            min=-100, max=100,
-            default=1.0,
-            description="Translation"
-            )
-    offx: FloatProperty(
-            name="Loc X",
-            soft_min=-10.0, soft_max=10.0,
-            min=-100.0, max=100.0,
-            default=0.0,
-            description="Global Translation X"
-            )
-    offy: FloatProperty(
-            name="Loc Y",
-            soft_min=-10.0, soft_max=10.0,
-            min=-100.0, max=100.0,
-            default=0.0,
-            description="Global Translation Y"
-            )
-    offz: FloatProperty(
-            name="Loc Z",
-            soft_min=-10.0, soft_max=10.0,
-            min=-100.0, max=100.0,
-            default=0.0,
-            description="Global Translation Z"
-            )
-    rotx: FloatProperty(
-            name="Rot X",
-            min=-85, max=85,
-            soft_min=-30, soft_max=30,
-            default=0,
-            description="X Rotation"
-            )
-    roty: FloatProperty(
-            name="Rot Y",
-            min=-85, max=85,
-            soft_min=-30,
-            soft_max=30,
-            default=0,
-            description="Y Rotation"
-            )
-    rotz: FloatProperty(
-            name="Rot Z",
-            min=-85, max=85,
-            soft_min=-30, soft_max=30,
-            default=-0,
-            description="Z Rotation"
-            )
-    nrotx: FloatProperty(
-            name="N Rot X",
-            min=-85, max=85,
-            soft_min=-30, soft_max=30,
-            default=0,
-            description="Normal X Rotation"
-            )
-    nroty: FloatProperty(
-            name="N Rot Y",
-            min=-85, max=85,
-            soft_min=-30, soft_max=30,
-            default=0,
-            description="Normal Y Rotation"
-            )
-    nrotz: FloatProperty(
-            name="N Rot Z",
-            min=-85, max=85,
-            soft_min=-30, soft_max=30,
-            default=-0,
-            description="Normal Z Rotation"
-            )
-    sca: FloatProperty(
-            name="Scale",
-            min=0.01, max=10,
-            soft_min=0.5, soft_max=1.5,
-            default=1.0,
-            description="Scaling of the selected faces after extrusion"
-            )
-    var1: FloatProperty(
-            name="Offset Var", min=-10, max=10,
-            soft_min=-1, soft_max=1,
-            default=0,
-            description="Offset variation"
-            )
-    var2: FloatProperty(
-            name="Rotation Var",
-            min=-10, max=10,
-            soft_min=-1, soft_max=1,
-            default=0,
-            description="Rotation variation"
-            )
-    var3: FloatProperty(
-            name="Scale Noise",
-            min=-10, max=10,
-            soft_min=-1, soft_max=1,
-            default=0,
-            description="Scaling noise"
-            )
-    var4: IntProperty(
-            name="Probability",
-            min=0, max=100,
-            default=100,
-            description="Probability, chance of extruding a face"
-            )
-    num: IntProperty(
-            name="Repeat",
-            min=1, max=500,
-            soft_max=100,
-            default=5,
-            description="Repetitions"
-            )
-    ran: IntProperty(
-            name="Seed",
-            min=-9999, max=9999,
-            default=0,
-            description="Seed to feed random values"
-            )
-    opt1: BoolProperty(
-            name="Polygon coordinates",
-            default=True,
-            description="Polygon coordinates, Object coordinates"
-            )
-    opt2: BoolProperty(
-            name="Proportional offset",
-            default=False,
-            description="Scale * Offset"
-            )
-    opt3: BoolProperty(
-            name="Per step rotation noise",
-            default=False,
-            description="Per step rotation noise, Initial rotation noise"
-            )
-    opt4: BoolProperty(
-            name="Per step scale noise",
-            default=False,
-            description="Per step scale noise, Initial scale noise"
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.object
-        return (obj and obj.type == 'MESH')
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column(align=True)
-        col.label(text="Transformations:")
-        col.prop(self, "off", slider=True)
-        col.prop(self, "offx", slider=True)
-        col.prop(self, "offy", slider=True)
-        col.prop(self, "offz", slider=True)
-
-        col = layout.column(align=True)
-        col.prop(self, "rotx", slider=True)
-        col.prop(self, "roty", slider=True)
-        col.prop(self, "rotz", slider=True)
-        col.prop(self, "nrotx", slider=True)
-        col.prop(self, "nroty", slider=True)
-        col.prop(self, "nrotz", slider=True)
-        col = layout.column(align=True)
-        col.prop(self, "sca", slider=True)
-
-        col = layout.column(align=True)
-        col.label(text="Variation settings:")
-        col.prop(self, "var1", slider=True)
-        col.prop(self, "var2", slider=True)
-        col.prop(self, "var3", slider=True)
-        col.prop(self, "var4", slider=True)
-        col.prop(self, "ran")
-        col = layout.column(align=False)
-        col.prop(self, 'num')
-
-        col = layout.column(align=True)
-        col.label(text="Options:")
-        col.prop(self, "opt1")
-        col.prop(self, "opt2")
-        col.prop(self, "opt3")
-        col.prop(self, "opt4")
-
-    def execute(self, context):
-        obj = bpy.context.object
-        om = obj.mode
-        bpy.context.tool_settings.mesh_select_mode = [False, False, True]
-        origin = Vector([0.0, 0.0, 0.0])
-
-        # bmesh operations
-        bpy.ops.object.mode_set()
-        bm = bmesh.new()
-        bm.from_mesh(obj.data)
-        sel = [f for f in bm.faces if f.select]
-
-        after = []
-
-        # faces loop
-        for i, of in enumerate(sel):
-            nro = nrot(self, of.normal)
-            off = vloc(self, i)
-            loc = gloc(self, i)
-            of.normal_update()
-
-            # initial rotation noise
-            if self.opt3 is False:
-                rot = vrot(self, i)
-            # initial scale noise
-            if self.opt4 is False:
-                s = vsca(self, i)
-
-            # extrusion loop
-            for r in range(self.num):
-                # random probability % for extrusions
-                if self.var4 > int(random.random() * 100):
-                    nf = of.copy()
-                    nf.normal_update()
-                    no = nf.normal.copy()
-
-                    # face/obj coördinates
-                    if self.opt1 is True:
-                        ce = nf.calc_center_bounds()
-                    else:
-                        ce = origin
-
-                    # per step rotation noise
-                    if self.opt3 is True:
-                        rot = vrot(self, i + r)
-                    # per step scale noise
-                    if self.opt4 is True:
-                        s = vsca(self, i + r)
-
-                    # proportional, scale * offset
-                    if self.opt2 is True:
-                        off = s * off
-
-                    for v in nf.verts:
-                        v.co -= ce
-                        v.co.rotate(nro)
-                        v.co.rotate(rot)
-                        v.co += ce + loc + no * off
-                        v.co = v.co.lerp(ce, 1 - s)
-
-                    # extrude code from TrumanBlending
-                    for a, b in zip(of.loops, nf.loops):
-                        sf = bm.faces.new((a.vert, a.link_loop_next.vert,
-                                           b.link_loop_next.vert, b.vert))
-                        sf.normal_update()
-                    bm.faces.remove(of)
-                    of = nf
-
-            after.append(of)
-
-        for v in bm.verts:
-            v.select = False
-        for e in bm.edges:
-            e.select = False
-
-        for f in after:
-            if f not in sel:
-                f.select = True
-            else:
-                f.select = False
-
-        bm.to_mesh(obj.data)
-        obj.data.update()
-
-        # restore user settings
-        bpy.ops.object.mode_set(mode=om)
-
-        if not len(sel):
-            self.report({"WARNING"},
-                        "No suitable Face selection found. Operation cancelled")
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == '__main__':
-    register()
diff --git a/mesh_extra_tools/mesh_offset_edges.py b/mesh_extra_tools/mesh_offset_edges.py
deleted file mode 100644
index b6d760b16..000000000
--- a/mesh_extra_tools/mesh_offset_edges.py
+++ /dev/null
@@ -1,823 +0,0 @@
-# ##### 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 #####
-
-bl_info = {
-    "name": "Offset Edges",
-    "author": "Hidesato Ikeya",
-    "version": (0, 2, 6),
-    "blender": (2, 70, 0),
-    "location": "VIEW3D > Edge menu(CTRL-E) > Offset Edges",
-    "description": "Offset Edges",
-    "warning": "",
-    "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
-                "Py/Scripts/Modeling/offset_edges",
-    "category": "Mesh"}
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from math import sin, cos, pi, radians
-from mathutils import Vector
-from time import perf_counter
-
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        EnumProperty,
-        )
-
-# Globals
-X_UP = Vector((1.0, .0, .0))
-Y_UP = Vector((.0, 1.0, .0))
-Z_UP = Vector((.0, .0, 1.0))
-ZERO_VEC = Vector((.0, .0, .0))
-ANGLE_90 = pi / 2
-ANGLE_180 = pi
-ANGLE_360 = 2 * pi
-
-# switch performance logging
-ENABLE_DEBUG = False
-
-
-def calc_loop_normal(verts, fallback=Z_UP):
-    # Calculate normal from verts using Newell's method
-    normal = ZERO_VEC.copy()
-
-    if verts[0] is verts[-1]:
-        # Perfect loop
-        range_verts = range(1, len(verts))
-    else:
-        # Half loop
-        range_verts = range(0, len(verts))
-
-    for i in range_verts:
-        v1co, v2co = verts[i - 1].co, verts[i].co
-        normal.x += (v1co.y - v2co.y) * (v1co.z + v2co.z)
-        normal.y += (v1co.z - v2co.z) * (v1co.x + v2co.x)
-        normal.z += (v1co.x - v2co.x) * (v1co.y + v2co.y)
-
-    if normal != ZERO_VEC:
-        normal.normalize()
-    else:
-        normal = fallback
-
-    return normal
-
-
-def collect_edges(bm):
-    set_edges_orig = set()
-    for e in bm.edges:
-        if e.select:
-            co_faces_selected = 0
-            for f in e.link_faces:
-                if f.select:
-                    co_faces_selected += 1
-                    if co_faces_selected == 2:
-                        break
-            else:
-                set_edges_orig.add(e)
-
-    if not set_edges_orig:
-        return None
-
-    return set_edges_orig
-
-
-def collect_loops(set_edges_orig):
-    set_edges_copy = set_edges_orig.copy()
-
-    loops = []  # [v, e, v, e, ... , e, v]
-    while set_edges_copy:
-        edge_start = set_edges_copy.pop()
-        v_left, v_right = edge_start.verts
-        lp = [v_left, edge_start, v_right]
-        reverse = False
-        while True:
-            edge = None
-            for e in v_right.link_edges:
-                if e in set_edges_copy:
-                    if edge:
-                        # Overlap detected.
-                        return None
-                    edge = e
-                    set_edges_copy.remove(e)
-            if edge:
-                v_right = edge.other_vert(v_right)
-                lp.extend((edge, v_right))
-                continue
-            else:
-                if v_right is v_left:
-                    # Real loop.
-                    loops.append(lp)
-                    break
-                elif reverse is False:
-                    # Right side of half loop
-                    # Reversing the loop to operate same procedure on the left side
-                    lp.reverse()
-                    v_right, v_left = v_left, v_right
-                    reverse = True
-                    continue
-                else:
-                    # Half loop, completed
-                    loops.append(lp)
-                    break
-    return loops
-
-
-def get_adj_ix(ix_start, vec_edges, half_loop):
-    # Get adjacent edge index, skipping zero length edges
-    len_edges = len(vec_edges)
-    if half_loop:
-        range_right = range(ix_start, len_edges)
-        range_left = range(ix_start - 1, -1, -1)
-    else:
-        range_right = range(ix_start, ix_start + len_edges)
-        range_left = range(ix_start - 1, ix_start - 1 - len_edges, -1)
-
-    ix_right = ix_left = None
-    for i in range_right:
-        # Right
-        i %= len_edges
-        if vec_edges[i] != ZERO_VEC:
-            ix_right = i
-            break
-    for i in range_left:
-        # Left
-        i %= len_edges
-        if vec_edges[i] != ZERO_VEC:
-            ix_left = i
-            break
-    if half_loop:
-        # If index of one side is None, assign another index
-        if ix_right is None:
-            ix_right = ix_left
-        if ix_left is None:
-            ix_left = ix_right
-
-    return ix_right, ix_left
-
-
-def get_adj_faces(edges):
-    adj_faces = []
-    for e in edges:
-        adj_f = None
-        co_adj = 0
-        for f in e.link_faces:
-            # Search an adjacent face
-            # Selected face has precedence
-            if not f.hide and f.normal != ZERO_VEC:
-                adj_f = f
-                co_adj += 1
-                if f.select:
-                    adj_faces.append(adj_f)
-                    break
-        else:
-            if co_adj == 1:
-                adj_faces.append(adj_f)
-            else:
-                adj_faces.append(None)
-    return adj_faces
-
-
-def get_edge_rail(vert, set_edges_orig):
-    co_edges = co_edges_selected = 0
-    vec_inner = None
-    for e in vert.link_edges:
-        if (e not in set_edges_orig and
-                (e.select or (co_edges_selected == 0 and not e.hide))):
-            v_other = e.other_vert(vert)
-            vec = v_other.co - vert.co
-            if vec != ZERO_VEC:
-                vec_inner = vec
-                if e.select:
-                    co_edges_selected += 1
-                    if co_edges_selected == 2:
-                        return None
-                else:
-                    co_edges += 1
-    if co_edges_selected == 1:
-        vec_inner.normalize()
-        return vec_inner
-    elif co_edges == 1:
-        # No selected edges, one unselected edge
-        vec_inner.normalize()
-        return vec_inner
-    else:
-        return None
-
-
-def get_cross_rail(vec_tan, vec_edge_r, vec_edge_l, normal_r, normal_l):
-    # Cross rail is a cross vector between normal_r and normal_l
-    vec_cross = normal_r.cross(normal_l)
-    if vec_cross.dot(vec_tan) < .0:
-        vec_cross *= -1
-    cos_min = min(vec_tan.dot(vec_edge_r), vec_tan.dot(-vec_edge_l))
-    cos = vec_tan.dot(vec_cross)
-    if cos >= cos_min:
-        vec_cross.normalize()
-        return vec_cross
-    else:
-        return None
-
-
-def move_verts(width, depth, verts, directions, geom_ex):
-    if geom_ex:
-        geom_s = geom_ex['side']
-        verts_ex = []
-        for v in verts:
-            for e in v.link_edges:
-                if e in geom_s:
-                    verts_ex.append(e.other_vert(v))
-                    break
-        verts = verts_ex
-
-    for v, (vec_width, vec_depth) in zip(verts, directions):
-        v.co += width * vec_width + depth * vec_depth
-
-
-def extrude_edges(bm, edges_orig):
-    extruded = bmesh.ops.extrude_edge_only(bm, edges=edges_orig)['geom']
-    n_edges = n_faces = len(edges_orig)
-    n_verts = len(extruded) - n_edges - n_faces
-
-    geom = dict()
-    geom['verts'] = verts = set(extruded[:n_verts])
-    geom['edges'] = edges = set(extruded[n_verts:n_verts + n_edges])
-    geom['faces'] = set(extruded[n_verts + n_edges:])
-    geom['side'] = set(e for v in verts for e in v.link_edges if e not in edges)
-
-    return geom
-
-
-def clean(bm, mode, edges_orig, geom_ex=None):
-    for f in bm.faces:
-        f.select = False
-    if geom_ex:
-        for e in geom_ex['edges']:
-            e.select = True
-        if mode == 'offset':
-            lis_geom = list(geom_ex['side']) + list(geom_ex['faces'])
-            bmesh.ops.delete(bm, geom=lis_geom, context=2)
-    else:
-        for e in edges_orig:
-            e.select = True
-
-
-def collect_mirror_planes(edit_object):
-    mirror_planes = []
-    eob_mat_inv = edit_object.matrix_world.inverted()
-    for m in edit_object.modifiers:
-        if (m.type == 'MIRROR' and m.use_mirror_merge):
-            merge_limit = m.merge_threshold
-            if not m.mirror_object:
-                loc = ZERO_VEC
-                norm_x, norm_y, norm_z = X_UP, Y_UP, Z_UP
-            else:
-                mirror_mat_local = eob_mat_inv * m.mirror_object.matrix_world
-                loc = mirror_mat_local.to_translation()
-                norm_x, norm_y, norm_z, _ = mirror_mat_local.adjugated()
-                norm_x = norm_x.to_3d().normalized()
-                norm_y = norm_y.to_3d().normalized()
-                norm_z = norm_z.to_3d().normalized()
-            if m.use_x:
-                mirror_planes.append((loc, norm_x, merge_limit))
-            if m.use_y:
-                mirror_planes.append((loc, norm_y, merge_limit))
-            if m.use_z:
-                mirror_planes.append((loc, norm_z, merge_limit))
-    return mirror_planes
-
-
-def get_vert_mirror_pairs(set_edges_orig, mirror_planes):
-    if mirror_planes:
-        set_edges_copy = set_edges_orig.copy()
-        vert_mirror_pairs = dict()
-        for e in set_edges_orig:
-            v1, v2 = e.verts
-            for mp in mirror_planes:
-                p_co, p_norm, mlimit = mp
-                v1_dist = abs(p_norm.dot(v1.co - p_co))
-                v2_dist = abs(p_norm.dot(v2.co - p_co))
-                if v1_dist <= mlimit:
-                    # v1 is on a mirror plane
-                    vert_mirror_pairs[v1] = mp
-                if v2_dist <= mlimit:
-                    # v2 is on a mirror plane
-                    vert_mirror_pairs[v2] = mp
-                if v1_dist <= mlimit and v2_dist <= mlimit:
-                    # This edge is on a mirror_plane, so should not be offsetted
-                    set_edges_copy.remove(e)
-        return vert_mirror_pairs, set_edges_copy
-    else:
-        return None, set_edges_orig
-
-
-def get_mirror_rail(mirror_plane, vec_up):
-    p_norm = mirror_plane[1]
-    mirror_rail = vec_up.cross(p_norm)
-    if mirror_rail != ZERO_VEC:
-        mirror_rail.normalize()
-        # Project vec_up to mirror_plane
-        vec_up = vec_up - vec_up.project(p_norm)
-        vec_up.normalize()
-        return mirror_rail, vec_up
-    else:
-        return None, vec_up
-
-
-def reorder_loop(verts, edges, lp_normal, adj_faces):
-    for i, adj_f in enumerate(adj_faces):
-        if adj_f is None:
-            continue
-
-        v1, v2 = verts[i], verts[i + 1]
-        fv = tuple(adj_f.verts)
-        if fv[fv.index(v1) - 1] is v2:
-            # Align loop direction
-            verts.reverse()
-            edges.reverse()
-            adj_faces.reverse()
-
-        if lp_normal.dot(adj_f.normal) < .0:
-            lp_normal *= -1
-        break
-    else:
-        # All elements in adj_faces are None
-        for v in verts:
-            if v.normal != ZERO_VEC:
-                if lp_normal.dot(v.normal) < .0:
-                    verts.reverse()
-                    edges.reverse()
-                    lp_normal *= -1
-                break
-
-    return verts, edges, lp_normal, adj_faces
-
-
-def get_directions(lp, vec_upward, normal_fallback, vert_mirror_pairs, **options):
-    opt_follow_face = options['follow_face']
-    opt_edge_rail = options['edge_rail']
-    opt_er_only_end = options['edge_rail_only_end']
-    opt_threshold = options['threshold']
-
-    verts, edges = lp[::2], lp[1::2]
-    set_edges = set(edges)
-    lp_normal = calc_loop_normal(verts, fallback=normal_fallback)
-
-    # Loop order might be changed below
-    if lp_normal.dot(vec_upward) < .0:
-        # Make this loop's normal towards vec_upward
-        verts.reverse()
-        edges.reverse()
-        lp_normal *= -1
-
-    if opt_follow_face:
-        adj_faces = get_adj_faces(edges)
-        verts, edges, lp_normal, adj_faces = \
-            reorder_loop(verts, edges, lp_normal, adj_faces)
-    else:
-        adj_faces = (None, ) * len(edges)
-    # Loop order might be changed above
-
-    vec_edges = tuple((e.other_vert(v).co - v.co).normalized()
-                      for v, e in zip(verts, edges))
-
-    if verts[0] is verts[-1]:
-        # Real loop. Popping last vertex
-        verts.pop()
-        HALF_LOOP = False
-    else:
-        # Half loop
-        HALF_LOOP = True
-
-    len_verts = len(verts)
-    directions = []
-    for i in range(len_verts):
-        vert = verts[i]
-        ix_right, ix_left = i, i - 1
-
-        VERT_END = False
-        if HALF_LOOP:
-            if i == 0:
-                # First vert
-                ix_left = ix_right
-                VERT_END = True
-            elif i == len_verts - 1:
-                # Last vert
-                ix_right = ix_left
-                VERT_END = True
-
-        edge_right, edge_left = vec_edges[ix_right], vec_edges[ix_left]
-        face_right, face_left = adj_faces[ix_right], adj_faces[ix_left]
-
-        norm_right = face_right.normal if face_right else lp_normal
-        norm_left = face_left.normal if face_left else lp_normal
-        if norm_right.angle(norm_left) > opt_threshold:
-            # Two faces are not flat
-            two_normals = True
-        else:
-            two_normals = False
-
-        tan_right = edge_right.cross(norm_right).normalized()
-        tan_left = edge_left.cross(norm_left).normalized()
-        tan_avr = (tan_right + tan_left).normalized()
-        norm_avr = (norm_right + norm_left).normalized()
-
-        rail = None
-        if two_normals or opt_edge_rail:
-            # Get edge rail
-            # edge rail is a vector of an inner edge
-            if two_normals or (not opt_er_only_end) or VERT_END:
-                rail = get_edge_rail(vert, set_edges)
-        if vert_mirror_pairs and VERT_END:
-            if vert in vert_mirror_pairs:
-                rail, norm_avr = get_mirror_rail(vert_mirror_pairs[vert], norm_avr)
-        if (not rail) and two_normals:
-            # Get cross rail
-            # Cross rail is a cross vector between norm_right and norm_left
-            rail = get_cross_rail(
-                tan_avr, edge_right, edge_left, norm_right, norm_left)
-        if rail:
-            dot = tan_avr.dot(rail)
-            if dot > .0:
-                tan_avr = rail
-            elif dot < .0:
-                tan_avr = -rail
-
-        vec_plane = norm_avr.cross(tan_avr)
-        e_dot_p_r = edge_right.dot(vec_plane)
-        e_dot_p_l = edge_left.dot(vec_plane)
-        if e_dot_p_r or e_dot_p_l:
-            if e_dot_p_r > e_dot_p_l:
-                vec_edge, e_dot_p = edge_right, e_dot_p_r
-            else:
-                vec_edge, e_dot_p = edge_left, e_dot_p_l
-
-            vec_tan = (tan_avr - tan_avr.project(vec_edge)).normalized()
-            # Make vec_tan perpendicular to vec_edge
-            vec_up = vec_tan.cross(vec_edge)
-
-            vec_width = vec_tan - (vec_tan.dot(vec_plane) / e_dot_p) * vec_edge
-            vec_depth = vec_up - (vec_up.dot(vec_plane) / e_dot_p) * vec_edge
-        else:
-            vec_width = tan_avr
-            vec_depth = norm_avr
-
-        directions.append((vec_width, vec_depth))
-
-    return verts, directions
-
-
-angle_presets = {'0°': 0,
-                 '15°': radians(15),
-                 '30°': radians(30),
-                 '45°': radians(45),
-                 '60°': radians(60),
-                 '75°': radians(75),
-                 '90°': radians(90),
-                }
-
-
-def use_cashes(self, context):
-    self.caches_valid = True
-
-
-def assign_angle_presets(self, context):
-    use_cashes(self, context)
-    self.angle = angle_presets[self.angle_presets]
-
-
-class OffsetEdges(Operator):
-    bl_idname = "mesh.offset_edges"
-    bl_label = "Offset Edges"
-    bl_description = ("Extrude, Move or Offset the selected Edges\n"
-                      "Operates only on separate Edge loops selections")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    geometry_mode: EnumProperty(
-            items=[('offset', "Offset", "Offset edges"),
-                   ('extrude', "Extrude", "Extrude edges"),
-                   ('move', "Move", "Move selected edges")],
-            name="Geometry mode",
-            default='offset',
-            update=use_cashes
-            )
-    width: FloatProperty(
-            name="Width",
-            default=.2,
-            precision=4, step=1,
-            update=use_cashes
-            )
-    flip_width: BoolProperty(
-            name="Flip Width",
-            default=False,
-            description="Flip width direction",
-            update=use_cashes
-            )
-    depth: FloatProperty(
-            name="Depth",
-            default=.0,
-            precision=4, step=1,
-            update=use_cashes
-            )
-    flip_depth: BoolProperty(
-            name="Flip Depth",
-            default=False,
-            description="Flip depth direction",
-            update=use_cashes
-            )
-    depth_mode: EnumProperty(
-            items=[('angle', "Angle", "Angle"),
-                   ('depth', "Depth", "Depth")],
-            name="Depth mode",
-            default='angle',
-            update=use_cashes
-            )
-    angle: FloatProperty(
-            name="Angle", default=0,
-            precision=3, step=.1,
-            min=-2 * pi, max=2 * pi,
-            subtype='ANGLE',
-            description="Angle",
-            update=use_cashes
-            )
-    flip_angle: BoolProperty(
-            name="Flip Angle",
-            default=False,
-            description="Flip Angle",
-            update=use_cashes
-            )
-    follow_face: BoolProperty(
-            name="Follow Face",
-            default=False,
-            description="Offset along faces around"
-            )
-    mirror_modifier: BoolProperty(
-            name="Mirror Modifier",
-            default=False,
-            description="Take into account of Mirror modifier"
-            )
-    edge_rail: BoolProperty(
-            name="Edge Rail",
-            default=False,
-            description="Align vertices along inner edges"
-            )
-    edge_rail_only_end: BoolProperty(
-            name="Edge Rail Only End",
-            default=False,
-            description="Apply edge rail to end verts only"
-            )
-    threshold: FloatProperty(
-            name="Flat Face Threshold",
-            default=radians(0.05), precision=5,
-            step=1.0e-4, subtype='ANGLE',
-            description="If difference of angle between two adjacent faces is "
-                        "below this value, those faces are regarded as flat",
-            options={'HIDDEN'}
-            )
-    caches_valid: BoolProperty(
-            name="Caches Valid",
-            default=False,
-            options={'HIDDEN'}
-            )
-    angle_presets: EnumProperty(
-            items=[('0°', "0°", "0°"),
-                   ('15°', "15°", "15°"),
-                   ('30°', "30°", "30°"),
-                   ('45°', "45°", "45°"),
-                   ('60°', "60°", "60°"),
-                   ('75°', "75°", "75°"),
-                   ('90°', "90°", "90°"), ],
-            name="Angle Presets",
-            default='0°',
-            update=assign_angle_presets
-            )
-
-    _cache_offset_infos = None
-    _cache_edges_orig_ixs = None
-
-    @classmethod
-    def poll(self, context):
-        return context.mode == 'EDIT_MESH'
-
-    def draw(self, context):
-        layout = self.layout
-        layout.prop(self, 'geometry_mode', text="")
-
-        row = layout.row(align=True)
-        row.prop(self, 'width')
-        row.prop(self, 'flip_width', icon='ARROW_LEFTRIGHT', icon_only=True)
-        layout.prop(self, 'depth_mode', expand=True)
-
-        if self.depth_mode == 'angle':
-            d_mode = 'angle'
-            flip = 'flip_angle'
-        else:
-            d_mode = 'depth'
-            flip = 'flip_depth'
-        row = layout.row(align=True)
-        row.prop(self, d_mode)
-        row.prop(self, flip, icon='ARROW_LEFTRIGHT', icon_only=True)
-        if self.depth_mode == 'angle':
-            layout.prop(self, 'angle_presets', text="Presets", expand=True)
-
-        layout.separator()
-
-        layout.prop(self, 'follow_face')
-
-        row = layout.row()
-        row.prop(self, 'edge_rail')
-        if self.edge_rail:
-            row.prop(self, 'edge_rail_only_end', text="OnlyEnd", toggle=True)
-
-        layout.prop(self, 'mirror_modifier')
-        layout.operator('mesh.offset_edges', text="Repeat")
-
-        if self.follow_face:
-            layout.separator()
-            layout.prop(self, 'threshold', text="Threshold")
-
-    def get_offset_infos(self, bm, edit_object):
-        if self.caches_valid and self._cache_offset_infos is not None:
-            # Return None, indicating to use cache
-            return None, None
-
-        if ENABLE_DEBUG:
-            time = perf_counter()
-
-        set_edges_orig = collect_edges(bm)
-        if set_edges_orig is None:
-            self.report({'WARNING'},
-                        "No edges selected or edge loops could not be determined")
-            return False, False
-
-        if self.mirror_modifier:
-            mirror_planes = collect_mirror_planes(edit_object)
-            vert_mirror_pairs, set_edges = \
-                get_vert_mirror_pairs(set_edges_orig, mirror_planes)
-
-            if set_edges:
-                set_edges_orig = set_edges
-            else:
-                vert_mirror_pairs = None
-        else:
-            vert_mirror_pairs = None
-
-        loops = collect_loops(set_edges_orig)
-        if loops is None:
-            self.report({'WARNING'},
-                        "Overlap detected. Select non-overlapping edge loops")
-            return False, False
-
-        vec_upward = (X_UP + Y_UP + Z_UP).normalized()
-        # vec_upward is used to unify loop normals when follow_face is off
-        normal_fallback = Z_UP
-        # normal_fallback = Vector(context.region_data.view_matrix[2][:3])
-        # normal_fallback is used when loop normal cannot be calculated
-
-        follow_face = self.follow_face
-        edge_rail = self.edge_rail
-        er_only_end = self.edge_rail_only_end
-        threshold = self.threshold
-
-        offset_infos = []
-        for lp in loops:
-            verts, directions = get_directions(
-                lp, vec_upward, normal_fallback, vert_mirror_pairs,
-                follow_face=follow_face, edge_rail=edge_rail,
-                edge_rail_only_end=er_only_end,
-                threshold=threshold)
-            if verts:
-                offset_infos.append((verts, directions))
-
-        # Saving caches
-        self._cache_offset_infos = _cache_offset_infos = []
-        for verts, directions in offset_infos:
-            v_ixs = tuple(v.index for v in verts)
-            _cache_offset_infos.append((v_ixs, directions))
-        self._cache_edges_orig_ixs = tuple(e.index for e in set_edges_orig)
-
-        if ENABLE_DEBUG:
-            print("Preparing OffsetEdges: ", perf_counter() - time)
-
-        return offset_infos, set_edges_orig
-
-    def do_offset_and_free(self, bm, me, offset_infos=None, set_edges_orig=None):
-        # If offset_infos is None, use caches
-        # Makes caches invalid after offset
-
-        if ENABLE_DEBUG:
-            time = perf_counter()
-
-        if offset_infos is None:
-            # using cache
-            bmverts = tuple(bm.verts)
-            bmedges = tuple(bm.edges)
-            edges_orig = [bmedges[ix] for ix in self._cache_edges_orig_ixs]
-            verts_directions = []
-            for ix_vs, directions in self._cache_offset_infos:
-                verts = tuple(bmverts[ix] for ix in ix_vs)
-                verts_directions.append((verts, directions))
-        else:
-            verts_directions = offset_infos
-            edges_orig = list(set_edges_orig)
-
-        if self.depth_mode == 'angle':
-            w = self.width if not self.flip_width else -self.width
-            angle = self.angle if not self.flip_angle else -self.angle
-            width = w * cos(angle)
-            depth = w * sin(angle)
-        else:
-            width = self.width if not self.flip_width else -self.width
-            depth = self.depth if not self.flip_depth else -self.depth
-
-        # Extrude
-        if self.geometry_mode == 'move':
-            geom_ex = None
-        else:
-            geom_ex = extrude_edges(bm, edges_orig)
-
-        for verts, directions in verts_directions:
-            move_verts(width, depth, verts, directions, geom_ex)
-
-        clean(bm, self.geometry_mode, edges_orig, geom_ex)
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        bm.to_mesh(me)
-        bpy.ops.object.mode_set(mode="EDIT")
-        bm.free()
-        self.caches_valid = False  # Make caches invalid
-
-        if ENABLE_DEBUG:
-            print("OffsetEdges offset: ", perf_counter() - time)
-
-    def execute(self, context):
-        # In edit mode
-        edit_object = context.edit_object
-        bpy.ops.object.mode_set(mode="OBJECT")
-
-        me = edit_object.data
-        bm = bmesh.new()
-        bm.from_mesh(me)
-
-        offset_infos, edges_orig = self.get_offset_infos(bm, edit_object)
-        if offset_infos is False:
-            bpy.ops.object.mode_set(mode="EDIT")
-            return {'CANCELLED'}
-
-        self.do_offset_and_free(bm, me, offset_infos, edges_orig)
-
-        return {'FINISHED'}
-
-    def restore_original_and_free(self, context):
-        self.caches_valid = False  # Make caches invalid
-        context.area.header_text_set(None)
-
-        me = context.edit_object.data
-        bpy.ops.object.mode_set(mode="OBJECT")
-        self._bm_orig.to_mesh(me)
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        self._bm_orig.free()
-        context.area.header_text_set(None)
-
-    def invoke(self, context, event):
-        # In edit mode
-        edit_object = context.edit_object
-        me = edit_object.data
-        bpy.ops.object.mode_set(mode="OBJECT")
-        for p in me.polygons:
-            if p.select:
-                self.follow_face = True
-                break
-
-        self.caches_valid = False
-        bpy.ops.object.mode_set(mode="EDIT")
-        return self.execute(context)
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == '__main__':
-    register()
diff --git a/mesh_extra_tools/mesh_pen_tool.py b/mesh_extra_tools/mesh_pen_tool.py
deleted file mode 100644
index 76d5e0aa6..000000000
--- a/mesh_extra_tools/mesh_pen_tool.py
+++ /dev/null
@@ -1,568 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# ##### 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 #####
-
-bl_info = {
-    "name": "Pen Tool",
-    "author": "zmj100",
-    "version": (0, 3, 1),
-    "blender": (2, 78, 0),
-    "location": "View3D > Tool Shelf",
-    "description": "",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh",
-    }
-
-import bpy
-import bpy_extras
-import blf
-import bgl
-import bmesh
-from bpy.types import (
-        Operator,
-        PropertyGroup,
-        Panel
-        )
-from bpy.props import (
-        FloatProperty,
-        IntProperty,
-        PointerProperty,
-        BoolProperty
-        )
-from bpy_extras.view3d_utils import (
-        region_2d_to_location_3d,
-        location_3d_to_region_2d,
-        )
-from mathutils import (
-        Vector,
-        Matrix,
-        )
-from math import degrees
-
-
-def edit_mode_out():
-    bpy.ops.object.mode_set(mode='OBJECT')
-
-
-def edit_mode_in():
-    bpy.ops.object.mode_set(mode='EDIT')
-
-
-def get_direction_(bme, list_, ob_act):
-    n = len(list_)
-    for i in range(n):
-        p = ob_act.matrix_world * (bme.verts[list_[i]].co).copy()
-        p1 = ob_act.matrix_world * (bme.verts[list_[(i - 1) % n]].co).copy()
-        p2 = ob_act.matrix_world * (bme.verts[list_[(i + 1) % n]].co).copy()
-
-        if p == p1 or p == p2:
-            continue
-        ang = round(degrees((p - p1).angle((p - p2), any)))
-        if ang == 0 or ang == 180:
-            continue
-        elif ang != 0 or ang != 180:
-            return(((p - p1).cross((p - p2))).normalized())
-            break
-
-
-def store_restore_view(context, store=True):
-    if not context.scene.pen_tool_props.restore_view:
-        return
-
-    if store is True:
-        # copy the original view_matrix and rotation for restoring
-        pt_buf.store_view_matrix = context.space_data.region_3d.view_matrix.copy()
-        pt_buf.view_location = context.space_data.region_3d.view_location.copy()
-    else:
-        context.space_data.region_3d.view_matrix = pt_buf.store_view_matrix
-        context.space_data.region_3d.view_location = pt_buf.view_location
-
-
-def align_view_to_face_(context, bme, f):
-    store_restore_view(context, True)
-    ob_act = context.active_object
-    list_e = [[v.index for v in e.verts] for e in f.edges][0]
-    vec0 = -get_direction_(bme, [v.index for v in f.verts], ob_act)
-    vec1 = ((ob_act.matrix_world * bme.verts[list_e[0]].co.copy()) -
-            (ob_act.matrix_world * bme.verts[list_e[1]].co.copy())).normalized()
-    vec2 = (vec0.cross(vec1)).normalized()
-    context.space_data.region_3d.view_matrix = ((Matrix((vec1, vec2, vec0))).to_4x4()).inverted()
-    context.space_data.region_3d.view_location = f.calc_center_median()
-
-
-def draw_callback_px(self, context):
-    font_id = 0
-    alpha = context.scene.pen_tool_props.a
-    font_size = context.scene.pen_tool_props.fs
-
-    bgl.glColor4f(0.0, 0.6, 1.0, alpha)
-    bgl.glPointSize(4.0)
-    bgl.glBegin(bgl.GL_POINTS)
-    bgl.glVertex2f(pt_buf.x, pt_buf.y)
-    bgl.glEnd()
-    bgl.glDisable(bgl.GL_BLEND)
-
-    # location 3d
-    if context.scene.pen_tool_props.b2 is True:
-        mloc3d = region_2d_to_location_3d(
-                        context.region,
-                        context.space_data.region_3d, Vector((pt_buf.x, pt_buf.y)),
-                        pt_buf.depth_location
-                        )
-        blf.position(font_id, pt_buf.x + 15, pt_buf.y - 15, 0)
-        blf.size(font_id, font_size, context.preferences.system.dpi)
-        blf.draw(font_id,
-                '(' + str(round(mloc3d[0], 4)) + ', ' + str(round(mloc3d[1], 4)) +
-                ', ' + str(round(mloc3d[2], 4)) + ')')
-
-    n = len(pt_buf.list_m_loc_3d)
-
-    if n != 0:
-        # add points
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glPointSize(4.0)
-        bgl.glBegin(bgl.GL_POINTS)
-        for i in pt_buf.list_m_loc_3d:
-            loc_0 = location_3d_to_region_2d(
-                            context.region, context.space_data.region_3d, i
-                            )
-            bgl.glVertex2f(loc_0[0], loc_0[1])
-        bgl.glEnd()
-        bgl.glDisable(bgl.GL_BLEND)
-
-        # text next to the mouse
-        m_loc_3d = region_2d_to_location_3d(
-                            context.region,
-                            context.space_data.region_3d, Vector((pt_buf.x, pt_buf.y)),
-                            pt_buf.depth_location
-                            )
-        vec0 = pt_buf.list_m_loc_3d[-1] - m_loc_3d
-        blf.position(font_id, pt_buf.x + 15, pt_buf.y + 15, 0)
-        blf.size(font_id, font_size, context.preferences.system.dpi)
-        blf.draw(font_id, str(round(vec0.length, 4)))
-
-        #  angle first after mouse
-        if n >= 2:
-            vec1 = pt_buf.list_m_loc_3d[-2] - pt_buf.list_m_loc_3d[-1]
-            if vec0.length == 0.0 or vec1.length == 0.0:
-                pass
-            else:
-                ang = vec0.angle(vec1)
-
-                if round(degrees(ang), 2) == 180.0:
-                    text_0 = '0.0'
-                elif round(degrees(ang), 2) == 0.0:
-                    text_0 = '180.0'
-                else:
-                    text_0 = str(round(degrees(ang), 2))
-
-                loc_4 = location_3d_to_region_2d(
-                                        context.region,
-                                        context.space_data.region_3d,
-                                        pt_buf.list_m_loc_3d[-1]
-                                        )
-                bgl.glColor4f(0.0, 1.0, 0.525, alpha)
-                blf.position(font_id, loc_4[0] + 10, loc_4[1] + 10, 0)
-                blf.size(font_id, font_size, context.preferences.system.dpi)
-                blf.draw(font_id, text_0 + '')
-
-        bgl.glLineStipple(4, 0x5555)
-        bgl.glEnable(bgl.GL_LINE_STIPPLE)      # enable line stipple
-
-        bgl.glColor4f(0.0, 0.6, 1.0, alpha)
-        #  draw line between last point and mouse
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glBegin(bgl.GL_LINES)
-        loc_1 = location_3d_to_region_2d(
-                                context.region,
-                                context.space_data.region_3d,
-                                pt_buf.list_m_loc_3d[-1]
-                                )
-        bgl.glVertex2f(loc_1[0], loc_1[1])
-        bgl.glVertex2f(pt_buf.x, pt_buf.y)
-        bgl.glEnd()
-        bgl.glDisable(bgl.GL_BLEND)
-
-        # draw lines between points
-        bgl.glEnable(bgl.GL_BLEND)
-        bgl.glBegin(bgl.GL_LINE_STRIP)
-        for j in pt_buf.list_m_loc_3d:
-            loc_2 = location_3d_to_region_2d(context.region, context.space_data.region_3d, j)
-            bgl.glVertex2f(loc_2[0], loc_2[1])
-        bgl.glEnd()
-        bgl.glDisable(bgl.GL_BLEND)
-
-        bgl.glDisable(bgl.GL_LINE_STIPPLE)      # disable line stipple
-
-        # draw line length between points
-        if context.scene.pen_tool_props.b1 is True:
-            for k in range(n - 1):
-                loc_3 = location_3d_to_region_2d(
-                                context.region, context.space_data.region_3d,
-                                (pt_buf.list_m_loc_3d[k] + pt_buf.list_m_loc_3d[(k + 1) % n]) * 0.5
-                                )
-                blf.position(font_id, loc_3[0] + 10, loc_3[1] + 10, 0)
-                blf.size(font_id, font_size, context.preferences.system.dpi)
-                blf.draw(font_id,
-                         str(round((pt_buf.list_m_loc_3d[k] - pt_buf.list_m_loc_3d[(k + 1) % n]).length, 4)))
-
-        # draw all angles
-        if context.scene.pen_tool_props.b0 is True:
-            for h in range(n - 1):
-                if n >= 2:
-                    if h == 0:
-                        pass
-                    else:
-                        vec_ = pt_buf.list_m_loc_3d[h] - pt_buf.list_m_loc_3d[(h - 1) % n]
-                        vec_1_ = pt_buf.list_m_loc_3d[h]
-                        vec_2_ = pt_buf.list_m_loc_3d[(h - 1) % n]
-                        if vec_.length == 0.0 or vec_1_.length == 0.0 or vec_2_.length == 0.0:
-                            pass
-                        else:
-                            ang = vec_.angle(vec_1_ - vec_2_)
-                            if round(degrees(ang)) == 0.0:
-                                pass
-                            else:
-                                loc_4 = location_3d_to_region_2d(
-                                                context.region, context.space_data.region_3d,
-                                                pt_buf.list_m_loc_3d[h]
-                                                )
-                                bgl.glColor4f(0.0, 1.0, 0.525, alpha)
-                                blf.position(font_id, loc_4[0] + 10, loc_4[1] + 10, 0)
-                                blf.size(font_id, font_size, context.preferences.system.dpi)
-                                blf.draw(font_id, str(round(degrees(ang), 2)) + '')
-    # tools on / off
-    bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
-    blf.position(font_id, self.text_location, 20, 0)
-    blf.size(font_id, 15, context.preferences.system.dpi)
-    blf.draw(font_id, "Draw On")
-    blf.position(font_id, self.text_location, 40, 0)
-    blf.draw(font_id, "Extrude On" if pt_buf.ctrl else "Extrude Off")
-
-
-class pen_tool_properties(PropertyGroup):
-    a: FloatProperty(
-            name="Alpha",
-            description="Set Font Alpha",
-            default=1.0,
-            min=0.1, max=1.0,
-            step=10,
-            precision=1
-            )
-    fs: IntProperty(
-            name="Size",
-            description="Set Font Size",
-            default=14,
-            min=12, max=40,
-            step=1
-            )
-    b0: BoolProperty(
-            name="Angles",
-            description="Display All Angles on Drawn Edges",
-            default=False
-            )
-    b1: BoolProperty(
-            name="Edge Length",
-            description="Display All Lengths of Drawn Edges",
-            default=False
-            )
-    b2: BoolProperty(
-            name="Mouse Location 3D",
-            description="Display the location coordinates of the mouse cursor",
-            default=False
-            )
-    restore_view: BoolProperty(
-            name="Restore View",
-            description="After the tool has finished, is the Viewport restored\n"
-                        "to it's previous state",
-            default=True
-            )
-
-
-class pt_buf():
-    list_m_loc_2d = []
-    list_m_loc_3d = []
-    x = 0
-    y = 0
-    sws = 'off'
-    depth_location = Vector((0.0, 0.0, 0.0))
-    alt = False
-    shift = False
-    ctrl = False
-    store_view_matrix = Matrix()
-    view_location = (0.0, 0.0, 0.0)
-
-
-# ------ Panel  ------
-class pen_tool_panel(Panel):
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_category = "Tools"
-    bl_label = "Pen Tool"
-    bl_context = "mesh_edit"
-    bl_options = {"DEFAULT_CLOSED"}
-
-    def draw(self, context):
-        layout = self.layout
-        pen_tool_props = context.scene.pen_tool_props
-
-        if pt_buf.sws == "on":
-            layout.active = False
-            layout.label(text="Pen Tool Active", icon="INFO")
-        else:
-            col = layout.column(align=True)
-            col.label(text="Font:")
-            col.prop(pen_tool_props, "fs", text="Size", slider=True)
-            col.prop(pen_tool_props, "a", text="Alpha", slider=True)
-
-            col = layout.column(align=True)
-            col.label(text="Settings:")
-            col.prop(pen_tool_props, "b0", text="Angles", toggle=True)
-            col.prop(pen_tool_props, "b1", text="Edge Length", toggle=True)
-            col.prop(pen_tool_props, "b2", text="Mouse Location 3D", toggle=True)
-            col.prop(pen_tool_props, "restore_view", text="Restore View", toggle=True)
-
-            split = layout.split(0.80, align=True)
-            split.operator("pen_tool.operator", text="Draw")
-            split.operator("mesh.extra_tools_help",
-                           icon="LAYER_USED").help_ids = "mesh_pen_tool"
-
-
-# Operator
-class pen_tool_operator(Operator):
-    bl_idname = "pen_tool.operator"
-    bl_label = "Pen Tool"
-    bl_options = {"REGISTER", "UNDO", "INTERNAL"}
-
-    text_location: IntProperty(
-            name="",
-            default=0,
-            options={'HIDDEN'}
-            )
-
-    @classmethod
-    def poll(cls, context):
-        # do not run in object mode
-        return (context.active_object and context.active_object.type == 'MESH' and
-                context.mode == 'EDIT_MESH')
-
-    def execute(self, context):
-        edit_mode_out()
-        ob_act = context.active_object
-        bme = bmesh.new()
-        bme.from_mesh(ob_act.data)
-
-        mtrx = ob_act.matrix_world.inverted()   # ob_act matrix world inverted
-
-        # add vertices
-        list_ = []
-        for i in pt_buf.list_m_loc_3d:
-            bme.verts.new(mtrx * i)
-            bme.verts.index_update()
-            bme.verts.ensure_lookup_table()
-            list_.append(bme.verts[-1])
-
-        # add edges
-        n = len(list_)
-        for j in range(n - 1):
-            bme.edges.new((list_[j], list_[(j + 1) % n]))
-            bme.edges.index_update()
-
-        bme.to_mesh(ob_act.data)
-        store_restore_view(context, False)
-        edit_mode_in()
-
-        pt_buf.list_m_loc_2d[:] = []
-        pt_buf.list_m_loc_3d[:] = []
-        pt_buf.depth_location = Vector((0.0, 0.0, 0.0))
-        pt_buf.store_view_matrix = Matrix()
-        pt_buf.view_location = (0.0, 0.0, 0.0)
-        pt_buf.ctrl = False
-
-        context.area.tag_redraw()
-        return {'FINISHED'}
-
-    def modal(self, context, event):
-        context.area.tag_redraw()
-
-        # allow moving in the 3D View
-        if event.type in {
-                'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE',
-                'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_6',
-                'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9', 'NUMPAD_5'}:
-            return {'PASS_THROUGH'}
-
-        if event.type in {'LEFT_ALT', 'RIGHT_ALT'}:
-            if event.value == 'PRESS':
-                pt_buf.alt = True
-            if event.value == 'RELEASE':
-                pt_buf.alt = False
-            return {'RUNNING_MODAL'}
-
-        elif event.type in {'LEFT_CTRL', 'RIGHT_CTRL'}:
-            if event.value == 'PRESS':
-                pt_buf.ctrl = not pt_buf.ctrl
-            return {'RUNNING_MODAL'}
-
-        elif event.type in {'LEFT_SHIFT', 'RIGHT_SHIFT'}:
-            if event.value == 'PRESS':
-                pt_buf.shift = True
-            if event.value == 'RELEASE':
-                pt_buf.shift = False
-            return {'RUNNING_MODAL'}
-
-        elif event.type == 'MOUSEMOVE':
-            if pt_buf.list_m_loc_2d != []:
-                pt_buf_list_m_loc_3d_last_2d = location_3d_to_region_2d(
-                                                context.region,
-                                                context.space_data.region_3d,
-                                                pt_buf.list_m_loc_3d[-1]
-                                                )
-                if pt_buf.alt is True:
-                    pt_buf.x = pt_buf_list_m_loc_3d_last_2d[0]
-                    pt_buf.y = event.mouse_region_y
-                elif pt_buf.shift is True:
-                    pt_buf.x = event.mouse_region_x
-                    pt_buf.y = pt_buf_list_m_loc_3d_last_2d[1]
-                else:
-                    pt_buf.x = event.mouse_region_x
-                    pt_buf.y = event.mouse_region_y
-            else:
-                pt_buf.x = event.mouse_region_x
-                pt_buf.y = event.mouse_region_y
-
-        elif event.type == 'LEFTMOUSE':
-            if event.value == 'PRESS':
-                mouse_loc_2d = Vector((pt_buf.x, pt_buf.y))
-                pt_buf.list_m_loc_2d.append(mouse_loc_2d)
-
-                mouse_loc_3d = region_2d_to_location_3d(
-                                                context.region, context.space_data.region_3d,
-                                                mouse_loc_2d, pt_buf.depth_location
-                                                )
-                pt_buf.list_m_loc_3d.append(mouse_loc_3d)
-
-                pt_buf.depth_location = pt_buf.list_m_loc_3d[-1]   # <-- depth location
-                # run Extrude at cursor
-                if pt_buf.ctrl:
-                    try:
-                        bpy.ops.mesh.dupli_extrude_cursor('INVOKE_DEFAULT', rotate_source=False)
-                    except:
-                        pass
-            elif event.value == 'RELEASE':
-                pass
-        elif event.type == 'RIGHTMOUSE':
-            context.space_data.draw_handler_remove(self._handle_px, 'WINDOW')
-            self.execute(context)
-            pt_buf.sws = 'off'
-            return {'FINISHED'}
-        elif event.type == 'ESC':
-            context.space_data.draw_handler_remove(self._handle_px, 'WINDOW')
-            store_restore_view(context, False)
-            pt_buf.list_m_loc_2d[:] = []
-            pt_buf.list_m_loc_3d[:] = []
-            pt_buf.depth_location = Vector((0.0, 0.0, 0.0))
-            pt_buf.sws = 'off'
-            pt_buf.store_view_matrix = Matrix()
-            pt_buf.view_location = (0.0, 0.0, 0.0)
-            pt_buf.ctrl = False
-            return {'CANCELLED'}
-
-        # Return has to be modal or the tool can crash
-        # It's better to define PASS_THROUGH as the exception and not the default
-        return {'RUNNING_MODAL'}
-
-    def invoke(self, context, event):
-        bme = bmesh.from_edit_mesh(context.active_object.data)
-        list_f = [f for f in bme.faces if f.select]
-
-        if len(list_f) != 0:
-            f = list_f[0]
-            pt_buf.depth_location = f.calc_center_median()
-            align_view_to_face_(context, bme, f)
-
-        if context.area.type == 'VIEW_3D':
-            # pre-compute the text location (thanks to the Carver add-on)
-            self.text_location = 100
-            overlap = context.preferences.system.use_region_overlap
-            for region in context.area.regions:
-                if region.type == "WINDOW":
-                    self.text_location = region.width - 100
-            if overlap:
-                for region in context.area.regions:
-                    # The Properties Region on the right is of UI type
-                    if region.type == "UI":
-                        self.text_location = self.text_location - region.width
-
-            if pt_buf.sws == 'on':
-                return {'RUNNING_MODAL'}
-            elif pt_buf.sws != 'on':
-                context.window_manager.modal_handler_add(self)
-                self._handle_px = context.space_data.draw_handler_add(
-                                            draw_callback_px,
-                                            (self, context),
-                                            'WINDOW', 'POST_PIXEL'
-                                            )
-                pt_buf.sws = 'on'
-                return {'RUNNING_MODAL'}
-        else:
-            self.report({'WARNING'}, "Pen Tool: Operation Cancelled. View3D not found")
-            return {'CANCELLED'}
-
-
-class_list = (
-        pen_tool_panel,
-        pen_tool_operator,
-        pen_tool_properties
-        )
-
-
-KEYMAPS = (
-    # First, keymap identifiers (last bool is True for modal km).
-    (("3D View", "VIEW_3D", "WINDOW", False), (
-    # Then a tuple of keymap items, defined by a dict of kwargs
-    # for the km new func, and a tuple of tuples (name, val)
-    # for ops properties, if needing non-default values.
-        ({"idname": pen_tool_operator.bl_idname, "type": 'D', "value": 'PRESS', "ctrl": True},
-         ()),
-    )),
-)
-
-
-def register():
-    for c in class_list:
-        bpy.utils.register_class(c)
-
-    bpy.types.Scene.pen_tool_props = PointerProperty(type=pen_tool_properties)
-
-    bpy_extras.keyconfig_utils.addon_keymap_register(bpy.context.window_manager, KEYMAPS)
-
-
-def unregister():
-    bpy_extras.keyconfig_utils.addon_keymap_unregister(bpy.context.window_manager, KEYMAPS)
-
-    del bpy.types.Scene.pen_tool_props
-
-    for c in class_list:
-        bpy.utils.unregister_class(c)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_select_tools/__init__.py b/mesh_extra_tools/mesh_select_tools/__init__.py
deleted file mode 100644
index 74d42f1cf..000000000
--- a/mesh_extra_tools/mesh_select_tools/__init__.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# ##### 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 #####
-
-# menu & updates by meta-androcto #
-# contributed to by :
-# Macouno, dustractor, liero, lijenstina, #
-# CoDEmanX, Dolf Veenvliet, meta-androcto #
-
-bl_info = {
-    "name": "Select Tools",
-    "author": "Multiple Authors",
-    "version": (0, 3, 1),
-    "blender": (2, 64, 0),
-    "location": "Editmode Select Menu/Toolshelf Tools Tab",
-    "description": "Adds More vert/face/edge select modes.",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"
-    }
-
-if "bpy" in locals():
-    import importlib
-    importlib.reload(mesh_select_by_direction)
-    importlib.reload(mesh_select_by_edge_length)
-    importlib.reload(mesh_select_by_pi)
-    importlib.reload(mesh_select_by_type)
-    importlib.reload(mesh_select_connected_faces)
-    importlib.reload(mesh_index_select)
-    importlib.reload(mesh_selection_topokit)
-    importlib.reload(mesh_info_select)
-else:
-    from . import mesh_select_by_direction
-    from . import mesh_select_by_edge_length
-    from . import mesh_select_by_pi
-    from . import mesh_select_by_type
-    from . import mesh_select_connected_faces
-    from . import mesh_index_select
-    from . import mesh_selection_topokit
-    from . import mesh_info_select
-
-import bpy
-
-
-# Register
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_select_tools/mesh_index_select.py b/mesh_extra_tools/mesh_select_tools/mesh_index_select.py
deleted file mode 100644
index a9e14dfe2..000000000
--- a/mesh_extra_tools/mesh_select_tools/mesh_index_select.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# gpl author: liero
-
-bl_info = {
-    "name": "Select by index",
-    "author": "liero",
-    "version": (0, 2),
-    "blender": (2, 55, 0),
-    "location": "View3D > Tool Shelf",
-    "description": "Select mesh data by index / area / length / cursor",
-    "category": "Mesh",
-    }
-
-import bpy
-from bpy.types import Operator
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        EnumProperty,
-        )
-
-
-class SelVertEdgeFace(Operator):
-    bl_idname = "mesh.select_vert_edge_face_index"
-    bl_label = "Select mesh index"
-    bl_description = "Select Vertices, Edges, Faces by their indices"
-    bl_options = {"REGISTER", "UNDO"}
-
-    select_type: EnumProperty(
-            items=[
-                   ('VERT', "Vertices", "Select Vertices by index"),
-                   ('EDGE', "Edges", "Select Edges by index"),
-                   ('FACE', "Faces", "Select Faces by index"),
-                   ],
-            name="Selection Mode",
-            description="",
-            default='VERT',
-            )
-    indice: FloatProperty(
-            name="Selected",
-            default=0,
-            min=0, max=100,
-            description="Percentage of selection",
-            precision=2,
-            subtype="PERCENTAGE"
-            )
-    delta: BoolProperty(
-            name="Use Parameter",
-            default=False,
-            description="Select by Index / Parameter"
-            )
-    flip: BoolProperty(
-            name="Reverse Order",
-            default=False,
-            description="Reverse selecting order"
-            )
-    start_new: BoolProperty(
-            name="Fresh Start",
-            default=False,
-            description="Start from no previous selection\n"
-                        "If unchecked the previous selection is kept"
-            )
-    delta_text = {'VERT': "Use Cursor",
-                  'EDGE': "Use Edges' Length",
-                  'FACE': "Use Faces' Area"}
-
-    @classmethod
-    def poll(cls, context):
-        return (context.object is not None and context.object.type == 'MESH')
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.label(text="Selection Type:")
-        layout.prop(self, "select_type", text="")
-        layout.separator()
-
-        layout.label(text="Selected:")
-        layout.prop(self, "indice", text="", slider=True)
-
-        d_text = self.delta_text[self.select_type]
-        layout.prop(self, "delta", text=d_text)
-
-        layout.prop(self, "flip")
-        layout.prop(self, "start_new")
-
-    def execute(self, context):
-        obj = bpy.context.object
-
-        if self.start_new:
-            bpy.ops.mesh.select_all(action='DESELECT')
-
-        # Selection mode - Vertex, Edge, Face
-        if self.select_type == 'VERT':
-            bpy.context.tool_settings.mesh_select_mode = [True, False, False]
-            ver = obj.data.vertices
-            loc = context.scene.cursor.location
-            sel = []
-            for v in ver:
-                d = v.co - loc
-                sel.append((d.length, v.index))
-            sel.sort(reverse=self.flip)
-            bpy.ops.object.mode_set()
-            valor = round(len(sel) / 100 * self.indice)
-            if self.delta:
-                for i in range(len(sel[:valor])):
-                    ver[sel[i][1]].select = True
-            else:
-                for i in range(len(sel[:valor])):
-                    if self.flip:
-                        ver[len(sel) - i - 1].select = True
-                    else:
-                        ver[i].select = True
-
-        elif self.select_type == 'EDGE':
-            bpy.context.tool_settings.mesh_select_mode = [False, True, False]
-            ver = obj.data.vertices
-            edg = obj.data.edges
-            sel = []
-            for e in edg:
-                d = ver[e.vertices[0]].co - ver[e.vertices[1]].co
-                sel.append((d.length, e.index))
-            sel.sort(reverse=self.flip)
-            bpy.ops.object.mode_set()
-            valor = round(len(sel) / 100 * self.indice)
-            if self.delta:
-                for i in range(len(sel[:valor])):
-                    edg[sel[i][1]].select = True
-            else:
-                for i in range(len(sel[:valor])):
-                    if self.flip:
-                        edg[len(sel) - i - 1].select = True
-                    else:
-                        edg[i].select = True
-
-        elif self.select_type == 'FACE':
-            bpy.context.tool_settings.mesh_select_mode = [False, False, True]
-            fac = obj.data.polygons
-            sel = []
-            for f in fac:
-                sel.append((f.area, f.index))
-            sel.sort(reverse=self.flip)
-            bpy.ops.object.mode_set()
-            valor = round(len(sel) / 100 * self.indice)
-            if self.delta:
-                for i in range(len(sel[:valor])):
-                    fac[sel[i][1]].select = True
-            else:
-                for i in range(len(sel[:valor])):
-                    if self.flip:
-                        fac[len(sel) - i - 1].select = True
-                    else:
-                        fac[i].select = True
-
-        bpy.ops.object.mode_set(mode='EDIT')
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(SelVertEdgeFace)
-
-
-def unregister():
-    bpy.utils.register_class(SelVertEdgeFace)
-
-
-if __name__ == '__main__':
-    register()
diff --git a/mesh_extra_tools/mesh_select_tools/mesh_info_select.py b/mesh_extra_tools/mesh_select_tools/mesh_info_select.py
deleted file mode 100644
index 2a9f1991b..000000000
--- a/mesh_extra_tools/mesh_select_tools/mesh_info_select.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# ##### 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 #####
-
-# By CoDEmanX
-# updated by lijenstina
-
-import bpy
-import bmesh
-from bpy.types import Panel
-import time
-
-# Define Globals
-STORE_COUNT = (0, 0, 0)  # Store the previous count
-TIMER_STORE = 1          # Store the time.time floats
-
-
-def check_the_obj_polycount(context, delay=0.0):
-    global STORE_COUNT
-    global TIMER_STORE
-
-    info_str = ""
-    tris = quads = ngons = 0
-    try:
-        # it's weak sauce but this will in certain cases run many times a second
-        if TIMER_STORE == 1 or delay == 0 or time.time() > TIMER_STORE + delay:
-            ob = context.active_object
-            if ob.mode == 'EDIT':
-                me = ob.data
-                bm = bmesh.from_edit_mesh(me)
-                for f in bm.faces:
-                    v = len(f.verts)
-                    if v == 3:
-                        tris += 1
-                    elif v == 4:
-                        quads += 1
-                    else:
-                        ngons += 1
-                bmesh.update_edit_mesh(me)
-            else:
-                for p in ob.data.polygons:
-                    count = p.loop_total
-                    if count == 3:
-                        tris += 1
-                    elif count == 4:
-                        quads += 1
-                    else:
-                        ngons += 1
-            STORE_COUNT = (ngons, quads, tris)
-            info_str = "  Ngons: %i  Quads: %i  Tris: %i" % (ngons, quads, tris)
-            TIMER_STORE = time.time()
-        else:
-            info_str = "  Ngons: %i  Quads: %i  Tris: %i" % STORE_COUNT
-    except:
-        info_str = "  Polygon info could not be retrieved"
-
-    return info_str
-
-
-class DATA_PT_info_panel(Panel):
-    """Creates a face info / select panel in the Object properties window"""
-    bl_label = "Face Info / Select"
-    bl_idname = "DATA_PT_face_info"
-    bl_space_type = "PROPERTIES"
-    bl_region_type = "WINDOW"
-    bl_context = "data"
-    bl_options = {'DEFAULT_CLOSED'}
-
-    @classmethod
-    def poll(self, context):
-        return (context.active_object is not None and
-                context.active_object.type == 'MESH')
-
-    def draw(self, context):
-        layout = self.layout
-        mesh_extra_tools = context.scene.mesh_extra_tools
-        check_used = mesh_extra_tools.mesh_info_show
-        check_delay = mesh_extra_tools.mesh_info_delay
-        info_str = ""
-
-        box = layout.box()
-        col = box.column()
-        split = col.split(factor=0.6 if check_used else 0.75, align=True)
-        split.prop(mesh_extra_tools, "mesh_info_show", toggle=True)
-        split.prop(mesh_extra_tools, "mesh_info_delay")
-
-        if check_used:
-            info_str = check_the_obj_polycount(context, check_delay)
-            col.label(text=info_str, icon='MESH_DATA')
-
-        col = layout.column()
-        col.label(text="Select faces by type:")
-
-        row = layout.row()
-        row.operator("data.facetype_select", text="Ngons").face_type = "5"
-        row.operator("data.facetype_select", text="Quads").face_type = "4"
-        row.operator("data.facetype_select", text="Tris").face_type = "3"
diff --git a/mesh_extra_tools/mesh_select_tools/mesh_select_by_direction.py b/mesh_extra_tools/mesh_select_tools/mesh_select_by_direction.py
deleted file mode 100644
index cf25cf6fc..000000000
--- a/mesh_extra_tools/mesh_select_tools/mesh_select_by_direction.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# Copyright (C) 2011, Dolf Veenvliet
-# Extrude a selection from a mesh multiple times
-
-# ##### 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 #####
-
-"""
-Usage:
-    Select all items whose normals face a certain direction
-Additional links:
-    Author Site: http://www.macouno.com
-    e-mail: dolf {at} macouno {dot} com
-"""
-
-import bpy
-from bpy.types import Operator
-from mathutils import Vector
-from math import radians
-from bpy.props import (
-        FloatVectorProperty,
-        FloatProperty,
-        BoolProperty,
-        EnumProperty,
-        )
-
-
-class Select_by_direction():
-
-    # Initialise the class
-    def __init__(self, context, direction, divergence, extend, space):
-
-        self.ob = context.active_object
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-        self.space = space
-
-        # if we do stuff in global space we need to object matrix
-        if self.space == 'GLO':
-            # TODO: not sure if this is the correct way to solve the crash - lijenstina
-            mat = self.ob.matrix_world
-            mat_rot = mat.to_3x3().inverted()
-            direction = mat_rot * Vector(direction)
-        else:
-            direction = Vector(direction)
-
-        direction = direction.normalized()
-
-        vertSelect = bpy.context.tool_settings.mesh_select_mode[0]
-        edgeSelect = bpy.context.tool_settings.mesh_select_mode[1]
-        faceSelect = bpy.context.tool_settings.mesh_select_mode[2]
-
-        if Vector(direction).length:
-            # Vert select
-            if vertSelect:
-                hasSelected = self.hasSelected(self.ob.data.vertices)
-
-                for v in self.ob.data.vertices:
-                    normal = v.normal
-                    s = self.selectCheck(v.select, hasSelected, extend)
-                    d = self.deselectCheck(v.select, hasSelected, extend)
-
-                    if s or d:
-                        angle = direction.angle(normal)
-
-                    # Check if the verts match any of the directions
-                    if s and angle <= divergence:
-                        v.select = True
-
-                    if d and angle > divergence:
-                        v.select = False
-            # Edge select
-            if edgeSelect:
-                hasSelected = self.hasSelected(self.ob.data.edges)
-
-                for e in self.ob.data.edges:
-                    s = self.selectCheck(e.select, hasSelected, extend)
-                    d = self.deselectCheck(e.select, hasSelected, extend)
-
-                    # Check if the edges match any of the directions
-                    if s or d:
-                        normal = self.ob.data.vertices[e.vertices[0]].normal
-                        normal += self.ob.data.vertices[e.vertices[1]].normal
-
-                        angle = direction.angle(normal)
-
-                    if s and angle <= divergence:
-                        e.select = True
-
-                    if d and angle > divergence:
-                        e.select = False
-
-            # Face select
-            if faceSelect:
-                hasSelected = self.hasSelected(self.ob.data.polygons)
-
-                # Loop through all the given faces
-                for f in self.ob.data.polygons:
-                    s = self.selectCheck(f.select, hasSelected, extend)
-                    d = self.deselectCheck(f.select, hasSelected, extend)
-
-                    if s or d:
-                        angle = direction.angle(f.normal)
-
-                    # Check if the faces match any of the directions
-                    if s and angle <= divergence:
-                        f.select = True
-
-                    if d and angle > divergence:
-                        f.select = False
-
-        bpy.ops.object.mode_set(mode='EDIT')
-
-    # See if the current item should be selected or not
-    def selectCheck(self, isSelected, hasSelected, extend):
-        # If the current item is not selected we may want to select
-        if not isSelected:
-            # If we are extending or nothing is selected we want to select
-            if extend or not hasSelected:
-                return True
-
-        return False
-
-    # See if the current item should be deselected or not
-    def deselectCheck(self, isSelected, hasSelected, extend):
-        # If the current item is selected we may want to deselect
-        if isSelected:
-
-            # If something is selected and we're not extending we want to deselect
-            if hasSelected and not extend:
-                return True
-
-        return False
-
-    # See if there is at least one selected item
-    def hasSelected(self, items):
-        for item in items:
-            if item.select:
-                return True
-
-        return False
-
-
-class Select_init(Operator):
-    bl_idname = "mesh.select_by_direction"
-    bl_label = "Select by direction"
-    bl_description = ("Select all items with normals facing a certain direction,\n"
-                      "defined by a vector with coordinates X, Y, Z")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    direction: FloatVectorProperty(
-            name="Direction",
-            description="Define a vector from the inputs axis X, Y, Z\n"
-                        "Used to define the normals direction",
-            default=(0.0, 0.0, 1.0),
-            min=-100.0, max=100.0,
-            soft_min=-10.0, soft_max=10.0,
-            step=100,
-            precision=2
-            )
-    divergence: FloatProperty(
-            name="Divergence",
-            description="The number of degrees the selection may differ from the Vector\n"
-                        "(Input is converted to radians)",
-            default=radians(30.0),
-            min=0.0, max=radians(360.0),
-            soft_min=0.0, soft_max=radians(360.0),
-            step=radians(5000),
-            precision=2,
-            subtype='ANGLE'
-            )
-    extend: BoolProperty(
-            name="Extend",
-            description="Extend the current selection",
-            default=False
-            )
-    # The spaces we use
-    spaces = (('LOC', 'Local', ''), ('GLO', 'Global', ''))
-    space: EnumProperty(
-            items=spaces,
-            name="Space",
-            description="The space to interpret the directions in",
-            default='LOC'
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH')
-
-    def execute(self, context):
-        Select_by_direction(context, self.direction, self.divergence, self.extend, self.space)
-
-        return {'FINISHED'}
diff --git a/mesh_extra_tools/mesh_select_tools/mesh_select_by_edge_length.py b/mesh_extra_tools/mesh_select_tools/mesh_select_by_edge_length.py
deleted file mode 100644
index cea9976f2..000000000
--- a/mesh_extra_tools/mesh_select_tools/mesh_select_by_edge_length.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# mesh_select_by_edge_length.py Copyright (C) 2011, Dolf Veenvliet
-# Extrude a selection from a mesh multiple times
-
-# ##### 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 #####
-
-"""
-Usage:
-    Launch from from "Select -> By edge length"
-    Select all items whose scale/length/surface matches a certain edge length
-
-Additional links:
-    Author Site: http://www.macouno.com
-    e-mail: dolf {at} macouno {dot} com
-"""
-
-import bpy
-from bpy.props import (
-        FloatProperty,
-        BoolProperty,
-        EnumProperty,
-        )
-
-
-class Select_by_edge_length():
-
-    # Initialize the class
-    def __init__(self, context, edgeLength, edgeSize, extend, space, start_new):
-
-        if start_new:
-            bpy.ops.mesh.select_all(action='DESELECT')
-
-        self.ob = context.active_object
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-        self.space = space
-        self.obMat = self.ob.matrix_world
-
-        bigger = (True if edgeSize == 'BIG' else False)
-        smaller = (True if edgeSize == 'SMALL' else False)
-
-        # We ignore vert selections completely
-        edgeSelect = bpy.context.tool_settings.mesh_select_mode[1]
-        faceSelect = bpy.context.tool_settings.mesh_select_mode[2]
-
-        # Edge select
-        if edgeSelect:
-            hasSelected = self.hasSelected(self.ob.data.edges)
-
-            for e in self.ob.data.edges:
-
-                if self.selectCheck(e.select, hasSelected, extend):
-
-                    lene = self.getEdgeLength(e.vertices)
-
-                    if (lene == edgeLength or (bigger and lene >= edgeLength) or
-                      (smaller and lene <= edgeLength)):
-                        e.select = True
-
-                if self.deselectCheck(e.select, hasSelected, extend):
-                    lene = self.getEdgeLength(e.vertices)
-
-                    if (lene != edgeLength and not (bigger and lene >= edgeLength) and
-                       not (smaller and lene <= edgeLength)):
-                        e.select = False
-
-        # Face select
-        if faceSelect:
-            hasSelected = self.hasSelected(self.ob.data.polygons)
-
-            # Loop through all the given faces
-            for f in self.ob.data.polygons:
-
-                # Check if the faces match any of the directions
-                if self.selectCheck(f.select, hasSelected, extend):
-
-                    mine, maxe = 0.0, 0.0
-
-                    for i, e in enumerate(f.edge_keys):
-                        lene = self.getEdgeLength(e)
-                        if not i:
-                            mine = lene
-                            maxe = lene
-                        elif lene < mine:
-                            mine = lene
-                        elif lene > maxe:
-                            maxe = lene
-
-                    if ((mine == edgeLength and maxe == edgeLength) or
-                       (bigger and mine >= edgeLength) or
-                       (smaller and maxe <= edgeLength)):
-
-                        f.select = True
-
-                if self.deselectCheck(f.select, hasSelected, extend):
-
-                    mine, maxe = 0.0, 0.0
-
-                    for i, e in enumerate(f.edge_keys):
-                        lene = self.getEdgeLength(e)
-                        if not i:
-                            mine = lene
-                            maxe = lene
-                        elif lene < mine:
-                            mine = lene
-                        elif lene > maxe:
-                            maxe = lene
-
-                    if ((mine != edgeLength and maxe != edgeLength) and
-                       not (bigger and mine >= edgeLength) and
-                       not (smaller and maxe <= edgeLength)):
-
-                        f.select = False
-
-        bpy.ops.object.mode_set(mode='EDIT')
-
-    # Get the length of an edge, by giving this function all verts (2) in the edge
-    def getEdgeLength(self, verts):
-
-        vec1 = self.ob.data.vertices[verts[0]].co
-        vec2 = self.ob.data.vertices[verts[1]].co
-
-        vec = vec1 - vec2
-
-        if self.space == 'GLO':
-            vec = self.obMat * vec
-
-        return round(vec.length, 5)
-
-    # See if the current item should be selected or not
-    def selectCheck(self, isSelected, hasSelected, extend):
-
-        # If the current item is not selected we may want to select
-        if not isSelected:
-
-            # If we are extending or nothing is selected we want to select
-            if extend or not hasSelected:
-                return True
-
-        return False
-
-    # See if the current item should be deselected or not
-    def deselectCheck(self, isSelected, hasSelected, extend):
-
-        # If the current item is selected we may want to deselect
-        if isSelected:
-
-            # If something is selected and we're not extending we want to deselect
-            if hasSelected and not extend:
-                return True
-
-        return False
-
-    # See if there is at least one selected item
-    def hasSelected(self, items):
-
-        for item in items:
-            if item.select:
-                return True
-
-        return False
-
-
-class Select_init(bpy.types.Operator):
-    bl_idname = "mesh.select_by_edge_length"
-    bl_label = "Select by edge length"
-    bl_description = ("Select all items whose scale/length/surface matches a certain edge length \n"
-                      "Does not work in Vertex Select mode")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    edgeLength: FloatProperty(
-            name="Edge length",
-            description="The comparison scale in Blender units",
-            default=1.0,
-            min=0.0, max=1000.0,
-            soft_min=0.0, soft_max=100.0,
-            step=100,
-            precision=2
-            )
-    # Changed to Enum as two separate Booleans didn't make much sense
-    sizes = (('SMALL', 'Smaller', "Select items smaller or equal the size setting"),
-             ('BIG', 'Bigger', "Select items bigger or equal to the size setting"),
-             ('EQUAL', 'Equal', "Select edges equal to the size setting"))
-    edgeSize: EnumProperty(
-            items=sizes,
-            name="Edge comparison",
-            description="Choose the relation to set edge length",
-            default='EQUAL'
-            )
-    extend: BoolProperty(
-            name="Extend",
-            description="Extend the current selection",
-            default=False
-            )
-    start_new: BoolProperty(
-            name="Fresh Start",
-            default=False,
-            description="Start from no previous selection"
-            )
-    # The spaces we use
-    spaces = (('LOC', 'Local', "Use Local space"),
-              ('GLO', 'Global', "Use Global Space"))
-    space: EnumProperty(
-            items=spaces,
-            name="Space",
-            description="The space to interpret the directions in",
-            default='LOC'
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH' and not bpy.context.tool_settings.mesh_select_mode[0])
-
-    def execute(self, context):
-        Select_by_edge_length(context, self.edgeLength, self.edgeSize,
-                              self.extend, self.space, self.start_new)
-
-        return {'FINISHED'}
diff --git a/mesh_extra_tools/mesh_select_tools/mesh_select_by_pi.py b/mesh_extra_tools/mesh_select_tools/mesh_select_by_pi.py
deleted file mode 100644
index cecf564c8..000000000
--- a/mesh_extra_tools/mesh_select_tools/mesh_select_by_pi.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# mesh_select_by_pi.py Copyright (C) 2011, Dolf Veenvliet
-# Extrude a selection from a mesh multiple times
-
-# ##### 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 #####
-
-"""
-Usage:
-    Select fake random based on pi
-Additional links:
-    Author Site: http://www.macouno.com
-    e-mail: dolf {at} macouno {dot} com
-"""
-
-import bpy
-from bpy.types import Operator
-from bpy.props import BoolProperty
-
-
-class Select_by_pi():
-
-    # Initialise the class
-    def __init__(self, context, e, invert, extend, start_new):
-
-        self.ob = context.active_object
-        # keep or not the original selection (helps with selected all)
-        if start_new:
-            bpy.ops.mesh.select_all(action='DESELECT')
-
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-        self.invert = invert
-
-        # Make pi as a list of integers
-        if e:
-            self.pi = list('27182818284590452353602874713526624977572470936999')
-        else:
-            self.pi = list('31415926535897932384626433832795028841971693993751')
-
-        self.piLen = len(self.pi)
-        self.piPos = 0
-
-        vertSelect = bpy.context.tool_settings.mesh_select_mode[0]
-        edgeSelect = bpy.context.tool_settings.mesh_select_mode[1]
-        faceSelect = bpy.context.tool_settings.mesh_select_mode[2]
-
-        # Vert select
-        if vertSelect:
-            hasSelected = self.hasSelected(self.ob.data.vertices)
-
-            for v in self.ob.data.vertices:
-                s = self.selectCheck(v.select, hasSelected, extend)
-                d = self.deselectCheck(v.select, hasSelected, extend)
-
-                # Check if the verts match any of the directions
-                if s and self.choose():
-                    v.select = True
-
-                if d and not self.choose():
-                    v.select = False
-
-        # Edge select
-        if edgeSelect:
-            hasSelected = self.hasSelected(self.ob.data.edges)
-
-            for e in self.ob.data.edges:
-                s = self.selectCheck(e.select, hasSelected, extend)
-                d = self.deselectCheck(e.select, hasSelected, extend)
-
-                if s and self.choose():
-                    e.select = True
-
-                if d and not self.choose():
-                    e.select = False
-
-        # Face select
-        if faceSelect:
-            hasSelected = self.hasSelected(self.ob.data.polygons)
-
-            # Loop through all the given faces
-            for f in self.ob.data.polygons:
-                s = self.selectCheck(f.select, hasSelected, extend)
-                d = self.deselectCheck(f.select, hasSelected, extend)
-
-                # Check if the faces match any of the directions
-                if s and self.choose():
-                    f.select = True
-
-                if d and not self.choose():
-                    f.select = False
-
-        bpy.ops.object.mode_set(mode='EDIT')
-
-    # Choose by pi
-    def choose(self):
-        choice = True
-
-        # We just choose the odd numbers
-        if int(self.pi[self.piPos]) % 2:
-            choice = False
-
-        if self.invert:
-            choice = not choice
-
-        self.incrementPiPos()
-        return choice
-
-    # Increment the pi position
-    def incrementPiPos(self):
-        self.piPos += 1
-        if self.piPos == self.piLen:
-            self.piPos = 0
-
-    # See if the current item should be selected or not
-    def selectCheck(self, isSelected, hasSelected, extend):
-
-        # If the current item is not selected we may want to select
-        if not isSelected:
-
-            # If we are extending or nothing is selected we want to select
-            if extend or not hasSelected:
-                return True
-
-        return False
-
-    # See if the current item should be deselected or not
-    def deselectCheck(self, isSelected, hasSelected, extend):
-        # If the current item is selected we may want to deselect
-        if isSelected:
-            # If something is selected and we're not extending we want to deselect
-            if hasSelected and not extend:
-                return True
-
-        return False
-
-    # See if there is at least one selected item
-    def hasSelected(self, items):
-        for item in items:
-            if item.select:
-                return True
-
-        return False
-
-
-class Select_init(Operator):
-    bl_idname = "mesh.select_by_pi"
-    bl_label = "Select by Pi or e"
-    bl_description = ("Select Vertices/Edges/Faces based on pi or e for a random-like selection\n"
-                      "Number Pi (3.14 etc.) or e (2.71828 - Euler's number)")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    e: BoolProperty(
-            name="Use e",
-            description="Use e as the base of selection instead of pi",
-            default=False
-            )
-    invert: BoolProperty(
-            name="Invert",
-            description="Invert the selection result",
-            default=False
-            )
-    extend: BoolProperty(
-            name="Extend",
-            description="Extend the current selection",
-            default=False
-            )
-    start_new: BoolProperty(
-            name="Fresh Start",
-            default=False,
-            description="Start from no previous selection"
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH')
-
-    def execute(self, context):
-        Select_by_pi(context, self.e, self.invert, self.extend, self.start_new)
-
-        return {'FINISHED'}
diff --git a/mesh_extra_tools/mesh_select_tools/mesh_select_by_type.py b/mesh_extra_tools/mesh_select_tools/mesh_select_by_type.py
deleted file mode 100644
index 7afe80fe2..000000000
--- a/mesh_extra_tools/mesh_select_tools/mesh_select_by_type.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# ##### 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 #####
-
-# By CoDEmanX
-
-import bpy
-from bpy.types import Operator
-from bpy.props import (
-        EnumProperty,
-        BoolProperty,
-        )
-
-
-class DATA_OP_facetype_select(Operator):
-    bl_idname = "data.facetype_select"
-    bl_label = "Select by face type"
-    bl_description = "Select all faces of a certain type"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    face_type: EnumProperty(
-            name="Select faces:",
-            items=(("3", "Triangles", "Faces made up of 3 vertices"),
-                   ("4", "Quads", "Faces made up of 4 vertices"),
-                   ("5", "Ngons", "Faces made up of 5 and more vertices")),
-            default="5"
-            )
-    extend: BoolProperty(
-            name="Extend",
-            description="Extend Selection",
-            default=False
-            )
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None and context.active_object.type == 'MESH'
-
-    def execute(self, context):
-        try:
-            bpy.ops.object.mode_set(mode='EDIT')
-
-            if not self.extend:
-                bpy.ops.mesh.select_all(action='DESELECT')
-
-            context.tool_settings.mesh_select_mode = (False, False, True)
-
-            if self.face_type == "3":
-                bpy.ops.mesh.select_face_by_sides(number=3, type='EQUAL')
-            elif self.face_type == "4":
-                bpy.ops.mesh.select_face_by_sides(number=4, type='EQUAL')
-            else:
-                bpy.ops.mesh.select_face_by_sides(number=4, type='GREATER')
-
-            return {'FINISHED'}
-
-        except Exception as e:
-            print("\n[Select by face type]\nOperator: data.facetype_select\nERROR: %s\n" % e)
-            self.report({'WARNING'},
-                        "Face selection could not be performed (Check the console for more info)")
-
-            return {'CANCELLED'}
diff --git a/mesh_extra_tools/mesh_select_tools/mesh_select_connected_faces.py b/mesh_extra_tools/mesh_select_tools/mesh_select_connected_faces.py
deleted file mode 100644
index 2c574f2df..000000000
--- a/mesh_extra_tools/mesh_select_tools/mesh_select_connected_faces.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright (C) 2011, Dolf Veenvliet
-# Extrude a selection from a mesh multiple times
-
-# ##### 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 #####
-
-"""
-Usage:
-Launch from from "Select -> Connected faces"
-
-Additional links:
-    Author Site: http://www.macouno.com
-    e-mail: dolf {at} macouno {dot} com
-"""
-
-
-import bpy
-from bpy.types import Operator
-from bpy.props import (
-        IntProperty,
-        BoolProperty,
-        )
-
-
-class Select_connected_faces():
-    # Initialize the class
-    def __init__(self, context, iterations, extend):
-
-        self.ob = context.active_object
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-        # Make a list of all selected vertices
-        selVerts = [v.index for v in self.ob.data.vertices if v.select]
-        hasSelected = self.hasSelected(self.ob.data.polygons)
-
-        for i in range(iterations):
-            nextVerts = []
-
-            for f in self.ob.data.polygons:
-                if self.selectCheck(f.select, hasSelected, extend):
-
-                    for v in f.vertices:
-                        if v in selVerts:
-                            f.select = True
-
-                    if f.select:
-                        for v in f.vertices:
-                            if v not in selVerts:
-                                nextVerts.append(v)
-
-                elif self.deselectCheck(f.select, hasSelected, extend):
-                    for v in f.vertices:
-                        if v in selVerts:
-                            f.select = False
-
-            selVerts = nextVerts
-
-        bpy.ops.object.mode_set(mode='EDIT')
-
-    # See if the current item should be selected or not
-    def selectCheck(self, isSelected, hasSelected, extend):
-        # If the current item is not selected we may want to select
-        if not isSelected:
-            return True
-
-        return False
-
-    # See if the current item should be deselected or not
-    def deselectCheck(self, isSelected, hasSelected, extend):
-        # If the current item is selected we may want to deselect
-        if isSelected:
-            # If something is selected and we're not extending we want to deselect
-            if hasSelected and not extend:
-                return True
-
-        return False
-
-    # See if there is at least one selected item
-    def hasSelected(self, items):
-        for item in items:
-            if item.select:
-                return True
-
-        return False
-
-
-class Select_init(Operator):
-    bl_idname = "mesh.select_connected_faces"
-    bl_label = "Select connected faces"
-    bl_description = ("Select all faces connected to the current selection \n"
-                      "Works only in Face Selection mode")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    # Iterations
-    iterations: IntProperty(
-            name="Iterations",
-            description="Run the selection the given number of times",
-            default=1,
-            min=0, max=300,
-            soft_min=0, soft_max=100
-            )
-    extend: BoolProperty(
-            name="Extend",
-            description="Extend the current selection",
-            default=False
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH' and
-                bpy.context.tool_settings.mesh_select_mode[0] is False and
-                bpy.context.tool_settings.mesh_select_mode[1] is False and
-                bpy.context.tool_settings.mesh_select_mode[2] is True)
-
-    def execute(self, context):
-        Select_connected_faces(context, self.iterations, self.extend)
-
-        return {'FINISHED'}
diff --git a/mesh_extra_tools/mesh_select_tools/mesh_selection_topokit.py b/mesh_extra_tools/mesh_select_tools/mesh_selection_topokit.py
deleted file mode 100644
index c787b3058..000000000
--- a/mesh_extra_tools/mesh_select_tools/mesh_selection_topokit.py
+++ /dev/null
@@ -1,632 +0,0 @@
-# ##### 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 #####
-
-bl_info = {
-    "name": "Topokit 2",
-    "author": "dustractor",
-    "version": (2, 0),
-    "blender": (2, 60, 0),
-    "location": "Edit mesh > Vertices/ Edges/ Faces menus",
-    "description": "",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"}
-
-
-import bpy
-from bpy.types import Operator
-# In between calls, this stores any data that is expensive or static,
-# matched to the size of the mesh and the id of the operator that created it
-cachedata = dict()
-# tkey is moved to mesh_extra_tools\__init__.py register function
-
-
-# just a mix-in for the operators...
-class meshpoller:
-    @classmethod
-    def poll(self, context):
-        try:
-            assert context.active_object.type == "MESH"
-        except:
-            return False
-        finally:
-            return True
-
-
-# BEGIN VERTICES SECTION
-
-# This one works similarly to normal 'grow' (ctrl + NUMPAD_PLUS),
-# except the original selection is not part of the result,
-#
-#   0--0--0         0--1--0
-#   |  |  |         |  |  |
-#   0--1--0  -->    1--0--1
-#   |  |  |         |  |  |
-#   0--0--0         0--1--0
-
-class MESH_OT_vneighbors_edgewise(meshpoller, Operator):
-    bl_idname = "mesh.v2v_by_edge"
-    bl_label = "Neighbors by Edge"
-    bl_description = ("Select neighbour vertices of a starting selected vertex\n"
-                      "Similar to Grow Selection - apart from the\n"
-                      "original selection is not part of the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-        next_state = bytearray(meshkey[0])
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            vert_to_vert_map, prev_state = cachedata[meshkey]
-        else:
-            vert_to_vert_map = {i: {} for i in range(meshkey[0])}
-            for a, b in mesh.edge_keys:
-                vert_to_vert_map[a][b] = 1
-                vert_to_vert_map[b][a] = 1
-            obj.tkkey = meshkey
-            prev_state = None
-
-        if not prev_state:
-            selected_vert_indices = filter(
-                    lambda _: mesh.vertices[_].select,
-                    range(len(mesh.vertices))
-                    )
-        else:
-            selected_vert_indices = filter(
-                    lambda _: mesh.vertices[_].select and not prev_state[_],
-                    range(len(mesh.vertices))
-                    )
-
-        for v in selected_vert_indices:
-            for neighbor_index in vert_to_vert_map[v]:
-                next_state[neighbor_index] = True
-        mesh.vertices.foreach_set("select", next_state)
-        cachedata[meshkey] = (vert_to_vert_map, next_state)
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-# This one is an alternate / counterpart to the previous.
-# Think: diagonal opposite corners of a quad
-# NOTE: does not apply to a triangle, since verts have no "opposite"
-#
-#   0--0--0     1--0--1
-#   |  |  |     |  |  |
-#   0--1--0 --> 0--0--0
-#   |  |  |     |  |  |
-#   0--0--0     1--0--1
-
-class MESH_OT_vneighbors_facewise(meshpoller, Operator):
-    bl_idname = "mesh.v2v_facewise"
-    bl_label = "Neighbors by Face - Edge"
-    bl_description = ("Select diagonal opposite vertices of neighbour quads\n"
-                      "Does not work with triangles\n"
-                      "The original selection is not part of the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-        next_state = bytearray(meshkey[0])
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            vert_to_vert_map = cachedata[meshkey]
-        else:
-            vert_to_vert_map = {i: {} for i in range(meshkey[0])}
-            for a, b in mesh.edge_keys:
-                vert_to_vert_map[a][b] = 1
-                vert_to_vert_map[b][a] = 1
-            obj.tkkey = meshkey
-        faces = filter(lambda face: (len(face.vertices) == 4) and
-                       (face.select is False), mesh.polygons)
-        for f in faces:
-            has = False
-            t = set()
-            for v in f.vertices:
-                if mesh.vertices[v].select:
-                    has = True
-                    t.update(vert_to_vert_map[v])
-            if has:
-                for v in f.vertices:
-                    if not mesh.vertices[v].select:
-                        if v not in t:
-                            next_state[v] = 1
-        mesh.vertices.foreach_set("select", next_state)
-        cachedata[meshkey] = vert_to_vert_map
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-# END VERTICES SECTION
-
-
-# BEGIN EDGES SECTION
-#   +--0--+--0--+--0--+          +--0--+--0--+--0--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     1     1     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--1--+--0--+   --->   +--0--+--0--+--0--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     1     1     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--0--+--0--+          +--0--+--0--+--0--+
-
-class MESH_OT_eneighbors_shared_v_f(meshpoller, Operator):
-    bl_idname = "mesh.e2e_evfe"
-    bl_label = "Neighbors by Vert and Face"
-    bl_description = ("Select edges that share the neighbour vertices and faces\n"
-                      "of the starting selected edge\n"
-                      "The original selection is not part of the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-        state_mask = bytearray(meshkey[1])
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            edge_to_edges_dict = cachedata
-        else:
-            edge_key_to_index = {k: i for i, k in enumerate(mesh.edge_keys)}
-            edge_to_edges_dict = {i: set() for i in range(len(mesh.edges))}
-            for f in mesh.polygons:
-                fed = [edge_key_to_index[k] for k in f.edge_keys]
-                for k in f.edge_keys:
-                    edge_to_edges_dict[edge_key_to_index[k]].update(fed)
-            obj.tkkey = meshkey
-
-        for e in filter(lambda _: mesh.edges[_].select, edge_to_edges_dict):
-            k1 = set(mesh.edges[e].key)
-            for n in edge_to_edges_dict[e]:
-                k2 = set(mesh.edges[n].key)
-                if not k1.isdisjoint(k2):
-                    state_mask[n] = True
-
-        for e in mesh.edges:
-            e.select ^= state_mask[e.index]
-        cachedata[meshkey] = edge_key_to_index
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-#   +--0--+--0--+--0--+          +--0--+--0--+--0--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     1     1     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--1--+--0--+   --->   +--1--+--0--+--1--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     1     1     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--0--+--0--+          +--0--+--0--+--0--+
-
-class MESH_OT_eneighbors_shared_v(meshpoller, Operator):
-    bl_idname = "mesh.e2e_eve"
-    bl_label = "Neighbors by Vert"
-    bl_description = ("Select edges that share the neighbour vertices\n"
-                     "of the starting selected edge\n"
-                     "The original selection is not part of the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        bpy.ops.object.mode_set(mode="OBJECT")
-        mesh = context.active_object.data
-        state_mask = bytearray(len(mesh.edges))
-
-        for e in mesh.edges:
-            state_mask[e.index] = \
-                    mesh.vertices[e.vertices[0]].select ^ mesh.vertices[e.vertices[1]].select
-        mesh.edges.foreach_set('select', state_mask)
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-#   +--0--+--0--+--0--+          +--0--+--1--+--0--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     1     1     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--1--+--0--+   --->   +--0--+--0--+--0--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     1     1     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--0--+--0--+          +--0--+--1--+--0--+
-
-class MESH_OT_eneighbors_shared_f(meshpoller, Operator):
-    bl_idname = "mesh.e2e_efe"
-    bl_label = "Neighbors by Face"
-    bl_description = ("Select edges of neighbour faces to the starting selected edge\n"
-                     "The original selection is not part of the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            edge_to_edges_dict = cachedata
-        else:
-            edge_key_to_index = {k: i for i, k in enumerate(mesh.edge_keys)}
-            edge_to_edges_dict = {i: set() for i in range(len(mesh.edges))}
-
-            for f in mesh.polygons:
-                fed = [edge_key_to_index[k] for k in f.edge_keys]
-                for k in f.edge_keys:
-                    edge_to_edges_dict[edge_key_to_index[k]].update(fed)
-
-            obj.tkkey = meshkey
-        state_mask, esel = (bytearray(meshkey[1]), bytearray(meshkey[1]))
-        mesh.edges.foreach_get('select', esel)
-
-        for e in filter(lambda _: mesh.edges[_].select, range(meshkey[1])):
-            for n in edge_to_edges_dict[e]:
-                state_mask[n] = 1
-
-        for e in range(meshkey[1]):
-            esel[e] ^= state_mask[e]
-        mesh.edges.foreach_set('select', esel)
-        cachedata[meshkey] = edge_to_edges_dict
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-# Notice that on these next two, the original selection stays
-#   +--0--+--0--+--0--+          +--0--+--1--+--0--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     0     0     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--1--+--0--+   --->   +--0--+--1--+--0--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     0     0     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--0--+--0--+          +--0--+--1--+--0--+
-
-class MESH_OT_eneighbors_shared_f_notv(meshpoller, Operator):
-    bl_idname = "mesh.e2e_efnve"
-    bl_label = "Lateral Neighbors"
-    bl_description = ("Select edges that are lateral neighbours\n"
-                      "The original selection is included in the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-        state_mask = bytearray(meshkey[1])
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            edge_to_face_map, edge_key_to_index = cachedata[meshkey]
-        else:
-            edge_key_to_index = {}
-            edge_to_face_map = {i: set() for i in range(meshkey[1])}
-            for i, k in enumerate(mesh. edge_keys):
-                edge_key_to_index[k] = i
-
-            for f in mesh.polygons:
-                for k in f.edge_keys:
-                    edge_to_face_map[edge_key_to_index[k]].add(f.index)
-            obj.tkkey = meshkey
-        selected_edge_indices = filter(lambda _: mesh.edges[_].select, range(meshkey[1]))
-
-        for e in selected_edge_indices:
-            for f in edge_to_face_map[e]:
-                for k in mesh.polygons[f].edge_keys:
-                    hasv_in = False
-                    for v in mesh.edges[e].key:
-                        if v in k:
-                            hasv_in = True
-                    if hasv_in:
-                        continue
-                    else:
-                        state_mask[edge_key_to_index[k]] = True
-
-        for e in filter(lambda _: state_mask[_], range(meshkey[1])):
-            mesh.edges[e].select |= state_mask[e]
-        cachedata[meshkey] = (edge_to_face_map, edge_key_to_index)
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-#   +--0--+--0--+--0--+          +--0--+--0--+--0--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     0     0     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--1--+--0--+   --->   +--1--+--1--+--1--+
-#   |     |     |     |          |     |     |     |
-#   0     0     0     0          0     0     0     0
-#   |     |     |     |          |     |     |     |
-#   +--0--+--0--+--0--+          +--0--+--0--+--0--+
-
-class MESH_OT_eneighbors_shared_v_notf(meshpoller, Operator):
-    bl_idname = "mesh.e2e_evnfe"
-    bl_label = "Longitudinal Edges"
-    bl_description = ("Select Edges along the same longitude of the starting edge\n"
-                      "The original selection is included in the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-        state_mask = bytearray(meshkey[1])
-        vstate = bytearray(meshkey[0])
-        mesh.vertices.foreach_get('select', vstate)
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            edge_to_face_map, vert_to_vert_map, edge_key_to_index = cachedata[meshkey]
-        else:
-            edge_key_to_index = {}
-            vert_to_vert_map = {i: set() for i in range(meshkey[0])}
-            edge_to_face_map = {i: set() for i in range(meshkey[1])}
-
-            for i, k in enumerate(mesh.edge_keys):
-                edge_key_to_index[k] = i
-                vert_to_vert_map[k[0]].add(k[1])
-                vert_to_vert_map[k[1]].add(k[0])
-
-            for f in mesh.polygons:
-                for k in f.edge_keys:
-                    edge_to_face_map[edge_key_to_index[k]].add(f.index)
-            obj.tkkey = meshkey
-        selected_edge_indices = filter(lambda _: mesh.edges[_].select, range(meshkey[1]))
-
-        for e in selected_edge_indices:
-            for v in mesh.edges[e].key:
-                state_mask[v] ^= 1
-
-            for f in edge_to_face_map[e]:
-                for v in mesh.polygons[f].vertices:
-                    vstate[v] = 1
-
-        for v in filter(lambda _: state_mask[_], range(meshkey[1])):
-            for n in vert_to_vert_map[v]:
-                if not vstate[n] and (n != v):
-                    mesh.edges[edge_key_to_index[(min(v, n), max(v, n))]].select = True
-        cachedata[meshkey] = (edge_to_face_map, vert_to_vert_map, edge_key_to_index)
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-# Deselects edges which are at the edge of a face-selection,
-# causing selection to 'shrink in'
-class MESH_OT_inner_edges(meshpoller, Operator):
-    bl_idname = "mesh.ie"
-    bl_label = "Inner Edge Selection"
-    bl_description = ("Deselects edges which are at the border\n"
-                      "of a starting face selection\n"
-                      "causing the selection to shrink inwards")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-        state_mask = bytearray(meshkey[1])
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            edge_to_face_map = cachedata[meshkey]
-        else:
-            edge_key_to_index = {k: i for i, k in enumerate(mesh.edge_keys)}
-            edge_to_face_map = {i: set() for i in range(meshkey[1])}
-            for f in mesh.polygons:
-                for k in f.edge_keys:
-                    edge_to_face_map[edge_key_to_index[k]].add(f.index)
-            obj.tkkey = meshkey
-
-        for e in filter(lambda _: mesh.edges[_].select, range(meshkey[1])):
-            for f in edge_to_face_map[e]:
-                if mesh.polygons[f].select:
-                    state_mask[e] ^= 1
-
-        for e in range(meshkey[1]):
-            mesh.edges[e].select ^= state_mask[e]
-        cachedata[meshkey] = edge_to_face_map
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-# END EDGES SECTION
-
-
-# BEGIN FACES SECTION
-
-# here is another one which functions very similarly to the ctrl+NUMPAD_PLUS 'growth'
-# but it deselects the original selection, of course.
-# This would be your checkerboard-type growth.
-#   [0][0][0]          [0][1][0]
-#   [0][1][0]   --->   [1][0][1]
-#   [0][0][0]          [0][1][0]
-
-class MESH_OT_fneighbors_shared_e(meshpoller, Operator):
-    bl_idname = "mesh.f2f_fef"
-    bl_label = "Neighbor Faces sharing an Edge"
-    bl_description = ("Selects faces that share an edge with the starting face selection\n"
-                      "Similar to the Grow selection \n"
-                      "The original selection is not part of the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            face_to_face_map = cachedata[meshkey]
-        else:
-            edge_key_to_index = {k: i for i, k in enumerate(mesh.edge_keys)}
-            edge_to_face_map = {i: set() for i in range(meshkey[1])}
-            for f in mesh.polygons:
-                for k in f.edge_keys:
-                    edge_to_face_map[edge_key_to_index[k]].add(f.index)
-            face_to_face_map = {i: set() for i in range(meshkey[2])}
-            for f in mesh.polygons:
-                for k in f.edge_keys:
-                    face_to_face_map[f.index].update(edge_to_face_map[edge_key_to_index[k]])
-            obj.tkkey = meshkey
-        mask_state = bytearray(meshkey[2])
-
-        for f in filter(lambda _: mesh.polygons[_].select, range(meshkey[2])):
-            for n in face_to_face_map[f]:
-                mask_state[n] = True
-
-        for f in range(meshkey[2]):
-            mesh.polygons[f].select ^= mask_state[f]
-        cachedata[meshkey] = face_to_face_map
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-#   [0][0][0]          [1][0][1]
-#   [0][1][0]   --->   [0][0][0]
-#   [0][0][0]          [1][0][1]
-
-class MESH_OT_fneighbors_shared_v_note(meshpoller, Operator):
-    bl_idname = "mesh.f2f_fvnef"
-    bl_label = "Neighbors by Vertex not Edge"
-    bl_description = ("Select neighbour faces that share a vertex\n"
-                      "with the starting selection\n"
-                      "The original selection is not part of the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            edge_key_to_index = cachedata[meshkey]
-        else:
-            edge_key_to_index = {k: i for i, k in enumerate(mesh.edge_keys)}
-            obj.tkkey = meshkey
-        state_mask = bytearray(meshkey[2])
-        face_verts = set()
-
-        for f in filter(lambda _: mesh.polygons[_].select, range(meshkey[2])):
-            face_verts.update(mesh.polygons[f].vertices)
-
-        for f in filter(lambda _: not mesh.polygons[_].select, range(meshkey[2])):
-            ct = 0
-            for v in mesh.polygons[f].vertices:
-                ct += (v in face_verts)
-            if ct == 1:
-                state_mask[f] = 1
-        mesh.polygons.foreach_set('select', state_mask)
-        cachedata[meshkey] = edge_key_to_index
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-# https://en.wikipedia.org/wiki/Conway's_Game_of_Life
-class MESH_OT_conway(meshpoller, Operator):
-    bl_idname = "mesh.conway"
-    bl_label = "Conway's Selection"
-    bl_description = ("Select Faces with the Conway's game of life algorithm\n"
-                      "Requires an initial Face selection\n"
-                      "The edges of the original selection are included in the result")
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-        global cachedata
-
-        bpy.ops.object.mode_set(mode="OBJECT")
-        obj = context.active_object
-        mesh = obj.data
-        meshkey = (len(mesh.vertices), len(mesh.edges), len(mesh.polygons), id(self))
-
-        if (meshkey == obj.tkkey) and (meshkey in cachedata):
-            vert_to_face_map = cachedata[meshkey]
-        else:
-            vert_to_face_map = {i: set() for i in range(meshkey[0])}
-            for f in mesh.polygons:
-                for v in f.vertices:
-                    vert_to_face_map[v].add(f.index)
-            obj.tkkey = meshkey
-        sel = set()
-        uns = set()
-        F = {i: set() for i in range(meshkey[2])}
-
-        for f in range(meshkey[2]):
-            for v in mesh.polygons[f].vertices:
-                for n in filter(lambda _: mesh.polygons[_].select and (_ != f), vert_to_face_map[v]):
-                    F[f].add(n)
-
-        for f in F:
-            if len(F[f]) == 3:
-                sel.add(f)
-            elif len(F[f]) != 2:
-                uns.add(f)
-
-        for f in range(meshkey[2]):
-            if f in sel:
-                mesh.polygons[f].select = True
-            if f in uns:
-                mesh.polygons[f].select = False
-        cachedata[meshkey] = vert_to_face_map
-        bpy.ops.object.mode_set(mode="EDIT")
-
-        return {"FINISHED"}
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/mesh_vertex_chamfer.py b/mesh_extra_tools/mesh_vertex_chamfer.py
deleted file mode 100644
index d3a4bc7b0..000000000
--- a/mesh_extra_tools/mesh_vertex_chamfer.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# ##### 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 compliant>
-
-bl_info = {
-    "name": "Vertex Chamfer",
-    "author": "Andrew Hale (TrumanBlending)",
-    "version": (0, 1),
-    "blender": (2, 63, 0),
-    "location": "Spacebar Menu",
-    "description": "Chamfer vertex",
-    "wiki_url": "",
-    "category": "Mesh"}
-
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        )
-
-
-class VertexChamfer(Operator):
-    bl_idname = "mesh.vertex_chamfer"
-    bl_label = "Chamfer Vertex"
-    bl_description = "Tri chamfer selected vertices"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    factor: FloatProperty(
-            name="Factor",
-            description="Size of the Champfer",
-            default=0.1,
-            min=0.0,
-            soft_max=1.0
-            )
-    relative: BoolProperty(
-            name="Relative",
-            description="If Relative, Champfer size is relative to the edge length",
-            default=True
-            )
-    dissolve: BoolProperty(
-            name="Remove",
-            description="Remove/keep the original selected vertices\n"
-                        "Remove creates a new triangle face between the Champfer edges,\n"
-                        "similar to the Dissolve Vertices operator",
-            default=True
-            )
-    displace: FloatProperty(
-            name="Displace",
-            description="Active only if Remove option is disabled\n"
-                        "Displaces the original selected vertices along the normals\n"
-                        "defined by the Champfer edges",
-            soft_min=-5.0,
-            soft_max=5.0
-            )
-
-    @classmethod
-    def poll(self, context):
-        return (context.active_object.type == 'MESH' and
-                context.mode == 'EDIT_MESH')
-
-    def draw(self, context):
-        layout = self.layout
-        layout.prop(self, "factor", text="Distance" if self.relative else "Factor")
-        sub = layout.row()
-        sub.prop(self, "relative")
-        sub.prop(self, "dissolve")
-        if not self.dissolve:
-            layout.prop(self, "displace")
-
-    def execute(self, context):
-        ob = context.active_object
-        me = ob.data
-        bm = bmesh.from_edit_mesh(me)
-
-        bm.select_flush(True)
-
-        fac = self.factor
-        rel = self.relative
-        dissolve = self.dissolve
-        displace = self.displace
-
-        for v in bm.verts:
-            v.tag = False
-
-        # Loop over edges to find those with both verts selected
-        for e in bm.edges[:]:
-            e.tag = e.select
-            if not e.select:
-                continue
-            elen = e.calc_length()
-            val = fac if rel else fac / elen
-            val = min(val, 0.5)
-            # Loop over the verts of the edge to split
-            for v in e.verts:
-                # if val == 0.5 and e.other_vert(v).tag:
-                #    continue
-                en, vn = bmesh.utils.edge_split(e, v, val)
-                en.tag = vn.tag = True
-                val = 1.0 if val == 1.0 else val / (1.0 - val)
-
-        # Get all verts which are selected but not created previously
-        verts = [v for v in bm.verts if v.select and not v.tag]
-
-        # Loop over all verts to split their linked edges
-        for v in verts:
-            for e in v.link_edges[:]:
-                if e.tag:
-                    continue
-                elen = e.calc_length()
-                val = fac if rel else fac / elen
-                bmesh.utils.edge_split(e, v, val)
-
-            # Loop over all the loops of the vert
-            for l in v.link_loops:
-                # Split the face
-                bmesh.utils.face_split(
-                            l.face,
-                            l.link_loop_next.vert,
-                            l.link_loop_prev.vert
-                            )
-
-            # Remove the vert or displace otherwise
-            if dissolve:
-                bmesh.utils.vert_dissolve(v)
-            else:
-                v.co += displace * v.normal
-
-        me.calc_loop_triangles()
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(VertexChamfer)
-
-
-def unregister():
-    bpy.utils.unregister_class(VertexChamfer)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/pkhg_faces.py b/mesh_extra_tools/pkhg_faces.py
deleted file mode 100644
index 31497aa45..000000000
--- a/mesh_extra_tools/pkhg_faces.py
+++ /dev/null
@@ -1,835 +0,0 @@
-# gpl author: PHKG
-
-bl_info = {
-    "name": "PKHG faces",
-    "author": "PKHG",
-    "version": (0, 0, 6),
-    "blender": (2, 71, 0),
-    "location": "View3D > Tools > PKHG (tab)",
-    "description": "Faces selected will become added faces of different style",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh",
-}
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from mathutils import Vector
-from bpy.props import (
-        BoolProperty,
-        StringProperty,
-        IntProperty,
-        FloatProperty,
-        EnumProperty,
-        )
-
-
-class MESH_OT_add_faces_to_object(Operator):
-    bl_idname = "mesh.add_faces_to_object"
-    bl_label = "Face Extrude"
-    bl_description = "Set parameters and build object with added faces"
-    bl_options = {'REGISTER', 'UNDO', 'PRESET'}
-
-    reverse_faces: BoolProperty(
-            name="Reverse Faces",
-            default=False,
-            description="Revert the normals of selected faces"
-            )
-    name_source_object: StringProperty(
-            name="Mesh",
-            description="Choose a Source Mesh",
-            default="Cube"
-            )
-    remove_start_faces: BoolProperty(
-            name="Remove Start Faces",
-            default=True,
-            description="Make a choice about removal of Original Faces"
-            )
-    base_height: FloatProperty(
-            name="Base Height",
-            min=-20,
-            soft_max=10, max=20,
-            default=0.2,
-            description="Set general Base Height"
-            )
-    use_relative_base_height: BoolProperty(
-            name="Relative Base Height",
-            default=False,
-            description="Relative or absolute Base Height"
-            )
-    second_height: FloatProperty(
-            name="2nd height", min=-5,
-            soft_max=5, max=20,
-            default=0.2,
-            description="Second height for various shapes"
-            )
-    width: FloatProperty(
-            name="Width Faces",
-            min=-20, max=20,
-            default=0.5,
-            description="Set general width"
-            )
-    repeat_extrude: IntProperty(
-            name="Repeat",
-            min=1,
-            soft_max=5, max=20,
-            description="For longer base"
-            )
-    move_inside: FloatProperty(
-            name="Move Inside",
-            min=0.0,
-            max=1.0,
-            default=0.5,
-            description="How much move to inside"
-            )
-    thickness: FloatProperty(
-            name="Thickness",
-            soft_min=0.01, min=0,
-            soft_max=5.0, max=20.0,
-            default=0
-            )
-    depth: FloatProperty(
-            name="Depth",
-            min=-5,
-            soft_max=5.0, max=20.0,
-            default=0
-            )
-    collapse_edges: BoolProperty(
-            name="Make Point",
-            default=False,
-            description="Collapse the vertices of edges"
-            )
-    spike_base_width: FloatProperty(
-            name="Spike Base Width",
-            default=0.4,
-            min=-4.0,
-            soft_max=1, max=20,
-            description="Base width of a spike"
-            )
-    base_height_inset: FloatProperty(
-            name="Base Height Inset",
-            default=0.0,
-            min=-5, max=5,
-            description="To elevate or drop the Base height Inset"
-            )
-    top_spike: FloatProperty(
-            name="Top Spike",
-            default=1.0,
-            min=-10.0, max=10.0,
-            description="The Base Height of a spike"
-            )
-    top_extra_height: FloatProperty(
-            name="Top Extra Height",
-            default=0.0,
-            min=-10.0, max=10.0,
-            description="Add extra height"
-            )
-    step_with_real_spike: BoolProperty(
-            name="Step with Real Spike",
-            default=False,
-            description="In stepped, use a real spike"
-            )
-    use_relative: BoolProperty(
-            name="Use Relative",
-            default=False,
-            description="Change size using area, min or max"
-            )
-    face_types: EnumProperty(
-            name="Face Types",
-            description="Different types of Faces",
-            default="no",
-            items=[
-                ('no', "Pick an Option", "Choose one of the available options"),
-                ('open_inset', "Open Inset", "Inset without closing faces (holes)"),
-                ('with_base', "With Base", "Base and ..."),
-                ('clsd_vertical', "Closed Vertical", "Closed Vertical"),
-                ('open_vertical', "Open Vertical", "Open Vertical"),
-                ('spiked', "Spiked", "Spike"),
-                ('stepped', "Stepped", "Stepped"),
-                ('boxed', "Boxed", "Boxed"),
-                ('bar', "Bar", "Bar"),
-                ]
-            )
-    strange_boxed_effect: BoolProperty(
-            name="Strange Effect",
-            default=False,
-            description="Do not show one extrusion"
-            )
-    use_boundary: BoolProperty(
-            name="Use Boundary",
-            default=True
-            )
-    use_even_offset: BoolProperty(
-            name="Even Offset",
-            default=True
-            )
-    use_relative_offset: BoolProperty(
-            name="Relative Offset",
-            default=True
-            )
-    use_edge_rail: BoolProperty(
-            name="Edge Rail",
-            default=False
-            )
-    use_outset: BoolProperty(
-            name="Outset",
-            default=False
-            )
-    use_select_inset: BoolProperty(
-            name="Inset",
-            default=False
-            )
-    use_interpolate: BoolProperty(
-            name="Interpolate",
-            default=True
-            )
-
-    @classmethod
-    def poll(cls, context):
-        result = False
-        active_object = context.active_object
-        if active_object:
-            mesh_objects_name = [el.name for el in bpy.data.objects if el.type == "MESH"]
-            if active_object.name in mesh_objects_name:
-                result = True
-
-        return result
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-
-        col.separator()
-        col.label(text="Using Active Object", icon="INFO")
-        col.separator()
-        col.label(text="Face Types:")
-        col.prop(self, "face_types", text="")
-        col.separator()
-        col.prop(self, "use_relative")
-
-        if self.face_types == "open_inset":
-            col.prop(self, "move_inside")
-            col.prop(self, "base_height")
-
-        elif self.face_types == "with_base":
-            col.prop(self, "move_inside")
-            col.prop(self, "base_height")
-            col.prop(self, "second_height")
-            col.prop(self, "width")
-
-        elif self.face_types == "clsd_vertical":
-            col.prop(self, "base_height")
-
-        elif self.face_types == "open_vertical":
-            col.prop(self, "base_height")
-
-        elif self.face_types == "boxed":
-            col.prop(self, "move_inside")
-            col.prop(self, "base_height")
-            col.prop(self, "top_spike")
-            col.prop(self, "strange_boxed_effect")
-
-        elif self.face_types == "spiked":
-            col.prop(self, "spike_base_width")
-            col.prop(self, "base_height_inset")
-            col.prop(self, "top_spike")
-
-        elif self.face_types == "bar":
-            col.prop(self, "spike_base_width")
-            col.prop(self, "top_spike")
-            col.prop(self, "top_extra_height")
-
-        elif self.face_types == "stepped":
-            col.prop(self, "spike_base_width")
-            col.prop(self, "base_height_inset")
-            col.prop(self, "top_extra_height")
-            col.prop(self, "second_height")
-            col.prop(self, "step_with_real_spike")
-
-    def execute(self, context):
-        obj_name = self.name_source_object
-        face_type = self.face_types
-
-        is_selected = check_is_selected()
-
-        if not is_selected:
-            self.report({'WARNING'},
-                        "Operation Cancelled. No selected Faces found on the Active Object")
-            return {'CANCELLED'}
-
-        if face_type == "spiked":
-            Spiked(spike_base_width=self.spike_base_width,
-                   base_height_inset=self.base_height_inset,
-                   top_spike=self.top_spike, top_relative=self.use_relative)
-
-        elif face_type == "boxed":
-            startinfo = prepare(self, context, self.remove_start_faces)
-            bm = startinfo['bm']
-            top = self.top_spike
-            obj = startinfo['obj']
-            obj_matrix_local = obj.matrix_local
-
-            distance = None
-            base_heights = None
-            t = self.move_inside
-            areas = startinfo['areas']
-            base_height = self.base_height
-
-            if self.use_relative:
-                distance = [min(t * area, 1.0) for i, area in enumerate(areas)]
-                base_heights = [base_height * area for i, area in enumerate(areas)]
-            else:
-                distance = [t] * len(areas)
-                base_heights = [base_height] * len(areas)
-
-            rings = startinfo['rings']
-            centers = startinfo['centers']
-            normals = startinfo['normals']
-            for i in range(len(rings)):
-                make_one_inset(self, context, bm=bm, ringvectors=rings[i],
-                               center=centers[i], normal=normals[i],
-                               t=distance[i], base_height=base_heights[i])
-                bpy.ops.mesh.select_mode(type="EDGE")
-                bpy.ops.mesh.select_more()
-                bpy.ops.mesh.select_more()
-            bpy.ops.object.mode_set(mode='OBJECT')
-            # PKHG>INFO base extrusion done and set to the mesh
-
-            # PKHG>INFO if the extrusion is NOT  done ... it'll look strange soon!
-            if not self.strange_boxed_effect:
-                bpy.ops.object.mode_set(mode='EDIT')
-                obj = context.active_object
-                bm = bmesh.from_edit_mesh(obj.data)
-                bmfaces = [face for face in bm.faces if face.select]
-                res = extrude_faces(self, context, bm=bm, face_l=bmfaces)
-                ring_edges = [face.edges[:] for face in res]
-
-            bpy.ops.object.mode_set(mode='OBJECT')
-
-            # PKHG>INFO now the extruded facec have to move in normal direction
-            bpy.ops.object.mode_set(mode='EDIT')
-            obj = bpy.context.view_layer.objects.active
-            bm = bmesh.from_edit_mesh(obj.data)
-            todo_faces = [face for face in bm.faces if face.select]
-            for face in todo_faces:
-                bmesh.ops.translate(bm, vec=face.normal * top, space=obj_matrix_local,
-                                    verts=face.verts)
-            bpy.ops.object.mode_set(mode='OBJECT')
-
-        elif face_type == "stepped":
-            Stepped(spike_base_width=self.spike_base_width,
-                    base_height_inset=self.base_height_inset,
-                    top_spike=self.second_height,
-                    top_extra_height=self.top_extra_height,
-                    use_relative_offset=self.use_relative, with_spike=self.step_with_real_spike)
-
-        elif face_type == "open_inset":
-            startinfo = prepare(self, context, self.remove_start_faces)
-            bm = startinfo['bm']
-
-            # PKHG>INFO adjust for relative, via areas
-            t = self.move_inside
-            areas = startinfo['areas']
-            base_height = self.base_height
-            base_heights = None
-            distance = None
-            if self.use_relative:
-                distance = [min(t * area, 1.0) for i, area in enumerate(areas)]
-                base_heights = [base_height * area for i, area in enumerate(areas)]
-            else:
-                distance = [t] * len(areas)
-                base_heights = [base_height] * len(areas)
-
-            rings = startinfo['rings']
-            centers = startinfo['centers']
-            normals = startinfo['normals']
-            for i in range(len(rings)):
-                make_one_inset(self, context, bm=bm, ringvectors=rings[i],
-                               center=centers[i], normal=normals[i],
-                               t=distance[i], base_height=base_heights[i])
-            bpy.ops.object.mode_set(mode='OBJECT')
-
-        elif face_type == "with_base":
-            startinfo = prepare(self, context, self.remove_start_faces)
-            bm = startinfo['bm']
-            obj = startinfo['obj']
-            object_matrix = obj.matrix_local
-
-            # PKHG>INFO for relative (using areas)
-            t = self.move_inside
-            areas = startinfo['areas']
-            base_height = self.base_height
-            distance = None
-            base_heights = None
-
-            if self.use_relative:
-                distance = [min(t * area, 1.0) for i, area in enumerate(areas)]
-                base_heights = [base_height * area for i, area in enumerate(areas)]
-            else:
-                distance = [t] * len(areas)
-                base_heights = [base_height] * len(areas)
-
-            next_rings = []
-            rings = startinfo['rings']
-            centers = startinfo['centers']
-            normals = startinfo['normals']
-            for i in range(len(rings)):
-                next_rings.append(make_one_inset(self, context, bm=bm, ringvectors=rings[i],
-                                                 center=centers[i], normal=normals[i],
-                                                 t=distance[i], base_height=base_heights[i]))
-
-            prepare_ring = extrude_edges(self, context, bm=bm, edge_l_l=next_rings)
-
-            second_height = self.second_height
-            width = self.width
-            vectors = [[ele.verts[:] for ele in edge] for edge in prepare_ring]
-            n_ring_vecs = []
-
-            for rings in vectors:
-                v = []
-                for edgv in rings:
-                    v.extend(edgv)
-                # PKHF>INFO no double verts allowed, coming from two adjacents edges!
-                bm.verts.ensure_lookup_table()
-                vv = list(set([ele.index for ele in v]))
-
-                vvv = [bm.verts[i].co for i in vv]
-                n_ring_vecs.append(vvv)
-
-            for i, ring in enumerate(n_ring_vecs):
-                make_one_inset(self, context, bm=bm, ringvectors=ring,
-                               center=centers[i], normal=normals[i],
-                               t=width, base_height=base_heights[i] + second_height)
-            bpy.ops.object.mode_set(mode='OBJECT')
-
-        else:
-            if face_type == "clsd_vertical":
-                obj_name = context.active_object.name
-                ClosedVertical(name=obj_name, base_height=self.base_height,
-                               use_relative_base_height=self.use_relative)
-
-            elif face_type == "open_vertical":
-                obj_name = context.active_object.name
-                OpenVertical(name=obj_name, base_height=self.base_height,
-                             use_relative_base_height=self.use_relative)
-
-            elif face_type == "bar":
-                startinfo = prepare(self, context, self.remove_start_faces)
-
-                result = []
-                bm = startinfo['bm']
-                rings = startinfo['rings']
-                centers = startinfo['centers']
-                normals = startinfo['normals']
-                spike_base_width = self.spike_base_width
-                for i, ring in enumerate(rings):
-                    result.append(make_one_inset(self, context, bm=bm,
-                                                 ringvectors=ring, center=centers[i],
-                                                 normal=normals[i], t=spike_base_width))
-
-                next_ring_edges_list = extrude_edges(self, context, bm=bm,
-                                                     edge_l_l=result)
-                top_spike = self.top_spike
-                fac = top_spike
-                object_matrix = startinfo['obj'].matrix_local
-                for i in range(len(next_ring_edges_list)):
-                    translate_ONE_ring(
-                            self, context, bm=bm,
-                            object_matrix=object_matrix,
-                            ring_edges=next_ring_edges_list[i],
-                            normal=normals[i], distance=fac
-                            )
-                next_ring_edges_list_2 = extrude_edges(self, context, bm=bm,
-                                                       edge_l_l=next_ring_edges_list)
-
-                top_extra_height = self.top_extra_height
-                for i in range(len(next_ring_edges_list_2)):
-                    move_corner_vecs_outside(
-                            self, context, bm=bm,
-                            edge_list=next_ring_edges_list_2[i],
-                            center=centers[i], normal=normals[i],
-                            base_height_erlier=fac + top_extra_height,
-                            distance=fac
-                            )
-                bpy.ops.mesh.select_mode(type="VERT")
-                bpy.ops.mesh.select_more()
-
-                bpy.ops.object.mode_set(mode='OBJECT')
-
-        return {'FINISHED'}
-
-
-def find_one_ring(sel_vertices):
-    ring0 = sel_vertices.pop(0)
-    to_delete = []
-
-    for i, edge in enumerate(sel_vertices):
-        len_nu = len(ring0)
-        if len(ring0 - edge) < len_nu:
-            to_delete.append(i)
-            ring0 = ring0.union(edge)
-
-    to_delete.reverse()
-
-    for el in to_delete:
-        sel_vertices.pop(el)
-
-    return (ring0, sel_vertices)
-
-
-class Stepped:
-    def __init__(self, spike_base_width=0.5, base_height_inset=0.0, top_spike=0.2,
-                 top_relative=False, top_extra_height=0, use_relative_offset=False,
-                 with_spike=False):
-
-        bpy.ops.object.mode_set(mode='EDIT')
-        bpy.ops.mesh.inset(
-                use_boundary=True, use_even_offset=True, use_relative_offset=False,
-                use_edge_rail=False, thickness=spike_base_width, depth=0, use_outset=True,
-                use_select_inset=False, use_individual=True, use_interpolate=True
-                )
-        bpy.ops.mesh.inset(
-                use_boundary=True, use_even_offset=True, use_relative_offset=use_relative_offset,
-                use_edge_rail=False, thickness=top_extra_height, depth=base_height_inset,
-                use_outset=True, use_select_inset=False, use_individual=True, use_interpolate=True
-                )
-        bpy.ops.mesh.inset(
-                use_boundary=True, use_even_offset=True, use_relative_offset=use_relative_offset,
-                use_edge_rail=False, thickness=spike_base_width, depth=0, use_outset=True,
-                use_select_inset=False, use_individual=True, use_interpolate=True
-                )
-        bpy.ops.mesh.inset(
-                use_boundary=True, use_even_offset=True, use_relative_offset=False,
-                use_edge_rail=False, thickness=0, depth=top_spike, use_outset=True,
-                use_select_inset=False, use_individual=True, use_interpolate=True
-                )
-        if with_spike:
-            bpy.ops.mesh.merge(type='COLLAPSE')
-
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-
-class Spiked:
-    def __init__(self, spike_base_width=0.5, base_height_inset=0.0, top_spike=0.2, top_relative=False):
-
-        obj = bpy.context.active_object
-        bpy.ops.object.mode_set(mode='EDIT')
-        bpy.ops.mesh.inset(
-                use_boundary=True, use_even_offset=True, use_relative_offset=False,
-                use_edge_rail=False, thickness=spike_base_width, depth=base_height_inset,
-                use_outset=True, use_select_inset=False, use_individual=True, use_interpolate=True
-                )
-        bpy.ops.mesh.inset(
-                use_boundary=True, use_even_offset=True, use_relative_offset=top_relative,
-                use_edge_rail=False, thickness=0, depth=top_spike, use_outset=True,
-                use_select_inset=False, use_individual=True, use_interpolate=True
-                )
-
-        bm = bmesh.from_edit_mesh(obj.data)
-        bpy.ops.mesh.merge(type='COLLAPSE')
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-
-class ClosedVertical:
-    def __init__(self, name="Plane", base_height=1, use_relative_base_height=False):
-        obj = bpy.data.objects[name]
-
-        bm = bmesh.new()
-        bm.from_mesh(obj.data)
-        # PKHG>INFO deselect chosen faces
-        sel = [f for f in bm.faces if f.select]
-        for f in sel:
-            f.select = False
-        res = bmesh.ops.extrude_discrete_faces(bm, faces=sel)
-        # PKHG>INFO select extruded faces
-        for f in res['faces']:
-            f.select = True
-
-        factor = base_height
-        for face in res['faces']:
-            if use_relative_base_height:
-                area = face.calc_area()
-                factor = area * base_height
-            else:
-                factor = base_height
-            for el in face.verts:
-                tmp = el.co + face.normal * factor
-                el.co = tmp
-
-        me = bpy.data.meshes[name]
-        bm.to_mesh(me)
-        bm.free()
-
-
-class OpenVertical:
-    def __init__(self, name="Plane", base_height=1, use_relative_base_height=False):
-
-        obj = bpy.data.objects[name]
-        bm = bmesh.new()
-        bm.from_mesh(obj.data)
-        # PKHG>INFO deselect chosen faces
-        sel = [f for f in bm.faces if f.select]
-        for f in sel:
-            f.select = False
-        res = bmesh.ops.extrude_discrete_faces(bm, faces=sel)
-        # PKHG>INFO select extruded faces
-        for f in res['faces']:
-            f.select = True
-
-        # PKHG>INFO adjust extrusion by a vector
-        factor = base_height
-        for face in res['faces']:
-            if use_relative_base_height:
-                area = face.calc_area()
-                factor = area * base_height
-            else:
-                factor = base_height
-            for el in face.verts:
-                tmp = el.co + face.normal * factor
-                el.co = tmp
-
-        me = bpy.data.meshes[name]
-        bm.to_mesh(me)
-        bm.free()
-
-        bpy.ops.object.editmode_toggle()
-        bpy.ops.mesh.delete(type='FACE')
-        bpy.ops.object.editmode_toggle()
-
-
-class StripFaces:
-    def __init__(self, use_boundary=True, use_even_offset=True, use_relative_offset=False,
-                 use_edge_rail=True, thickness=0.0, depth=0.0, use_outset=False,
-                 use_select_inset=False, use_individual=True, use_interpolate=True):
-
-        bpy.ops.object.mode_set(mode='EDIT')
-        bpy.ops.mesh.inset(
-                use_boundary=use_boundary, use_even_offset=True, use_relative_offset=False,
-                use_edge_rail=True, thickness=thickness, depth=depth, use_outset=use_outset,
-                use_select_inset=use_select_inset, use_individual=use_individual,
-                use_interpolate=use_interpolate
-                )
-
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-        # PKHG>IMFO only 3 parameters inc execution context supported!!
-        if False:
-            bpy.ops.mesh.inset(
-                    use_boundary, use_even_offset, use_relative_offset, use_edge_rail,
-                    thickness, depth, use_outset, use_select_inset, use_individual,
-                    use_interpolate
-                    )
-        elif type == 0:
-            bpy.ops.mesh.inset(
-                    use_boundary=True, use_even_offset=True, use_relative_offset=False,
-                    use_edge_rail=True, thickness=thickness, depth=depth, use_outset=False,
-                    use_select_inset=False, use_individual=True, use_interpolate=True
-                    )
-        elif type == 1:
-            bpy.ops.mesh.inset(
-                    use_boundary=True, use_even_offset=True, use_relative_offset=False,
-                    use_edge_rail=True, thickness=thickness, depth=depth, use_outset=False,
-                    use_select_inset=False, use_individual=True, use_interpolate=False
-                    )
-            bpy.ops.mesh.delete(type='FACE')
-
-        elif type == 2:
-            bpy.ops.mesh.inset(
-                    use_boundary=True, use_even_offset=False, use_relative_offset=True,
-                    use_edge_rail=True, thickness=thickness, depth=depth, use_outset=False,
-                    use_select_inset=False, use_individual=True, use_interpolate=False
-                    )
-
-            bpy.ops.mesh.delete(type='FACE')
-
-        elif type == 3:
-            bpy.ops.mesh.inset(
-                    use_boundary=True, use_even_offset=False, use_relative_offset=True,
-                    use_edge_rail=True, thickness=depth, depth=thickness, use_outset=False,
-                    use_select_inset=False, use_individual=True, use_interpolate=True
-                    )
-            bpy.ops.mesh.delete(type='FACE')
-        elif type == 4:
-            bpy.ops.mesh.inset(
-                    use_boundary=True, use_even_offset=False, use_relative_offset=True,
-                    use_edge_rail=True, thickness=thickness, depth=depth, use_outset=True,
-                    use_select_inset=False, use_individual=True, use_interpolate=True
-                    )
-            bpy.ops.mesh.inset(
-                    use_boundary=True, use_even_offset=False, use_relative_offset=True,
-                    use_edge_rail=True, thickness=thickness, depth=depth, use_outset=True,
-                    use_select_inset=False, use_individual=True, use_interpolate=True
-                    )
-        bpy.ops.mesh.delete(type='FACE')
-
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-
-def check_is_selected():
-    is_selected = False
-    for face in bpy.context.active_object.data.polygons:
-        if face.select:
-            is_selected = True
-            break
-    return is_selected
-
-
-def prepare(self, context, remove_start_faces=True):
-    """
-       Start for a face selected change of faces
-       select an object of type mesh, with activated several (all) faces
-    """
-    obj = bpy.context.view_layer.objects.active
-    bpy.ops.object.mode_set(mode='OBJECT')
-    selectedpolygons = [el for el in obj.data.polygons if el.select]
-
-    # PKHG>INFO copies of the vectors are needed, otherwise Blender crashes!
-    centers = [face.center for face in selectedpolygons]
-    centers_copy = [Vector((el[0], el[1], el[2])) for el in centers]
-    normals = [face.normal for face in selectedpolygons]
-    normals_copy = [Vector((el[0], el[1], el[2])) for el in normals]
-
-    vertindicesofpolgons = [
-            [vert for vert in face.vertices] for face in selectedpolygons
-            ]
-    vertVectorsOfSelectedFaces = [
-            [obj.data.vertices[ind].co for ind in vertIndiceofface] for
-            vertIndiceofface in vertindicesofpolgons
-            ]
-    vertVectorsOfSelectedFaces_copy = [
-            [Vector((el[0], el[1], el[2])) for el in listofvecs] for
-            listofvecs in vertVectorsOfSelectedFaces
-            ]
-
-    bpy.ops.object.mode_set(mode='EDIT')
-    bm = bmesh.from_edit_mesh(obj.data)
-    selected_bm_faces = [ele for ele in bm.faces if ele.select]
-
-    selected_edges_per_face_ind = [
-            [ele.index for ele in face.edges] for face in selected_bm_faces
-            ]
-    indices = [el.index for el in selectedpolygons]
-    selected_faces_areas = [bm.faces[:][i] for i in indices]
-    tmp_area = [el.calc_area() for el in selected_faces_areas]
-
-    # PKHG>INFO, selected faces are removed, only their edges are used!
-    if remove_start_faces:
-        bpy.ops.mesh.delete(type='ONLY_FACE')
-        bpy.ops.object.mode_set(mode='OBJECT')
-        obj.data.update()
-        bpy.ops.object.mode_set(mode='EDIT')
-        bm = bmesh.from_edit_mesh(obj.data)
-        bm.verts.ensure_lookup_table()
-        bm.faces.ensure_lookup_table()
-
-    start_ring_raw = [
-            [bm.verts[ind].index for ind in vertIndiceofface] for
-            vertIndiceofface in vertindicesofpolgons
-            ]
-    start_ring = []
-
-    for el in start_ring_raw:
-        start_ring.append(set(el))
-    bm.edges.ensure_lookup_table()
-
-    bm_selected_edges_l_l = [
-            [bm.edges[i] for i in bm_ind_list] for
-            bm_ind_list in selected_edges_per_face_ind
-            ]
-    result = {
-            'obj': obj, 'centers': centers_copy, 'normals': normals_copy,
-            'rings': vertVectorsOfSelectedFaces_copy, 'bm': bm,
-            'areas': tmp_area, 'startBMRingVerts': start_ring,
-            'base_edges': bm_selected_edges_l_l
-            }
-
-    return result
-
-
-def make_one_inset(self, context, bm=None, ringvectors=None, center=None,
-                   normal=None, t=None, base_height=0):
-    # a face will get 'inserted' faces to create (normally) a hole if t is > 0 and < 1)
-    tmp = []
-
-    for el in ringvectors:
-        tmp.append((el * (1 - t) + center * t) + normal * base_height)
-
-    tmp = [bm.verts.new(v) for v in tmp]  # the new corner bmvectors
-    # PKHG>INFO so to say sentinells, to use ONE for ...
-    tmp.append(tmp[0])
-    vectorsFace_i = [bm.verts.new(v) for v in ringvectors]
-    vectorsFace_i.append(vectorsFace_i[0])
-    myres = []
-    for ii in range(len(vectorsFace_i) - 1):
-        # PKHG>INFO next line: sequence is important! for added edge
-        bmvecs = [vectorsFace_i[ii], vectorsFace_i[ii + 1], tmp[ii + 1], tmp[ii]]
-        res = bm.faces.new(bmvecs)
-        myres.append(res.edges[2])
-        myres[-1].select = True  # PKHG>INFO to be used later selected!
-    return (myres)
-
-
-def extrude_faces(self, context, bm=None, face_l=None):
-    # to make a ring extrusion
-    res = bmesh.ops.extrude_discrete_faces(bm, faces=face_l)['faces']
-
-    for face in res:
-        face.select = True
-    return res
-
-
-def extrude_edges(self, context, bm=None, edge_l_l=None):
-    # to make a ring extrusion
-    all_results = []
-    for edge_l in edge_l_l:
-        for edge in edge_l:
-            edge.select = False
-        res = bmesh.ops.extrude_edge_only(bm, edges=edge_l)
-        tmp = [ele for ele in res['geom'] if isinstance(ele, bmesh.types.BMEdge)]
-        for edge in tmp:
-            edge.select = True
-        all_results.append(tmp)
-    return all_results
-
-
-def translate_ONE_ring(self, context, bm=None, object_matrix=None, ring_edges=None,
-                       normal=(0, 0, 1), distance=0.5):
-    # translate a ring in given (normal?!) direction with given (global) amount
-    tmp = []
-    for edge in ring_edges:
-        tmp.extend(edge.verts[:])
-    # PKHG>INFO no double vertices allowed by bmesh!
-    tmp = set(tmp)
-    tmp = list(tmp)
-    bmesh.ops.translate(bm, vec=normal * distance, space=object_matrix, verts=tmp)
-    # PKHG>INFO relevant edges will stay selected
-    return ring_edges
-
-
-def move_corner_vecs_outside(self, context, bm=None, edge_list=None, center=None,
-                             normal=None, base_height_erlier=0.5, distance=0.5):
-    # move corners (outside meant mostly) dependent on the parameters
-    tmp = []
-    for edge in edge_list:
-        tmp.extend([ele for ele in edge.verts if isinstance(ele, bmesh.types.BMVert)])
-    # PKHG>INFO to remove vertices, they are all used twice in the ring!
-    tmp = set(tmp)
-    tmp = list(tmp)
-
-    for i in range(len(tmp)):
-        vec = tmp[i].co
-        direction = vec + (vec - (normal * base_height_erlier + center)) * distance
-        tmp[i].co = direction
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/random_vertices.py b/mesh_extra_tools/random_vertices.py
deleted file mode 100644
index 51f8be242..000000000
--- a/mesh_extra_tools/random_vertices.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# gpl authors: Oscurart, Greg
-
-bl_info = {
-    "name": "Random Vertices",
-    "author": "Oscurart, Greg",
-    "version": (1, 3),
-    "blender": (2, 63, 0),
-    "location": "Object > Transform > Random Vertices",
-    "description": "Randomize selected components of active object",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"}
-
-
-import bpy
-from bpy.types import Operator
-import random
-import bmesh
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        IntVectorProperty,
-        )
-
-
-def add_object(self, context, valmin, valmax, factor, vgfilter):
-    # select an option with weight map or not
-    mode = bpy.context.active_object.mode
-    # generate variables
-    objact = bpy.context.active_object
-    listver = []
-    warn_message = False
-
-    # switch to edit mode
-    bpy.ops.object.mode_set(mode='OBJECT')
-    bpy.ops.object.mode_set(mode='EDIT')
-
-    # bmesh object
-    odata = bmesh.from_edit_mesh(objact.data)
-    odata.select_flush(False)
-
-    # if the vertex is selected add to the list
-    for vertice in odata.verts[:]:
-        if vertice.select:
-            listver.append(vertice.index)
-
-    # If the minimum value is greater than the maximum,
-    # it adds a value to the maximum
-    if valmin[0] >= valmax[0]:
-        valmax[0] = valmin[0] + 1
-
-    if valmin[1] >= valmax[1]:
-        valmax[1] = valmin[1] + 1
-
-    if valmin[2] >= valmax[2]:
-        valmax[2] = valmin[2] + 1
-
-    odata.verts.ensure_lookup_table()
-
-    random_factor = factor
-    for vertice in listver:
-        odata.verts.ensure_lookup_table()
-        if odata.verts[vertice].select:
-            if vgfilter is True:
-                has_group = getattr(objact.data.vertices[vertice], "groups", None)
-                vertex_group = has_group[0] if has_group else None
-                vertexweight = getattr(vertex_group, "weight", None)
-                if vertexweight:
-                    random_factor = factor * vertexweight
-                else:
-                    random_factor = factor
-                    warn_message = True
-
-            odata.verts[vertice].co = (
-                (((random.randrange(valmin[0], valmax[0], 1)) * random_factor) / 1000) +
-                odata.verts[vertice].co[0],
-                (((random.randrange(valmin[1], valmax[1], 1)) * random_factor) / 1000) +
-                odata.verts[vertice].co[1],
-                (((random.randrange(valmin[2], valmax[2], 1)) * random_factor) / 1000) +
-                odata.verts[vertice].co[2]
-                )
-
-    if warn_message:
-        self.report({'WARNING'},
-                    "Some of the Selected Vertices don't have a Group with Vertex Weight assigned")
-    bpy.ops.object.mode_set(mode=mode)
-
-
-class MESH_OT_random_vertices(Operator):
-    bl_idname = "mesh.random_vertices"
-    bl_label = "Random Vertices"
-    bl_description = ("Randomize the location of vertices by a specified\n"
-                      "Multiplier Factor and random values in the defined range\n"
-                      "or a multiplication of them and the Vertex Weights")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    vgfilter: BoolProperty(
-            name="Vertex Group",
-            description="Use Vertex Weight defined in the Active Group",
-            default=False
-            )
-    factor: FloatProperty(
-            name="Factor",
-            description="Base Multiplier of the randomization effect",
-            default=1
-            )
-    valmin: IntVectorProperty(
-            name="Min XYZ",
-            description="Define the minimum range of randomization values",
-            default=(0, 0, 0)
-            )
-    valmax: IntVectorProperty(
-            name="Max XYZ",
-            description="Define the maximum range of randomization values",
-            default=(1, 1, 1)
-            )
-
-    @classmethod
-    def poll(cls, context):
-        return (context.object and context.object.type == "MESH" and
-               context.mode == "EDIT_MESH")
-
-    def execute(self, context):
-        add_object(self, context, self.valmin, self.valmax, self.factor, self.vgfilter)
-
-        return {'FINISHED'}
-
-
-# Registration
-
-def register():
-    bpy.utils.register_class(MESH_OT_random_vertices)
-
-
-def unregister():
-    bpy.utils.unregister_class(MESH_OT_random_vertices)
-
-
-if __name__ == '__main__':
-    register()
diff --git a/mesh_extra_tools/split_solidify.py b/mesh_extra_tools/split_solidify.py
deleted file mode 100644
index 16a1c3275..000000000
--- a/mesh_extra_tools/split_solidify.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# ##### 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 #####
-
-bl_info = {
-    "name": "Split Solidify",
-    "author": "zmj100, updated by zeffii to BMesh",
-    "version": (0, 1, 2),
-    "blender": (2, 77, 0),
-    "location": "View3D > Tool Shelf",
-    "description": "",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"}
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from bpy.props import (
-        EnumProperty,
-        FloatProperty,
-        BoolProperty,
-        )
-import random
-from math import cos
-
-
-# define the functions
-def solidify_split(self, list_0):
-
-    loc_random = self.loc_random
-    random_dist = self.random_dist
-    distance = self.distance
-    thickness = self.thickness
-    normal_extr = self.normal_extr
-
-    bm = self.bm
-
-    for fi in list_0:
-        bm.faces.ensure_lookup_table()
-        f = bm.faces[fi]
-        list_1 = []
-        list_2 = []
-
-        if loc_random:
-            d = random_dist * random.randrange(0, 10)
-        elif not loc_random:
-            d = distance
-
-        # add new vertices
-        for vi in f.verts:
-            bm.verts.ensure_lookup_table()
-            v = bm.verts[vi.index]
-
-            if normal_extr == 'opt0':
-                p1 = (v.co).copy() + ((f.normal).copy() * d)                # out
-                p2 = (v.co).copy() + ((f.normal).copy() * (d - thickness))  # in
-            elif normal_extr == 'opt1':
-                ang = ((v.normal).copy()).angle((f.normal).copy())
-                h = thickness / cos(ang)
-                p1 = (v.co).copy() + ((f.normal).copy() * d)
-                p2 = p1 + (-h * (v.normal).copy())
-
-            v1 = bm.verts.new(p1)
-            v2 = bm.verts.new(p2)
-            v1.select = False
-            v2.select = False
-            list_1.append(v1)
-            list_2.append(v2)
-
-        # add new faces, allows faces with more than 4 verts
-        n = len(list_1)
-
-        k = bm.faces.new(list_1)
-        k.select = False
-        for i in range(n):
-            j = (i + 1) % n
-            vseq = list_1[i], list_2[i], list_2[j], list_1[j]
-            k = bm.faces.new(vseq)
-            k.select = False
-
-        list_2.reverse()
-        k = bm.faces.new(list_2)
-        k.select = False
-    bpy.ops.mesh.normals_make_consistent(inside=False)
-
-    bmesh.update_edit_mesh(self.me, True)
-
-
-class MESH_OT_split_solidify(Operator):
-    bl_idname = "mesh.split_solidify"
-    bl_label = "Split Solidify"
-    bl_description = "Split and Solidify selected Faces"
-    bl_options = {"REGISTER", "UNDO"}
-
-    distance: FloatProperty(
-            name="",
-            description="Distance of the splitted Faces to the original geometry",
-            default=0.4,
-            min=-100.0, max=100.0,
-            step=1,
-            precision=3
-            )
-    thickness: FloatProperty(
-            name="",
-            description="Thickness of the splitted Faces",
-            default=0.04,
-            min=-100.0, max=100.0,
-            step=1,
-            precision=3
-            )
-    random_dist: FloatProperty(
-            name="",
-            description="Randomization factor of the splitted Faces' location",
-            default=0.06,
-            min=-10.0, max=10.0,
-            step=1,
-            precision=3
-            )
-    loc_random: BoolProperty(
-            name="Random",
-            description="Randomize the locations of splitted faces",
-            default=False
-            )
-    del_original: BoolProperty(
-            name="Delete original faces",
-            default=True
-            )
-    normal_extr: EnumProperty(
-            items=(('opt0', "Face", "Solidify along Face Normals"),
-                   ('opt1', "Vertex", "Solidify along Vertex Normals")),
-            name="Normal",
-            default='opt0'
-           )
-
-    def draw(self, context):
-        layout = self.layout
-        layout.label(text="Normal:")
-        layout.prop(self, "normal_extr", expand=True)
-        layout.prop(self, "loc_random")
-
-        if not self.loc_random:
-            layout.label(text="Distance:")
-            layout.prop(self, "distance")
-        elif self.loc_random:
-            layout.label(text="Random distance:")
-            layout.prop(self, "random_dist")
-
-        layout.label(text="Thickness:")
-        layout.prop(self, "thickness")
-        layout.prop(self, "del_original")
-
-    def execute(self, context):
-        obj = bpy.context.active_object
-        self.me = obj.data
-        self.bm = bmesh.from_edit_mesh(self.me)
-        self.me.update()
-
-        list_0 = [f.index for f in self.bm.faces if f.select]
-
-        if len(list_0) == 0:
-            self.report({'WARNING'},
-                        "No suitable selection found. Operation cancelled")
-
-            return {'CANCELLED'}
-
-        elif len(list_0) != 0:
-            solidify_split(self, list_0)
-            context.tool_settings.mesh_select_mode = (True, True, True)
-            if self.del_original:
-                bpy.ops.mesh.delete(type='FACE')
-            else:
-                pass
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(MESH_OT_split_solidify)
-
-
-def unregister():
-    bpy.utils.unregister_class(MESH_OT_split_solidify)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/vertex_align.py b/mesh_extra_tools/vertex_align.py
deleted file mode 100644
index eb66d747e..000000000
--- a/mesh_extra_tools/vertex_align.py
+++ /dev/null
@@ -1,301 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# ##### 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 #####
-
-# Note: Property group was moved to __init__
-
-bl_info = {
-    "name": "Vertex Align",
-    "author": "",
-    "version": (0, 1, 7),
-    "blender": (2, 61, 0),
-    "location": "View3D > Tool Shelf",
-    "description": "",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"}
-
-
-import bpy
-from bpy.props import (
-        BoolVectorProperty,
-        FloatVectorProperty,
-        )
-from mathutils import Vector
-from bpy.types import Operator
-
-
-# Edit Mode Toggle
-def edit_mode_out():
-    bpy.ops.object.mode_set(mode='OBJECT')
-
-
-def edit_mode_in():
-    bpy.ops.object.mode_set(mode='EDIT')
-
-
-def get_mesh_data_():
-    edit_mode_out()
-    ob_act = bpy.context.active_object
-    me = ob_act.data
-    edit_mode_in()
-    return me
-
-
-def list_clear_(l):
-    l[:] = []
-    return l
-
-
-class va_buf():
-    list_v = []
-    list_0 = []
-
-
-# Store The Vertex coordinates
-class Vertex_align_store(Operator):
-    bl_idname = "vertex_align.store_id"
-    bl_label = "Active Vertex"
-    bl_description = ("Store Selected Vertex coordinates as an align point\n"
-                      "Single Selected Vertex only")
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def execute(self, context):
-        try:
-            me = get_mesh_data_()
-            list_0 = [v.index for v in me.vertices if v.select]
-
-            if len(list_0) == 1:
-                list_clear_(va_buf.list_v)
-                for v in me.vertices:
-                    if v.select:
-                        va_buf.list_v.append(v.index)
-                        bpy.ops.mesh.select_all(action='DESELECT')
-            else:
-                self.report({'WARNING'}, "Please select just One Vertex")
-                return {'CANCELLED'}
-        except:
-            self.report({'WARNING'}, "Storing selection could not be completed")
-            return {'CANCELLED'}
-
-        self.report({'INFO'}, "Selected Vertex coordinates are stored")
-
-        return {'FINISHED'}
-
-
-# Align to original
-class Vertex_align_original(Operator):
-    bl_idname = "vertex_align.align_original"
-    bl_label = "Align to original"
-    bl_description = "Align selection to stored single vertex coordinates"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def draw(self, context):
-        layout = self.layout
-        layout.label(text="Axis:")
-
-        row = layout.row(align=True)
-        row.prop(context.scene.mesh_extra_tools, "vert_align_axis",
-                 text="X", index=0, toggle=True)
-        row.prop(context.scene.mesh_extra_tools, "vert_align_axis",
-                 text="Y", index=1, toggle=True)
-        row.prop(context.scene.mesh_extra_tools, "vert_align_axis",
-                 text="Z", index=2, toggle=True)
-
-    def execute(self, context):
-        edit_mode_out()
-        ob_act = context.active_object
-        me = ob_act.data
-        cen1 = context.scene.mesh_extra_tools.vert_align_axis
-        list_0 = [v.index for v in me.vertices if v.select]
-
-        if len(va_buf.list_v) == 0:
-            self.report({'INFO'},
-                        "Original vertex not stored in memory. Operation Cancelled")
-            edit_mode_in()
-            return {'CANCELLED'}
-
-        elif len(va_buf.list_v) != 0:
-            if len(list_0) == 0:
-                self.report({'INFO'}, "No vertices selected. Operation Cancelled")
-                edit_mode_in()
-                return {'CANCELLED'}
-
-            elif len(list_0) != 0:
-                vo = (me.vertices[va_buf.list_v[0]].co).copy()
-                if cen1[0] is True:
-                    for i in list_0:
-                        v = (me.vertices[i].co).copy()
-                        me.vertices[i].co = Vector((vo[0], v[1], v[2]))
-                if cen1[1] is True:
-                    for i in list_0:
-                        v = (me.vertices[i].co).copy()
-                        me.vertices[i].co = Vector((v[0], vo[1], v[2]))
-                if cen1[2] is True:
-                    for i in list_0:
-                        v = (me.vertices[i].co).copy()
-                        me.vertices[i].co = Vector((v[0], v[1], vo[2]))
-        edit_mode_in()
-
-        return {'FINISHED'}
-
-
-# Align to custom coordinates
-class Vertex_align_coord_list(Operator):
-    bl_idname = "vertex_align.coord_list_id"
-    bl_label = ""
-    bl_description = "Align to custom coordinates"
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
-
-    def execute(self, context):
-        edit_mode_out()
-        ob_act = context.active_object
-        me = ob_act.data
-        list_clear_(va_buf.list_0)
-        va_buf.list_0 = [v.index for v in me.vertices if v.select][:]
-
-        if len(va_buf.list_0) == 0:
-            self.report({'INFO'}, "No vertices selected. Operation Cancelled")
-            edit_mode_in()
-            return {'CANCELLED'}
-
-        elif len(va_buf.list_0) != 0:
-            bpy.ops.vertex_align.coord_menu_id('INVOKE_DEFAULT')
-
-        edit_mode_in()
-
-        return {'FINISHED'}
-
-
-# Align to custom coordinates menu
-class Vertex_align_coord_menu(Operator):
-    bl_idname = "vertex_align.coord_menu_id"
-    bl_label = "Tweak custom coordinates"
-    bl_description = "Change the custom coordinates for aligning"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    def_axis_coord: FloatVectorProperty(
-            name="",
-            description="Enter the values of coordinates",
-            default=(0.0, 0.0, 0.0),
-            min=-100.0, max=100.0,
-            step=1, size=3,
-            subtype='XYZ',
-            precision=3
-            )
-    use_axis_coord = BoolVectorProperty(
-            name="Axis",
-            description="Choose Custom Coordinates axis",
-            default=(False,) * 3,
-            size=3,
-            )
-    is_not_undo = False
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == 'MESH')
-
-    def using_store(self, context):
-        scene = context.scene
-        return scene.mesh_extra_tools.vert_align_use_stored
-
-    def draw(self, context):
-        layout = self.layout
-
-        if self.using_store(context) and self.is_not_undo:
-            layout.label(text="Using Stored Coordinates", icon="INFO")
-
-        row = layout.split(0.25)
-        row.prop(self, "use_axis_coord", index=0, text="X")
-        row.prop(self, "def_axis_coord", index=0)
-
-        row = layout.split(0.25)
-        row.prop(self, "use_axis_coord", index=1, text="Y")
-        row.prop(self, "def_axis_coord", index=1)
-
-        row = layout.split(0.25)
-        row.prop(self, "use_axis_coord", index=2, text="Z")
-        row.prop(self, "def_axis_coord", index=2)
-
-    def invoke(self, context, event):
-        self.is_not_undo = True
-        scene = context.scene
-        if self.using_store(context):
-            self.def_axis_coord = scene.mesh_extra_tools.vert_align_store_axis
-
-        return context.window_manager.invoke_props_dialog(self, width=200)
-
-    def execute(self, context):
-        self.is_not_undo = False
-        edit_mode_out()
-        ob_act = context.active_object
-        me = ob_act.data
-
-        for i in va_buf.list_0:
-            v = (me.vertices[i].co).copy()
-            tmp = Vector((v[0], v[1], v[2]))
-
-            if self.use_axis_coord[0] is True:
-                tmp[0] = self.def_axis_coord[0]
-            if self.use_axis_coord[1] is True:
-                tmp[1] = self.def_axis_coord[1]
-            if self.use_axis_coord[2] is True:
-                tmp[2] = self.def_axis_coord[2]
-            me.vertices[i].co = tmp
-
-        edit_mode_in()
-
-        return {'FINISHED'}
-
-
-#  Register
-classes = (
-    Vertex_align_store,
-    Vertex_align_original,
-    Vertex_align_coord_list,
-    Vertex_align_coord_menu,
-    )
-
-
-def register():
-    for cls in classes:
-        bpy.utils.register_class(cls)
-
-
-def unregister():
-    for cls in classes:
-        bpy.utils.unregister_class(cls)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/mesh_extra_tools/vfe_specials.py b/mesh_extra_tools/vfe_specials.py
deleted file mode 100644
index 714f1b3e1..000000000
--- a/mesh_extra_tools/vfe_specials.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# gpl author: Stanislav Blinov
-
-bl_info = {
-    "name": "V/E/F Context Menu",
-    "author": "Stanislav Blinov",
-    "version": (1, 0, 1),
-    "blender": (2, 78, 0),
-    "description": "Vert Edge Face Double Right Click Edit Mode",
-    "category": "Mesh",
-}
-
-import bpy
-import bpy_extras
-from bpy.types import (
-        Menu,
-        Operator,
-        )
-
-
-class MESH_MT_CombinedMenu(Menu):
-    bl_idname = "mesh.addon_combined_component_menu"
-    bl_label = "Components"
-
-    @classmethod
-    def poll(cls, context):
-        return context.mode == 'EDIT_MESH'
-
-    def draw(self, context):
-        layout = self.layout
-
-        mode = context.tool_settings.mesh_select_mode
-        if mode[0]:
-            layout.menu("VIEW3D_MT_edit_mesh_vertices")
-        if mode[1]:
-            layout.menu("VIEW3D_MT_edit_mesh_edges")
-        if mode[2]:
-            layout.menu("VIEW3D_MT_edit_mesh_faces")
-
-
-class MESH_OT_CallContextMenu(Operator):
-    bl_idname = "mesh.addon_call_context_menu"
-    bl_label = "Context Menu"
-
-    @classmethod
-    def poll(cls, context):
-        return context.mode == 'EDIT_MESH'
-
-    def execute(self, context):
-        mode = context.tool_settings.mesh_select_mode
-        num = sum(int(m) for m in mode)
-        if num == 1:
-            if mode[0]:
-                return bpy.ops.wm.call_menu(name="VIEW3D_MT_edit_mesh_vertices")
-            if mode[1]:
-                return bpy.ops.wm.call_menu(name="VIEW3D_MT_edit_mesh_edges")
-            if mode[2]:
-                return bpy.ops.wm.call_menu(name="VIEW3D_MT_edit_mesh_faces")
-        else:
-            return bpy.ops.wm.call_menu(name=MESH_MT_CombinedMenu.bl_idname)
-
-
-classes = (
-    MESH_MT_CombinedMenu,
-    MESH_OT_CallContextMenu,
-    )
-
-
-KEYMAPS = (
-    # First, keymap identifiers (last bool is True for modal km).
-    (("3D View", "VIEW_3D", "WINDOW", False), (
-    # Then a tuple of keymap items, defined by a dict of kwargs
-    # for the km new func, and a tuple of tuples (name, val)
-    # for ops properties, if needing non-default values.
-        ({"idname": MESH_OT_CallContextMenu.bl_idname, "type": 'RIGHTMOUSE', "value": 'DOUBLE_CLICK'},
-         ()),
-    )),
-)
-
-
-def register():
-    for cls in classes:
-        bpy.utils.register_class(cls)
-
-    bpy_extras.keyconfig_utils.addon_keymap_register(bpy.context.window_manager, KEYMAPS)
-
-
-def unregister():
-    bpy_extras.keyconfig_utils.addon_keymap_unregister(bpy.context.window_manager, KEYMAPS)
-
-    for cls in classes:
-        bpy.utils.unregister_class(cls)
-
-
-if __name__ == "__main__":
-    register()
-- 
GitLab