diff --git a/add_advanced_objects_menu/__init__.py b/add_advanced_objects_menu/__init__.py
deleted file mode 100644
index 91ddcb18472c64b7c000b3eb13f3d2ab2dbea58b..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/__init__.py
+++ /dev/null
@@ -1,547 +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, Bill Currie, Jorge Hernandez - Melenedez  Jacob Morris, Oscurart  #
-# Rebellion, Antonis Karvelas, Eleanor Howick, lijenstina, Daniel Schalla, Domlysz #
-# Unnikrishnan(kodemax), Florian Meyer, Omar ahmed, Brian Hinton (Nichod), liero   #
-# Atom, Dannyboy, Mano-Wii, Kursad Karatas, teldredge, Phil Cote #
-
-bl_info = {
-    "name": "Add Advanced Objects",
-    "author": "Meta Androcto",
-    "version": (0, 1, 6),
-    "blender": (2, 78, 0),
-    "location": "View3D > Add ",
-    "description": "Add Object & Camera extras",
-    "warning": "",
-    "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6"
-                "/Py/Scripts/Object/Add_Advanced",
-    "category": "Object"}
-
-if "bpy" in locals():
-    import importlib
-
-    importlib.reload(add_light_template)
-    importlib.reload(scene_objects_bi)
-    importlib.reload(scene_objects_cycles)
-    importlib.reload(scene_texture_render)
-    importlib.reload(trilighting)
-    importlib.reload(pixelate_3d)
-    importlib.reload(object_add_chain)
-    importlib.reload(oscurart_chain_maker)
-    importlib.reload(circle_array)
-    importlib.reload(copy2)
-    importlib.reload(make_struts)
-    importlib.reload(random_box_structure)
-    importlib.reload(cubester)
-    importlib.reload(rope_alpha)
-    importlib.reload(add_mesh_aggregate)
-    importlib.reload(arrange_on_curve)
-    importlib.reload(mesh_easylattice)
-
-else:
-    from . import add_light_template
-    from . import scene_objects_bi
-    from . import scene_objects_cycles
-    from . import scene_texture_render
-    from . import trilighting
-    from . import pixelate_3d
-    from . import object_add_chain
-    from . import oscurart_chain_maker
-    from . import circle_array
-    from . import copy2
-    from . import make_struts
-    from . import random_box_structure
-    from . import cubester
-    from . import rope_alpha
-    from . import add_mesh_aggregate
-    from . import arrange_on_curve
-    from . import mesh_easylattice
-
-
-import bpy
-from bpy.types import (
-    AddonPreferences,
-    Menu,
-    PropertyGroup,
-)
-from bpy.props import (
-    BoolProperty,
-    EnumProperty,
-    FloatProperty,
-    IntProperty,
-    StringProperty,
-    PointerProperty,
-)
-
-
-# Define the "Scenes" menu
-class VIEW3D_MT_scene_elements_add(Menu):
-    bl_idname = "VIEW3D_MT_scene_elements"
-    bl_label = "Test Scenes"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-        layout.operator("bi.add_scene",
-                        text="Scene_Objects_BI")
-        layout.operator("objects_cycles.add_scene",
-                        text="Scene_Objects_Cycles")
-        layout.operator("objects_texture.add_scene",
-                        text="Scene_Textures_Cycles")
-
-
-# Define the "Lights" menu
-class VIEW3D_MT_mesh_lights_add(Menu):
-    bl_idname = "VIEW3D_MT_scene_lights"
-    bl_label = "Lighting Sets"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-        layout.operator("object.add_light_template",
-                        text="Add Light Template")
-        layout.operator("object.trilighting",
-                        text="Add Tri Lighting")
-
-
-# Define the "Chains" menu
-class VIEW3D_MT_mesh_chain_add(Menu):
-    bl_idname = "VIEW3D_MT_mesh_chain"
-    bl_label = "Chains"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-        layout.operator("mesh.primitive_chain_add", icon="LINKED")
-        layout.operator("mesh.primitive_oscurart_chain_add", icon="LINKED")
-
-
-# Define the "Array" Menu
-class VIEW3D_MT_array_mods_add(Menu):
-    bl_idname = "VIEW3D_MT_array_mods"
-    bl_label = "Array Mods"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.menu("VIEW3D_MT_mesh_chain", icon="LINKED")
-
-        layout.operator("objects.circle_array_operator",
-                        text="Circle Array", icon="MOD_ARRAY")
-        layout.operator("object.agregate_mesh",
-                        text="Aggregate Mesh", icon="MOD_ARRAY")
-        layout.operator("mesh.copy2",
-                text="Copy To Vert/Edge", icon="MOD_ARRAY")
-
-
-# Define the "Blocks" Menu
-class VIEW3D_MT_quick_blocks_add(Menu):
-    bl_idname = "VIEW3D_MT_quick_tools"
-    bl_label = "Block Tools"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.operator("object.pixelate", icon="MESH_GRID")
-        layout.operator("mesh.generate_struts",
-                    text="Struts", icon="GRID")
-        layout.operator("object.make_structure",
-                    text="Random Boxes", icon="SEQ_SEQUENCER")
-        layout.operator("object.easy_lattice",
-                    text="Easy Lattice", icon="MOD_LATTICE")
-
-
-# Define the "Phsysics Tools" Menu
-class VIEW3D_MT_Physics_tools_add(Menu):
-    bl_idname = "VIEW3D_MT_physics_tools"
-    bl_label = "Physics Tools"
-
-    def draw(self, context):
-        layout = self.layout
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.operator("ball.rope",
-                        text="Wrecking Ball", icon='PHYSICS')
-        layout.operator("clot.rope",
-                        text="Cloth Rope", icon='PHYSICS')
-
-
-# Define "Extras" menu
-def menu(self, context):
-    layout = self.layout
-    layout.operator_context = 'INVOKE_REGION_WIN'
-    self.layout.separator()
-    self.layout.menu("VIEW3D_MT_scene_elements", icon="SCENE_DATA")
-    self.layout.menu("VIEW3D_MT_scene_lights", icon="LIGHT_SPOT")
-    self.layout.separator()
-    self.layout.menu("VIEW3D_MT_array_mods", icon="MOD_ARRAY")
-    self.layout.menu("VIEW3D_MT_quick_tools", icon="MOD_BUILD")
-    self.layout.menu("VIEW3D_MT_physics_tools", icon="PHYSICS")
-
-
-# Addons Preferences
-class AdvancedObjPreferences(AddonPreferences):
-    bl_idname = __name__
-
-    show_menu_list: BoolProperty(
-        name="Menu List",
-        description="Show/Hide the Add Menu items",
-        default=False
-    )
-    show_panel_list: BoolProperty(
-        name="Panels List",
-        description="Show/Hide the Panel items",
-        default=False
-    )
-
-    def draw(self, context):
-        layout = self.layout
-
-        icon_1 = "TRIA_RIGHT" if not self.show_menu_list else "TRIA_DOWN"
-        box = layout.box()
-        box.prop(self, "show_menu_list", emboss=False, icon=icon_1)
-
-        if self.show_menu_list:
-            box.label(text="Items located in the Add Menu (default shortcut Ctrl + A):",
-                      icon="LAYER_USED")
-            box.label(text="Test Scenes:", icon="LAYER_ACTIVE")
-            box.label(text="Scene Objects BI, Scene Objects Cycles, Scene Textures Cycles",
-                      icon="LAYER_USED")
-            box.label(text="Lighting Sets:", icon="LAYER_ACTIVE")
-            box.label(text="Add Light Template, Add Tri Lighting", icon="LAYER_USED")
-            box.label(text="Array Mods:", icon="LAYER_ACTIVE")
-            box.label(text="Circle Array, Chains submenu, Copy Vert/Edge and Aggregate Mesh",
-                         icon="LAYER_ACTIVE")
-            box.label(text="Chains Submenu - Add Chain, Chain to Bones",
-                      icon="LAYER_ACTIVE")
-            box.label(text="Block Tools:", icon="LAYER_ACTIVE")
-            box.label(text="Pixelate Object, Struts, Random Boxes, Easy Lattice",
-                      icon="LAYER_USED")
-            box.label(text="Physics Tools:", icon="LAYER_ACTIVE")
-            box.label(text="Wrecking Ball and Cloth Rope", icon="LAYER_USED")
-
-        icon_2 = "TRIA_RIGHT" if not self.show_panel_list else "TRIA_DOWN"
-        box = layout.box()
-        box.prop(self, "show_panel_list", emboss=False, icon=icon_2)
-
-        if self.show_panel_list:
-            box.label(text="Panels located in 3D View Tools Region > Create",
-                      icon="LAYER_ACTIVE")
-            box.label(text="CubeSter", icon="LAYER_USED")
-            box.label(text="Arrange on Curve  (Shown if an Active Curve Object is it the 3D View)",
-                      icon="LAYER_USED")
-
-
-# Cubester update functions
-def find_audio_length(self, context):
-    adv_obj = context.scene.advanced_objects
-    audio_file = adv_obj.cubester_audio_path
-    length = 0
-
-    if audio_file != "":
-        # confirm that strip hasn't been loaded yet
-        get_sequence = getattr(context.scene.sequence_editor, "sequences_all", [])
-        for strip in get_sequence:
-            if type(strip) == bpy.types.SoundSequence and strip.sound.filepath == audio_file:
-                length = strip.frame_final_duration
-
-        if length == 0:
-            area = context.area
-            old_type = area.type
-            area.type = "SEQUENCE_EDITOR"
-            try:
-                bpy.ops.sequencer.sound_strip_add(filepath=audio_file)
-                adv_obj.cubester_check_audio = True
-            except Exception as e:
-                print("\n[Add Advanced Objects]\n Function: "
-                      "find_audio_length\n {}\n".format(e))
-                adv_obj.cubester_check_audio = False
-                pass
-
-            area.type = old_type
-
-        # find audio file
-        for strip in context.scene.sequence_editor.sequences_all:
-            if type(strip) == bpy.types.SoundSequence and strip.sound.filepath == audio_file:
-                adv_obj.cubester_check_audio = True
-                length = strip.frame_final_duration
-
-    adv_obj.cubester_audio_file_length = length
-
-
-# load image if possible
-def adjust_selected_image(self, context):
-    scene = context.scene.advanced_objects
-    try:
-        image = bpy.data.images.load(scene.cubester_load_image)
-        scene.cubester_image = image.name
-    except Exception as e:
-        print("\n[Add Advanced Objects]\n Function: "
-              "adjust_selected_image\n {}\n".format(e))
-
-
-# load color image if possible
-def adjust_selected_color_image(self, context):
-    scene = context.scene.advanced_objects
-    try:
-        image = bpy.data.images.load(scene.cubester_load_color_image)
-        scene.cubester_color_image = image.name
-    except Exception as e:
-        print("\nAdd Advanced Objects]\n Function: "
-              "adjust_selected_color_image\n {}\n".format(e))
-
-
-class AdvancedObjProperties(PropertyGroup):
-    # cubester
-    # main properties
-    cubester_check_audio: BoolProperty(
-        name="",
-        default=False
-    )
-    cubester_audio_image: EnumProperty(
-        name="Input Type",
-        items=(("image", "Image",
-                "Use an Image as input for generating Geometry", "IMAGE_COL", 0),
-               ("audio", "Audio",
-                "Use a Sound Strip as input for generating Geometry", "FILE_SOUND", 1))
-    )
-    cubester_audio_file_length: IntProperty(
-        default=0
-    )
-    # audio
-    cubester_audio_path: StringProperty(
-        default="",
-        name="Audio File",
-        subtype="FILE_PATH",
-        update=find_audio_length
-    )
-    cubester_audio_min_freq: IntProperty(
-        name="Minimum Frequency",
-        min=20, max=100000,
-        default=20
-    )
-    cubester_audio_max_freq: IntProperty(
-        name="Maximum Frequency",
-        min=21, max=999999,
-        default=5000
-    )
-    cubester_audio_offset_type: EnumProperty(
-        name="Offset Type",
-        items=(("freq", "Frequency Offset", ""),
-               ("frame", "Frame Offset", "")),
-        description="Type of offset per row of mesh"
-    )
-    cubester_audio_frame_offset: IntProperty(
-        name="Frame Offset",
-        min=0, max=10,
-        default=2
-    )
-    cubester_audio_block_layout: EnumProperty(
-        name="Block Layout",
-        items=(("rectangle", "Rectangular", ""),
-              ("radial", "Radial", ""))
-    )
-    cubester_audio_width_blocks: IntProperty(
-        name="Width Block Count",
-        min=1, max=10000,
-        default=5
-    )
-    cubester_audio_length_blocks: IntProperty(
-        name="Length Block Count",
-        min=1, max=10000,
-        default=50
-    )
-    # image
-    cubester_load_type: EnumProperty(
-        name="Image Input Type",
-        items=(("single", "Single Image", ""),
-              ("multiple", "Image Sequence", ""))
-    )
-    cubester_image: StringProperty(
-        default="",
-        name=""
-    )
-    cubester_load_image: StringProperty(
-        default="",
-        name="Load Image",
-        subtype="FILE_PATH",
-        update=adjust_selected_image
-    )
-    cubester_skip_images: IntProperty(
-        name="Image Step",
-        min=1, max=30,
-        default=1,
-        description="Step from image to image by this number"
-    )
-    cubester_max_images: IntProperty(
-        name="Max Number Of Images",
-        min=2, max=1000,
-        default=10,
-        description="Maximum number of images to be used"
-    )
-    cubester_frame_step: IntProperty(
-        name="Frame Step Size",
-        min=1, max=10,
-        default=4,
-        description="The number of frames each picture is used"
-    )
-    cubester_skip_pixels: IntProperty(
-        name="Skip # Pixels",
-        min=0, max=256,
-        default=64,
-        description="Skip this number of pixels before placing the next"
-    )
-    cubester_mesh_style: EnumProperty(
-        name="Mesh Type",
-        items=(("blocks", "Blocks", ""),
-               ("plane", "Plane", "")),
-        description="Compose mesh of multiple blocks or of a single plane"
-    )
-    cubester_block_style: EnumProperty(
-        name="Block Style",
-        items=(("size", "Vary Size", ""),
-               ("position", "Vary Position", "")),
-        description="Vary Z-size of block, or vary Z-position"
-    )
-    cubester_height_scale: FloatProperty(
-        name="Height Scale",
-        subtype="DISTANCE",
-        min=0.1, max=2,
-        default=0.2
-    )
-    cubester_invert: BoolProperty(
-        name="Invert Height",
-        default=False
-    )
-    # general adjustments
-    cubester_size_per_hundred_pixels: FloatProperty(
-        name="Size Per 100 Blocks/Points",
-        subtype="DISTANCE",
-        min=0.001, max=5,
-        default=1
-    )
-    # material based stuff
-    cubester_materials: EnumProperty(
-        name="Material",
-        items=(("vertex", "Vertex Colors", ""),
-               ("image", "Image", "")),
-        description="Color with vertex colors, or uv unwrap and use an image"
-    )
-    cubester_use_image_color: BoolProperty(
-        name="Use Original Image Colors'?",
-        default=True,
-        description="Use original image colors, or replace with an another one"
-    )
-    cubester_color_image: StringProperty(
-        default="",
-        name=""
-    )
-    cubester_load_color_image: StringProperty(
-        default="",
-        name="Load Color Image",
-        subtype="FILE_PATH",
-        update=adjust_selected_color_image
-    )
-    cubester_vertex_colors = {}
-    # advanced
-    cubester_advanced: BoolProperty(
-        name="Advanced Options",
-        default=False
-    )
-    cubester_random_weights: BoolProperty(
-        name="Random Weights",
-        default=False
-    )
-    cubester_weight_r: FloatProperty(
-        name="Red",
-        subtype="FACTOR",
-        min=0.01, max=1.0,
-        default=0.25
-    )
-    cubester_weight_g: FloatProperty(
-        name="Green",
-        subtype="FACTOR",
-        min=0.01, max=1.0,
-        default=0.25
-    )
-    cubester_weight_b: FloatProperty(
-        name="Blue",
-        subtype="FACTOR",
-        min=0.01, max=1.0,
-        default=0.25
-    )
-    cubester_weight_a: FloatProperty(
-        name="Alpha",
-        subtype="FACTOR",
-        min=0.01, max=1.0,
-        default=0.25
-    )
-
-    # arrange_on_curve
-    arrange_c_use_selected: BoolProperty(
-        name="Use Selected",
-        description="Use the selected objects to duplicate",
-        default=True,
-    )
-    arrange_c_obj_arranjar: StringProperty(
-        name=""
-    )
-    arrange_c_select_type: EnumProperty(
-        name="Type",
-        description="Select object or group",
-        items=[
-            ('O', "Object", "Make duplicates of a specific object"),
-            ('G', "Group", "Make duplicates of the objects in a group"),
-        ],
-        default='O',
-    )
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-    bpy.types.Scene.advanced_objects = PointerProperty(
-        type=AdvancedObjProperties
-    )
-
-    # Add "Extras" menu to the "Add" menu
-    bpy.types.VIEW3D_MT_add.append(menu)
-    try:
-        bpy.types.VIEW3D_MT_AddMenu.append(menu)
-    except:
-        pass
-
-
-def unregister():
-    # Remove "Extras" menu from the "Add" menu.
-    bpy.types.VIEW3D_MT_add.remove(menu)
-    try:
-        bpy.types.VIEW3D_MT_AddMenu.remove(menu)
-    except:
-        pass
-
-    bpy.utils.unregister_module(__name__)
-    del bpy.types.Scene.advanced_objects
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/add_light_template.py b/add_advanced_objects_menu/add_light_template.py
deleted file mode 100644
index 3d6d880e8c66325b12602506a9e045454e82e31a..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/add_light_template.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# gpl: author Rebellion
-
-import bpy
-from bpy.types import Operator
-from bpy.props import BoolProperty
-
-
-def add_lights(self, context):
-
-    if self.bKeyLight:
-        keyLight = bpy.data.lights.new(name="Key_Light", type="SPOT")
-        ob = bpy.data.objects.new("Key_Light", keyLight)
-        constraint = ob.constraints.new(type='COPY_LOCATION')
-        constraint.use_offset = True
-        constraint.owner_space = 'LOCAL'
-        constraint.target = self.camera
-        constraint = ob.constraints.new(type='TRACK_TO')
-        constraint.target = self.target
-        constraint.track_axis = 'TRACK_NEGATIVE_Z'
-        constraint.up_axis = 'UP_X'
-        constraint.owner_space = 'LOCAL'
-        bpy.context.collection.objects.link(ob)
-        ob.rotation_euler[2] = -0.785398
-
-    if self.bFillLight:
-        fillLight = bpy.data.lights.new(name="Fill_Light", type="SPOT")
-        ob = bpy.data.objects.new("Fill_Light", fillLight)
-        constraint = ob.constraints.new(type='COPY_LOCATION')
-        constraint.use_offset = True
-        constraint.owner_space = 'LOCAL'
-        constraint.target = self.camera
-        constraint = ob.constraints.new(type='TRACK_TO')
-        constraint.target = self.target
-        constraint.track_axis = 'TRACK_NEGATIVE_Z'
-        constraint.up_axis = 'UP_X'
-        constraint.owner_space = 'LOCAL'
-        bpy.context.collection.objects.link(ob)
-        ob.rotation_euler[2] = 0.785398
-        ob.data.energy = 0.3
-
-    if self.bBackLight:
-        backLight = bpy.data.lights.new(name="Back_Light", type="SPOT")
-        ob = bpy.data.objects.new("Back_Light", backLight)
-        constraint = ob.constraints.new(type='COPY_LOCATION')
-        constraint.use_offset = True
-        constraint.owner_space = 'LOCAL'
-        constraint.target = self.camera
-        constraint = ob.constraints.new(type='TRACK_TO')
-        constraint.target = self.target
-        constraint.track_axis = 'TRACK_NEGATIVE_Z'
-        constraint.up_axis = 'UP_X'
-        constraint.owner_space = 'LOCAL'
-        bpy.context.collection.objects.link(ob)
-        ob.rotation_euler[2] = 3.14159
-        ob.data.energy = 0.2
-
-    if self.camera_constraint and self.camera is not None and \
-       self.camera.type == "CAMERA":
-
-        constraint = self.camera.constraints.new(type='TRACK_TO')
-        constraint.target = self.target
-        constraint.track_axis = 'TRACK_NEGATIVE_Z'
-        constraint.up_axis = 'UP_Y'
-
-
-class OBJECT_OT_add_light_template(Operator):
-    bl_idname = "object.add_light_template"
-    bl_label = "Add Light Template"
-    bl_description = ("Add Key, Fill and Back Lights to the Scene\n"
-                      "Needs an existing Active Object")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    camera = None
-    target = None
-
-    bKeyLight: BoolProperty(
-            name="Key Light",
-            description="Enable Key Light in the Scene",
-            default=True
-            )
-    bFillLight: BoolProperty(
-            name="Fill Light",
-            description="Enable Fill Light in the Scene",
-            default=True
-            )
-    bBackLight: BoolProperty(
-            name="Back Light",
-            description="Enable Back Light in the Scene",
-            default=True
-            )
-    camera_constraint: BoolProperty(
-            name="Camera Constraint",
-            description="Add a Constraint to the Camera Object",
-            default=False
-            )
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def execute(self, context):
-        try:
-            objects = context.selected_objects
-
-            if len(objects) == 2:
-                for ob in objects:
-                    if ob.type == 'CAMERA':
-                        self.camera = ob
-                    else:
-                        self.target = ob
-            elif len(objects) == 1:
-                if objects[0].type == 'CAMERA':
-                    self.camera = objects[0]
-                    bpy.ops.object.empty_add()
-                    self.target = context.active_object
-                else:
-                    self.camera = context.scene.camera
-                    self.target = context.active_object
-            elif len(objects) == 0:
-                bpy.ops.object.empty_add()
-                self.target = context.active_object
-                self.camera = context.scene.camera
-
-            add_lights(self, context)
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Some operations could not be performed (See Console for more info)")
-
-            print("\n[Add Advanced  Objects]\nOperator: "
-                  "object.add_light_template\nError: {}".format(e))
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(OBJECT_OT_add_light_template)
-
-
-def unregister():
-    bpy.utils.unregister_class(OBJECT_OT_add_light_template)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/add_mesh_aggregate.py b/add_advanced_objects_menu/add_mesh_aggregate.py
deleted file mode 100644
index 2665df139bb1a1b245775f9f0309c9f0d631c249..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/add_mesh_aggregate.py
+++ /dev/null
@@ -1,338 +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 #####
-
-# Simple aggregate of particles / meshes
-# Copy the selected objects on the active object
-# Based on the position of the cursor and a defined volume
-# Allows to control growth by using a Build modifier
-
-bl_info = {
-    "name": "Aggregate Mesh",
-    "author": "liero",
-    "version": (0, 0, 5),
-    "blender": (2, 70, 0),
-    "location": "View3D > Tool Shelf",
-    "description": "Adds geometry to a mesh like in DLA aggregators",
-    "category": "Object"}
-
-
-import bpy
-import bmesh
-from random import (
-        choice,
-        gauss,
-        seed,
-        )
-from mathutils import Matrix
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        IntProperty,
-        )
-from bpy.types import Operator
-
-
-def use_random_seed(self):
-    seed(self.rSeed)
-    return
-
-
-def rg(n):
-    return (round(gauss(0, n), 2))
-
-
-def remover(sel=False):
-    bpy.ops.object.editmode_toggle()
-    if sel:
-        bpy.ops.mesh.select_all(action='SELECT')
-    bpy.ops.mesh.remove_doubles(threshold=0.0001)
-    bpy.ops.object.mode_set()
-
-
-class OBJECT_OT_agregate_mesh(Operator):
-    bl_idname = "object.agregate_mesh"
-    bl_label = "Aggregate"
-    bl_description = ("Adds geometry to a mesh like in DLA aggregators\n"
-                      "Needs at least two selected Mesh objects")
-    bl_options = {'REGISTER', 'UNDO', 'PRESET'}
-
-    volX: FloatProperty(
-            name="Volume X",
-            min=0.1, max=25,
-            default=3,
-            description="The cloud around cursor"
-            )
-    volY: FloatProperty(
-            name="Volume Y",
-            min=0.1, max=25,
-            default=3,
-            description="The cloud around cursor"
-            )
-    volZ: FloatProperty(
-            name="Volume Z",
-            min=0.1, max=25,
-            default=3,
-            description="The cloud around cursor"
-            )
-    baseSca: FloatProperty(
-            name="Scale",
-            min=0.01, max=5,
-            default=.25,
-            description="Particle Scale"
-            )
-    varSca: FloatProperty(
-            name="Var",
-            min=0, max=1,
-            default=0,
-            description="Particle Scale Variation"
-            )
-    rotX: FloatProperty(
-            name="Rot Var X",
-            min=0, max=2,
-            default=0,
-            description="X Rotation Variation"
-            )
-    rotY: FloatProperty(
-            name="Rot Var Y",
-            min=0, max=2,
-            default=0,
-            description="Y Rotation Variation"
-            )
-    rotZ: FloatProperty(
-            name="Rot Var Z",
-            min=0, max=2,
-            default=1,
-            description="Z Rotation Variation"
-            )
-    rSeed: IntProperty(
-            name="Random seed",
-            min=0, max=999999,
-            default=1,
-            description="Seed to feed random values"
-            )
-    numP: IntProperty(
-            name="Number",
-            min=1,
-            max=9999, soft_max=500,
-            default=50,
-            description="Number of particles"
-            )
-    nor: BoolProperty(
-            name="Normal Oriented",
-            default=False,
-            description="Align Z axis with Faces normals"
-            )
-    cent: BoolProperty(
-            name="Use Face Center",
-            default=False,
-            description="Center on Faces"
-            )
-    track: BoolProperty(
-            name="Cursor Follows",
-            default=False,
-            description="Cursor moves as structure grows / more compact results"
-            )
-    anim: BoolProperty(
-            name="Animatable",
-            default=False,
-            description="Sort faces so you can regrow with Build Modifier, materials are lost"
-            )
-    refresh: BoolProperty(
-            name="Update",
-            default=False
-            )
-    auto_refresh: BoolProperty(
-            name="Auto",
-            description="Auto update spline",
-            default=False
-            )
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column(align=True)
-        row = col.row(align=True)
-
-        if self.auto_refresh is False:
-            self.refresh = False
-        elif self.auto_refresh is True:
-            self.refresh = True
-
-        row.prop(self, "auto_refresh", toggle=True, icon="AUTO")
-        row.prop(self, "refresh", toggle=True, icon="FILE_REFRESH")
-
-        col = layout.column(align=True)
-        col.separator()
-
-        col = layout.column(align=True)
-        col.prop(self, "volX", slider=True)
-        col.prop(self, "volY", slider=True)
-        col.prop(self, "volZ", slider=True)
-
-        layout.label(text="Particles:")
-        col = layout.column(align=True)
-        col.prop(self, "baseSca", slider=True)
-        col.prop(self, "varSca", 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 = layout.column(align=True)
-        col.prop(self, "rSeed", slider=False)
-        col.prop(self, "numP")
-
-        row = layout.row(align=True)
-        row.prop(self, "nor")
-        row.prop(self, "cent")
-
-        row = layout.row(align=True)
-        row.prop(self, "track")
-        row.prop(self, "anim")
-
-    @classmethod
-    def poll(cls, context):
-        return (len(bpy.context.selected_objects) > 1 and
-                bpy.context.object.type == 'MESH')
-
-    def invoke(self, context, event):
-        self.refresh = True
-        return self.execute(context)
-
-    def execute(self, context):
-        if not self.refresh:
-            return {'PASS_THROUGH'}
-
-        scn = bpy.context.scene
-        obj = bpy.context.active_object
-
-        use_random_seed(self)
-
-        mat = Matrix((
-                (1, 0, 0, 0),
-                (0, 1, 0, 0),
-                (0, 0, 1, 0),
-                (0, 0, 0, 1))
-                )
-        if obj.matrix_world != mat:
-            self.report({'WARNING'},
-                         "Please, Apply transformations to Active Object first")
-            return{'FINISHED'}
-
-        par = [o for o in bpy.context.selected_objects if o.type == 'MESH' and o != obj]
-        if not par:
-            return{'FINISHED'}
-
-        bpy.ops.object.mode_set()
-        bpy.ops.object.select_all(action='DESELECT')
-        obj.select_set(True)
-        msv = []
-
-        for i in range(len(obj.modifiers)):
-            msv.append(obj.modifiers[i].show_viewport)
-            obj.modifiers[i].show_viewport = False
-
-        cur = scn.cursor.location
-        for i in range(self.numP):
-
-            mes = choice(par).data
-            newobj = bpy.data.objects.new('nuevo', mes)
-            scn.objects.link(newobj)
-            origen = (rg(self.volX) + cur[0], rg(self.volY) + cur[1], rg(self.volZ) + cur[2])
-
-            cpom = obj.closest_point_on_mesh(origen)
-
-            if self.cent:
-                bm = bmesh.new()
-                bm.from_mesh(obj.data)
-                if hasattr(bm.verts, "ensure_lookup_table"):
-                    bm.verts.ensure_lookup_table()
-                    bm.faces.ensure_lookup_table()
-
-                newobj.location = bm.faces[cpom[3]].calc_center_median()
-
-                bm.free()
-            else:
-                newobj.location = cpom[1]
-
-            if self.nor:
-                newobj.rotation_mode = 'QUATERNION'
-                newobj.rotation_quaternion = cpom[1].to_track_quat('Z', 'Y')
-                newobj.rotation_mode = 'XYZ'
-                newobj.rotation_euler[0] += rg(self.rotX)
-                newobj.rotation_euler[1] += rg(self.rotY)
-                newobj.rotation_euler[2] += rg(self.rotZ)
-            else:
-                newobj.rotation_euler = (rg(self.rotX), rg(self.rotY), rg(self.rotZ))
-
-            newobj.scale = [self.baseSca + self.baseSca * rg(self.varSca)] * 3
-
-            if self.anim:
-                newobj.select_set(True)
-                bpy.ops.object.make_single_user(type='SELECTED_OBJECTS', obdata=True)
-                bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
-
-                bme = bmesh.new()
-                bme.from_mesh(obj.data)
-
-                tmp = bmesh.new()
-                tmp.from_mesh(newobj.data)
-
-                for f in tmp.faces:
-                    # z = len(bme.verts)
-                    for v in f.verts:
-                        bme.verts.new(list(v.co))
-                    bme.faces.new(bme.verts[-len(f.verts):])
-
-                bme.to_mesh(obj.data)
-                remover(True)
-                # Note: foo.user_clear() is deprecated use do_unlink=True instead
-                bpy.data.meshes.remove(newobj.data, do_unlink=True)
-
-            else:
-                scn.objects.active = obj
-                newobj.select_set(True)
-                bpy.ops.object.join()
-
-            if self.track:
-                cur = scn.cursor.location = cpom[1]
-
-        for i in range(len(msv)):
-            obj.modifiers[i].show_viewport = msv[i]
-
-        for o in par:
-            o.select_set(True)
-
-        obj.select_set(True)
-
-        if self.auto_refresh is False:
-            self.refresh = False
-
-        return{'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(OBJECT_OT_agregate_mesh)
-
-
-def unregister():
-    bpy.utils.unregister_class(OBJECT_OT_agregate_mesh)
-
-
-if __name__ == '__main__':
-    register()
diff --git a/add_advanced_objects_menu/arrange_on_curve.py b/add_advanced_objects_menu/arrange_on_curve.py
deleted file mode 100644
index 38fbb92af4901c67ee2adbd0303ecb254c4837cc..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/arrange_on_curve.py
+++ /dev/null
@@ -1,356 +0,0 @@
-# gpl author: Mano-Wii
-
-bl_info = {
-    "name": "Arrange on Curve",
-    "author": "Mano-Wii",
-    "version": (6, 3, 0),
-    "blender": (2, 77, 0),
-    "location": "3D View > Toolshelf > Create > Arrange on Curve",
-    "description": "Arrange objects along a curve",
-    "warning": "Select curve",
-    "wiki_url": "",
-    "category": "3D View"
-    }
-
-# Note: scene properties are moved into __init__
-# search for patterns advanced_objects and adv_obj
-
-import bpy
-import mathutils
-from bpy.types import (
-        Operator,
-        Panel,
-        )
-from bpy.props import (
-        EnumProperty,
-        FloatProperty,
-        IntProperty,
-        )
-
-FLT_MIN = 0.004
-
-
-class PanelDupliCurve(Panel):
-    bl_idname = "VIEW3D_PT_arranjar_numa_curva"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_context = "objectmode"
-    bl_category = "Create"
-    bl_label = "Arrange on Curve"
-    bl_options = {'DEFAULT_CLOSED'}
-
-    @classmethod
-    def poll(cls, context):
-        return context.object and context.mode == 'OBJECT' and context.object.type == 'CURVE'
-
-    def draw(self, context):
-        layout = self.layout
-        adv_obj = context.scene.advanced_objects
-
-        layout.prop(adv_obj, "arrange_c_use_selected")
-
-        if not adv_obj.arrange_c_use_selected:
-            layout.prop(adv_obj, "arrange_c_select_type", expand=True)
-            if adv_obj.arrange_c_select_type == 'O':
-                layout.column(align=True).prop_search(
-                              adv_obj, "arrange_c_obj_arranjar",
-                              bpy.data, "objects"
-                              )
-            elif adv_obj.arrange_c_select_type == 'G':
-                layout.column(align=True).prop_search(
-                              adv_obj, "arrange_c_obj_arranjar",
-                              bpy.data, "collections"
-                              )
-        if context.object.type == 'CURVE':
-            layout.operator("object.arranjar_numa_curva", text="Arrange Objects")
-
-
-class DupliCurve(Operator):
-    bl_idname = "object.arranjar_numa_curva"
-    bl_label = "Arrange Objects along a Curve"
-    bl_description = "Arange chosen / selected objects along the Active Curve"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    use_distance: EnumProperty(
-            name="Arrangement",
-            items=[
-                ("D", "Distance", "Objects are arranged depending on the distance", 0),
-                ("Q", "Quantity", "Objects are arranged depending on the quantity", 1),
-                ("R", "Range", "Objects are arranged uniformly between the corners", 2)
-                ]
-            )
-    distance: FloatProperty(
-            name="Distance",
-            description="Distance between Objects",
-            default=1.0,
-            min=FLT_MIN,
-            soft_min=0.1,
-            unit='LENGTH',
-            )
-    object_qt: IntProperty(
-            name="Quantity",
-            description="Object amount",
-            default=2,
-            min=0,
-            )
-    scale: FloatProperty(
-            name="Scale",
-            description="Object Scale",
-            default=1.0,
-            min=FLT_MIN,
-            unit='LENGTH',
-                )
-    Yaw: FloatProperty(
-            name="X",
-            description="Rotate around the X axis (Yaw)",
-            default=0.0,
-            unit='ROTATION'
-            )
-    Pitch: FloatProperty(
-            default=0.0,
-            description="Rotate around the Y axis (Pitch)",
-            name="Y",
-            unit='ROTATION'
-            )
-    Roll: FloatProperty(
-            default=0.0,
-            description="Rotate around the Z axis (Roll)",
-            name="Z",
-            unit='ROTATION'
-            )
-    max_angle: FloatProperty(
-            default=1.57079,
-            max=3.141592,
-            name="Angle",
-            unit='ROTATION'
-            )
-    offset: FloatProperty(
-            default=0.0,
-            name="Offset",
-            unit='LENGTH'
-            )
-
-    @classmethod
-    def poll(cls, context):
-        return context.mode == 'OBJECT'
-
-    def draw(self, context):
-        layout = self.layout
-        col = layout.column()
-        col.prop(self, "use_distance", text="")
-        col = layout.column(align=True)
-        if self.use_distance == "D":
-            col.prop(self, "distance")
-        elif self.use_distance == "Q":
-            col.prop(self, "object_qt")
-        else:
-            col.prop(self, "distance")
-            col.prop(self, "max_angle")
-            col.prop(self, "offset")
-
-        col = layout.column(align=True)
-        col.prop(self, "scale")
-        col.prop(self, "Yaw")
-        col.prop(self, "Pitch")
-        col.prop(self, "Roll")
-
-    def Glpoints(self, curve):
-        Gpoints = []
-        for i, spline in enumerate(curve.data.splines):
-            segments = len(spline.bezier_points)
-            if segments >= 2:
-                r = spline.resolution_u + 1
-
-                points = []
-                for j in range(segments):
-                    bp1 = spline.bezier_points[j]
-                    inext = (j + 1)
-                    if inext == segments:
-                        if not spline.use_cyclic_u:
-                            break
-                        inext = 0
-                    bp2 = spline.bezier_points[inext]
-                    if bp1.handle_right_type == bp2.handle_left_type == 'VECTOR':
-                        _points = (bp1.co, bp2.co) if j == 0 else (bp2.co,)
-                    else:
-                        knot1 = bp1.co
-                        handle1 = bp1.handle_right
-                        handle2 = bp2.handle_left
-                        knot2 = bp2.co
-                        _points = mathutils.geometry.interpolate_bezier(knot1, handle1, handle2, knot2, r)
-                    points.extend(_points)
-                Gpoints.append(tuple((curve.matrix_world * p for p in points)))
-            elif len(spline.points) >= 2:
-                l = [curve.matrix_world * p.co.xyz for p in spline.points]
-                if spline.use_cyclic_u:
-                    l.append(l[0])
-                Gpoints.append(tuple(l))
-
-            if self.use_distance == "R":
-                max_angle = self.max_angle
-                tmp_Gpoints = []
-                sp = Gpoints[i]
-                sp2 = [sp[0], sp[1]]
-                lp = sp[1]
-                v1 = lp - sp[0]
-                for p in sp[2:]:
-                    v2 = p - lp
-                    try:
-                        if (3.14158 - v1.angle(v2)) < max_angle:
-                            tmp_Gpoints.append(tuple(sp2))
-                            sp2 = [lp]
-                    except Exception as e:
-                        print("\n[Add Advanced  Objects]\nOperator: "
-                              "object.arranjar_numa_curva\nError: {}".format(e))
-                        pass
-                    sp2.append(p)
-                    v1 = v2
-                    lp = p
-                tmp_Gpoints.append(tuple(sp2))
-                Gpoints = Gpoints[:i] + tmp_Gpoints
-
-        lengths = []
-        if self.use_distance != "D":
-            for sp in Gpoints:
-                lp = sp[1]
-                leng = (lp - sp[0]).length
-                for p in sp[2:]:
-                    leng += (p - lp).length
-                    lp = p
-                lengths.append(leng)
-        return Gpoints, lengths
-
-    def execute(self, context):
-        if context.object.type != 'CURVE':
-            return {'CANCELLED'}
-
-        curve = context.active_object
-        Gpoints, lengs = self.Glpoints(curve)
-        adv_obj = context.scene.advanced_objects
-
-        if adv_obj.arrange_c_use_selected:
-            G_Objeto = context.selected_objects
-            G_Objeto.remove(curve)
-
-            if not G_Objeto:
-                return {'CANCELLED'}
-
-        elif adv_obj.arrange_c_select_type == 'O':
-            G_Objeto = bpy.data.objects[adv_obj.arrange_c_obj_arranjar],
-        elif adv_obj.arrange_c_select_type == 'G':
-            G_Objeto = bpy.data.collections[adv_obj.arrange_c_obj_arranjar].objects
-
-        yawMatrix = mathutils.Matrix.Rotation(self.Yaw, 4, 'X')
-        pitchMatrix = mathutils.Matrix.Rotation(self.Pitch, 4, 'Y')
-        rollMatrix = mathutils.Matrix.Rotation(self.Roll, 4, 'Z')
-
-        max_angle = self.max_angle  # max_angle is called in Glpoints
-
-        if self.use_distance == "D":
-            dist = self.distance
-            for sp_points in Gpoints:
-                dx = 0.0  # Length of initial calculation of section
-                last_point = sp_points[0]
-                j = 0
-                for point in sp_points[1:]:
-                    vetorx = point - last_point  # Vector spline section
-                    quat = mathutils.Vector.to_track_quat(vetorx, 'X', 'Z')  # Tracking the selected objects
-                    quat = quat.to_matrix().to_4x4()
-
-                    v_len = vetorx.length
-                    if v_len > 0.0:
-                        dx += v_len  # Defined length calculation equal total length of the spline section
-                        v_norm = vetorx / v_len
-                        while dx > dist:
-                            object = G_Objeto[j % len(G_Objeto)]
-                            j += 1
-                            dx -= dist  # Calculating the remaining length of the section
-                            obj = object.copy()
-                            context.collection.objects.link(obj)
-                            obj.matrix_world = quat * yawMatrix * pitchMatrix * rollMatrix
-                            # Placing in the correct position
-                            obj.matrix_world.translation = point - v_norm * dx
-                            obj.scale *= self.scale
-                        last_point = point
-
-        elif self.use_distance == "Q":
-            object_qt = self.object_qt + 1
-            for i, sp_points in enumerate(Gpoints):
-                dx = 0.0  # Length of initial calculation of section
-                dist = lengs[i] / object_qt
-                last_point = sp_points[0]
-                j = 0
-                for point in sp_points[1:]:
-                    vetorx = point - last_point  # Vector spline section
-                    # Tracking the selected objects
-                    quat = mathutils.Vector.to_track_quat(vetorx, 'X', 'Z')
-                    quat = quat.to_matrix().to_4x4()
-
-                    v_len = vetorx.length
-                    if v_len > 0.0:
-                        # Defined length calculation equal total length of the spline section
-                        dx += v_len
-                        v_norm = vetorx / v_len
-                        while dx > dist:
-                            object = G_Objeto[j % len(G_Objeto)]
-                            j += 1
-                            dx -= dist  # Calculating the remaining length of the section
-                            obj = object.copy()
-                            context.collection.objects.link(obj)
-                            obj.matrix_world = quat * yawMatrix * pitchMatrix * rollMatrix
-                            # Placing in the correct position
-                            obj.matrix_world.translation = point - v_norm * dx
-                            obj.scale *= self.scale
-                        last_point = point
-
-        else:
-            dist = self.distance
-            offset2 = 2 * self.offset
-            for i, sp_points in enumerate(Gpoints):
-                leng = lengs[i] - offset2
-                rest = leng % dist
-                offset = offset2 + rest
-                leng -= rest
-                offset /= 2
-                last_point = sp_points[0]
-
-                dx = dist - offset  # Length of initial calculation of section
-                j = 0
-                for point in sp_points[1:]:
-                    vetorx = point - last_point  # Vector spline section
-                    # Tracking the selected objects
-                    quat = mathutils.Vector.to_track_quat(vetorx, 'X', 'Z')
-                    quat = quat.to_matrix().to_4x4()
-
-                    v_len = vetorx.length
-                    if v_len > 0.0:
-                        dx += v_len
-                        v_norm = vetorx / v_len
-                        while dx >= dist and leng >= 0.0:
-                            leng -= dist
-                            dx -= dist  # Calculating the remaining length of the section
-                            object = G_Objeto[j % len(G_Objeto)]
-                            j += 1
-                            obj = object.copy()
-                            context.collection.objects.link(obj)
-                            obj.matrix_world = quat * yawMatrix * pitchMatrix * rollMatrix
-                            # Placing in the correct position
-                            obj.matrix_world.translation = point - v_norm * dx
-                            obj.scale *= self.scale
-                        last_point = point
-
-        return {"FINISHED"}
-
-
-def register():
-    bpy.utils.register_class(PanelDupliCurve)
-    bpy.utils.register_class(DupliCurve)
-
-
-def unregister():
-    bpy.utils.unregister_class(PanelDupliCurve)
-    bpy.utils.unregister_class(DupliCurve)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/circle_array.py b/add_advanced_objects_menu/circle_array.py
deleted file mode 100644
index 6d4a945939d8d650e1100544a497043065dbbb1c..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/circle_array.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# gpl author: Antonis Karvelas
-
-# -*- coding: utf-8 -*-
-
-bl_info = {
-    "name": "Circle Array",
-    "author": "Antonis Karvelas",
-    "version": (1, 0, 1),
-    "blender": (2, 67, 0),
-    "location": "View3D > Object > Circle_Array",
-    "description": "Uses an existing array and creates an empty, "
-                   "rotates it properly and makes a Circle Array",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Mesh"
-    }
-
-
-import bpy
-from bpy.types import Operator
-from math import radians
-
-
-class Circle_Array(Operator):
-    bl_label = "Circle Array"
-    bl_idname = "objects.circle_array_operator"
-    bl_description = ("Creates an Array Modifier with offset empty object\n"
-                      "Works with Mesh, Curve, Text and Surface\n"
-                      "Use an object with an existing Array modifier\n"
-                      "or rotate the newly created Empty with the name pattern\n"
-                      "EMPTY_C_Array_ if the Array doesn't exist (angle: 360/Count)")
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def check_empty_name(self, context):
-        new_name, def_name = "", "EMPTY_C_Array"
-        suffix = 1
-        try:
-            # first slap a simple linear count + 1 for numeric suffix, if it fails
-            # harvest for the rightmost numbers and append the max value
-            list_obj = []
-            obj_all = context.scene.objects
-            list_obj = [obj.name for obj in obj_all if obj.name.startswith(def_name)]
-            new_name = "{}_{}".format(def_name, len(list_obj) + 1)
-
-            if new_name in list_obj:
-                from re import findall
-                test_num = [findall("\d+", words) for words in list_obj]
-                suffix += max([int(l[-1]) for l in test_num])
-                new_name = "{}_{}".format(def_name, suffix)
-            return new_name
-        except:
-            return None
-
-    def execute(self, context):
-        is_allowed = True
-        try:
-            allowed_obj = ['MESH', 'CURVE', 'SURFACE', 'FONT']
-            for obj in context.selected_objects:
-                if obj.type not in allowed_obj:
-                    is_allowed = False
-                    break
-
-            if not is_allowed:
-                self.report(
-                    {"WARNING"},
-                    "The Active/Selected objects are not of "
-                    "Mesh, Curve, Surface or Font type. Operation Cancelled"
-                    )
-                return {'CANCELLED'}
-
-            default_name = self.check_empty_name(context) or "EMPTY_C_Array"
-            bpy.ops.object.modifier_add(type='ARRAY')
-
-            if len(context.selected_objects) == 2:
-                selected = context.selected_objects
-                lists = [obj for obj in selected if obj != context.active_object]
-                active = lists[0]
-                # check if the list object has a modifier
-                check_mod = None
-                for mod in active.modifiers[:]:
-                    if mod.type == "ARRAY":
-                        check_mod = mod
-                        break
-
-                if check_mod:
-                    check_mod.use_object_offset = True
-                    check_mod.use_relative_offset = False
-                else:
-                    # fallback
-                    bpy.context.view_layer.objects.active = active
-                    bpy.ops.object.modifier_add(type='ARRAY')
-                    active.modifiers[0].use_object_offset = True
-                    active.modifiers[0].use_relative_offset = False
-
-                active.modifiers[0].use_object_offset = True
-                active.modifiers[0].use_relative_offset = False
-                active.select_set(False)
-                bpy.context.view_layer.objects.active = context.active_object
-                bpy.ops.view3d.snap_cursor_to_selected()
-
-                if active.modifiers[0].offset_object is None:
-                    bpy.ops.object.add(type='EMPTY')
-                    empty_name = bpy.context.active_object
-                    empty_name.name = default_name
-                    active.modifiers[0].offset_object = empty_name
-                else:
-                    empty_name = active.modifiers[0].offset_object
-
-                bpy.context.view_layer.objects.active = active
-                num = active.modifiers["Array"].count
-                rotate_num = 360 / num
-                active.select_set(True)
-                bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
-                empty_name.rotation_euler = (0, 0, radians(rotate_num))
-                empty_name.select_set(False)
-                active.select_set(True)
-                bpy.ops.object.origin_set(type="ORIGIN_CURSOR")
-
-                return {'FINISHED'}
-            else:
-                active = context.active_object
-                active.modifiers[0].use_object_offset = True
-                active.modifiers[0].use_relative_offset = False
-                bpy.ops.view3d.snap_cursor_to_selected()
-
-                if active.modifiers[0].offset_object is None:
-                    bpy.ops.object.add(type='EMPTY')
-                    empty_name = bpy.context.active_object
-                    empty_name.name = default_name
-                    active.modifiers[0].offset_object = empty_name
-                else:
-                    empty_name = active.modifiers[0].offset_object
-
-                bpy.context.view_layer.objects.active = active
-                num = active.modifiers["Array"].count
-                rotate_num = 360 / num
-                active.select_set(True)
-                bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
-                empty_name.rotation_euler = (0, 0, radians(rotate_num))
-                empty_name.select_set(False)
-                active.select_set(True)
-
-                return {'FINISHED'}
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Circle Array operator could not be executed (See the console for more info)")
-            print("\n[objects.circle_array_operator]\nError: {}\n".format(e))
-
-            return {'CANCELLED'}
-
-
-# Register
-def register():
-    bpy.utils.register_class(Circle_Array)
-
-
-def unregister():
-    bpy.utils.unregister_class(Circle_Array)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/copy2.py b/add_advanced_objects_menu/copy2.py
deleted file mode 100644
index 5b1bceb1453f42887271f084e1b7ad9768ed2fa1..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/copy2.py
+++ /dev/null
@@ -1,339 +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/
-#  or write to the Free Software Foundation, Inc., 51 Franklin Street,
-#  Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-bl_info = {
-    "name": "Copy2 Vertices, Edges or Faces",
-    "author": "Eleanor Howick (elfnor.com)",
-    "version": (0, 1, 1),
-    "blender": (2, 71, 0),
-    "location": "3D View > Object > Copy 2",
-    "description": "Copy one object to the selected vertices, edges or faces of another object",
-    "warning": "",
-    "category": "Object"
-}
-
-import bpy
-from bpy.types import Operator
-from bpy.props import (
-        BoolProperty,
-        EnumProperty,
-        FloatProperty,
-        )
-from mathutils import (
-        Vector,
-        Matrix,
-        )
-
-
-class Copy2(Operator):
-    bl_idname = "mesh.copy2"
-    bl_label = "Copy 2"
-    bl_description = ("Copy Vertices, Edges or Faces to the Selected object\n"
-                      "Needs an existing Active Mesh Object")
-    bl_options = {"REGISTER", "UNDO"}
-
-    obj_list = None
-
-    def obj_list_cb(self, context):
-        return Copy2.obj_list
-
-    def sec_axes_list_cb(self, context):
-        if self.priaxes == 'X':
-            sec_list = [('Y', "Y", "Secondary axis Y"),
-                        ('Z', "Z", "Secondary axis Z")]
-
-        if self.priaxes == 'Y':
-            sec_list = [('X', "X", "Secondary axis X"),
-                        ('Z', "Z", "Secondary axis Z")]
-
-        if self.priaxes == 'Z':
-            sec_list = [('X', "X", "Secondary axis X"),
-                        ('Y', "Y", "Secondary axis Y")]
-        return sec_list
-
-    copytype: EnumProperty(
-            items=(('V', "Vertex",
-                    "Paste the Copied Geometry to Vertices of the Active Object", 'VERTEXSEL', 0),
-                   ('E', "Edge",
-                    "Paste the Copied Geometry to Edges of the Active Object", 'EDGESEL', 1),
-                   ('F', "Face",
-                    "Paste the Copied Geometry to Faces of the Active Object", 'FACESEL', 2)),
-            )
-    copyfromobject: EnumProperty(
-            name="Copy from",
-            description="Copy an Object from the list",
-            items=obj_list_cb
-            )
-    priaxes: EnumProperty(
-            description="Primary axes used for Copied Object orientation",
-            items=(('X', "X", "Along X"),
-                   ('Y', "Y", "Along Y"),
-                   ('Z', "Z", "Along Z")),
-            )
-    edgescale: BoolProperty(
-            name="Scale to fill edge",
-            default=False
-            )
-    secaxes: EnumProperty(
-            name="Secondary Axis",
-            description="Secondary axis used for Copied Object orientation",
-            items=sec_axes_list_cb
-            )
-    scale: FloatProperty(
-            name="Scale",
-            default=1.0,
-            min=0.0,
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return obj and obj.type == "MESH"
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.prop(self, "copyfromobject")
-        layout.label(text="to:")
-        layout.prop(self, "copytype", expand=True)
-        layout.label(text="Primary axis:")
-        layout.prop(self, "priaxes", expand=True)
-        layout.label(text="Secondary axis:")
-        layout.prop(self, "secaxes", expand=True)
-        if self.copytype == "E":
-            layout.prop(self, "edgescale")
-            if self.edgescale:
-                layout.prop(self, "scale")
-        return
-
-    def execute(self, context):
-        copytoobject = context.active_object.name
-        axes = self.priaxes + self.secaxes
-
-        # check if there is a problem with the strings related to some chars
-        copy_to_object = bpy.data.objects[copytoobject] if \
-                         copytoobject in bpy.data.objects else None
-
-        copy_from_object = bpy.data.objects[self.copyfromobject] if \
-                           self.copyfromobject in bpy.data.objects else None
-
-        if copy_to_object is None or copy_from_object is None:
-            self.report({"WARNING"},
-                        "There was a problem with retrieving Object data. Operation Cancelled")
-            return {"CANCELLED"}
-        try:
-            copy_to_from(
-                    context.collection,
-                    copy_to_object,
-                    copy_from_object,
-                    self.copytype,
-                    axes,
-                    self.edgescale,
-                    self.scale
-                    )
-        except Exception as e:
-            self.report({"WARNING"},
-                        "Copy2 could not be completed (Check the Console for more info)")
-            print("\n[Add Advanced Objects]\nOperator: mesh.copy2\n{}\n".format(e))
-
-            return {"CANCELLED"}
-
-        return {"FINISHED"}
-
-    def invoke(self, context, event):
-        Copy2.obj_list = [(obj.name, obj.name, obj.name) for obj in bpy.data.objects]
-
-        return {"FINISHED"}
-
-
-def copy_to_from(collection, to_obj, from_obj, copymode, axes, edgescale, scale):
-    if copymode == 'V':
-        vertex_copy(collection, to_obj, from_obj, axes)
-
-    if copymode == 'E':
-        # don't pass edgescalling to object types that cannot be scaled
-        if from_obj.type in ["CAMERA", "LIGHT", "EMPTY", "ARMATURE", "SPEAKER", "META"]:
-            edgescale = False
-        edge_copy(collection, to_obj, from_obj, axes, edgescale, scale)
-
-    if copymode == 'F':
-        face_copy(collection, to_obj, from_obj, axes)
-
-
-axes_dict = {'XY': (1, 2, 0),
-             'XZ': (2, 1, 0),
-             'YX': (0, 2, 1),
-             'YZ': (2, 0, 1),
-             'ZX': (0, 1, 2),
-             'ZY': (1, 0, 2)}
-
-
-def copyto(collection, source_obj, pos, xdir, zdir, axes, scale=None):
-    """
-    copy the source_obj to pos, so its primary axis points in zdir and its
-    secondary axis points in xdir
-    """
-    copy_obj = source_obj.copy()
-    collection.objects.link(copy_obj)
-
-    xdir = xdir.normalized()
-    zdir = zdir.normalized()
-    # rotation first
-    z_axis = zdir
-    x_axis = xdir
-    y_axis = z_axis.cross(x_axis)
-    # use axes_dict to assign the axis as chosen in panel
-    A, B, C = axes_dict[axes]
-    rot_mat = Matrix()
-    rot_mat[A].xyz = x_axis
-    rot_mat[B].xyz = y_axis
-    rot_mat[C].xyz = z_axis
-    rot_mat.transpose()
-
-    # rotate object
-    copy_obj.matrix_world = rot_mat
-
-    # move object into position
-    copy_obj.location = pos
-
-    # scale object
-    if scale is not None:
-        copy_obj.scale = scale
-
-    return copy_obj
-
-
-def vertex_copy(collection, obj, source_obj, axes):
-    # vertex select mode
-    sel_verts = []
-    copy_list = []
-
-    for v in obj.data.vertices:
-        if v.select is True:
-            sel_verts.append(v)
-
-    # make a set for each vertex. The set contains all the connected vertices
-    # use sets so the list is unique
-    vert_con = [set() for i in range(len(obj.data.vertices))]
-    for e in obj.data.edges:
-        vert_con[e.vertices[0]].add(e.vertices[1])
-        vert_con[e.vertices[1]].add(e.vertices[0])
-
-    for v in sel_verts:
-        pos = v.co * obj.matrix_world.transposed()
-        xco = obj.data.vertices[list(vert_con[v.index])[0]].co * obj.matrix_world.transposed()
-
-        zdir = (v.co + v.normal) * obj.matrix_world.transposed() - pos
-        zdir = zdir.normalized()
-
-        edir = pos - xco
-
-        # edir is nor perpendicular to z dir
-        # want xdir to be projection of edir onto plane through pos with direction zdir
-        xdir = edir - edir.dot(zdir) * zdir
-        xdir = -xdir.normalized()
-
-        copy = copyto(collection, source_obj, pos, xdir, zdir, axes)
-        copy_list.append(copy)
-
-    # select all copied objects
-    for copy in copy_list:
-        copy.select_set(True)
-    obj.select_set(False)
-
-
-def edge_copy(collection, obj, source_obj, axes, es, scale):
-    # edge select mode
-    sel_edges = []
-    copy_list = []
-
-    for e in obj.data.edges:
-        if e.select is True:
-            sel_edges.append(e)
-
-    for e in sel_edges:
-        # pos is average of two edge vertexs
-        v0 = obj.data.vertices[e.vertices[0]].co * obj.matrix_world.transposed()
-        v1 = obj.data.vertices[e.vertices[1]].co * obj.matrix_world.transposed()
-        pos = (v0 + v1) / 2
-        # xdir is along edge
-        xdir = v0 - v1
-        xlen = xdir.magnitude
-        xdir = xdir.normalized()
-        # project each edge vertex normal onto plane normal to xdir
-        vn0 = (obj.data.vertices[e.vertices[0]].co * obj.matrix_world.transposed() +
-               obj.data.vertices[e.vertices[0]].normal) - v0
-        vn1 = (obj.data.vertices[e.vertices[1]].co * obj.matrix_world.transposed() +
-               obj.data.vertices[e.vertices[1]].normal) - v1
-        vn0p = vn0 - vn0.dot(xdir) * xdir
-        vn1p = vn1 - vn1.dot(xdir) * xdir
-        # the mean of the two projected normals is the zdir
-        zdir = vn0p + vn1p
-        zdir = zdir.normalized()
-        escale = None
-        if es:
-            escale = Vector([1.0, 1.0, 1.0])
-            i = list('XYZ').index(axes[1])
-            escale[i] = scale * xlen / source_obj.dimensions[i]
-
-        copy = copyto(collection, source_obj, pos, xdir, zdir, axes, scale=escale)
-        copy_list.append(copy)
-
-    # select all copied objects
-    for copy in copy_list:
-        copy.select_set(True)
-    obj.select_set(False)
-
-
-def face_copy(collection, obj, source_obj, axes):
-    # face select mode
-    sel_faces = []
-    copy_list = []
-
-    for f in obj.data.polygons:
-        if f.select is True:
-            sel_faces.append(f)
-
-    for f in sel_faces:
-        fco = f.center * obj.matrix_world.transposed()
-        # get first vertex corner of transformed object
-        vco = obj.data.vertices[f.vertices[0]].co * obj.matrix_world.transposed()
-        # get face normal of transformed object
-        fn = (f.center + f.normal) * obj.matrix_world.transposed() - fco
-        fn = fn.normalized()
-
-        copy = copyto(collection, source_obj, fco, vco - fco, fn, axes)
-        copy_list.append(copy)
-
-    # select all copied objects
-    for copy in copy_list:
-        copy.select_set(True)
-    obj.select_set(False)
-
-
-def register():
-    bpy.utils.register_class(Copy2)
-
-
-def unregister():
-    bpy.utils.unregister_class(Copy2)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/cubester.py b/add_advanced_objects_menu/cubester.py
deleted file mode 100644
index 8925171aa071c49a411b7cab34ca78f68a3c722b..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/cubester.py
+++ /dev/null
@@ -1,957 +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 #####
-
-# Original Author = Jacob Morris
-# URL = blendingjacob.blogspot.com
-
-# Note: scene properties are moved into __init__ together with the 3 update functions
-#       for properties search for the name patterns adv_obj and advanced_objects
-
-bl_info = {
-    "name": "CubeSter",
-    "author": "Jacob Morris",
-    "version": (0, 7, 2),
-    "blender": (2, 78, 0),
-    "location": "View 3D > Toolbar > CubeSter",
-    "description": "Takes image, image sequence, or audio file and converts it "
-                   "into a height map based on pixel color and alpha values",
-    "category": "Add Mesh"
-}
-
-import bpy
-import bmesh
-from bpy.types import (
-    Operator,
-    Panel,
-)
-
-import timeit
-from random import uniform
-from math import radians
-from os import (
-    path,
-    listdir,
-)
-
-
-# create block at center position x, y with block width 2 * hx and 2 * hy and height of h
-def create_block(x, y, hw, h, verts: list, faces: list):
-    if bpy.context.scene.advanced_objects.cubester_block_style == "size":
-        z = 0.0
-    else:
-        z = h
-        h = 2 * hw
-
-    p = len(verts)
-    verts += [(x - hw, y - hw, z), (x + hw, y - hw, z), (x + hw, y + hw, z), (x - hw, y + hw, z)]
-    verts += [(x - hw, y - hw, z + h), (x + hw, y - hw, z + h),
-              (x + hw, y + hw, z + h), (x - hw, y + hw, z + h)]
-
-    faces += [(p, p + 1, p + 5, p + 4), (p + 1, p + 2, p + 6, p + 5),
-              (p + 2, p + 3, p + 7, p + 6), (p, p + 4, p + 7, p + 3),
-              (p + 4, p + 5, p + 6, p + 7), (p, p + 3, p + 2, p + 1)]
-
-
-# go through all frames in len(frames), adjusting values at frames[x][y]
-def create_f_curves(mesh, frames, frame_step_size, style):
-    # use data to animate mesh
-    action = bpy.data.actions.new("CubeSterAnimation")
-
-    mesh.animation_data_create()
-    mesh.animation_data.action = action
-
-    data_path = "vertices[%d].co"
-
-    vert_index = 4 if style == "blocks" else 0  # index of first vertex
-
-    # loop for every face height value
-    for frame_start_vert in range(len(frames[0])):
-        # only go once if plane, otherwise do all four vertices that are in top plane if blocks
-        end_point = frame_start_vert + 4 if style == "blocks" else frame_start_vert + 1
-
-        # loop through to get the four vertices that compose the face
-        for frame_vert in range(frame_start_vert, end_point):
-            # fcurves for x, y, z
-            fcurves = [action.fcurves.new(data_path % vert_index, i) for i in range(3)]
-            frame_counter = 0  # go through each frame and add position
-            temp_v = mesh.vertices[vert_index].co
-
-            # loop through frames
-            for frame in frames:
-                # new x, y, z positions
-                vals = [temp_v[0], temp_v[1], frame[frame_start_vert]]
-                for i in range(3):  # for each x, y, z set each corresponding fcurve
-                    fcurves[i].keyframe_points.insert(frame_counter, vals[i], {'FAST'})
-
-                frame_counter += frame_step_size  # skip frames for smoother animation
-
-            vert_index += 1
-
-        # only skip vertices if made of blocks
-        if style == "blocks":
-            vert_index += 4
-
-
-# create material with given name, apply to object
-def create_material(scene, ob, name):
-    mat = bpy.data.materials.new("CubeSter_" + name)
-    adv_obj = scene.advanced_objects
-    image = None
-
-    # image
-    if not adv_obj.cubester_use_image_color and adv_obj.cubester_color_image in bpy.data.images:
-        try:
-            image = bpy.data.images[adv_obj.cubester_color_image]
-        except:
-            pass
-    else:
-        try:
-            image = bpy.data.images[adv_obj.cubester_image]
-        except:
-            pass
-
-    if scene.render.engine == "CYCLES":
-        mat.use_nodes = True
-        nodes = mat.node_tree.nodes
-
-        att = nodes.new("ShaderNodeAttribute")
-        att.attribute_name = "Col"
-        att.location = (-200, 300)
-
-        att = nodes.new("ShaderNodeTexImage")
-        if image:
-            att.image = image
-
-        if adv_obj.cubester_load_type == "multiple":
-            att.image.source = "SEQUENCE"
-        att.location = (-200, 700)
-
-        att = nodes.new("ShaderNodeTexCoord")
-        att.location = (-450, 600)
-
-        if adv_obj.cubester_materials == "image":
-            mat.node_tree.links.new(
-                nodes["Image Texture"].outputs[0],
-                nodes["Diffuse BSDF"].inputs[0]
-            )
-            mat.node_tree.links.new(
-                nodes["Texture Coordinate"].outputs[2],
-                nodes["Image Texture"].inputs[0]
-            )
-        else:
-            mat.node_tree.links.new(
-                nodes["Attribute"].outputs[0],
-                nodes["Diffuse BSDF"].inputs[0]
-            )
-    else:
-        if adv_obj.cubester_materials == "image" or scene.render.engine != "BLENDER_RENDER":
-            tex = bpy.data.textures.new("CubeSter_" + name, "IMAGE")
-            if image:
-                tex.image = image
-            slot = mat.texture_slots.add()
-            slot.texture = tex
-        else:
-            mat.use_vertex_color_paint = True
-
-    ob.data.materials.append(mat)
-
-
-# generate mesh from audio
-def create_mesh_from_audio(self, context, verts, faces):
-    scene = context.scene
-    view_layer = context.view_layer
-    adv_obj = scene.advanced_objects
-    audio_filepath = adv_obj.cubester_audio_path
-    width = adv_obj.cubester_audio_width_blocks
-    length = adv_obj.cubester_audio_length_blocks
-
-    size_per_hundred = adv_obj.cubester_size_per_hundred_pixels
-    size = size_per_hundred / 100
-    # Note: used for compatibility with vertex colors changes
-    bl_version = bool(bpy.app.version >= (2, 79, 1))
-
-    # create all blocks
-    y = -(width / 2) * size + (size / 2)
-    for r in range(width):
-        x = -(length / 2) * size + (size / 2)
-        for c in range(length):
-            create_block(x, y, size / 2, 1, verts, faces)
-
-            x += size
-        y += size
-
-    # create object
-    mesh = bpy.data.meshes.new("cubed")
-    mesh.from_pydata(verts, [], faces)
-    ob = bpy.data.objects.new("cubed", mesh)
-    bpy.context.collection.objects.link(ob)
-    bpy.context.view_layer.objects.active = ob
-    ob.select_set(True)
-
-    # initial vertex colors
-    if adv_obj.cubester_materials == "image" and adv_obj.cubester_color_image != "":
-        picture = bpy.data.images[adv_obj.cubester_color_image]
-        pixels = list(picture.pixels)
-        vert_colors = []
-
-        skip_y = int(picture.size[1] / width)
-        skip_x = int(picture.size[0] / length)
-
-        for row in range(0, picture.size[1], skip_y + 1):
-            # go through each column, step by appropriate amount
-            for column in range(0, picture.size[0] * 4, 4 + skip_x * 4):
-                r, g, b, a = get_pixel_values(picture, pixels, row, column)
-                get_colors = (r, g, b, a) if bl_version else (r, g, b)
-                vert_colors += [get_colors for i in range(24)]
-
-        bpy.ops.mesh.vertex_color_add()
-
-        i = 0
-        vert_colors_size = len(vert_colors)
-        for c in ob.data.vertex_colors[0].data:
-            if i < vert_colors_size:
-                c.color = vert_colors[i]
-                i += 1
-
-        # image sequence handling
-        if adv_obj.cubester_load_type == "multiple":
-            images = find_sequence_images(self, bpy.context)
-
-            frames_vert_colors = []
-
-            max_images = adv_obj.cubester_max_images + 1 if \
-                        len(images[0]) > adv_obj.cubester_max_images else len(images[0])
-
-            # goes through and for each image for each block finds new height
-            for image_index in range(0, max_images, adv_obj.cubester_skip_images):
-                filepath = images[0][image_index]
-                name = images[1][image_index]
-                picture = fetch_image(self, name, filepath)
-                pixels = list(picture.pixels)
-
-                frame_colors = []
-
-                for row in range(0, picture.size[1], skip_y + 1):
-                    for column in range(0, picture.size[0] * 4, 4 + skip_x * 4):
-                        r, g, b, a = get_pixel_values(picture, pixels, row, column)
-                        get_colors = (r, g, b, a) if bl_version else (r, g, b)
-                        frame_colors += [get_colors for i in range(24)]
-
-                frames_vert_colors.append(frame_colors)
-
-            adv_obj.cubester_vertex_colors[ob.name] = \
-                                    {"type": "vertex", "frames": frames_vert_colors,
-                                    "frame_skip": adv_obj.cubester_frame_step,
-                                    "total_images": max_images}
-
-        # either add material or create
-        if ("CubeSter_" + "Vertex") in bpy.data.materials:
-            ob.data.materials.append(bpy.data.materials["CubeSter_" + "Vertex"])
-        else:
-            create_material(scene, ob, "Vertex")
-
-    # set keyframe for each object as initial point
-    frame = [1 for i in range(int(len(verts) / 8))]
-    frames = [frame]
-
-    area = bpy.context.area
-    old_type = area.type
-    area.type = "GRAPH_EDITOR"
-
-    scene.frame_current = 0
-
-    create_f_curves(mesh, frames, 1, "blocks")
-
-    # deselect all fcurves
-    fcurves = ob.data.animation_data.action.fcurves.data.fcurves
-    for i in fcurves:
-        i.select = False
-
-    max_images = adv_obj.cubester_audio_max_freq
-    min_freq = adv_obj.cubester_audio_min_freq
-    freq_frame = adv_obj.cubester_audio_offset_type
-
-    freq_step = (max_images - min_freq) / length
-    freq_sub_step = freq_step / width
-
-    frame_step = adv_obj.cubester_audio_frame_offset
-
-    # animate each block with a portion of the frequency
-    for c in range(length):
-        frame_off = 0
-        for r in range(width):
-            if freq_frame == "frame":
-                scene.frame_current = frame_off
-                l = c * freq_step
-                h = (c + 1) * freq_step
-                frame_off += frame_step
-            else:
-                l = c * freq_step + (r * freq_sub_step)
-                h = c * freq_step + ((r + 1) * freq_sub_step)
-
-            pos = c + (r * length)  # block number
-            index = pos * 4  # first index for vertex
-
-            # select curves
-            for i in range(index, index + 4):
-                curve = i * 3 + 2  # fcurve location
-                fcurves[curve].select = True
-            try:
-                bpy.ops.graph.sound_bake(filepath=bpy.path.abspath(audio_filepath), low=l, high=h)
-            except:
-                pass
-
-            # deselect curves
-            for i in range(index, index + 4):
-                curve = i * 3 + 2  # fcurve location
-                fcurves[curve].select = False
-
-    area.type = old_type
-
-    # UV unwrap
-    create_uv_map(bpy.context, width, length)
-
-    # if radial apply needed modifiers
-    if adv_obj.cubester_audio_block_layout == "radial":
-        # add bezier curve of correct width
-        bpy.ops.curve.primitive_bezier_circle_add()
-        curve = bpy.context.object
-        # slope determined off of collected data
-        curve_size = (0.319 * (width * (size * 100)) - 0.0169) / 100
-        curve.dimensions = (curve_size, curve_size, 0.0)
-        # correct for z height
-        curve.scale = (curve.scale[0], curve.scale[0], curve.scale[0])
-
-        ob.select_set(True)
-        curve.select_set(False)
-        view_layer.objects.active = ob
-
-        # data was collected and then multi-variable regression was done in Excel
-        # influence of width and length
-        width_infl, length_infl, intercept = -0.159125, 0.49996, 0.007637
-        x_offset = ((width * (size * 100) * width_infl) +
-                   (length * (size * 100) * length_infl) + intercept) / 100
-        ob.location = (ob.location[0] + x_offset, ob.location[1], ob.location[2])
-
-        ob.rotation_euler = (radians(-90), 0.0, 0.0)
-        bpy.ops.object.modifier_add(type="CURVE")
-        ob.modifiers["Curve"].object = curve
-        ob.modifiers["Curve"].deform_axis = "POS_Z"
-
-
-# generate mesh from image(s)
-def create_mesh_from_image(self, scene, verts, faces):
-    context = bpy.context
-    adv_obj = scene.advanced_objects
-    picture = bpy.data.images[adv_obj.cubester_image]
-    pixels = list(picture.pixels)
-    # Note: used for compatibility with vertex colors changes
-    bl_version = bool(bpy.app.version >= (2, 79, 1))
-
-    x_pixels = picture.size[0] / (adv_obj.cubester_skip_pixels + 1)
-    y_pixels = picture.size[1] / (adv_obj.cubester_skip_pixels + 1)
-
-    width = x_pixels / 100 * adv_obj.cubester_size_per_hundred_pixels
-    height = y_pixels / 100 * adv_obj.cubester_size_per_hundred_pixels
-
-    step = width / x_pixels
-    half_width = step / 2
-
-    y = -height / 2 + half_width
-
-    vert_colors = []
-    rows = 0
-
-    # go through each row of pixels stepping by adv_obj.cubester_skip_pixels + 1
-    for row in range(0, picture.size[1], adv_obj.cubester_skip_pixels + 1):
-        rows += 1
-        x = -width / 2 + half_width  # reset to left edge of mesh
-        # go through each column, step by appropriate amount
-        for column in range(0, picture.size[0] * 4, 4 + adv_obj.cubester_skip_pixels * 4):
-            r, g, b, a = get_pixel_values(picture, pixels, row, column)
-            get_colors = (r, g, b, a) if bl_version else (r, g, b)
-            h = find_point_height(r, g, b, a, scene)
-
-            # if not transparent
-            if h != -1:
-                if adv_obj.cubester_mesh_style == "blocks":
-                    create_block(x, y, half_width, h, verts, faces)
-                    vert_colors += [get_colors for i in range(24)]
-                else:
-                    verts += [(x, y, h)]
-                    vert_colors += [get_colors for i in range(4)]
-
-            x += step
-        y += step
-
-        # if plane not blocks, then remove last 4 items from vertex_colors
-        # as the faces have already wrapped around
-        if adv_obj.cubester_mesh_style == "plane":
-            del vert_colors[len(vert_colors) - 4:len(vert_colors)]
-
-    # create faces if plane based and not block based
-    if adv_obj.cubester_mesh_style == "plane":
-        off = int(len(verts) / rows)
-        for r in range(rows - 1):
-            for c in range(off - 1):
-                faces += [(r * off + c, r * off + c + 1, (r + 1) * off + c + 1, (r + 1) * off + c)]
-
-    mesh = bpy.data.meshes.new("cubed")
-    mesh.from_pydata(verts, [], faces)
-    ob = bpy.data.objects.new("cubed", mesh)
-    context.collection.objects.link(ob)
-    context.view_layer.objects.active = ob
-    ob.select_set(True)
-
-    # uv unwrap
-    if adv_obj.cubester_mesh_style == "blocks":
-        create_uv_map(context, rows, int(len(faces) / 6 / rows))
-    else:
-        create_uv_map(context, rows - 1, int(len(faces) / (rows - 1)))
-
-    # material
-    # determine name and if already created
-    if adv_obj.cubester_materials == "vertex":  # vertex color
-        image_name = "Vertex"
-    elif not adv_obj.cubester_use_image_color and \
-       adv_obj.cubester_color_image in bpy.data.images and \
-       adv_obj.cubester_materials == "image":  # replaced image
-        image_name = adv_obj.cubester_color_image
-    else:  # normal image
-        image_name = adv_obj.cubester_image
-
-    # either add material or create
-    if ("CubeSter_" + image_name) in bpy.data.materials:
-        ob.data.materials.append(bpy.data.materials["CubeSter_" + image_name])
-
-    # create material
-    else:
-        create_material(scene, ob, image_name)
-
-    # vertex colors
-    bpy.ops.mesh.vertex_color_add()
-    i = 0
-    for c in ob.data.vertex_colors[0].data:
-        c.color = vert_colors[i]
-        i += 1
-
-    frames = []
-    # image sequence handling
-    if adv_obj.cubester_load_type == "multiple":
-        images = find_sequence_images(self, context)
-        frames_vert_colors = []
-
-        max_images = adv_obj.cubester_max_images + 1 if \
-                    len(images[0]) > adv_obj.cubester_max_images else len(images[0])
-
-        # goes through and for each image for each block finds new height
-        for image_index in range(0, max_images, adv_obj.cubester_skip_images):
-            filepath = images[0][image_index]
-            name = images[1][image_index]
-            picture = fetch_image(self, name, filepath)
-            pixels = list(picture.pixels)
-
-            frame_heights = []
-            frame_colors = []
-
-            for row in range(0, picture.size[1], adv_obj.cubester_skip_pixels + 1):
-                for column in range(0, picture.size[0] * 4, 4 + adv_obj.cubester_skip_pixels * 4):
-                    r, g, b, a = get_pixel_values(picture, pixels, row, column)
-                    get_colors = (r, g, b, a) if bl_version else (r, g, b)
-                    h = find_point_height(r, g, b, a, scene)
-
-                    if h != -1:
-                        frame_heights.append(h)
-                        if adv_obj.cubester_mesh_style == "blocks":
-                            frame_colors += [get_colors for i in range(24)]
-                        else:
-                            frame_colors += [get_colors for i in range(4)]
-
-            if adv_obj.cubester_mesh_style == "plane":
-                del vert_colors[len(vert_colors) - 4:len(vert_colors)]
-
-            frames.append(frame_heights)
-            frames_vert_colors.append(frame_colors)
-
-        # determine what data to use
-        if adv_obj.cubester_materials == "vertex" or scene.render.engine == "BLENDER_ENGINE":
-            adv_obj.cubester_vertex_colors[ob.name] = {
-                "type": "vertex", "frames": frames_vert_colors,
-                "frame_skip": adv_obj.cubester_frame_step,
-                "total_images": max_images
-            }
-        else:
-            adv_obj.cubester_vertex_colors[ob.name] = {
-                "type": "image", "frame_skip": adv_obj.cubester_frame_step,
-                "total_images": max_images
-            }
-            att = get_image_node(ob.data.materials[0])
-            att.image_user.frame_duration = len(frames) * adv_obj.cubester_frame_step
-
-        # animate mesh
-        create_f_curves(
-            mesh, frames,
-            adv_obj.cubester_frame_step,
-            adv_obj.cubester_mesh_style
-        )
-
-
-# generate uv map for object
-def create_uv_map(context, rows, columns):
-    adv_obj = context.scene.advanced_objects
-    mesh = context.object.data
-    mesh.uv_textures.new("cubester")
-    bm = bmesh.new()
-    bm.from_mesh(mesh)
-
-    uv_layer = bm.loops.layers.uv[0]
-    bm.faces.ensure_lookup_table()
-
-    x_scale = 1 / columns
-    y_scale = 1 / rows
-
-    y_pos = 0.0
-    x_pos = 0.0
-    count = columns - 1  # hold current count to compare to if need to go to next row
-
-    # if blocks
-    if adv_obj.cubester_mesh_style == "blocks":
-        for fa in range(int(len(bm.faces) / 6)):
-            for i in range(6):
-                pos = (fa * 6) + i
-                bm.faces[pos].loops[0][uv_layer].uv = (x_pos, y_pos)
-                bm.faces[pos].loops[1][uv_layer].uv = (x_pos + x_scale, y_pos)
-                bm.faces[pos].loops[2][uv_layer].uv = (x_pos + x_scale, y_pos + y_scale)
-                bm.faces[pos].loops[3][uv_layer].uv = (x_pos, y_pos + y_scale)
-
-            x_pos += x_scale
-
-            if fa >= count:
-                y_pos += y_scale
-                x_pos = 0.0
-                count += columns
-
-    # if planes
-    else:
-        for fa in range(len(bm.faces)):
-            bm.faces[fa].loops[0][uv_layer].uv = (x_pos, y_pos)
-            bm.faces[fa].loops[1][uv_layer].uv = (x_pos + x_scale, y_pos)
-            bm.faces[fa].loops[2][uv_layer].uv = (x_pos + x_scale, y_pos + y_scale)
-            bm.faces[fa].loops[3][uv_layer].uv = (x_pos, y_pos + y_scale)
-
-            x_pos += x_scale
-
-            if fa >= count:
-                y_pos += y_scale
-                x_pos = 0.0
-                count += columns
-
-    bm.to_mesh(mesh)
-
-
-# if already loaded return image, else load and return
-def fetch_image(self, name, load_path):
-    if name in bpy.data.images:
-        return bpy.data.images[name]
-    else:
-        try:
-            image = bpy.data.images.load(load_path)
-            return image
-        except RuntimeError:
-            self.report({"ERROR"}, "CubeSter: '{}' could not be loaded".format(load_path))
-            return None
-
-
-# find height for point
-def find_point_height(r, g, b, a, scene):
-    adv_obj = scene.advanced_objects
-    if a:  # if not completely transparent
-        normalize = 1
-
-        # channel weighting
-        if not adv_obj.cubester_advanced:
-            composed = 0.25 * r + 0.25 * g + 0.25 * b + 0.25 * a
-        else:
-            # user defined weighting
-            if not adv_obj.cubester_random_weights:
-                composed = adv_obj.cubester_weight_r * r + adv_obj.cubester_weight_g * g + \
-                        adv_obj.cubester_weight_b * b + adv_obj.cubester_weight_a * a
-                total = adv_obj.cubester_weight_r + adv_obj.cubester_weight_g + adv_obj.cubester_weight_b + \
-                        adv_obj.cubester_weight_a
-
-                normalize = 1 / total
-            # random weighting
-            else:
-                weights = [uniform(0.0, 1.0) for i in range(4)]
-                composed = weights[0] * r + weights[1] * g + weights[2] * b + weights[3] * a
-                total = weights[0] + weights[1] + weights[2] + weights[3]
-                normalize = 1 / total
-
-        if adv_obj.cubester_invert:
-            h = (1 - composed) * adv_obj.cubester_height_scale * normalize
-        else:
-            h = composed * adv_obj.cubester_height_scale * normalize
-
-        return h
-    else:
-        return -1
-
-
-# find all images that would belong to sequence
-def find_sequence_images(self, context):
-    scene = context.scene
-    images = [[], []]
-
-    if scene.advanced_objects.cubester_image in bpy.data.images:
-        image = bpy.data.images[scene.advanced_objects.cubester_image]
-        main = image.name.split(".")[0]
-
-        # first part of name to check against other files
-        length = len(main)
-        keep_going = True
-        for i in range(length - 1, -1, -1):
-            if main[i].isdigit() and keep_going:
-                length -= 1
-            else:
-                keep_going = not keep_going
-        name = main[0:length]
-
-        dir_name = path.dirname(bpy.path.abspath(image.filepath))
-
-        try:
-            for file in listdir(dir_name):
-                if path.isfile(path.join(dir_name, file)) and file.startswith(name):
-                    images[0].append(path.join(dir_name, file))
-                    images[1].append(file)
-        except FileNotFoundError:
-            self.report({"ERROR"}, "CubeSter: '{}' directory not found".format(dir_name))
-
-    return images
-
-
-# get image node
-def get_image_node(mat):
-    nodes = mat.node_tree.nodes
-    att = nodes["Image Texture"]
-
-    return att
-
-
-# get the RGBA values from pixel
-def get_pixel_values(picture, pixels, row, column):
-    # determine i position to start at based on row and column position
-    i = (row * picture.size[0] * 4) + column
-    pixs = pixels[i: i + 4]
-    r = pixs[0]
-    g = pixs[1]
-    b = pixs[2]
-    a = pixs[3]
-
-    return r, g, b, a
-
-
-# frame change handler for materials
-def material_frame_handler(scene):
-    frame = scene.frame_current
-    adv_obj = scene.advanced_objects
-
-    keys = list(adv_obj.cubester_vertex_colors.keys())
-
-    # get keys and see if object is still in scene
-    for i in keys:
-        # if object is in scene then update information
-        if i in bpy.data.objects:
-            ob = bpy.data.objects[i]
-            data = adv_obj.advanced_objects.cubester_vertex_colors[ob.name]
-            skip_frames = data["frame_skip"]
-
-            # update materials using vertex colors
-            if data['type'] == "vertex":
-                colors = data["frames"]
-
-                if frame % skip_frames == 0 and 0 <= frame < (data['total_images'] - 1) * skip_frames:
-                    use_frame = int(frame / skip_frames)
-                    color = colors[use_frame]
-
-                    i = 0
-                    for c in ob.data.vertex_colors[0].data:
-                        c.color = color[i]
-                        i += 1
-
-            else:
-                att = get_image_node(ob.data.materials[0])
-                offset = frame - int(frame / skip_frames)
-                att.image_user.frame_offset = -offset
-
-        # if the object is no longer in the scene then delete then entry
-        else:
-            del adv_obj.advanced_objects.cubester_vertex_colors[i]
-
-
-class CubeSterPanel(Panel):
-    bl_idname = "OBJECT_PT_cubester"
-    bl_label = "CubeSter"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_category = "Create"
-    bl_options = {"DEFAULT_CLOSED"}
-    bl_context = "objectmode"
-
-    def draw(self, context):
-        layout = self.layout.box()
-        scene = bpy.context.scene
-        adv_obj = scene.advanced_objects
-        images_found = 0
-        rows = 0
-        columns = 0
-
-        layout.prop(adv_obj, "cubester_audio_image")
-
-        if adv_obj.cubester_audio_image == "image":
-            box = layout.box()
-            box.prop(adv_obj, "cubester_load_type")
-            box.label(text="Image To Convert:")
-            box.prop_search(adv_obj, "cubester_image", bpy.data, "images")
-            box.prop(adv_obj, "cubester_load_image")
-
-            # find number of appropriate images if sequence
-            if adv_obj.cubester_load_type == "multiple":
-                box = layout.box()
-                # display number of images found there
-                images = find_sequence_images(self, context)
-                images_found = len(images[0]) if len(images[0]) <= adv_obj.cubester_max_images \
-                               else adv_obj.cubester_max_images
-
-                if len(images[0]):
-                    box.label(str(len(images[0])) + " Images Found", icon="PACKAGE")
-
-                box.prop(adv_obj, "cubester_max_images")
-                box.prop(adv_obj, "cubester_skip_images")
-                box.prop(adv_obj, "cubester_frame_step")
-
-            box = layout.box()
-            col = box.column(align=True)
-            col.prop(adv_obj, "cubester_skip_pixels")
-            col.prop(adv_obj, "cubester_size_per_hundred_pixels")
-            col.prop(adv_obj, "cubester_height_scale")
-            box.prop(adv_obj, "cubester_invert", icon="FILE_REFRESH")
-
-            box = layout.box()
-            box.prop(adv_obj, "cubester_mesh_style", icon="MESH_GRID")
-
-            if adv_obj.cubester_mesh_style == "blocks":
-                box.prop(adv_obj, "cubester_block_style")
-        else:
-            # audio file
-            layout.prop(adv_obj, "cubester_audio_path")
-
-            box = layout.box()
-            col = box.column(align=True)
-            col.prop(adv_obj, "cubester_audio_min_freq")
-            col.prop(adv_obj, "cubester_audio_max_freq")
-
-            box.separator()
-            box.prop(adv_obj, "cubester_audio_offset_type")
-
-            if adv_obj.cubester_audio_offset_type == "frame":
-                box.prop(adv_obj, "cubester_audio_frame_offset")
-            box.prop(adv_obj, "cubester_audio_block_layout")
-            box.separator()
-
-            col = box.column(align=True)
-            col.prop(adv_obj, "cubester_audio_width_blocks")
-            col.prop(adv_obj, "cubester_audio_length_blocks")
-
-            rows = adv_obj.cubester_audio_width_blocks
-            columns = adv_obj.cubester_audio_length_blocks
-
-            col.prop(adv_obj, "cubester_size_per_hundred_pixels")
-
-        # materials
-        box = layout.box()
-        box.prop(adv_obj, "cubester_materials", icon="MATERIAL")
-
-        if adv_obj.cubester_materials == "image":
-            box.prop(adv_obj, "cubester_load_type")
-
-            # find number of appropriate images if sequence
-            if adv_obj.cubester_load_type == "multiple":
-                # display number of images found there
-                images = find_sequence_images(self, context)
-                images_found = len(images[0]) if len(images[0]) <= adv_obj.cubester_max_images \
-                    else adv_obj.cubester_max_images
-
-                if len(images[0]):
-                    box.label(str(len(images[0])) + " Images Found", icon="PACKAGE")
-                box.prop(adv_obj, "cubester_max_images")
-                box.prop(adv_obj, "cubester_skip_images")
-                box.prop(adv_obj, "cubester_frame_step")
-
-            box.separator()
-
-            if adv_obj.cubester_audio_image == "image":
-                box.prop(adv_obj, "cubester_use_image_color", icon="COLOR")
-
-            if not adv_obj.cubester_use_image_color or adv_obj.cubester_audio_image == "audio":
-                box.label(text="Image To Use For Colors:")
-                box.prop_search(adv_obj, "cubester_color_image", bpy.data, "images")
-                box.prop(adv_obj, "cubester_load_color_image")
-
-            if adv_obj.cubester_image in bpy.data.images:
-                rows = int(bpy.data.images[adv_obj.cubester_image].size[1] /
-                          (adv_obj.cubester_skip_pixels + 1))
-                columns = int(bpy.data.images[adv_obj.cubester_image].size[0] /
-                             (adv_obj.cubester_skip_pixels + 1))
-
-        box = layout.box()
-
-        if adv_obj.cubester_mesh_style == "blocks":
-            box.label(text="Approximate Cube Count: " + str(rows * columns))
-            box.label(text="Expected Verts/Faces: " + str(rows * columns * 8) + " / " + str(rows * columns * 6))
-        else:
-            box.label(text="Approximate Point Count: " + str(rows * columns))
-            box.label(text="Expected Verts/Faces: " + str(rows * columns) + " / " + str(rows * (columns - 1)))
-
-        # blocks and plane generation time values
-        if adv_obj.cubester_mesh_style == "blocks":
-            slope = 0.0000876958
-            intercept = 0.02501
-            block_infl, frame_infl, intercept2 = 0.0025934, 0.38507, -0.5840189
-        else:
-            slope = 0.000017753
-            intercept = 0.04201
-            block_infl, frame_infl, intercept2 = 0.000619, 0.344636, -0.272759
-
-        # if creating image based mesh
-        points = rows * columns
-        if adv_obj.cubester_audio_image == "image":
-            if adv_obj.cubester_load_type == "single":
-                time = rows * columns * slope + intercept  # approximate time count for mesh
-            else:
-                time = (points * slope) + intercept + (points * block_infl) + \
-                       (images_found / adv_obj.cubester_skip_images * frame_infl) + intercept2
-
-                box.label(text="Images To Be Used: " + str(int(images_found / adv_obj.cubester_skip_images)))
-        else:
-            # audio based mesh
-            box.label(text="Audio Track Length: " + str(adv_obj.cubester_audio_file_length) + " frames")
-
-            block_infl, frame_infl, intercept = 0.0948, 0.0687566, -25.85985
-            time = (points * block_infl) + (adv_obj.cubester_audio_file_length * frame_infl) + intercept
-            if time < 0.0:  # usually no audio loaded
-                time = 0.0
-
-        time_mod = "s"
-        if time > 60:  # convert to minutes if needed
-            time /= 60
-            time_mod = "min"
-        time = round(time, 3)
-
-        box.label(text="Expected Time: " + str(time) + " " + time_mod)
-
-        # advanced
-        if adv_obj.cubester_audio_image == "image":
-            icon_1 = "TRIA_DOWN" if adv_obj.cubester_advanced else "TRIA_RIGHT"
-            # layout.separator()
-            box = layout.box()
-            box.prop(adv_obj, "cubester_advanced", icon=icon_1)
-
-            if adv_obj.cubester_advanced:
-                box.prop(adv_obj, "cubester_random_weights", icon="RNDCURVE")
-
-                if not adv_obj.cubester_random_weights:
-                    box.label(text="RGBA Channel Weights", icon="COLOR")
-                    col = box.column(align=True)
-                    col.prop(adv_obj, "cubester_weight_r")
-                    col.prop(adv_obj, "cubester_weight_g")
-                    col.prop(adv_obj, "cubester_weight_b")
-                    col.prop(adv_obj, "cubester_weight_a")
-
-        # generate mesh
-        layout.operator("mesh.cubester", icon="OBJECT_DATA")
-
-
-class CubeSter(Operator):
-    bl_idname = "mesh.cubester"
-    bl_label = "Generate CubeSter Mesh"
-    bl_description = "Generate a mesh from an Image or Sound File"
-    bl_options = {"REGISTER", "UNDO"}
-
-    def execute(self, context):
-
-        verts, faces = [], []
-
-        start = timeit.default_timer()
-        scene = bpy.context.scene
-        adv_obj = scene.advanced_objects
-
-        if adv_obj.cubester_audio_image == "image":
-            if adv_obj.cubester_image != "":
-                create_mesh_from_image(self, scene, verts, faces)
-                frames = find_sequence_images(self, context)
-                created = len(frames[0])
-            else:
-                self.report({'WARNING'},
-                            "Please add an Image for Object generation. Operation Cancelled")
-                return {"CANCELLED"}
-        else:
-            if (adv_obj.cubester_audio_path != "" and
-                    path.isfile(adv_obj.cubester_audio_path) and
-                    adv_obj.cubester_check_audio is True):
-
-                create_mesh_from_audio(self, context, verts, faces)
-                created = adv_obj.cubester_audio_file_length
-            else:
-                self.report({'WARNING'},
-                            "Please add an Sound File for Object generation. Operation Cancelled")
-                return {"CANCELLED"}
-
-        stop = timeit.default_timer()
-
-        if adv_obj.cubester_mesh_style == "blocks" or adv_obj.cubester_audio_image == "audio":
-            self.report(
-                {"INFO"},
-                "CubeSter: {} blocks and {} frame(s) "
-                "in {}s".format(str(int(len(verts) / 8)),
-                                str(created),
-                                str(round(stop - start, 4)))
-            )
-        else:
-            self.report(
-                {"INFO"},
-                "CubeSter: {} points and {} frame(s) "
-                "in {}s" .format(str(len(verts)),
-                                 str(created),
-                                 str(round(stop - start, 4)))
-            )
-
-        return {"FINISHED"}
-
-
-def register():
-    bpy.utils.register_module(__name__)
-    bpy.app.handlers.frame_change_pre.append(material_frame_handler)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-    bpy.app.handlers.frame_change_pre.remove(material_frame_handler)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/make_struts.py b/add_advanced_objects_menu/make_struts.py
deleted file mode 100644
index 547fb2f558cbd5d38359e3c913b893df43f49e81..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/make_struts.py
+++ /dev/null
@@ -1,592 +0,0 @@
-#  Copyright (C) 2012 Bill Currie <bill@taniwha.org>
-#  Date: 2012/2/20
-
-# ##### 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>
-
-import bpy
-import bmesh
-from bpy.types import Operator
-from bpy.props import (
-        FloatProperty,
-        IntProperty,
-        BoolProperty,
-        )
-from mathutils import (
-        Vector,
-        Matrix,
-        Quaternion,
-        )
-from math import (
-        pi, cos,
-        sin,
-        )
-
-cossin = []
-
-# Initialize the cossin table based on the number of segments.
-#
-#   @param n  The number of segments into which the circle will be
-#             divided.
-#   @return   None
-
-
-def build_cossin(n):
-    global cossin
-    cossin = []
-    for i in range(n):
-        a = 2 * pi * i / n
-        cossin.append((cos(a), sin(a)))
-
-
-def select_up(axis):
-    # if axis.length != 0 and (abs(axis[0] / axis.length) < 1e-5 and abs(axis[1] / axis.length) < 1e-5):
-    if (abs(axis[0] / axis.length) < 1e-5 and abs(axis[1] / axis.length) < 1e-5):
-        up = Vector((-1, 0, 0))
-    else:
-        up = Vector((0, 0, 1))
-    return up
-
-# Make a single strut in non-manifold mode.
-#
-#   The strut will be a "cylinder" with @a n sides. The vertices of the
-#   cylinder will be @a od / 2 from the center of the cylinder. Optionally,
-#   extra loops will be placed (@a od - @a id) / 2 from either end. The
-#   strut will be either a simple, open-ended single-surface "cylinder", or a
-#   double walled "pipe" with the outer wall vertices @a od / 2 from the center
-#   and the inner wall vertices @a id / 2 from the center. The two walls will
-#   be joined together at the ends with a face ring such that the entire strut
-#   is a manifold object. All faces of the strut will be quads.
-#
-#   @param v1       Vertex representing one end of the strut's center-line.
-#   @param v2       Vertex representing the other end of the strut's
-#                   center-line.
-#   @param id       The diameter of the inner wall of a solid strut. Used for
-#                   calculating the position of the extra loops irrespective
-#                   of the solidity of the strut.
-#   @param od       The diameter of the outer wall of a solid strut, or the
-#                   diameter of a non-solid strut.
-#   @param solid    If true, the strut will be made solid such that it has an
-#                   inner wall (diameter @a id), an outer wall (diameter
-#                   @a od), and face rings at either end of the strut such
-#                   the strut is a manifold object. If false, the strut is
-#                   a simple, open-ended "cylinder".
-#   @param loops    If true, edge loops will be placed at either end of the
-#                   strut, (@a od - @a id) / 2 from the end of the strut. The
-#                   loops make subsurfed solid struts work nicely.
-#   @return         A tuple containing a list of vertices and a list of faces.
-#                   The face vertex indices are accurate only for the list of
-#                   vertices for the created strut.
-
-
-def make_strut(v1, v2, ind, od, n, solid, loops):
-    v1 = Vector(v1)
-    v2 = Vector(v2)
-    axis = v2 - v1
-    pos = [(0, od / 2)]
-    if loops:
-        pos += [((od - ind) / 2, od / 2),
-                (axis.length - (od - ind) / 2, od / 2)]
-    pos += [(axis.length, od / 2)]
-    if solid:
-        pos += [(axis.length, ind / 2)]
-        if loops:
-            pos += [(axis.length - (od - ind) / 2, ind / 2),
-                    ((od - ind) / 2, ind / 2)]
-        pos += [(0, ind / 2)]
-    vps = len(pos)
-    fps = vps
-    if not solid:
-        fps -= 1
-    fw = axis.copy()
-    fw.normalize()
-    up = select_up(axis)
-    lf = up.cross(fw)
-    lf.normalize()
-    up = fw.cross(lf)
-    mat = Matrix((fw, lf, up))
-    mat.transpose()
-    verts = [None] * n * vps
-    faces = [None] * n * fps
-    for i in range(n):
-        base = (i - 1) * vps
-        x = cossin[i][0]
-        y = cossin[i][1]
-        for j in range(vps):
-            p = Vector((pos[j][0], pos[j][1] * x, pos[j][1] * y))
-            p = mat * p
-            verts[i * vps + j] = p + v1
-        if i:
-            for j in range(fps):
-                f = (i - 1) * fps + j
-                faces[f] = [base + j, base + vps + j,
-                            base + vps + (j + 1) % vps, base + (j + 1) % vps]
-    base = len(verts) - vps
-    i = n
-    for j in range(fps):
-        f = (i - 1) * fps + j
-        faces[f] = [base + j, j, (j + 1) % vps, base + (j + 1) % vps]
-
-    return verts, faces
-
-
-# Project a point along a vector onto a plane.
-#
-#   Really, just find the intersection of the line represented by @a point
-#   and @a dir with the plane represented by @a norm and @a p. However, if
-#   the point is on or in front of the plane, or the line is parallel to
-#   the plane, the original point will be returned.
-#
-#   @param point    The point to be projected onto the plane.
-#   @param dir      The vector along which the point will be projected.
-#   @param norm     The normal of the plane onto which the point will be
-#                   projected.
-#   @param p        A point through which the plane passes.
-#   @return         A vector representing the projected point, or the
-#                   original point.
-
-def project_point(point, dir, norm, p):
-    d = (point - p).dot(norm)
-    if d >= 0:
-        # the point is already on or in front of the plane
-        return point
-    v = dir.dot(norm)
-    if v * v < 1e-8:
-        # the plane is unreachable
-        return point
-    return point - dir * d / v
-
-
-# Make a simple strut for debugging.
-#
-#   The strut is just a single quad representing the Z axis of the edge.
-#
-#   @param mesh     The base mesh. Used for finding the edge vertices.
-#   @param edge_num The number of the current edge. For the face vertex
-#                   indices.
-#   @param edge     The edge for which the strut will be built.
-#   @param od       Twice the width of the strut.
-#   @return         A tuple containing a list of vertices and a list of faces.
-#                   The face vertex indices are pre-adjusted by the edge
-#                   number.
-#   @fixme          The face vertex indices should be accurate for the local
-#                   vertices (consistency)
-
-def make_debug_strut(mesh, edge_num, edge, od):
-    v = [mesh.verts[edge.verts[0].index].co,
-         mesh.verts[edge.verts[1].index].co,
-         None, None]
-    v[2] = v[1] + edge.z * od / 2
-    v[3] = v[0] + edge.z * od / 2
-    f = [[edge_num * 4 + 0, edge_num * 4 + 1,
-          edge_num * 4 + 2, edge_num * 4 + 3]]
-    return v, f
-
-
-# Make a cylinder with ends clipped to the end-planes of the edge.
-#
-#   The strut is just a single quad representing the Z axis of the edge.
-#
-#   @param mesh     The base mesh. Used for finding the edge vertices.
-#   @param edge_num The number of the current edge. For the face vertex
-#                   indices.
-#   @param edge     The edge for which the strut will be built.
-#   @param od       The diameter of the strut.
-#   @return         A tuple containing a list of vertices and a list of faces.
-#                   The face vertex indices are pre-adjusted by the edge
-#                   number.
-#   @fixme          The face vertex indices should be accurate for the local
-#                   vertices (consistency)
-
-def make_clipped_cylinder(mesh, edge_num, edge, od):
-    n = len(cossin)
-    cyl = [None] * n
-    v0 = mesh.verts[edge.verts[0].index].co
-    c0 = v0 + od * edge.y
-    v1 = mesh.verts[edge.verts[1].index].co
-    c1 = v1 - od * edge.y
-    for i in range(n):
-        x = cossin[i][0]
-        y = cossin[i][1]
-        r = (edge.z * x - edge.x * y) * od / 2
-        cyl[i] = [c0 + r, c1 + r]
-        for p in edge.verts[0].planes:
-            cyl[i][0] = project_point(cyl[i][0], edge.y, p, v0)
-        for p in edge.verts[1].planes:
-            cyl[i][1] = project_point(cyl[i][1], -edge.y, p, v1)
-    v = [None] * n * 2
-    f = [None] * n
-    base = edge_num * n * 2
-    for i in range(n):
-        v[i * 2 + 0] = cyl[i][1]
-        v[i * 2 + 1] = cyl[i][0]
-        f[i] = [None] * 4
-        f[i][0] = base + i * 2 + 0
-        f[i][1] = base + i * 2 + 1
-        f[i][2] = base + (i * 2 + 3) % (n * 2)
-        f[i][3] = base + (i * 2 + 2) % (n * 2)
-    return v, f
-
-
-# Represent a vertex in the base mesh, with additional information.
-#
-#   These vertices are @b not shared between edges.
-#
-#   @var index  The index of the vert in the base mesh
-#   @var edge   The edge to which this vertex is attached.
-#   @var edges  A tuple of indicess of edges attached to this vert, not
-#               including the edge to which this vertex is attached.
-#   @var planes List of vectors representing the normals of the planes that
-#               bisect the angle between this vert's edge and each other
-#               adjacant edge.
-
-class SVert:
-    # Create a vertex holding additional information about the bmesh vertex.
-    #   @param bmvert   The bmesh vertex for which additional information is
-    #                   to be stored.
-    #   @param bmedge   The edge to which this vertex is attached.
-
-    def __init__(self, bmvert, bmedge, edge):
-        self.index = bmvert.index
-        self.edge = edge
-        edges = bmvert.link_edges[:]
-        edges.remove(bmedge)
-        self.edges = tuple(map(lambda e: e.index, edges))
-        self.planes = []
-
-    def calc_planes(self, edges):
-        for ed in self.edges:
-            self.planes.append(calc_plane_normal(self.edge, edges[ed]))
-
-
-# Represent an edge in the base mesh, with additional information.
-#
-#   Edges do not share vertices so that the edge is always on the front (back?
-#   must verify) side of all the planes attached to its vertices. If the
-#   vertices were shared, the edge could be on either side of the planes, and
-#   there would be planes attached to the vertex that are irrelevant to the
-#   edge.
-#
-#   @var index      The index of the edge in the base mesh.
-#   @var bmedge     Cached reference to this edge's bmedge
-#   @var verts      A tuple of 2 SVert vertices, one for each end of the
-#                   edge. The vertices are @b not shared between edges.
-#                   However, if two edges are connected via a vertex in the
-#                   bmesh, their corresponding SVert vertices will have the
-#                   the same index value.
-#   @var x          The x axis of the edges local frame of reference.
-#                   Initially invalid.
-#   @var y          The y axis of the edges local frame of reference.
-#                   Initialized such that the edge runs from verts[0] to
-#                   verts[1] along the negative y axis.
-#   @var z          The z axis of the edges local frame of reference.
-#                   Initially invalid.
-
-
-class SEdge:
-
-    def __init__(self, bmesh, bmedge):
-
-        self.index = bmedge.index
-        self.bmedge = bmedge
-        bmesh.verts.ensure_lookup_table()
-        self.verts = (SVert(bmedge.verts[0], bmedge, self),
-                      SVert(bmedge.verts[1], bmedge, self))
-        self.y = (bmesh.verts[self.verts[0].index].co -
-                  bmesh.verts[self.verts[1].index].co)
-        self.y.normalize()
-        self.x = self.z = None
-
-    def set_frame(self, up):
-        self.x = self.y.cross(up)
-        self.x.normalize()
-        self.z = self.x.cross(self.y)
-
-    def calc_frame(self, base_edge):
-        baxis = base_edge.y
-        if (self.verts[0].index == base_edge.verts[0].index or
-              self.verts[1].index == base_edge.verts[1].index):
-            axis = -self.y
-        elif (self.verts[0].index == base_edge.verts[1].index or
-                self.verts[1].index == base_edge.verts[0].index):
-            axis = self.y
-        else:
-            raise ValueError("edges not connected")
-        if baxis.dot(axis) in (-1, 1):
-            # aligned axis have their up/z aligned
-            up = base_edge.z
-        else:
-            # Get the unit vector dividing the angle (theta) between baxis and
-            # axis in two equal parts
-            h = (baxis + axis)
-            h.normalize()
-            # (cos(theta/2), sin(theta/2) * n) where n is the unit vector of the
-            # axis rotating baxis onto axis
-            q = Quaternion([baxis.dot(h)] + list(baxis.cross(h)))
-            # rotate the base edge's up around the rotation axis (blender
-            # quaternion shortcut:)
-            up = q * base_edge.z
-        self.set_frame(up)
-
-    def calc_vert_planes(self, edges):
-        for v in self.verts:
-            v.calc_planes(edges)
-
-    def bisect_faces(self):
-        n1 = self.bmedge.link_faces[0].normal
-        if len(self.bmedge.link_faces) > 1:
-            n2 = self.bmedge.link_faces[1].normal
-            return (n1 + n2).normalized()
-        return n1
-
-    def calc_simple_frame(self):
-        return self.y.cross(select_up(self.y)).normalized()
-
-    def find_edge_frame(self, sedges):
-        if self.bmedge.link_faces:
-            return self.bisect_faces()
-        if self.verts[0].edges or self.verts[1].edges:
-            edges = list(self.verts[0].edges + self.verts[1].edges)
-            for i in range(len(edges)):
-                edges[i] = sedges[edges[i]]
-            while edges and edges[-1].y.cross(self.y).length < 1e-3:
-                edges.pop()
-            if not edges:
-                return self.calc_simple_frame()
-            n1 = edges[-1].y.cross(self.y).normalized()
-            edges.pop()
-            while edges and edges[-1].y.cross(self.y).cross(n1).length < 1e-3:
-                edges.pop()
-            if not edges:
-                return n1
-            n2 = edges[-1].y.cross(self.y).normalized()
-            return (n1 + n2).normalized()
-        return self.calc_simple_frame()
-
-
-def calc_plane_normal(edge1, edge2):
-    if edge1.verts[0].index == edge2.verts[0].index:
-        axis1 = -edge1.y
-        axis2 = edge2.y
-    elif edge1.verts[1].index == edge2.verts[1].index:
-        axis1 = edge1.y
-        axis2 = -edge2.y
-    elif edge1.verts[0].index == edge2.verts[1].index:
-        axis1 = -edge1.y
-        axis2 = -edge2.y
-    elif edge1.verts[1].index == edge2.verts[0].index:
-        axis1 = edge1.y
-        axis2 = edge2.y
-    else:
-        raise ValueError("edges not connected")
-    # Both axis1 and axis2 are unit vectors, so this will produce a vector
-    # bisects the two, so long as they are not 180 degrees apart (in which
-    # there are infinite solutions).
-    return (axis1 + axis2).normalized()
-
-
-def build_edge_frames(edges):
-    edge_set = set(edges)
-    while edge_set:
-        edge_queue = [edge_set.pop()]
-        edge_queue[0].set_frame(edge_queue[0].find_edge_frame(edges))
-        while edge_queue:
-            current_edge = edge_queue.pop()
-            for i in (0, 1):
-                for e in current_edge.verts[i].edges:
-                    edge = edges[e]
-                    if edge.x is not None:  # edge already processed
-                        continue
-                    edge_set.remove(edge)
-                    edge_queue.append(edge)
-                    edge.calc_frame(current_edge)
-
-
-def make_manifold_struts(truss_obj, od, segments):
-    bpy.context.view_layer.objects.active = truss_obj
-    bpy.ops.object.editmode_toggle()
-    truss_mesh = bmesh.from_edit_mesh(truss_obj.data).copy()
-    bpy.ops.object.editmode_toggle()
-    edges = [None] * len(truss_mesh.edges)
-    for i, e in enumerate(truss_mesh.edges):
-        edges[i] = SEdge(truss_mesh, e)
-    build_edge_frames(edges)
-    verts = []
-    faces = []
-    for e, edge in enumerate(edges):
-        # v, f = make_debug_strut(truss_mesh, e, edge, od)
-        edge.calc_vert_planes(edges)
-        v, f = make_clipped_cylinder(truss_mesh, e, edge, od)
-        verts += v
-        faces += f
-    return verts, faces
-
-
-def make_simple_struts(truss_mesh, ind, od, segments, solid, loops):
-    vps = 2
-    if solid:
-        vps *= 2
-    if loops:
-        vps *= 2
-    fps = vps
-    if not solid:
-        fps -= 1
-
-    verts = [None] * len(truss_mesh.edges) * segments * vps
-    faces = [None] * len(truss_mesh.edges) * segments * fps
-    vbase = 0
-    fbase = 0
-
-    for e in truss_mesh.edges:
-        v1 = truss_mesh.vertices[e.vertices[0]]
-        v2 = truss_mesh.vertices[e.vertices[1]]
-        v, f = make_strut(v1.co, v2.co, ind, od, segments, solid, loops)
-        for fv in f:
-            for i in range(len(fv)):
-                fv[i] += vbase
-        for i in range(len(v)):
-            verts[vbase + i] = v[i]
-        for i in range(len(f)):
-            faces[fbase + i] = f[i]
-        # if not base % 12800:
-        #    print (base * 100 / len(verts))
-        vbase += vps * segments
-        fbase += fps * segments
-
-    return verts, faces
-
-
-def create_struts(self, context, ind, od, segments, solid, loops, manifold):
-    build_cossin(segments)
-
-    for truss_obj in bpy.context.scene.objects:
-        if not truss_obj.select_get():
-            continue
-        truss_obj.select_set(False)
-        truss_mesh = truss_obj.to_mesh(context.scene, True, 'PREVIEW')
-        if not truss_mesh.edges:
-            continue
-        if manifold:
-            verts, faces = make_manifold_struts(truss_obj, od, segments)
-        else:
-            verts, faces = make_simple_struts(truss_mesh, ind, od, segments,
-                                              solid, loops)
-        mesh = bpy.data.meshes.new("Struts")
-        mesh.from_pydata(verts, [], faces)
-        obj = bpy.data.objects.new("Struts", mesh)
-        bpy.context.collection.objects.link(obj)
-        obj.select_set(True)
-        obj.location = truss_obj.location
-        bpy.context.view_layer.objects.active = obj
-        mesh.update()
-
-
-class Struts(Operator):
-    bl_idname = "mesh.generate_struts"
-    bl_label = "Struts"
-    bl_description = ("Add one or more struts meshes based on selected truss meshes \n"
-                      "Note: can get very high poly\n"
-                      "Needs an existing Active Mesh Object")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    ind: FloatProperty(
-            name="Inside Diameter",
-            description="Diameter of inner surface",
-            min=0.0, soft_min=0.0,
-            max=100, soft_max=100,
-            default=0.04
-            )
-    od: FloatProperty(
-            name="Outside Diameter",
-            description="Diameter of outer surface",
-            min=0.001, soft_min=0.001,
-            max=100, soft_max=100,
-            default=0.05
-            )
-    manifold: BoolProperty(
-            name="Manifold",
-            description="Connect struts to form a single solid",
-            default=False
-            )
-    solid: BoolProperty(
-            name="Solid",
-            description="Create inner surface",
-            default=False
-            )
-    loops: BoolProperty(
-            name="Loops",
-            description="Create sub-surf friendly loops",
-            default=False
-            )
-    segments: IntProperty(
-            name="Segments",
-            description="Number of segments around strut",
-            min=3, soft_min=3,
-            max=64, soft_max=64,
-            default=12
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        col = layout.column(align=True)
-        col.prop(self, "ind")
-        col.prop(self, "od")
-        col.prop(self, "segments")
-        col.separator()
-
-        col.prop(self, "manifold")
-        col.prop(self, "solid")
-        col.prop(self, "loops")
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return obj is not None and obj.type == "MESH"
-
-    def execute(self, context):
-        store_undo = bpy.context.preferences.edit.use_global_undo
-        bpy.context.preferences.edit.use_global_undo = False
-        keywords = self.as_keywords()
-
-        try:
-            create_struts(self, context, **keywords)
-            bpy.context.preferences.edit.use_global_undo = store_undo
-
-            return {"FINISHED"}
-
-        except Exception as e:
-            bpy.context.preferences.edit.use_global_undo = store_undo
-            self.report({"WARNING"},
-                        "Make Struts could not be performed. Operation Cancelled")
-            print("\n[mesh.generate_struts]\n{}".format(e))
-            return {"CANCELLED"}
-
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/mesh_easylattice.py b/add_advanced_objects_menu/mesh_easylattice.py
deleted file mode 100644
index 6c8fa49f5f76958255f0b07a7662c708839dd766..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/mesh_easylattice.py
+++ /dev/null
@@ -1,361 +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": "Easy Lattice Object",
-    "author": "Kursad Karatas",
-    "version": (0, 6, 0),
-    "blender": (2, 66, 0),
-    "location": "View3D > Easy Lattice",
-    "description": "Create a lattice for shape editing",
-    "warning": "",
-    "wiki_url": "https://wiki.blender.org/index.php/Easy_Lattice_Editing_Addon",
-    "tracker_url": "https://bitbucket.org/kursad/blender_addons_easylattice/src",
-    "category": "Mesh",
-}
-
-
-import bpy
-from mathutils import (
-    Matrix,
-    Vector,
-)
-from bpy.types import Operator
-from bpy.props import (
-    EnumProperty,
-    FloatProperty,
-    IntProperty,
-)
-
-
-def createLattice(context, obj, props):
-    # Create lattice and object
-    lat = bpy.data.lattices.new('EasyLattice')
-    ob = bpy.data.objects.new('EasyLattice', lat)
-
-    # Take into consideration any selected vertices (default: all vertices)
-    selectedVertices = createVertexGroup(obj)
-
-    size, pos = findBBox(obj, selectedVertices)
-    loc, rot = getTransformations(obj)
-
-    # the position comes from the bbox
-    ob.location = pos
-
-    # the size from bbox * the incoming scale factor
-    ob.scale = size * props[3]
-
-    # the rotation comes from the combined obj world
-    # matrix which was converted to euler pairs
-    ob.rotation_euler = buildRot_World(obj)
-    ob.show_in_front = True
-
-    # Link object to scene
-    scn = context.scene
-
-    # Take care of the local view
-    base = scn.objects.link(ob)
-    scn.objects.active = ob
-
-    v3d = None
-    if context.space_data and context.space_data.type == 'VIEW_3D':
-        v3d = context.space_data
-
-    if v3d and v3d.local_view:
-        base.layers_from_view(v3d)
-
-    scn.update()
-
-    # Set lattice attributes
-    lat.points_u = props[0]
-    lat.points_v = props[1]
-    lat.points_w = props[2]
-
-    lat.interpolation_type_u = props[4]
-    lat.interpolation_type_v = props[4]
-    lat.interpolation_type_w = props[4]
-
-    lat.use_outside = False
-
-    return ob
-
-
-def createVertexGroup(obj):
-    vertices = obj.data.vertices
-    selverts = []
-
-    if obj.mode == "EDIT":
-        bpy.ops.object.editmode_toggle()
-
-    group = obj.vertex_groups.new(name="easy_lattice_group")
-
-    for vert in vertices:
-        if vert.select is True:
-            selverts.append(vert)
-            group.add([vert.index], 1.0, "REPLACE")
-
-    # Default: use all vertices
-    if not selverts:
-        for vert in vertices:
-            selverts.append(vert)
-            group.add([vert.index], 1.0, "REPLACE")
-
-    return selverts
-
-
-def getTransformations(obj):
-    rot = obj.rotation_euler
-    loc = obj.location
-
-    return [loc, rot]
-
-
-def findBBox(obj, selvertsarray):
-
-    mat = buildTrnScl_WorldMat(obj)
-    mat_world = obj.matrix_world
-
-    minx, miny, minz = selvertsarray[0].co
-    maxx, maxy, maxz = selvertsarray[0].co
-
-    c = 1
-
-    for c in range(len(selvertsarray)):
-        co = selvertsarray[c].co
-
-        if co.x < minx:
-            minx = co.x
-        if co.y < miny:
-            miny = co.y
-        if co.z < minz:
-            minz = co.z
-
-        if co.x > maxx:
-            maxx = co.x
-        if co.y > maxy:
-            maxy = co.y
-        if co.z > maxz:
-            maxz = co.z
-        c += 1
-
-    minpoint = Vector((minx, miny, minz))
-    maxpoint = Vector((maxx, maxy, maxz))
-
-    # The middle position has to be calculated based on the real world matrix
-    pos = ((minpoint + maxpoint) / 2)
-
-    minpoint = mat * minpoint    # Calculate only based on loc/scale
-    maxpoint = mat * maxpoint    # Calculate only based on loc/scale
-    pos = mat_world * pos        # the middle position has to be calculated based on the real world matrix
-
-    size = maxpoint - minpoint
-    size = Vector((max(0.1, abs(size.x)), max(0.1, abs(size.y)), max(0.1, abs(size.z)))) # Prevent zero size dimensions
-
-    return [size, pos]
-
-
-def buildTrnSclMat(obj):
-    # This function builds a local matrix that encodes translation
-    # and scale and it leaves out the rotation matrix
-    # The rotation is applied at object level if there is any
-    mat_trans = Matrix.Translation(obj.location)
-    mat_scale = Matrix.Scale(obj.scale[0], 4, (1, 0, 0))
-    mat_scale *= Matrix.Scale(obj.scale[1], 4, (0, 1, 0))
-    mat_scale *= Matrix.Scale(obj.scale[2], 4, (0, 0, 1))
-
-    mat_final = mat_trans * mat_scale
-
-    return mat_final
-
-
-def buildTrnScl_WorldMat(obj):
-    # This function builds a real world matrix that encodes translation
-    # and scale and it leaves out the rotation matrix
-    # The rotation is applied at object level if there is any
-    loc, rot, scl = obj.matrix_world.decompose()
-    mat_trans = Matrix.Translation(loc)
-
-    mat_scale = Matrix.Scale(scl[0], 4, (1, 0, 0))
-    mat_scale *= Matrix.Scale(scl[1], 4, (0, 1, 0))
-    mat_scale *= Matrix.Scale(scl[2], 4, (0, 0, 1))
-
-    mat_final = mat_trans * mat_scale
-
-    return mat_final
-
-
-# Feature use
-def buildRot_WorldMat(obj):
-    # This function builds a real world matrix that encodes rotation
-    # and it leaves out translation and scale matrices
-    loc, rot, scl = obj.matrix_world.decompose()
-    rot = rot.to_euler()
-
-    mat_rot = Matrix.Rotation(rot[0], 4, 'X')
-    mat_rot *= Matrix.Rotation(rot[1], 4, 'Z')
-    mat_rot *= Matrix.Rotation(rot[2], 4, 'Y')
-    return mat_rot
-
-
-def buildTrn_WorldMat(obj):
-    # This function builds a real world matrix that encodes translation
-    # and scale and it leaves out the rotation matrix
-    # The rotation is applied at object level if there is any
-    loc, rot, scl = obj.matrix_world.decompose()
-    mat_trans = Matrix.Translation(loc)
-
-    return mat_trans
-
-
-def buildScl_WorldMat(obj):
-    # This function builds a real world matrix that encodes translation
-    # and scale and it leaves out the rotation matrix
-    # The rotation is applied at object level if there is any
-    loc, rot, scl = obj.matrix_world.decompose()
-
-    mat_scale = Matrix.Scale(scl[0], 4, (1, 0, 0))
-    mat_scale *= Matrix.Scale(scl[1], 4, (0, 1, 0))
-    mat_scale *= Matrix.Scale(scl[2], 4, (0, 0, 1))
-
-    return mat_scale
-
-
-def buildRot_World(obj):
-    # This function builds a real world rotation values
-    loc, rot, scl = obj.matrix_world.decompose()
-    rot = rot.to_euler()
-
-    return rot
-
-
-def main(context, lat_props):
-    obj = context.object
-
-    if obj.type == "MESH":
-        lat = createLattice(context, obj, lat_props)
-
-        modif = obj.modifiers.new("EasyLattice", "LATTICE")
-        modif.object = lat
-        modif.vertex_group = "easy_lattice_group"
-
-        bpy.ops.object.select_all(action='DESELECT')
-        bpy.ops.object.select_pattern(pattern=lat.name, extend=False)
-        context.view_layer.objects.active = lat
-
-        context.scene.update()
-
-    return
-
-
-class EasyLattice(Operator):
-    bl_idname = "object.easy_lattice"
-    bl_label = "Easy Lattice Creator"
-    bl_description = ("Create a Lattice modifier ready to edit\n"
-                      "Needs an existing Active Mesh Object\n")
-
-    lat_u: IntProperty(
-            name="Lattice u",
-            description="Points in u direction",
-            default=3
-            )
-    lat_v: IntProperty(
-            name="Lattice v",
-            description="Points in v direction",
-            default=3
-            )
-    lat_w: IntProperty(
-            name="Lattice w",
-            description="Points in w direction",
-            default=3
-            )
-    lat_scale_factor: FloatProperty(
-            name="Lattice scale factor",
-            description="Adjustment to the lattice scale",
-            default=1,
-            min=0.1,
-            step=1,
-            precision=2
-            )
-    lat_types = (('KEY_LINEAR', "Linear", "Linear Interpolation type"),
-                 ('KEY_CARDINAL', "Cardinal", "Cardinal Interpolation type"),
-                 ('KEY_CATMULL_ROM', "Catmull-Rom", "Catmull-Rom Interpolation type"),
-                 ('KEY_BSPLINE', "BSpline", "Key BSpline Interpolation Type")
-                )
-    lat_type: EnumProperty(
-            name="Lattice Type",
-            description="Choose Lattice Type",
-            items=lat_types,
-            default='KEY_BSPLINE'
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return obj is not None and obj.type == "MESH"
-
-    def draw(self, context):
-        layout = self.layout
-
-        col = layout.column(align=True)
-        col.prop(self, "lat_u")
-        col.prop(self, "lat_v")
-        col.prop(self, "lat_w")
-
-        layout.prop(self, "lat_scale_factor")
-
-        layout.prop(self, "lat_type")
-
-    def execute(self, context):
-        lat_u = self.lat_u
-        lat_v = self.lat_v
-        lat_w = self.lat_w
-
-        lat_scale_factor = self.lat_scale_factor
-
-        # enum property no need to complicate things
-        lat_type = self.lat_type
-        # XXX, should use keyword args
-        lat_props = [lat_u, lat_v, lat_w, lat_scale_factor, lat_type]
-        try:
-            main(context, lat_props)
-
-        except Exception as ex:
-            print("\n[Add Advanced Objects]\nOperator:object.easy_lattice\n{}\n".format(ex))
-            self.report(
-                {'WARNING'},
-                "Easy Lattice Creator could not be completed (See Console for more info)"
-            )
-            return {"CANCELLED"}
-
-        return {"FINISHED"}
-
-    def invoke(self, context, event):
-        wm = context.window_manager
-        return wm.invoke_props_dialog(self)
-
-
-def register():
-    bpy.utils.register_class(EasyLattice)
-
-
-def unregister():
-    bpy.utils.unregister_class(EasyLattice)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/object_add_chain.py b/add_advanced_objects_menu/object_add_chain.py
deleted file mode 100644
index 86da80f8edc9e8facced48d241952f8065b3e070..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/object_add_chain.py
+++ /dev/null
@@ -1,179 +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": "Add Chain",
-    "author": "Brian Hinton (Nichod)",
-    "version": (0, 1, 2),
-    "blender": (2, 71, 0),
-    "location": "Toolshelf > Create Tab",
-    "description": "Adds Chain with curve guide for easy creation",
-    "warning": "",
-    "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
-                "Scripts/Object/Add_Chain",
-    "category": "Object",
-}
-
-import bpy
-from bpy.types import Operator
-
-
-def Add_Chain():
-    # Adds Empty to scene
-    bpy.ops.object.add(
-            type='EMPTY',
-            view_align=False,
-            enter_editmode=False,
-            location=(0, 0, 0),
-            rotation=(0, 0, 0),
-            )
-
-    # Changes name of Empty to rot_link adds variable emp
-    emp = bpy.context.object
-    emp.name = "rot_link"
-
-    # Rotate emp ~ 90 degrees
-    emp.rotation_euler = [1.570796, 0, 0]
-
-    # Adds Curve Path to scene
-    bpy.ops.curve.primitive_nurbs_path_add(
-            view_align=False,
-            enter_editmode=False,
-            location=(0, 0, 0),
-            rotation=(0, 0, 0),
-            )
-
-    # Change Curve name to deform adds variable curv
-    curv = bpy.context.object
-    curv.name = "deform"
-
-    # Inserts Torus primitive
-    bpy.ops.mesh.primitive_torus_add(
-            major_radius=1,
-            minor_radius=0.25,
-            major_segments=12,
-            minor_segments=4,
-            abso_major_rad=1,
-            abso_minor_rad=0.5,
-            )
-
-    # Positions Torus primitive to center of scene
-    bpy.context.active_object.location = 0.0, 0.0, 0.0
-
-    # Resetting Torus rotation in case of 'Align to view' option enabled
-    bpy.context.active_object.rotation_euler = 0.0, 0.0, 0.0
-
-    # Changes Torus name to chain adds variable tor
-    tor = bpy.context.object
-    tor.name = "chain"
-
-    # Adds Array Modifier to tor
-    bpy.ops.object.modifier_add(type='ARRAY')
-
-    # Adds subsurf modifier tor
-    bpy.ops.object.modifier_add(type='SUBSURF')
-
-    # Smooths tor
-    bpy.ops.object.shade_smooth()
-
-    # Select curv
-    sce = bpy.context.scene
-    sce.objects.active = curv
-
-    # Toggle into editmode
-    bpy.ops.object.editmode_toggle()
-
-    # TODO, may be better to move objects directly
-    # Translate curve object
-    bpy.ops.transform.translate(
-            value=(2, 0, 0),
-            constraint_axis=(True, False, False),
-            orient_type='GLOBAL',
-            mirror=False,
-            proportional='DISABLED',
-            proportional_edit_falloff='SMOOTH',
-            proportional_size=1,
-            snap=False,
-            snap_target='CLOSEST',
-            snap_point=(0, 0, 0),
-            snap_align=False,
-            snap_normal=(0, 0, 0),
-            release_confirm=False,
-            )
-
-    # Toggle into objectmode
-    bpy.ops.object.editmode_toggle()
-
-    # Select tor or chain
-    sce.objects.active = tor
-
-    # Selects Array Modifier for editing
-    array = tor.modifiers['Array']
-
-    # Change Array Modifier Parameters
-    array.fit_type = 'FIT_CURVE'
-    array.curve = curv
-    array.offset_object = emp
-    array.use_object_offset = True
-    array.relative_offset_displace = 0.549, 0.0, 0.0
-
-    # Add curve modifier
-    bpy.ops.object.modifier_add(type='CURVE')
-
-    # Selects Curve Modifier for editing
-    cur = tor.modifiers['Curve']
-
-    # Change Curve Modifier Parameters
-    cur.object = curv
-
-
-class AddChain(Operator):
-    bl_idname = "mesh.primitive_chain_add"
-    bl_label = "Add Chain"
-    bl_description = ("Create a Chain segment with helper objects controlling modifiers:\n"
-                      "1) A Curve Modifier Object (deform) for the length and shape,\n"
-                      "Edit the Path to extend Chain Length\n"
-                      "2) An Empty (rot_link) as an Array Offset for rotation")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    def execute(self, context):
-        try:
-            Add_Chain()
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Some operations could not be performed (See Console for more info)")
-
-            print("\n[Add Advanced  Objects]\nOperator: "
-                  "mesh.primitive_chain_add\nError: {}".format(e))
-
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(AddChain)
-
-
-def unregister():
-    bpy.utils.unregister_class(AddChain)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/oscurart_chain_maker.py b/add_advanced_objects_menu/oscurart_chain_maker.py
deleted file mode 100644
index a553ae48b61eed325ae174de53834519ee3d326e..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/oscurart_chain_maker.py
+++ /dev/null
@@ -1,288 +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 #####
-
-# TODO: find English versions of created object names
-
-bl_info = {
-    "name": "Oscurart Chain Maker",
-    "author": "Oscurart",
-    "version": (1, 1),
-    "blender": (2, 56, 0),
-    "location": "Add > Mesh > Oscurart Chain",
-    "description": "Create chain links from armatures",
-    "warning": "",
-    "wiki_url": "oscurart.blogspot.com",
-    "category": "Object"}
-
-
-import bpy
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        )
-from bpy.types import Operator
-
-
-def makeChain(self, context, mult, curverig):
-
-    if not context.active_object.type == 'ARMATURE':
-        self.report({'WARNING'}, "Active Object must be an Armature")
-        return False
-
-    bpy.ops.object.mode_set(mode='OBJECT')
-    VAR_SWITCH = abs(1)
-    ARMATURE = bpy.context.active_object
-
-    def creahuesocero(hueso):
-        # create data to link
-        mesh = bpy.data.meshes.new("objectData" + str(hueso.name))
-        object = bpy.data.objects.new("HardLink" + str(hueso.name), mesh)
-        mesh.from_pydata(
-            [(-0.04986128956079483, -0.6918092370033264, -0.17846597731113434),
-             (-0.04986128956079483, -0.6918091773986816, 0.17846640944480896),
-             (-0.049861326813697815, -0.154555082321167, 0.17846627533435822),
-             (-0.049861326813697815, -0.15455523133277893, -0.17846614122390747),
-             (-0.04986133798956871, -0.03475356101989746, 0.25805795192718506),
-             (-0.04986133798956871, -0.03475397825241089, -0.25805795192718506),
-             (-0.049861278384923935, -0.8116106986999512, -0.2580576539039612),
-             (-0.049861278384923935, -0.8116104602813721, 0.25805822014808655),
-             (-0.04986128211021423, -0.7692053318023682, 2.6668965347198537e-07),
-             (-0.04986127093434334, -0.923523485660553, 2.7834033744511544e-07),
-             (-0.04986133426427841, -0.0771591067314148, 3.5627678585115063e-08),
-             (-0.04986134544014931, 0.0771591067314148, -3.5627678585115063e-08),
-             (0.04986133798956871, -0.03475397825241089, -0.25805795192718506),
-             (0.04986133053898811, 0.0771591067314148, -3.5627678585115063e-08),
-             (0.04986133798956871, -0.03475356101989746, 0.25805795192718506),
-             (0.04986134544014931, -0.15455523133277893, -0.17846614122390747),
-             (0.04986134544014931, -0.0771591067314148, 3.5627678585115063e-08),
-             (0.04986134544014931, -0.154555082321167, 0.17846627533435822),
-             (0.049861397594213486, -0.8116106986999512, -0.2580576539039612),
-             (0.04986140504479408, -0.923523485660553, 2.7834033744511544e-07),
-             (0.049861397594213486, -0.8116104602813721, 0.25805822014808655),
-             (0.04986139014363289, -0.6918091773986816, 0.17846640944480896),
-             (0.04986139014363289, -0.7692053318023682, 2.6668965347198537e-07),
-             (0.04986139014363289, -0.6918092370033264, -0.17846597731113434)],
-            [(1, 2), (0, 3), (3, 5), (2, 4), (0, 6), (5, 6), (1, 7), (4, 7), (0, 8), (1, 8),
-            (7, 9), (6, 9), (8, 9), (2, 10), (3, 10), (4, 11), (5, 11), (10, 11), (5, 12),
-            (12, 13), (11, 13), (13, 14), (4, 14), (10, 16), (15, 16), (3, 15), (2, 17),
-            (16, 17), (9, 19), (18, 19), (6, 18), (7, 20), (19, 20), (8, 22), (21, 22),
-            (1, 21), (0, 23), (22, 23), (14, 20), (12, 18), (15, 23), (17, 21), (12, 15),
-            (13, 16), (14, 17), (20, 21), (19, 22), (18, 23)],
-            [(6, 0, 3, 5), (1, 7, 4, 2), (0, 6, 9, 8), (8, 9, 7, 1), (2, 4, 11, 10), (10, 11, 5, 3),
-            (11, 13, 12, 5), (4, 14, 13, 11), (3, 15, 16, 10), (10, 16, 17, 2), (6, 18, 19, 9),
-            (9, 19, 20, 7), (1, 21, 22, 8), (23, 0, 8, 22), (7, 20, 14, 4), (5, 12, 18, 6),
-            (0, 23, 15, 3), (2, 17, 21, 1), (16, 15, 12, 13), (17, 16, 13, 14), (22, 21, 20, 19),
-            (23, 22, 19, 18), (21, 17, 14, 20), (15, 23, 18, 12)]
-            )
-        mesh.validate()
-        bpy.context.collection.objects.link(object)
-        # scale to the bone
-        bpy.data.objects["HardLink" + str(hueso.name)].scale = (hueso.length * mult,
-                                                                hueso.length * mult,
-                                                                hueso.length * mult)
-        # Parent Objects
-        bpy.data.objects["HardLink" + str(hueso.name)].parent = ARMATURE
-        bpy.data.objects["HardLink" + str(hueso.name)].parent_type = 'BONE'
-        bpy.data.objects["HardLink" + str(hueso.name)].parent_bone = hueso.name
-
-    def creahuesonoventa(hueso):
-        # create data to link
-        mesh = bpy.data.meshes.new("objectData" + str(hueso.name))
-        object = bpy.data.objects.new("NewLink" + str(hueso.name), mesh)
-        mesh.from_pydata(
-            [(0.1784660965204239, -0.6918091773986816, -0.049861203879117966),
-            (-0.1784662902355194, -0.6918091773986816, -0.04986126348376274),
-            (-0.17846627533435822, -0.1545550525188446, -0.04986134544014931),
-            (0.17846617102622986, -0.15455520153045654, -0.04986128583550453),
-            (-0.25805795192718506, -0.03475359082221985, -0.049861375242471695),
-            (0.25805795192718506, -0.034753888845443726, -0.04986129328608513),
-            (0.2580578327178955, -0.8116105794906616, -0.04986117407679558),
-            (-0.2580580413341522, -0.8116105198860168, -0.049861256033182144),
-            (-9.672299938756623e-08, -0.7692052721977234, -0.04986122250556946),
-            (-8.99775329799013e-08, -0.923523485660553, -0.04986120015382767),
-            (-7.764004550381287e-09, -0.07715904712677002, -0.049861326813697815),
-            (4.509517737005808e-08, 0.0771591067314148, -0.049861349165439606),
-            (0.25805795192718506, -0.034753888845443726, 0.049861375242471695),
-            (-2.2038317837314025e-08, 0.0771591067314148, 0.049861326813697815),
-            (-0.25805795192718506, -0.03475359082221985, 0.04986129328608513),
-            (0.17846617102622986, -0.15455520153045654, 0.04986138269305229),
-            (-1.529285498236277e-08, -0.07715907692909241, 0.049861352890729904),
-            (-0.17846627533435822, -0.1545550525188446, 0.049861323088407516),
-            (0.2580578029155731, -0.8116105794906616, 0.049861494451761246),
-            (-1.5711103173998708e-07, -0.923523485660553, 0.04986147582530975),
-            (-0.2580580711364746, -0.8116105198860168, 0.04986141249537468),
-            (-0.1784663051366806, -0.6918091773986816, 0.049861419945955276),
-            (-1.340541757599567e-07, -0.7692052721977234, 0.049861449748277664),
-            (0.1784660816192627, -0.6918091773986816, 0.04986146464943886)],
-            [(1, 2), (0, 3), (3, 5), (2, 4), (0, 6), (5, 6), (1, 7), (4, 7), (0, 8),
-            (1, 8), (7, 9), (6, 9), (8, 9), (2, 10), (3, 10), (4, 11), (5, 11), (10, 11),
-            (5, 12), (12, 13), (11, 13), (13, 14), (4, 14), (10, 16), (15, 16), (3, 15),
-            (2, 17), (16, 17), (9, 19), (18, 19), (6, 18), (7, 20), (19, 20), (8, 22),
-            (21, 22), (1, 21), (0, 23), (22, 23), (14, 20), (12, 18), (15, 23), (17, 21),
-            (12, 15), (13, 16), (14, 17), (20, 21), (19, 22), (18, 23)],
-            [(6, 0, 3, 5), (1, 7, 4, 2), (0, 6, 9, 8), (8, 9, 7, 1), (2, 4, 11, 10),
-            (10, 11, 5, 3), (11, 13, 12, 5), (4, 14, 13, 11), (3, 15, 16, 10), (10, 16, 17, 2),
-            (6, 18, 19, 9), (9, 19, 20, 7), (1, 21, 22, 8), (23, 0, 8, 22), (7, 20, 14, 4),
-            (5, 12, 18, 6), (0, 23, 15, 3), (2, 17, 21, 1), (16, 15, 12, 13), (17, 16, 13, 14),
-            (22, 21, 20, 19), (23, 22, 19, 18), (21, 17, 14, 20), (15, 23, 18, 12)]
-            )
-        mesh.validate()
-        bpy.context.collection.objects.link(object)
-        # scale to the bone
-        bpy.data.objects["NewLink" + str(hueso.name)].scale = (hueso.length * mult,
-                                                                  hueso.length * mult,
-                                                                  hueso.length * mult)
-        # Parent objects
-        bpy.data.objects["NewLink" + str(hueso.name)].parent = ARMATURE
-        bpy.data.objects["NewLink" + str(hueso.name)].parent_type = 'BONE'
-        bpy.data.objects["NewLink" + str(hueso.name)].parent_bone = hueso.name
-
-    for hueso in bpy.context.active_object.pose.bones:
-        if VAR_SWITCH == 1:
-            creahuesocero(hueso)
-        else:
-            creahuesonoventa(hueso)
-        if VAR_SWITCH == 1:
-            VAR_SWITCH = 0
-        else:
-            VAR_SWITCH = 1
-
-    # if curve rig is activated
-    if curverig is True:
-        # variables
-        LISTA_POINTC = []
-        ACTARM = bpy.context.active_object
-
-        # create data and link the object to the scene
-        crv = bpy.data.curves.new("CurvaCable", "CURVE")
-        obCable = bpy.data.objects.new("Cable", crv)
-        bpy.context.collection.objects.link(obCable)
-
-        # set the attributes
-        crv.dimensions = "3D"
-        crv.resolution_u = 10
-        crv.resolution_v = 10
-        crv.twist_mode = "MINIMUM"
-
-        # create the list of tail and head coordinates
-        LISTA_POINTC.append((
-                ACTARM.data.bones[0].head_local[0],
-                ACTARM.data.bones[0].head_local[1],
-                ACTARM.data.bones[0].head_local[2], 1
-                ))
-
-        for hueso in ACTARM.data.bones:
-            LISTA_POINTC.append((
-                    hueso.tail_local[0],
-                    hueso.tail_local[1],
-                    hueso.tail_local[2], 1
-                    ))
-
-        # create the Spline
-        spline = crv.splines.new("NURBS")
-        lencoord = len(LISTA_POINTC)
-        rango = range(lencoord)
-        spline.points.add(lencoord - 1)
-
-        for punto in rango:
-            spline.points[punto].co = LISTA_POINTC[punto]
-
-        # set the endpoint
-        bpy.data.objects['Cable'].data.splines[0].use_endpoint_u = True
-        # select the curve
-        bpy.ops.object.select_all(action='DESELECT')
-        bpy.data.objects['Cable'].select = 1
-        bpy.context.view_layer.objects.active = bpy.data.objects['Cable']
-        # switch to Edit mode
-        bpy.ops.object.mode_set(mode='EDIT')
-
-        # create hooks
-        POINTSTEP = 0
-        for POINT in bpy.data.objects['Cable'].data.splines[0].points:
-            bpy.ops.curve.select_all(action="DESELECT")
-            bpy.data.objects['Cable'].data.splines[0].points[POINTSTEP].select = 1
-            bpy.ops.object.hook_add_newob()
-            POINTSTEP += 1
-
-        # Objects selection step
-        bpy.ops.object.mode_set(mode='OBJECT')
-        bpy.ops.object.select_all(action='DESELECT')
-        ACTARM.select = 1
-        bpy.context.view_layer.objects.active = bpy.data.objects['Armature']
-        bpy.ops.object.mode_set(mode='POSE')
-        bpy.ops.pose.select_all(action='DESELECT')
-        ACTARM.data.bones[-1].select = 1
-        ACTARM.data.bones.active = ACTARM.data.bones[-1]
-
-        # set IK Spline
-        bpy.ops.pose.constraint_add_with_targets(type='SPLINE_IK')
-        ACTARM.pose.bones[-1].constraints['Spline IK'].target = bpy.data.objects['Cable']
-        ACTARM.pose.bones[-1].constraints['Spline IK'].chain_count = 100
-        bpy.context.active_object.pose.bones[-1].constraints['Spline IK'].use_y_stretch = False
-        # return to Object mode
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-
-class MESH_OT_primitive_oscurart_chain_add(Operator):
-    bl_idname = "mesh.primitive_oscurart_chain_add"
-    bl_label = "Chain to Bones"
-    bl_description = ("Add Chain Parented to an Existing Armature\n"
-                      "The Active/Last Selected Object must be an Armature")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    curverig: BoolProperty(
-            name="Curve Rig",
-            default=False
-            )
-    multiplier: FloatProperty(
-            name="Scale",
-            default=1,
-            min=0.01, max=100.0
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj is not None and obj.type == "ARMATURE")
-
-    def execute(self, context):
-        try:
-            makeChain(self, context, self.multiplier, self.curverig)
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Some operations could not be performed (See Console for more info)")
-
-            print("\n[Add Advanced  Objects]\nOperator: "
-                  "mesh.primitive_oscurart_chain_add\nError: {}".format(e))
-
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(MESH_OT_primitive_oscurart_chain_add)
-
-
-def unregister():
-    bpy.utils.unregister_class(MESH_OT_primitive_oscurart_chain_add)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/pixelate_3d.py b/add_advanced_objects_menu/pixelate_3d.py
deleted file mode 100644
index ea7c0e8296e8b104d016e937ac554796d258fa9f..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/pixelate_3d.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# gpl author: liero
-# very simple 'pixelization' or 'voxelization' engine #
-
-bl_info = {
-    "name": "3D Pixelate",
-    "author": "liero",
-    "version": (0, 5, 3),
-    "blender": (2, 74, 0),
-    "location": "View3D > Tool Shelf",
-    "description": "Creates a 3d pixelated version of the object",
-    "category": "Object"}
-
-# Note: winmgr properties are moved to the operator
-
-
-import bpy
-from bpy.types import Operator
-from bpy.props import (
-        FloatProperty,
-        IntProperty,
-        )
-
-
-def pix(self, obj):
-    sce = bpy.context.scene
-    obj.hide = obj.hide_render = True
-    mes = obj.to_mesh(sce, True, 'RENDER')
-    mes.transform(obj.matrix_world)
-    dup = bpy.data.objects.new('dup', mes)
-    sce.objects.link(dup)
-    dup.instance_type = 'VERTS'
-    sce.objects.active = dup
-    bpy.ops.object.mode_set()
-    ver = mes.vertices
-
-    for i in range(250):
-        fin = True
-        for i in dup.data.edges:
-            d = ver[i.vertices[0]].co - ver[i.vertices[1]].co
-            if d.length > self.size:
-                ver[i.vertices[0]].select = True
-                ver[i.vertices[1]].select = True
-                fin = False
-        bpy.ops.object.editmode_toggle()
-        bpy.ops.mesh.subdivide(number_cuts=1, smoothness=self.smooth)
-        bpy.ops.mesh.select_all(action='DESELECT')
-        bpy.ops.object.editmode_toggle()
-        if fin:
-            break
-
-    for i in ver:
-        for n in range(3):
-            i.co[n] -= (.001 + i.co[n]) % self.size
-
-    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
-    bpy.ops.mesh.select_all(action='SELECT')
-    bpy.ops.mesh.remove_doubles(threshold=0.0001)
-    bpy.ops.mesh.delete(type='EDGE_FACE')
-    bpy.ops.object.mode_set()
-    sca = self.size * (100 - self.gap) * .005
-    bpy.ops.mesh.primitive_cube_add(layers=[True] + [False] * 19)
-    bpy.ops.transform.resize(value=[sca] * 3)
-    bpy.context.view_layer.objects.active = dup
-    bpy.ops.object.parent_set(type='OBJECT')
-
-
-class Pixelate(Operator):
-    bl_idname = "object.pixelate"
-    bl_label = "Pixelate Object"
-    bl_description = ("Create a 3d pixelated version of the object\n"
-                      "using a Duplivert Box around each copied vertex\n"
-                      "With high poly objects, it can take some time\n"
-                      "Needs an existing Active Mesh Object")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    size: FloatProperty(
-            name="Size",
-            min=.05, max=5,
-            default=.25,
-            description="Size of the cube / grid \n"
-                        "Small values (below 0.1) can create a high polygon count"
-            )
-    gap: IntProperty(
-            name="Gap",
-            min=0, max=90,
-            default=10,
-            subtype='PERCENTAGE',
-            description="Separation - percent of size"
-            )
-    smooth: FloatProperty(
-            name="Smooth",
-            min=0, max=1,
-            default=.0,
-            description="Smooth factor when subdividing mesh"
-            )
-
-    @classmethod
-    def poll(cls, context):
-        return (context.active_object and
-                context.active_object.type == 'MESH' and
-                context.mode == 'OBJECT')
-
-    def draw(self, context):
-        layout = self.layout
-
-        col = layout.column(align=True)
-        col.prop(self, "size")
-        col.prop(self, "gap")
-        layout.prop(self, "smooth")
-
-    def execute(self, context):
-        objeto = bpy.context.object
-        try:
-            pix(self, objeto)
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Some operations could not be performed (See Console for more info)")
-
-            print("\n[Add Advanced  Objects]\nOperator: "
-                  "object.pixelate\nError: {}".format(e))
-
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(Pixelate)
-
-
-def unregister():
-    bpy.utils.unregister_class(Pixelate)
-
-
-if __name__ == '__main__':
-    register()
diff --git a/add_advanced_objects_menu/random_box_structure.py b/add_advanced_objects_menu/random_box_structure.py
deleted file mode 100644
index 819dd5ece3c0ea40c7dd7069c66e65202d2275de..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/random_box_structure.py
+++ /dev/null
@@ -1,201 +0,0 @@
-# gpl: author Dannyboy
-
-bl_info = {
-    "name": "Add Random Box Structure",
-    "author": "Dannyboy",
-    "version": (1, 0, 1),
-    "location": "View3D > Add > Make Box Structure",
-    "description": "Fill selected box shaped meshes with randomly sized cubes",
-    "warning": "",
-    "wiki_url": "",
-    "tracker_url": "dannyboypython.blogspot.com",
-    "category": "Object"}
-
-import bpy
-import random
-from bpy.types import Operator
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        FloatVectorProperty,
-        IntProperty,
-        )
-
-
-class makestructure(Operator):
-    bl_idname = "object.make_structure"
-    bl_label = "Add Random Box Structure"
-    bl_description = ("Create a randomized structure made of boxes\n"
-                      "with various control parameters\n"
-                      "Needs an existing Active Mesh Object")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    dc: BoolProperty(
-            name="Delete Base Mesh(es)",
-            default=True
-            )
-    wh: BoolProperty(
-            name="Stay Within Bounds",
-            description="Keeps cubes from exceeding base mesh bounds",
-            default=True
-            )
-    uf: BoolProperty(
-            name="Uniform Cube Quantity",
-            default=False
-            )
-    qn: IntProperty(
-            name="Cube Quantity",
-            default=10,
-            min=1, max=1500
-            )
-    mn: FloatVectorProperty(
-            name="Min Scales",
-            default=(0.1, 0.1, 0.1),
-            subtype='XYZ'
-            )
-    mx: FloatVectorProperty(
-            name="Max Scales",
-            default=(2.0, 2.0, 2.0),
-            subtype='XYZ'
-            )
-    lo: FloatVectorProperty(
-            name="XYZ Offset",
-            default=(0.0, 0.0, 0.0),
-            subtype='XYZ'
-            )
-    rsd: FloatProperty(
-            name="Random Seed",
-            default=1
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return obj is not None and obj.type == "MESH" and obj.mode == "OBJECT"
-
-    def draw(self, context):
-        layout = self.layout
-
-        box = layout.box()
-        box.label(text="Options:")
-        box.prop(self, "dc")
-        box.prop(self, "wh")
-        box.prop(self, "uf")
-
-        box = layout.box()
-        box.label(text="Parameters:")
-        box.prop(self, "qn")
-        box.prop(self, "mn")
-        box.prop(self, "mx")
-        box.prop(self, "lo")
-        box.prop(self, "rsd")
-
-    def execute(self, context):
-        rsdchange = self.rsd
-        oblst = []
-        uvyes = 0
-        bpy.ops.collection.create(name='Cubagrouper')
-        bpy.ops.collection.objects_remove()
-
-        for ob in bpy.context.selected_objects:
-            oblst.append(ob)
-
-        for obj in oblst:
-            bpy.ops.object.select_pattern(pattern=obj.name)  # Select base mesh
-            bpy.context.view_layer.objects.active = obj
-            if obj.data.uv_layers[:] != []:
-                uvyes = 1
-            else:
-                uvyes = 0
-            bpy.ops.object.collection_link(group='Cubagrouper')
-            dim = obj.dimensions
-            rot = obj.rotation_euler
-            if self.uf is True:
-                area = dim.x * dim.y * dim.z
-            else:
-                area = 75
-
-            for cube in range(round((area / 75) * self.qn)):
-                random.seed(rsdchange)
-                pmn = self.mn  # Proxy values
-                pmx = self.mx
-                if self.wh is True:
-                    if dim.x < pmx.x:  # Keeping things from exceeding proper size
-                        pmx.x = dim.x
-                    if dim.y < pmx.y:
-                        pmx.y = dim.y
-                    if dim.z < pmx.z:
-                        pmx.z = dim.z
-                if 0.0 > pmn.x:  # Keeping things from going under zero
-                    pmn.x = 0.0
-                if 0.0 > pmn.y:
-                    pmn.y = 0.0
-                if 0.0 > pmn.z:
-                    pmn.z = 0.0
-                sx = (random.random() * (pmx.x - pmn.x)) + pmn.x  # Just changed self.mx and .mn to pmx.
-                sy = (random.random() * (pmx.y - pmn.y)) + pmn.y
-                sz = (random.random() * (pmx.z - pmn.z)) + pmn.z
-                if self.wh is True:  # This keeps the cubes within the base mesh
-                    ex = (random.random() * (dim.x - sx)) - ((dim.x - sx) / 2) + obj.location.x
-                    wy = (random.random() * (dim.y - sy)) - ((dim.y - sy) / 2) + obj.location.y
-                    ze = (random.random() * (dim.z - sz)) - ((dim.z - sz) / 2) + obj.location.z
-                elif self.wh is False:
-                    ex = (random.random() * dim.x) - (dim.x / 2) + obj.location.x
-                    wy = (random.random() * dim.y) - (dim.y / 2) + obj.location.y
-                    ze = (random.random() * dim.z) - (dim.z / 2) + obj.location.z
-                bpy.ops.mesh.primitive_cube_add(
-                            radius=0.5, location=(ex + self.lo.x, wy + self.lo.y, ze + self.lo.z)
-                            )
-                bpy.ops.object.mode_set(mode='EDIT')
-                bpy.ops.mesh.select_all(action='SELECT')
-                bpy.ops.transform.resize(
-                    value=(sx, sy, sz), constraint_axis=(True, True, True),
-                    orient_type='GLOBAL', mirror=False, proportional='DISABLED',
-                    proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
-                    )
-                bpy.ops.object.mode_set(mode='OBJECT')
-                select = bpy.context.object  # This is used to keep something selected for poll()
-                bpy.ops.object.collection_link(group='Cubagrouper')
-                rsdchange += 3
-            bpy.ops.object.select_grouped(type='GROUP')
-            bpy.ops.transform.rotate(
-                    value=rot[0], axis=(1, 0, 0), constraint_axis=(False, False, False),
-                    orient_type='GLOBAL', mirror=False, proportional='DISABLED',
-                    proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
-                    )
-            bpy.ops.transform.rotate(
-                    value=rot[1], axis=(0, 1, 0), constraint_axis=(False, False, False),
-                    orient_type='GLOBAL', mirror=False, proportional='DISABLED',
-                    proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
-                    )
-            bpy.ops.transform.rotate(
-                    value=rot[2], axis=(0, 0, 1), constraint_axis=(False, False, False),
-                    orient_type='GLOBAL', mirror=False, proportional='DISABLED',
-                    proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
-                    )
-            bpy.context.view_layer.objects.active = obj  # Again needed to avoid poll() taking me down
-            bpy.ops.object.make_links_data(type='MODIFIERS')
-            bpy.ops.object.make_links_data(type='MATERIAL')
-
-            if uvyes == 1:
-                bpy.ops.object.join_uvs()
-
-            bpy.ops.collection.objects_remove()
-            bpy.context.view_layer.objects.active = select
-
-            if self.dc is True:
-                bpy.context.collection.objects.unlink(obj)
-
-        return {'FINISHED'}
-
-
-def register():
-    bpy.utils.register_class(makestructure)
-
-
-def unregister():
-    bpy.utils.unregister_class(makestructure)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/rope_alpha.py b/add_advanced_objects_menu/rope_alpha.py
deleted file mode 100644
index 7c9c5129c94709ddca5682106a99e6b4954a924b..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/rope_alpha.py
+++ /dev/null
@@ -1,832 +0,0 @@
-# Copyright (c) 2012 Jorge Hernandez - Melendez
-
-# ##### 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 #####
-
-# TODO : prop names into English, add missing tooltips
-
-bl_info = {
-    "name": "Rope Creator",
-    "description": "Dynamic rope (with cloth) creator",
-    "author": "Jorge Hernandez - Melenedez",
-    "version": (0, 2, 2),
-    "blender": (2, 73, 0),
-    "location": "Left Toolbar > ClothRope",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Add Mesh"
-}
-
-
-import bpy
-from bpy.types import Operator
-from bpy.props import (
-        BoolProperty,
-        FloatProperty,
-        IntProperty,
-        )
-
-
-def desocultar(quien):
-    if quien == "todo":
-        for ob in bpy.data.objects:
-            ob.hide = False
-    else:
-        bpy.data.objects[quien].hide = False
-
-
-def deseleccionar_todo():
-    bpy.ops.object.select_all(action='DESELECT')
-
-
-def seleccionar_todo():
-    bpy.ops.object.select_all(action='SELECT')
-
-
-def salir_de_editmode():
-    if bpy.context.mode in ["EDIT", "EDIT_MESH", "EDIT_CURVE"]:
-        bpy.ops.object.mode_set(mode='OBJECT')
-
-
-# Clear scene:
-def reset_scene():
-    desocultar("todo")
-    # playback to the start
-    bpy.ops.screen.frame_jump(end=False)
-    try:
-        salir_de_editmode()
-    except:
-        pass
-    try:
-        area = bpy.context.area
-        # expand everything in the outliner to be able to select children
-        old_type = area.type
-        area.type = 'OUTLINER'
-        bpy.ops.outliner.expanded_toggle()
-
-        # restore the original context
-        area.type = old_type
-
-        seleccionar_todo()
-        bpy.ops.object.delete(use_global=False)
-
-    except Exception as e:
-        print("\n[rope_alpha]\nfunction: reset_scene\nError: %s" % e)
-
-
-def entrar_en_editmode():
-    if bpy.context.mode == "OBJECT":
-        bpy.ops.object.mode_set(mode='EDIT')
-
-
-def select_all_in_edit_mode(ob):
-    if ob.mode != 'EDIT':
-        entrar_en_editmode()
-    bpy.ops.mesh.select_all(action="DESELECT")
-    bpy.context.tool_settings.mesh_select_mode = (True, False, False)
-    salir_de_editmode()
-    for v in ob.data.vertices:
-        if not v.select:
-            v.select = True
-    entrar_en_editmode()
-
-
-def deselect_all_in_edit_mode(ob):
-    if ob.mode != 'EDIT':
-        entrar_en_editmode()
-    bpy.ops.mesh.select_all(action="DESELECT")
-    bpy.context.tool_settings.mesh_select_mode = (True, False, False)
-    salir_de_editmode()
-    for v in ob.data.vertices:
-        if not v.select:
-            v.select = False
-    entrar_en_editmode()
-
-
-def which_vertex_are_selected(ob):
-    for v in ob.data.vertices:
-        if v.select:
-            print(str(v.index))
-            print("Vertex " + str(v.index) + " is selected")
-
-
-def seleccionar_por_nombre(nombre):
-    scn = bpy.context.scene
-    bpy.data.objects[nombre].select_set(True)
-
-    scn.objects.active = bpy.data.objects[nombre]
-
-
-def deseleccionar_por_nombre(nombre):
-    bpy.data.objects[nombre].select_set(False)
-
-
-def crear_vertices(ob):
-    ob.data.vertices.add(1)
-    ob.data.update
-
-
-def borrar_elementos_seleccionados(tipo):
-    if tipo == "vertices":
-        bpy.ops.mesh.delete(type='VERT')
-
-
-def obtener_coords_vertex_seleccionados():
-    coordenadas_de_vertices = []
-    for ob in bpy.context.selected_objects:
-        if ob.type == 'MESH':
-            for v in ob.data.vertices:
-                if v.select:
-                    coordenadas_de_vertices.append([v.co[0], v.co[1], v.co[2]])
-            return coordenadas_de_vertices[0]
-
-
-def crear_locator(pos):
-    bpy.ops.object.empty_add(
-            type='PLAIN_AXES', radius=1, view_align=False,
-            location=(pos[0], pos[1], pos[2]),
-            layers=(True, False, False, False, False, False, False,
-                    False, False, False, False, False, False, False,
-                    False, False, False, False, False, False)
-            )
-
-
-def extruir_vertices(longitud, cuantos_segmentos):
-    bpy.ops.mesh.extrude_region_move(
-            MESH_OT_extrude_region={"mirror": False},
-            TRANSFORM_OT_translate={
-                    "value": (longitud / cuantos_segmentos, 0, 0),
-                    "constraint_axis": (True, False, False),
-                    "orient_type": 'GLOBAL', "mirror": False,
-                    "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH',
-                    "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST',
-                    "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0),
-                    "gpencil_strokes": False, "texture_space": False,
-                    "remove_on_cancel": False, "release_confirm": False
-                    }
-            )
-
-
-def select_all_vertex_in_curve_bezier(bc):
-    for i in range(len(bc.data.splines[0].points)):
-        bc.data.splines[0].points[i].select = True
-
-
-def deselect_all_vertex_in_curve_bezier(bc):
-    for i in range(len(bc.data.splines[0].points)):
-        bc.data.splines[0].points[i].select = False
-
-
-def ocultar_relationships():
-    for area in bpy.context.screen.areas:
-        if area.type == 'VIEW_3D':
-            area.spaces[0].show_relationship_lines = False
-
-
-class ClothRope(Operator):
-    bl_idname = "clot.rope"
-    bl_label = "Rope Cloth"
-    bl_description = ("Create a new Scene with a Cloth modifier\n"
-                      "Rope Simulation with hooked Helper Objects")
-
-    ropelength: IntProperty(
-            name="Rope Length",
-            description="Length of the generated Rope",
-            default=5
-            )
-    ropesegments: IntProperty(
-            name="Rope Segments",
-            description="Number of the Rope Segments",
-            default=5
-            )
-    qcr: IntProperty(
-            name="Collision Quality",
-            description="Rope's Cloth modifier collsion quality",
-            min=1, max=20,
-            default=20
-            )
-    substeps: IntProperty(
-            name="Rope Substeps",
-            description="Rope's Cloth modifier quality",
-            min=4, max=80,
-            default=50
-            )
-    resrope: IntProperty(
-            name="Rope Resolution",
-            description="Rope's Bevel resolution",
-            default=5
-            )
-    radiusrope: FloatProperty(
-            name="Radius",
-            description="Rope's Radius",
-            min=0.04, max=1,
-            default=0.04
-            )
-    hide_emptys: BoolProperty(
-            name="Hide Empties",
-            description="Hide Helper Objects",
-            default=False
-            )
-
-    def execute(self, context):
-        # add a new scene
-        bpy.ops.scene.new(type="NEW")
-        scene = bpy.context.scene
-        scene.name = "Test Rope"
-        seleccionar_todo()
-        longitud = self.ropelength
-
-        # For the middle to have x segments between the first and
-        # last point, must add 1 to the quantity:
-        cuantos_segmentos = self.ropesegments + 1
-        calidad_de_colision = self.qcr
-        substeps = self.substeps
-        deseleccionar_todo()
-        # collect the possible empties that already exist in the data
-        empties_prev = [obj.name for obj in bpy.data.objects if obj.type == "EMPTY"]
-
-        # create an empty that will be the parent of everything
-        bpy.ops.object.empty_add(
-                type='SPHERE', radius=1, view_align=False, location=(0, 0, 0),
-                layers=(True, False, False, False, False, False, False, False,
-                        False, False, False, False, False, False, False, False,
-                        False, False, False, False)
-                )
-        ob = bpy.context.selected_objects[0]
-        ob.name = "Rope"
-        # .001 and friends
-        rope_name = ob.name
-        deseleccionar_todo()
-
-        # create a plane and delete it
-        bpy.ops.mesh.primitive_plane_add(
-                radius=1, view_align=False, enter_editmode=False, location=(0, 0, 0),
-                layers=(True, False, False, False, False, False, False, False, False,
-                        False, False, False, False, False, False, False, False,
-                        False, False, False)
-                )
-        ob = bpy.context.selected_objects[0]
-        # rename:
-        ob.name = "cuerda"
-        # .001 and friends
-        cuerda_1_name = ob.name
-
-        entrar_en_editmode()  # enter edit mode
-        select_all_in_edit_mode(ob)
-
-        borrar_elementos_seleccionados("vertices")
-        salir_de_editmode()  # leave edit mode
-        crear_vertices(ob)  # create a vertex
-
-        # Creating a Group for the PIN
-        # Group contains the vertices of the pin and the Group.001 contains the single main line
-        entrar_en_editmode()  # enter edit mode
-        bpy.ops.object.vertex_group_add()  # create a group
-        select_all_in_edit_mode(ob)
-        bpy.ops.object.vertex_group_assign()  # assign it
-
-        salir_de_editmode()  # leave edit mode
-        ob.vertex_groups[0].name = "Pin"
-        deseleccionar_todo()
-        seleccionar_por_nombre(cuerda_1_name)
-
-        # extrude vertices:
-        for i in range(cuantos_segmentos):
-            entrar_en_editmode()
-            extruir_vertices(longitud, cuantos_segmentos)
-            # delete the PIN group
-            bpy.ops.object.vertex_group_remove_from()
-            # get the direction to create the locator on it's position
-            pos = obtener_coords_vertex_seleccionados()
-
-            salir_de_editmode()  # leave edit mode
-            # create locator at position
-            crear_locator(pos)
-            deseleccionar_todo()
-            seleccionar_por_nombre(cuerda_1_name)
-        deseleccionar_todo()
-
-        seleccionar_por_nombre(cuerda_1_name)  # select the rope
-        entrar_en_editmode()
-
-        pos = obtener_coords_vertex_seleccionados()  # get their positions
-        salir_de_editmode()
-        # create the last locator
-        crear_locator(pos)
-        deseleccionar_todo()
-        seleccionar_por_nombre(cuerda_1_name)
-        entrar_en_editmode()  # enter edit mode
-        bpy.ops.object.vertex_group_add()  # Creating Master guide group
-        select_all_in_edit_mode(ob)
-        bpy.ops.object.vertex_group_assign()  # and assign it
-        ob.vertex_groups[1].name = "Guide_rope"
-
-        # extrude the Curve so it has a minimum thickness for collide
-        bpy.ops.mesh.extrude_region_move(
-                MESH_OT_extrude_region={"mirror": False},
-                TRANSFORM_OT_translate={
-                        "value": (0, 0.005, 0), "constraint_axis": (False, True, False),
-                        "orient_type": 'GLOBAL', "mirror": False,
-                        "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH',
-                        "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST',
-                        "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0),
-                        "gpencil_strokes": False, "texture_space": False,
-                        "remove_on_cancel": False, "release_confirm": False
-                        }
-                )
-        bpy.ops.object.vertex_group_remove_from()
-        deselect_all_in_edit_mode(ob)
-        salir_de_editmode()
-        bpy.ops.object.modifier_add(type='CLOTH')
-        bpy.context.object.modifiers["Cloth"].settings.use_pin_cloth = True
-        bpy.context.object.modifiers["Cloth"].settings.vertex_group_mass = "Pin"
-        bpy.context.object.modifiers["Cloth"].collision_settings.collision_quality = calidad_de_colision
-        bpy.context.object.modifiers["Cloth"].settings.quality = substeps
-
-        # Duplicate to convert into Curve:
-        # select the vertices that are the part of the Group.001
-        seleccionar_por_nombre(cuerda_1_name)
-        entrar_en_editmode()
-        bpy.ops.mesh.select_all(action="DESELECT")
-        bpy.context.tool_settings.mesh_select_mode = (True, False, False)
-        salir_de_editmode()
-        gi = ob.vertex_groups["Guide_rope"].index  # get group index
-
-        for v in ob.data.vertices:
-            for g in v.groups:
-                if g.group == gi:  # compare with index in VertexGroupElement
-                    v.select = True
-
-        # now we have to make a table of names of cuerdas to see which one will be new
-        cuerda_names = [obj.name for obj in bpy.data.objects if "cuerda" in obj.name]
-
-        entrar_en_editmode()
-
-        # we already have the selected guide:
-        # duplicate it:
-        bpy.ops.mesh.duplicate_move(
-                MESH_OT_duplicate={"mode": 1},
-                TRANSFORM_OT_translate={
-                        "value": (0, 0, 0), "constraint_axis": (False, False, False),
-                        "orient_type": 'GLOBAL', "mirror": False,
-                        "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH',
-                        "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST',
-                        "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0),
-                        "gpencil_strokes": False, "texture_space": False,
-                        "remove_on_cancel": False, "release_confirm": False
-                        }
-                )
-        # separate the selections:
-        bpy.ops.mesh.separate(type='SELECTED')
-        salir_de_editmode()
-        deseleccionar_todo()
-
-        cuerda_2_name = "cuerda.001"
-        test = []
-        for obj in bpy.data.objects:
-            if "cuerda" in obj.name and obj.name not in cuerda_names:
-                cuerda_2_name = obj.name
-                test.append(obj.name)
-
-        seleccionar_por_nombre(cuerda_2_name)
-
-        # from the newly created curve remove the Cloth:
-        bpy.ops.object.modifier_remove(modifier="Cloth")
-        # convert the Curve:
-        bpy.ops.object.convert(target='CURVE')
-
-        # all Empties that are not previously present
-        emptys = []
-        for eo in bpy.data.objects:
-            if eo.type == 'EMPTY' and eo.name not in empties_prev:
-                if eo.name != rope_name:
-                    emptys.append(eo)
-
-        # select and deselect:
-        bc = bpy.data.objects[cuerda_2_name]
-        n = 0
-
-        for e in emptys:
-            deseleccionar_todo()
-            seleccionar_por_nombre(e.name)
-            seleccionar_por_nombre(bc.name)
-            entrar_en_editmode()
-            deselect_all_vertex_in_curve_bezier(bc)
-            bc.data.splines[0].points[n].select = True
-            bpy.ops.object.hook_add_selob(use_bone=False)
-            salir_de_editmode()
-            n = n + 1
-
-        ob = bpy.data.objects[cuerda_1_name]
-        n = 0
-
-        for e in emptys:
-            deseleccionar_todo()
-            seleccionar_por_nombre(e.name)
-            seleccionar_por_nombre(ob.name)
-            entrar_en_editmode()
-            bpy.ops.mesh.select_all(action="DESELECT")
-            bpy.context.tool_settings.mesh_select_mode = (True, False, False)
-            salir_de_editmode()
-
-            for v in ob.data.vertices:
-                if v.select:
-                    v.select = False
-            ob.data.vertices[n].select = True
-            entrar_en_editmode()
-            bpy.ops.object.vertex_parent_set()
-
-            salir_de_editmode()
-            n = n + 1
-
-            # hide the Empties:
-            deseleccionar_todo()
-
-        # all parented to the spherical empty:
-        seleccionar_por_nombre(cuerda_2_name)
-        seleccionar_por_nombre(cuerda_1_name)
-        seleccionar_por_nombre(rope_name)
-        bpy.ops.object.parent_set(type='OBJECT', keep_transform=True)
-        deseleccionar_todo()
-
-        # do not display the relations
-        ocultar_relationships()
-        seleccionar_por_nombre(cuerda_2_name)
-
-        # curved rope settings:
-        bpy.context.object.data.fill_mode = 'FULL'
-        bpy.context.object.data.bevel_depth = self.radiusrope
-        bpy.context.object.data.bevel_resolution = self.resrope
-
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        return context.window_manager.invoke_props_dialog(self, width=350)
-
-    def draw(self, context):
-        layout = self.layout
-        box = layout.box()
-        col = box.column(align=True)
-
-        col.label(text="Rope settings:")
-        rowsub0 = col.row()
-        rowsub0.prop(self, "ropelength", text="Length")
-        rowsub0.prop(self, "ropesegments", text="Segments")
-        rowsub0.prop(self, "radiusrope", text="Radius")
-
-        col.label(text="Quality Settings:")
-        col.prop(self, "resrope", text="Resolution curve")
-        col.prop(self, "qcr", text="Quality Collision")
-        col.prop(self, "substeps", text="Substeps")
-
-
-class BallRope(Operator):
-    bl_idname = "ball.rope"
-    bl_label = "Wrecking Ball"
-    bl_description = ("Create a new Scene with a Rigid Body simulation of\n"
-                      "Wrecking Ball on a rope")
-
-    # defaults rope ball
-    ropelength2: IntProperty(
-            name="Rope Length",
-            description="Length of the Wrecking Ball rope",
-            default=10
-            )
-    ropesegments2: IntProperty(
-            name="Rope Segments",
-            description="Number of the Wrecking Ball rope segments",
-            min=0, max=999,
-            default=6
-            )
-    radiuscubes: FloatProperty(
-            name="Cube Radius",
-            description="Size of the Linked Cubes helpers",
-            default=0.5
-            )
-    radiusrope: FloatProperty(
-            name="Rope Radius",
-            description="Radius of the Rope",
-            default=0.4
-            )
-    worldsteps: IntProperty(
-            name="World Steps",
-            description="Rigid Body Solver world steps per second (update)",
-            min=60, max=1000,
-            default=250
-            )
-    solveriterations: IntProperty(
-            name="Solver Iterations",
-            description="How many times the Rigid Body Solver should run",
-            min=10, max=100,
-            default=50
-            )
-    massball: IntProperty(
-            name="Ball Mass",
-            description="Mass of the Wrecking Ball",
-            default=1
-            )
-    resrope: IntProperty(
-            name="Resolution",
-            description="Rope resolution",
-            default=4
-            )
-    grados: FloatProperty(
-            name="Degrees",
-            description="Angle of the Wrecking Ball compared to the Ground Plane",
-            default=45
-            )
-    separacion: FloatProperty(
-            name="Link Cubes Gap",
-            description="Space between the Rope's Linked Cubes",
-            default=0.1
-            )
-    hidecubes: BoolProperty(
-            name="Hide Link Cubes",
-            description="Hide helper geometry for the Rope",
-            default=False
-            )
-
-    def execute(self, context):
-        world_steps = self.worldsteps
-        solver_iterations = self.solveriterations
-        longitud = self.ropelength2
-
-        # make a + 2, so the segments will be between the two end points...
-        segmentos = self.ropesegments2 + 2
-        offset_del_suelo = 1
-        offset_del_suelo_real = (longitud / 2) + (segmentos / 2)
-        radio = self.radiuscubes
-        radiorope = self.radiusrope
-        masa = self.massball
-        resolucion = self.resrope
-        rotrope = self.grados
-        separation = self.separacion
-        hidecubeslinks = self.hidecubes
-
-        # add new scene
-        bpy.ops.scene.new(type="NEW")
-        scene = bpy.context.scene
-        scene.name = "Test Ball"
-
-        # collect the possible constraint empties that already exist in the data
-        constraint_prev = [obj.name for obj in bpy.data.objects if
-                           obj.type == "EMPTY" and "Constraint" in obj.name]
-        # floor:
-        bpy.ops.mesh.primitive_cube_add(
-                radius=1, view_align=False, enter_editmode=False, location=(0, 0, 0),
-                layers=(True, False, False, False, False, False, False, False, False,
-                        False, False, False, False, False, False, False, False,
-                        False, False, False)
-                )
-        bpy.context.object.scale.x = 10 + longitud
-        bpy.context.object.scale.y = 10 + longitud
-        bpy.context.object.scale.z = 0.05
-        bpy.context.object.name = "groundplane"
-        # The secret agents .001, 002 etc.
-        groundplane_name = bpy.context.object.name
-
-        bpy.ops.rigidbody.objects_add(type='PASSIVE')
-
-        # create the first cube:
-        cuboslink = []
-        n = 0
-        for i in range(segmentos):
-            # if 0 start from 1
-            if i == 0:
-                i = offset_del_suelo
-            else:  # if it is not 0, add one so it doesn't step on the first one starting from 1
-                i = i + offset_del_suelo
-            separacion = longitud * 2 / segmentos  # distance between linked cubes
-            bpy.ops.mesh.primitive_cube_add(
-                    radius=1, view_align=False, enter_editmode=False,
-                    location=(0, 0, i * separacion),
-                    layers=(True, False, False, False, False, False, False, False,
-                            False, False, False, False, False, False, False, False,
-                            False, False, False, False)
-                    )
-            bpy.ops.rigidbody.objects_add(type='ACTIVE')
-            bpy.context.object.name = "CubeLink"
-            if n != 0:
-                bpy.context.object.display_type = 'WIRE'
-                bpy.context.object.hide_render = True
-            n += 1
-            bpy.context.object.scale.z = (longitud * 2) / (segmentos * 2) - separation
-            bpy.context.object.scale.x = radio
-            bpy.context.object.scale.y = radio
-            cuboslink.append(bpy.context.object)
-
-        for i in range(len(cuboslink)):
-            deseleccionar_todo()
-            if i != len(cuboslink) - 1:
-                nombre1 = cuboslink[i]
-                nombre2 = cuboslink[i + 1]
-                seleccionar_por_nombre(nombre1.name)
-                seleccionar_por_nombre(nombre2.name)
-                bpy.ops.rigidbody.connect()
-
-        # select by name
-        constraint_new = [
-                    obj.name for obj in bpy.data.objects if
-                    obj.type == "EMPTY" and "Constraint" in obj.name and
-                    obj.name not in constraint_prev
-                    ]
-
-        for names in constraint_new:
-            seleccionar_por_nombre(names)
-
-        for c in bpy.context.selected_objects:
-            c.rigid_body_constraint.type = 'POINT'
-        deseleccionar_todo()
-
-        # create a Bezier curve:
-        bpy.ops.curve.primitive_bezier_curve_add(
-                radius=1, view_align=False, enter_editmode=False, location=(0, 0, 0),
-                layers=(True, False, False, False, False, False, False, False, False,
-                False, False, False, False, False, False, False, False, False, False, False)
-                )
-        bpy.context.object.name = "Cuerda"
-        # Blender will automatically append the .001
-        # if it is already in data
-        real_name = bpy.context.object.name
-
-        for i in range(len(cuboslink)):
-            cubonombre = cuboslink[i].name
-            seleccionar_por_nombre(cubonombre)
-            seleccionar_por_nombre(real_name)
-            x = cuboslink[i].location[0]
-            y = cuboslink[i].location[1]
-            z = cuboslink[i].location[2]
-
-            # if it is 0 make it start from 1 as the offset from the ground...
-            if i == 0:
-                i = offset_del_suelo
-            else:  # if it is not 0, add one so it doesn't step on the first one starting from 1
-                i = i + offset_del_suelo
-
-            salir_de_editmode()
-            entrar_en_editmode()
-
-            if i == 1:
-                # select all the vertices and delete them
-                select_all_vertex_in_curve_bezier(bpy.data.objects[real_name])
-                bpy.ops.curve.delete(type='VERT')
-                # create the first vertex:
-                bpy.ops.curve.vertex_add(location=(x, y, z))
-            else:
-                # extrude the rest:
-                bpy.ops.curve.extrude_move(
-                        CURVE_OT_extrude={"mode": 'TRANSLATION'},
-                        TRANSFORM_OT_translate={
-                            "value": (0, 0, z / i),
-                            "constraint_axis": (False, False, True),
-                            "orient_type": 'GLOBAL', "mirror": False,
-                            "proportional": 'DISABLED', "proportional_edit_falloff": 'SMOOTH',
-                            "proportional_size": 1, "snap": False, "snap_target": 'CLOSEST',
-                            "snap_point": (0, 0, 0), "snap_align": False, "snap_normal": (0, 0, 0),
-                            "gpencil_strokes": False, "texture_space": False,
-                            "remove_on_cancel": False, "release_confirm": False
-                            }
-                        )
-            bpy.ops.object.hook_add_selob(use_bone=False)
-            salir_de_editmode()
-            bpy.context.object.data.bevel_resolution = resolucion
-            deseleccionar_todo()
-
-        # create a sphere ball:
-        deseleccionar_todo()
-        seleccionar_por_nombre(cuboslink[0].name)
-        entrar_en_editmode()
-        z = cuboslink[0].scale.z + longitud / 2
-        bpy.ops.view3d.snap_cursor_to_selected()
-        bpy.ops.mesh.primitive_uv_sphere_add(
-                view_align=False, enter_editmode=False,
-                layers=(True, False, False, False, False, False, False,
-                        False, False, False, False, False, False, False,
-                        False, False, False, False, False, False)
-                )
-        bpy.ops.transform.translate(
-                value=(0, 0, -z + 2), constraint_axis=(False, False, True),
-                orient_type='GLOBAL', mirror=False, proportional='DISABLED',
-                proportional_edit_falloff='SMOOTH', proportional_size=1
-                )
-        bpy.ops.transform.resize(
-                value=(longitud / 2, longitud / 2, longitud / 2),
-                constraint_axis=(False, False, False),
-                orient_type='GLOBAL',
-                mirror=False, proportional='DISABLED',
-                proportional_edit_falloff='SMOOTH', proportional_size=1
-                )
-        deselect_all_in_edit_mode(cuboslink[0])
-        salir_de_editmode()
-        bpy.ops.object.shade_smooth()
-        bpy.context.object.rigid_body.mass = masa
-        bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')
-
-        # move it all up a bit more:
-        seleccionar_todo()
-        deseleccionar_por_nombre(groundplane_name)
-        bpy.ops.transform.translate(
-                value=(0, 0, offset_del_suelo_real),
-                constraint_axis=(False, False, True),
-                orient_type='GLOBAL', mirror=False,
-                proportional='DISABLED', proportional_edit_falloff='SMOOTH',
-                proportional_size=1
-                )
-
-        deseleccionar_todo()
-        seleccionar_por_nombre(cuboslink[-1].name)
-        bpy.ops.rigidbody.objects_add(type='PASSIVE')
-
-        bpy.context.scene.rigidbody_world.steps_per_second = world_steps
-        bpy.context.scene.rigidbody_world.solver_iterations = solver_iterations
-
-        # move everything from the top one:
-        seleccionar_por_nombre(cuboslink[-1].name)
-        bpy.ops.view3d.snap_cursor_to_selected()
-        seleccionar_todo()
-        deseleccionar_por_nombre(groundplane_name)
-        deseleccionar_por_nombre(cuboslink[-1].name)
-        bpy.context.space_data.pivot_point = 'CURSOR'
-        bpy.ops.transform.rotate(
-                value=rotrope, axis=(1, 0, 0),
-                constraint_axis=(True, False, False),
-                orient_type='GLOBAL',
-                mirror=False, proportional='DISABLED',
-                proportional_edit_falloff='SMOOTH',
-                proportional_size=1
-                )
-        bpy.context.space_data.pivot_point = 'MEDIAN_POINT'
-        deseleccionar_todo()
-
-        seleccionar_por_nombre(real_name)
-        bpy.context.object.data.fill_mode = 'FULL'
-        bpy.context.object.data.bevel_depth = radiorope
-        for ob in bpy.data.objects:
-            if ob.name != cuboslink[0].name:
-                if ob.name.find("CubeLink") >= 0:
-                    deseleccionar_todo()
-                    seleccionar_por_nombre(ob.name)
-                    if hidecubeslinks:
-                        bpy.context.object.hide = True
-        ocultar_relationships()
-        deseleccionar_todo()
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        return context.window_manager.invoke_props_dialog(self, width=350)
-
-    def draw(self, context):
-        layout = self.layout
-        box = layout.box()
-        col = box.column(align=True)
-
-        col.label(text="Rope settings:")
-        rowsub0 = col.row()
-        rowsub0.prop(self, "hidecubes", text="Hide Link Cubes")
-
-        rowsub1 = col.row(align=True)
-        rowsub1.prop(self, "ropelength2", text="Length")
-        rowsub1.prop(self, "ropesegments2", text="Segments")
-
-        rowsub2 = col.row(align=True)
-        rowsub2.prop(self, "radiuscubes", text="Radius Link Cubes")
-        rowsub2.prop(self, "radiusrope", text="Radius Rope")
-
-        rowsub3 = col.row(align=True)
-        rowsub3.prop(self, "grados", text="Degrees")
-        rowsub3.prop(self, "separacion", text="Separation Link Cubes")
-
-        col.label(text="Quality Settings:")
-        col.prop(self, "resrope", text="Resolution Rope")
-        col.prop(self, "massball", text="Ball Mass")
-        col.prop(self, "worldsteps", text="World Steps")
-        col.prop(self, "solveriterations", text="Solver Iterarions")
-
-
-# Register
-
-def register():
-    bpy.utils.register_module(__name__)
-
-
-def unregister():
-    bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_menu/scene_objects_bi.py b/add_advanced_objects_menu/scene_objects_bi.py
deleted file mode 100644
index 199289dd6aec3571563ee19e46331e5acefe9754..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/scene_objects_bi.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# gpl: author meta-androcto
-
-import bpy
-from bpy.types import Operator
-
-
-class add_BI_scene(Operator):
-    bl_idname = "bi.add_scene"
-    bl_label = "Create test scene"
-    bl_description = "Blender Internal renderer Scene with Objects"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    def execute(self, context):
-        try:
-            blend_data = context.blend_data
-            # ob = bpy.context.active_object
-
-            # add new scene
-            bpy.ops.scene.new(type="NEW")
-            scene = bpy.context.scene
-            scene.name = "scene_materials"
-
-            # render settings
-            render = scene.render
-            render.resolution_x = 1920
-            render.resolution_y = 1080
-            render.resolution_percentage = 50
-
-            # add new world
-            world = bpy.data.worlds.new("Materials_World")
-            scene.world = world
-            world.use_sky_blend = True
-            world.use_sky_paper = True
-            world.horizon_color = (0.004393, 0.02121, 0.050)
-            world.zenith_color = (0.03335, 0.227, 0.359)
-            world.light_settings.use_ambient_occlusion = True
-            world.light_settings.ao_factor = 0.25
-
-            # add camera
-            bpy.ops.object.camera_add(
-                    location=(7.48113, -6.50764, 5.34367),
-                    rotation=(1.109319, 0.010817, 0.814928)
-                    )
-            cam = bpy.context.active_object.data
-            cam.lens = 35
-            cam.display_size = 0.1
-            bpy.ops.view3d.viewnumpad(type='CAMERA')
-
-            # add point lamp
-            bpy.ops.object.light_add(
-                    type="POINT", location=(4.07625, 1.00545, 5.90386),
-                    rotation=(0.650328, 0.055217, 1.866391)
-                    )
-            lamp1 = bpy.context.active_object.data
-            lamp1.name = "Point_Right"
-            lamp1.energy = 1.0
-            lamp1.distance = 30.0
-            lamp1.shadow_method = "RAY_SHADOW"
-            lamp1.use_sphere = True
-
-            # add point lamp2
-            bpy.ops.object.light_add(
-                    type="POINT", location=(-0.57101, -4.24586, 5.53674),
-                    rotation=(1.571, 0, 0.785)
-                    )
-            lamp2 = bpy.context.active_object.data
-            lamp2.name = "Point_Left"
-            lamp2.energy = 1.0
-            lamp2.distance = 30.0
-
-            # Add cube
-            bpy.ops.mesh.primitive_cube_add()
-            bpy.ops.object.editmode_toggle()
-            bpy.ops.mesh.subdivide(number_cuts=2)
-            bpy.ops.uv.unwrap(method='CONFORMAL', margin=0.001)
-            bpy.ops.object.editmode_toggle()
-
-            cube = bpy.context.active_object
-            # add new material
-            cubeMaterial = blend_data.materials.new("Cube_Material")
-            bpy.ops.object.material_slot_add()
-            cube.material_slots[0].material = cubeMaterial
-            # Diffuse
-            cubeMaterial.preview_render_type = "CUBE"
-            cubeMaterial.diffuse_color = (1.000, 0.373, 0.00)
-            cubeMaterial.diffuse_shader = 'OREN_NAYAR'
-            cubeMaterial.diffuse_intensity = 1.0
-            cubeMaterial.roughness = 0.09002
-            # Specular
-            cubeMaterial.specular_color = (1.000, 0.800, 0.136)
-            cubeMaterial.specular_shader = "PHONG"
-            cubeMaterial.specular_intensity = 1.0
-            cubeMaterial.specular_hardness = 511.0
-            # Shading
-            cubeMaterial.ambient = 1.00
-            cubeMaterial.use_cubic = False
-            # Transparency
-            cubeMaterial.use_transparency = False
-            cubeMaterial.alpha = 0
-            # Mirror
-            cubeMaterial.raytrace_mirror.use = True
-            cubeMaterial.mirror_color = (1.000, 0.793, 0.0)
-            cubeMaterial.raytrace_mirror.reflect_factor = 0.394
-            cubeMaterial.raytrace_mirror.fresnel = 2.0
-            cubeMaterial.raytrace_mirror.fresnel_factor = 1.641
-            cubeMaterial.raytrace_mirror.fade_to = "FADE_TO_SKY"
-            cubeMaterial.raytrace_mirror.gloss_anisotropic = 1.0
-            # Shadow
-            cubeMaterial.use_transparent_shadows = True
-
-            # Add a texture
-            cubetex = blend_data.textures.new("CloudTex", type='CLOUDS')
-            cubetex.noise_type = 'SOFT_NOISE'
-            cubetex.noise_scale = 0.25
-            mtex = cubeMaterial.texture_slots.add()
-            mtex.texture = cubetex
-            mtex.texture_coords = 'ORCO'
-            mtex.scale = (0.800, 0.800, 0.800)
-            mtex.use_map_mirror = True
-            mtex.mirror_factor = 0.156
-            mtex.use_map_color_diffuse = True
-            mtex.diffuse_color_factor = 0.156
-            mtex.use_map_normal = True
-            mtex.normal_factor = 0.010
-            mtex.blend_type = "ADD"
-            mtex.use_rgb_to_intensity = True
-            mtex.color = (1.000, 0.207, 0.000)
-
-            # Add monkey
-            bpy.ops.mesh.primitive_monkey_add(location=(-0.1, 0.08901, 1.505))
-            bpy.ops.transform.rotate(value=(1.15019), axis=(0, 0, 1))
-            bpy.ops.transform.rotate(value=(-0.673882), axis=(0, 1, 0))
-            bpy.ops.transform.rotate(value=-0.055, axis=(1, 0, 0))
-            bpy.ops.object.modifier_add(type='SUBSURF')
-            bpy.ops.object.shade_smooth()
-            monkey = bpy.context.active_object
-            # add new material
-            monkeyMaterial = blend_data.materials.new("Monkey_Material")
-            bpy.ops.object.material_slot_add()
-            monkey.material_slots[0].material = monkeyMaterial
-            # Material settings
-            monkeyMaterial.preview_render_type = "MONKEY"
-            monkeyMaterial.diffuse_color = (0.239, 0.288, 0.288)
-            monkeyMaterial.specular_color = (0.604, 0.465, 0.136)
-            monkeyMaterial.diffuse_shader = 'LAMBERT'
-            monkeyMaterial.diffuse_intensity = 1.0
-            monkeyMaterial.specular_intensity = 0.3
-            monkeyMaterial.ambient = 0
-            monkeyMaterial.type = 'SURFACE'
-            monkeyMaterial.use_cubic = True
-            monkeyMaterial.use_transparency = False
-            monkeyMaterial.alpha = 0
-            monkeyMaterial.use_transparent_shadows = True
-            monkeyMaterial.raytrace_mirror.use = True
-            monkeyMaterial.raytrace_mirror.reflect_factor = 0.65
-            monkeyMaterial.raytrace_mirror.fade_to = "FADE_TO_MATERIAL"
-
-            # Add plane
-            bpy.ops.mesh.primitive_plane_add(
-                            radius=50, view_align=False, enter_editmode=False, location=(0, 0, -1)
-                            )
-            bpy.ops.object.editmode_toggle()
-            bpy.ops.transform.rotate(
-                    value=-0.8, axis=(0, 0, 1), constraint_axis=(False, False, True),
-                    orient_type='GLOBAL', mirror=False, proportional='DISABLED',
-                    proportional_edit_falloff='SMOOTH', proportional_size=1
-                    )
-            bpy.ops.uv.unwrap(method='CONFORMAL', margin=0.001)
-            bpy.ops.object.editmode_toggle()
-            plane = bpy.context.active_object
-            # add new material
-            planeMaterial = blend_data.materials.new("Plane_Material")
-            bpy.ops.object.material_slot_add()
-            plane.material_slots[0].material = planeMaterial
-            # Material settings
-            planeMaterial.preview_render_type = "CUBE"
-            planeMaterial.diffuse_color = (0.2, 0.2, 0.2)
-            planeMaterial.specular_color = (0.604, 0.465, 0.136)
-            planeMaterial.specular_intensity = 0.3
-            planeMaterial.ambient = 0
-            planeMaterial.use_cubic = True
-            planeMaterial.use_transparency = False
-            planeMaterial.alpha = 0
-            planeMaterial.use_transparent_shadows = True
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Some operations could not be performed (See Console for more info)")
-
-            print("\n[Add Advanced  Objects]\nOperator: "
-                  "bi.add_scene\nError: {}".format(e))
-
-            return {'CANCELLED'}
-
-        return {"FINISHED"}
diff --git a/add_advanced_objects_menu/scene_objects_cycles.py b/add_advanced_objects_menu/scene_objects_cycles.py
deleted file mode 100644
index 7158b02f18472de4638008efa977f333c2122ccf..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/scene_objects_cycles.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# gpl: author meta-androcto
-
-import bpy
-from bpy.types import Operator
-
-
-class add_cycles_scene(Operator):
-    bl_idname = "objects_cycles.add_scene"
-    bl_label = "Create test scene"
-    bl_description = "Cycles renderer Scene with Objects"
-    bl_options = {'REGISTER'}
-
-    def execute(self, context):
-        try:
-            blend_data = context.blend_data
-
-            # add new scene
-            bpy.ops.scene.new(type="NEW")
-            scene = bpy.context.scene
-            bpy.context.scene.render.engine = 'CYCLES'
-            scene.name = "scene_object_cycles"
-
-            # render settings
-            render = scene.render
-            render.resolution_x = 1920
-            render.resolution_y = 1080
-            render.resolution_percentage = 50
-
-            # add new world
-            world = bpy.data.worlds.new("Cycles_Object_World")
-            scene.world = world
-            world.use_sky_blend = True
-            world.use_sky_paper = True
-            world.horizon_color = (0.004393, 0.02121, 0.050)
-            world.zenith_color = (0.03335, 0.227, 0.359)
-            world.light_settings.use_ambient_occlusion = True
-            world.light_settings.ao_factor = 0.25
-
-            # add camera
-            bpy.ops.object.camera_add(
-                    location=(7.48113, -6.50764, 5.34367),
-                    rotation=(1.109319, 0.010817, 0.814928)
-                    )
-            cam = bpy.context.active_object.data
-            cam.lens = 35
-            cam.display_size = 0.1
-            bpy.ops.view3d.viewnumpad(type='CAMERA')
-
-            # add point lamp
-            bpy.ops.object.light_add(
-                    type="POINT", location=(4.07625, 1.00545, 5.90386),
-                    rotation=(0.650328, 0.055217, 1.866391)
-                    )
-            lamp1 = bpy.context.active_object.data
-            lamp1.name = "Point_Right"
-            lamp1.energy = 1.0
-            lamp1.distance = 30.0
-            lamp1.shadow_method = "RAY_SHADOW"
-            lamp1.use_sphere = True
-
-            # add point lamp2
-            bpy.ops.object.light_add(
-                    type="POINT", location=(-0.57101, -4.24586, 5.53674),
-                    rotation=(1.571, 0, 0.785)
-                    )
-            lamp2 = bpy.context.active_object.data
-            lamp2.name = "Point_Left"
-            lamp2.energy = 1.0
-            lamp2.distance = 30.0
-
-            # Add cube
-            bpy.ops.mesh.primitive_cube_add()
-            bpy.ops.object.editmode_toggle()
-            bpy.ops.mesh.subdivide(number_cuts=2)
-            bpy.ops.uv.unwrap(method='CONFORMAL', margin=0.001)
-            bpy.ops.object.editmode_toggle()
-            cube = bpy.context.active_object
-
-            # add cube material
-            cubeMaterial = blend_data.materials.new("Cycles_Cube_Material")
-            bpy.ops.object.material_slot_add()
-            cube.material_slots[0].material = cubeMaterial
-            # Diffuse
-            cubeMaterial.preview_render_type = "CUBE"
-            cubeMaterial.diffuse_color = (1.000, 0.373, 0.00)
-            # Cycles
-            cubeMaterial.use_nodes = True
-
-            # Add monkey
-            bpy.ops.mesh.primitive_monkey_add(location=(-0.1, 0.08901, 1.505))
-            bpy.ops.transform.rotate(value=(1.15019), axis=(0, 0, 1))
-            bpy.ops.transform.rotate(value=(-0.673882), axis=(0, 1, 0))
-            bpy.ops.transform.rotate(value=-0.055, axis=(1, 0, 0))
-
-            bpy.ops.object.modifier_add(type='SUBSURF')
-            bpy.ops.object.shade_smooth()
-            monkey = bpy.context.active_object
-
-            # add monkey material
-            monkeyMaterial = blend_data.materials.new("Cycles_Monkey_Material")
-            bpy.ops.object.material_slot_add()
-            monkey.material_slots[0].material = monkeyMaterial
-            # Diffuse
-            monkeyMaterial.preview_render_type = "MONKEY"
-            monkeyMaterial.diffuse_color = (0.239, 0.288, 0.288)
-            # Cycles
-            monkeyMaterial.use_nodes = True
-
-            # Add plane
-            bpy.ops.mesh.primitive_plane_add(
-                    radius=50, view_align=False,
-                    enter_editmode=False, location=(0, 0, -1)
-                    )
-            bpy.ops.object.editmode_toggle()
-            bpy.ops.transform.rotate(
-                    value=-0.8, axis=(0, 0, 1),
-                    constraint_axis=(False, False, True)
-                    )
-            bpy.ops.uv.unwrap(method='CONFORMAL', margin=0.001)
-            bpy.ops.object.editmode_toggle()
-            plane = bpy.context.active_object
-
-            # add plane material
-            planeMaterial = blend_data.materials.new("Cycles_Plane_Material")
-            bpy.ops.object.material_slot_add()
-            plane.material_slots[0].material = planeMaterial
-            # Diffuse
-            planeMaterial.preview_render_type = "FLAT"
-            planeMaterial.diffuse_color = (0.2, 0.2, 0.2)
-            # Cycles
-            planeMaterial.use_nodes = True
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Some operations could not be performed (See Console for more info)")
-
-            print("\n[Add Advanced  Objects]\nOperator: "
-                  "objects_cycles.add_scene\nError: {}".format(e))
-
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
diff --git a/add_advanced_objects_menu/scene_texture_render.py b/add_advanced_objects_menu/scene_texture_render.py
deleted file mode 100644
index 0f9ccc2b329321bc40a1525b454b394061d9388f..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/scene_texture_render.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# gpl: author meta-androcto
-
-import bpy
-from bpy.types import Operator
-
-
-class add_texture_scene(Operator):
-    bl_idname = "objects_texture.add_scene"
-    bl_label = "Create test scene"
-    bl_description = "Cycles renderer Scene: Camera aligned to a plane"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    def execute(self, context):
-        try:
-            blend_data = context.blend_data
-
-            # add new scene
-            bpy.ops.scene.new(type="NEW")
-            scene = bpy.context.scene
-            bpy.context.scene.render.engine = 'CYCLES'
-            scene.name = "scene_texture_cycles"
-
-            # render settings
-            render = scene.render
-            render.resolution_x = 1080
-            render.resolution_y = 1080
-            render.resolution_percentage = 100
-
-            # add new world
-            world = bpy.data.worlds.new("Cycles_Textures_World")
-            scene.world = world
-            world.use_sky_blend = True
-            world.use_sky_paper = True
-            world.horizon_color = (0.004393, 0.02121, 0.050)
-            world.zenith_color = (0.03335, 0.227, 0.359)
-            world.light_settings.use_ambient_occlusion = True
-            world.light_settings.ao_factor = 0.5
-
-            # add camera
-            bpy.ops.view3d.viewnumpad(type='TOP')
-            bpy.ops.object.camera_add(
-                    location=(0, 0, 2.1850), rotation=(0, 0, 0), view_align=True
-                    )
-            cam = bpy.context.active_object.data
-            cam.lens = 35
-            cam.display_size = 0.1
-
-            # add plane
-            bpy.ops.mesh.primitive_plane_add(enter_editmode=True, location=(0, 0, 0))
-            bpy.ops.mesh.subdivide(number_cuts=10, smoothness=0)
-            bpy.ops.uv.unwrap(method='CONFORMAL', margin=0.001)
-            bpy.ops.object.editmode_toggle()
-            plane = bpy.context.active_object
-
-            # add plane material
-            planeMaterial = blend_data.materials.new("Cycles_Plane_Material")
-            bpy.ops.object.material_slot_add()
-            plane.material_slots[0].material = planeMaterial
-            # Diffuse
-            planeMaterial.preview_render_type = "FLAT"
-            planeMaterial.diffuse_color = (0.2, 0.2, 0.2)
-            # Cycles
-            planeMaterial.use_nodes = True
-
-            # Back to Scene
-            sc = bpy.context.scene
-            bpy.ops.view3d.viewnumpad(type='CAMERA')
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Some operations could not be performed (See Console for more info)")
-
-            print("\n[Add Advanced  Objects]\nOperator: "
-                  "objects_texture.add_scene\nError: {}".format(e))
-
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
diff --git a/add_advanced_objects_menu/trilighting.py b/add_advanced_objects_menu/trilighting.py
deleted file mode 100644
index 8fee580be5e9932c94a7d6f04c1dabf7d038cb7c..0000000000000000000000000000000000000000
--- a/add_advanced_objects_menu/trilighting.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# gpl: author Daniel Schalla
-
-import bpy
-from bpy.types import Operator
-from bpy.props import (
-        EnumProperty,
-        FloatProperty,
-        IntProperty,
-        )
-from math import (
-        sin, cos,
-        radians,
-        sqrt,
-        )
-
-
-class TriLighting(Operator):
-    bl_idname = "object.trilighting"
-    bl_label = "Tri-Lighting Creator"
-    bl_description = ("Add 3 Point Lighting to Selected / Active Object\n"
-                      "Needs an existing Active Object")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    height: FloatProperty(
-            name="Height",
-            default=5
-            )
-    distance: FloatProperty(
-            name="Distance",
-            default=5,
-            min=0.1,
-            subtype="DISTANCE"
-            )
-    energy: IntProperty(
-            name="Base Energy",
-            default=3,
-            min=1
-            )
-    contrast: IntProperty(
-            name="Contrast",
-            default=50,
-            min=-100, max=100,
-            subtype="PERCENTAGE"
-            )
-    leftangle: IntProperty(
-            name="Left Angle",
-            default=26,
-            min=1, max=90,
-            subtype="ANGLE"
-            )
-    rightangle: IntProperty(
-            name="Right Angle",
-            default=45,
-            min=1, max=90,
-            subtype="ANGLE"
-            )
-    backangle: IntProperty(
-            name="Back Angle",
-            default=235,
-            min=90, max=270,
-            subtype="ANGLE"
-            )
-    Light_Type_List = [
-            ('POINT', "Point", "Point Light"),
-            ('SUN', "Sun", "Sun Light"),
-            ('SPOT', "Spot", "Spot Light"),
-            ('HEMI', "Hemi", "Hemi Light"),
-            ('AREA', "Area", "Area Light")
-            ]
-    primarytype: EnumProperty(
-            attr='tl_type',
-            name="Key Type",
-            description="Choose the types of Key Lights you would like",
-            items=Light_Type_List,
-            default='HEMI'
-            )
-    secondarytype: EnumProperty(
-            attr='tl_type',
-            name="Fill + Back Type",
-            description="Choose the types of secondary Lights you would like",
-            items=Light_Type_List,
-            default="POINT"
-            )
-
-    @classmethod
-    def poll(cls, context):
-        return context.active_object is not None
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.label(text="Position:")
-        col = layout.column(align=True)
-        col.prop(self, "height")
-        col.prop(self, "distance")
-
-        layout.label(text="Light:")
-        col = layout.column(align=True)
-        col.prop(self, "energy")
-        col.prop(self, "contrast")
-
-        layout.label(text="Orientation:")
-        col = layout.column(align=True)
-        col.prop(self, "leftangle")
-        col.prop(self, "rightangle")
-        col.prop(self, "backangle")
-
-        col = layout.column()
-        col.label(text="Key Light Type:")
-        col.prop(self, "primarytype", text="")
-        col.label(text="Fill + Back Type:")
-        col.prop(self, "secondarytype", text="")
-
-    def execute(self, context):
-        try:
-            collection = context.collection
-            scene = context.scene
-            view = context.space_data
-            if view.type == 'VIEW_3D' and not view.lock_camera_and_layers:
-                camera = view.camera
-            else:
-                camera = scene.camera
-
-            if (camera is None):
-                cam_data = bpy.data.cameras.new(name='Camera')
-                cam_obj = bpy.data.objects.new(name='Camera', object_data=cam_data)
-                collection.objects.link(cam_obj)
-                scene.camera = cam_obj
-                bpy.ops.view3d.camera_to_view()
-                camera = cam_obj
-                bpy.ops.view3d.viewnumpad(type='TOP')
-
-            obj = bpy.context.view_layer.objects.active
-
-            # Calculate Energy for each Lamp
-            if(self.contrast > 0):
-                keyEnergy = self.energy
-                backEnergy = (self.energy / 100) * abs(self.contrast)
-                fillEnergy = (self.energy / 100) * abs(self.contrast)
-            else:
-                keyEnergy = (self.energy / 100) * abs(self.contrast)
-                backEnergy = self.energy
-                fillEnergy = self.energy
-
-            # Calculate Direction for each Lamp
-
-            # Calculate current Distance and get Delta
-            obj_position = obj.location
-            cam_position = camera.location
-
-            delta_position = cam_position - obj_position
-            vector_length = sqrt(
-                            (pow(delta_position.x, 2) +
-                             pow(delta_position.y, 2) +
-                             pow(delta_position.z, 2))
-                            )
-            if not vector_length:
-                # division by zero most likely
-                self.report({'WARNING'},
-                            "Operation Cancelled. No viable object in the scene")
-
-                return {'CANCELLED'}
-
-            single_vector = (1 / vector_length) * delta_position
-
-            # Calc back position
-            singleback_vector = single_vector.copy()
-            singleback_vector.x = cos(radians(self.backangle)) * single_vector.x + \
-                                  (-sin(radians(self.backangle)) * single_vector.y)
-
-            singleback_vector.y = sin(radians(self.backangle)) * single_vector.x + \
-                                 (cos(radians(self.backangle)) * single_vector.y)
-
-            backx = obj_position.x + self.distance * singleback_vector.x
-            backy = obj_position.y + self.distance * singleback_vector.y
-
-            backData = bpy.data.lights.new(name="TriLamp-Back", type=self.secondarytype)
-            backData.energy = backEnergy
-
-            backLamp = bpy.data.objects.new(name="TriLamp-Back", object_data=backData)
-            collection.objects.link(backLamp)
-            backLamp.location = (backx, backy, self.height)
-
-            trackToBack = backLamp.constraints.new(type="TRACK_TO")
-            trackToBack.target = obj
-            trackToBack.track_axis = "TRACK_NEGATIVE_Z"
-            trackToBack.up_axis = "UP_Y"
-
-            # Calc right position
-            singleright_vector = single_vector.copy()
-            singleright_vector.x = cos(radians(self.rightangle)) * single_vector.x + \
-                                  (-sin(radians(self.rightangle)) * single_vector.y)
-
-            singleright_vector.y = sin(radians(self.rightangle)) * single_vector.x + \
-                                  (cos(radians(self.rightangle)) * single_vector.y)
-
-            rightx = obj_position.x + self.distance * singleright_vector.x
-            righty = obj_position.y + self.distance * singleright_vector.y
-
-            rightData = bpy.data.lights.new(name="TriLamp-Fill", type=self.secondarytype)
-            rightData.energy = fillEnergy
-            rightLamp = bpy.data.objects.new(name="TriLamp-Fill", object_data=rightData)
-            collection.objects.link(rightLamp)
-            rightLamp.location = (rightx, righty, self.height)
-            trackToRight = rightLamp.constraints.new(type="TRACK_TO")
-            trackToRight.target = obj
-            trackToRight.track_axis = "TRACK_NEGATIVE_Z"
-            trackToRight.up_axis = "UP_Y"
-
-            # Calc left position
-            singleleft_vector = single_vector.copy()
-            singleleft_vector.x = cos(radians(-self.leftangle)) * single_vector.x + \
-                                (-sin(radians(-self.leftangle)) * single_vector.y)
-            singleleft_vector.y = sin(radians(-self.leftangle)) * single_vector.x + \
-                                (cos(radians(-self.leftangle)) * single_vector.y)
-            leftx = obj_position.x + self.distance * singleleft_vector.x
-            lefty = obj_position.y + self.distance * singleleft_vector.y
-
-            leftData = bpy.data.lights.new(name="TriLamp-Key", type=self.primarytype)
-            leftData.energy = keyEnergy
-
-            leftLamp = bpy.data.objects.new(name="TriLamp-Key", object_data=leftData)
-            collection.objects.link(leftLamp)
-            leftLamp.location = (leftx, lefty, self.height)
-            trackToLeft = leftLamp.constraints.new(type="TRACK_TO")
-            trackToLeft.target = obj
-            trackToLeft.track_axis = "TRACK_NEGATIVE_Z"
-            trackToLeft.up_axis = "UP_Y"
-
-        except Exception as e:
-            self.report({'WARNING'},
-                        "Some operations could not be performed (See Console for more info)")
-
-            print("\n[Add Advanced  Objects]\nOperator: "
-                  "object.trilighting\nError: {}".format(e))
-
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
diff --git a/add_advanced_objects_panels/DelaunayVoronoi.py b/add_advanced_objects_panels/DelaunayVoronoi.py
deleted file mode 100644
index d291d7009a4f5323f73fa2e87987ce1a7b262e68..0000000000000000000000000000000000000000
--- a/add_advanced_objects_panels/DelaunayVoronoi.py
+++ /dev/null
@@ -1,998 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Voronoi diagram calculator/ Delaunay triangulator
-#
-# - Voronoi Diagram Sweepline algorithm and C code by Steven Fortune,
-#   1987, http://ect.bell-labs.com/who/sjf/
-# - Python translation to file voronoi.py by Bill Simons, 2005, http://www.oxfish.com/
-# - Additional changes for QGIS by Carson Farmer added November 2010
-# - 2012 Ported to Python 3 and additional clip functions by domlysz at gmail.com
-#
-# Calculate Delaunay triangulation or the Voronoi polygons for a set of
-# 2D input points.
-#
-# Derived from code bearing the following notice:
-#
-#  The author of this software is Steven Fortune.  Copyright (c) 1994 by AT&T
-#  Bell Laboratories.
-#  Permission to use, copy, modify, and distribute this software for any
-#  purpose without fee is hereby granted, provided that this entire notice
-#  is included in all copies of any software which is or includes a copy
-#  or modification of this software and in all copies of the supporting
-#  documentation for such software.
-#  THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
-#  WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
-#  REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
-#  OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
-#
-# Comments were incorporated from Shane O'Sullivan's translation of the
-# original code into C++ (http://mapviewer.skynet.ie/voronoi.html)
-#
-# Steve Fortune's homepage: http://netlib.bell-labs.com/cm/cs/who/sjf/index.html
-#
-# For programmatic use, two functions are available:
-#
-#   computeVoronoiDiagram(points, xBuff, yBuff, polygonsOutput=False, formatOutput=False):
-#   Takes :
-#       - a list of point objects (which must have x and y fields).
-#       - x and y buffer values which are the expansion percentages of the
-#         bounding box rectangle including all input points.
-#       Returns :
-#       - With default options :
-#         A list of 2-tuples, representing the two points of each Voronoi diagram edge.
-#         Each point contains 2-tuples which are the x,y coordinates of point.
-#         if formatOutput is True, returns :
-#               - a list of 2-tuples, which are the x,y coordinates of the Voronoi diagram vertices.
-#               - and a list of 2-tuples (v1, v2) representing edges of the Voronoi diagram.
-#                 v1 and v2 are the indices of the vertices at the end of the edge.
-#       - If polygonsOutput option is True, returns :
-#         A dictionary of polygons, keys are the indices of the input points,
-#         values contains n-tuples representing the n points of each Voronoi diagram polygon.
-#         Each point contains 2-tuples which are the x,y coordinates of point.
-#         if formatOutput is True, returns :
-#               - A list of 2-tuples, which are the x,y coordinates of the Voronoi diagram vertices.
-#               - and a dictionary of input points indices. Values contains n-tuples representing
-#                 the n points of each Voronoi diagram polygon.
-#                 Each tuple contains the vertex indices of the polygon vertices.
-#
-#   computeDelaunayTriangulation(points):
-#       Takes a list of point objects (which must have x and y fields).
-#       Returns a list of 3-tuples: the indices of the points that form a Delaunay triangle.
-
-import bpy
-import math
-
-# Globals
-TOLERANCE = 1e-9
-BIG_FLOAT = 1e38
-
-
-class Context(object):
-
-    def __init__(self):
-        self.doPrint = 0
-        self.debug = 0
-
-        # tuple (xmin, xmax, ymin, ymax)
-        self.extent = ()
-        self.triangulate = False
-        # list of vertex 2-tuples: (x,y)
-        self.vertices = []
-        # equation of line 3-tuple (a b c), for the equation of the line a*x+b*y = c
-        self.lines = []
-
-        # edge 3-tuple: (line index, vertex 1 index, vertex 2 index)
-        # if either vertex index is -1, the edge extends to infinity
-        self.edges = []
-        # 3-tuple of vertex indices
-        self.triangles = []
-        # a dict of site:[edges] pairs
-        self.polygons = {}
-
-
-# Clip functions #
-    def getClipEdges(self):
-        xmin, xmax, ymin, ymax = self.extent
-        clipEdges = []
-        for edge in self.edges:
-            equation = self.lines[edge[0]]       # line equation
-            if edge[1] != -1 and edge[2] != -1:  # finite line
-                x1, y1 = self.vertices[edge[1]][0], self.vertices[edge[1]][1]
-                x2, y2 = self.vertices[edge[2]][0], self.vertices[edge[2]][1]
-                pt1, pt2 = (x1, y1), (x2, y2)
-                inExtentP1, inExtentP2 = self.inExtent(x1, y1), self.inExtent(x2, y2)
-                if inExtentP1 and inExtentP2:
-                    clipEdges.append((pt1, pt2))
-                elif inExtentP1 and not inExtentP2:
-                    pt2 = self.clipLine(x1, y1, equation, leftDir=False)
-                    clipEdges.append((pt1, pt2))
-                elif not inExtentP1 and inExtentP2:
-                    pt1 = self.clipLine(x2, y2, equation, leftDir=True)
-                    clipEdges.append((pt1, pt2))
-            else:  # infinite line
-                if edge[1] != -1:
-                    x1, y1 = self.vertices[edge[1]][0], self.vertices[edge[1]][1]
-                    leftDir = False
-                else:
-                    x1, y1 = self.vertices[edge[2]][0], self.vertices[edge[2]][1]
-                    leftDir = True
-                if self.inExtent(x1, y1):
-                    pt1 = (x1, y1)
-                    pt2 = self.clipLine(x1, y1, equation, leftDir)
-                    clipEdges.append((pt1, pt2))
-        return clipEdges
-
-    def getClipPolygons(self, closePoly):
-        xmin, xmax, ymin, ymax = self.extent
-        poly = {}
-        for inPtsIdx, edges in self.polygons.items():
-            clipEdges = []
-            for edge in edges:
-                equation = self.lines[edge[0]]       # line equation
-                if edge[1] != -1 and edge[2] != -1:  # finite line
-                    x1, y1 = self.vertices[edge[1]][0], self.vertices[edge[1]][1]
-                    x2, y2 = self.vertices[edge[2]][0], self.vertices[edge[2]][1]
-                    pt1, pt2 = (x1, y1), (x2, y2)
-                    inExtentP1, inExtentP2 = self.inExtent(x1, y1), self.inExtent(x2, y2)
-                    if inExtentP1 and inExtentP2:
-                        clipEdges.append((pt1, pt2))
-                    elif inExtentP1 and not inExtentP2:
-                        pt2 = self.clipLine(x1, y1, equation, leftDir=False)
-                        clipEdges.append((pt1, pt2))
-                    elif not inExtentP1 and inExtentP2:
-                        pt1 = self.clipLine(x2, y2, equation, leftDir=True)
-                        clipEdges.append((pt1, pt2))
-                else:  # infinite line
-                    if edge[1] != -1:
-                        x1, y1 = self.vertices[edge[1]][0], self.vertices[edge[1]][1]
-                        leftDir = False
-                    else:
-                        x1, y1 = self.vertices[edge[2]][0], self.vertices[edge[2]][1]
-                        leftDir = True
-                    if self.inExtent(x1, y1):
-                        pt1 = (x1, y1)
-                        pt2 = self.clipLine(x1, y1, equation, leftDir)
-                        clipEdges.append((pt1, pt2))
-            # create polygon definition from edges and check if polygon is completely closed
-            polyPts, complete = self.orderPts(clipEdges)
-            if not complete:
-                startPt = polyPts[0]
-                endPt = polyPts[-1]
-                # if start & end points are collinear then they are along an extent border
-                if startPt[0] == endPt[0] or startPt[1] == endPt[1]:
-                    polyPts.append(polyPts[0])  # simple close
-                else:  # close at extent corner
-                    # upper left
-                    if (startPt[0] == xmin and endPt[1] == ymax) or (endPt[0] == xmin and startPt[1] == ymax):
-                        polyPts.append((xmin, ymax))  # corner point
-                        polyPts.append(polyPts[0])    # close polygon
-                    # upper right
-                    if (startPt[0] == xmax and endPt[1] == ymax) or (endPt[0] == xmax and startPt[1] == ymax):
-                        polyPts.append((xmax, ymax))
-                        polyPts.append(polyPts[0])
-                    # bottom right
-                    if (startPt[0] == xmax and endPt[1] == ymin) or (endPt[0] == xmax and startPt[1] == ymin):
-                        polyPts.append((xmax, ymin))
-                        polyPts.append(polyPts[0])
-                    # bottom left
-                    if (startPt[0] == xmin and endPt[1] == ymin) or (endPt[0] == xmin and startPt[1] == ymin):
-                        polyPts.append((xmin, ymin))
-                        polyPts.append(polyPts[0])
-            if not closePoly:  # unclose polygon
-                polyPts = polyPts[:-1]
-            poly[inPtsIdx] = polyPts
-        return poly
-
-    def clipLine(self, x1, y1, equation, leftDir):
-        xmin, xmax, ymin, ymax = self.extent
-        a, b, c = equation
-        if b == 0:       # vertical line
-            if leftDir:  # left is bottom of vertical line
-                return (x1, ymax)
-            else:
-                return (x1, ymin)
-        elif a == 0:     # horizontal line
-            if leftDir:
-                return (xmin, y1)
-            else:
-                return (xmax, y1)
-        else:
-            y2_at_xmin = (c - a * xmin) / b
-            y2_at_xmax = (c - a * xmax) / b
-            x2_at_ymin = (c - b * ymin) / a
-            x2_at_ymax = (c - b * ymax) / a
-            intersectPts = []
-            if ymin <= y2_at_xmin <= ymax:  # valid intersect point
-                intersectPts.append((xmin, y2_at_xmin))
-            if ymin <= y2_at_xmax <= ymax:
-                intersectPts.append((xmax, y2_at_xmax))
-            if xmin <= x2_at_ymin <= xmax:
-                intersectPts.append((x2_at_ymin, ymin))
-            if xmin <= x2_at_ymax <= xmax:
-                intersectPts.append((x2_at_ymax, ymax))
-            # delete duplicate (happens if intersect point is at extent corner)
-            intersectPts = set(intersectPts)
-            # choose target intersect point
-            if leftDir:
-                pt = min(intersectPts)  # smaller x value
-            else:
-                pt = max(intersectPts)
-            return pt
-
-    def inExtent(self, x, y):
-        xmin, xmax, ymin, ymax = self.extent
-        return x >= xmin and x <= xmax and y >= ymin and y <= ymax
-
-    def orderPts(self, edges):
-        poly = []  # returned polygon points list [pt1, pt2, pt3, pt4 ....]
-        pts = []
-        # get points list
-        for edge in edges:
-            pts.extend([pt for pt in edge])
-        # try to get start & end point
-        try:
-            startPt, endPt = [pt for pt in pts if pts.count(pt) < 2]  # start and end point aren't duplicate
-        except:  # all points are duplicate --> polygon is complete --> append some or other edge points
-            complete = True
-            firstIdx = 0
-            poly.append(edges[0][0])
-            poly.append(edges[0][1])
-        else:  # incomplete --> append the first edge points
-            complete = False
-            # search first edge
-            for i, edge in enumerate(edges):
-                if startPt in edge:  # find
-                    firstIdx = i
-                    break
-            poly.append(edges[firstIdx][0])
-            poly.append(edges[firstIdx][1])
-            if poly[0] != startPt:
-                poly.reverse()
-        # append next points in list
-        del edges[firstIdx]
-        while edges:  # all points will be treated when edges list will be empty
-            currentPt = poly[-1]  # last item
-            for i, edge in enumerate(edges):
-                if currentPt == edge[0]:
-                    poly.append(edge[1])
-                    break
-                elif currentPt == edge[1]:
-                    poly.append(edge[0])
-                    break
-            del edges[i]
-        return poly, complete
-
-    def setClipBuffer(self, xpourcent, ypourcent):
-        xmin, xmax, ymin, ymax = self.extent
-        width = xmax - xmin
-        height = ymax - ymin
-        xmin = xmin - width * xpourcent / 100
-        xmax = xmax + width * xpourcent / 100
-        ymin = ymin - height * ypourcent / 100
-        ymax = ymax + height * ypourcent / 100
-        self.extent = xmin, xmax, ymin, ymax
-
-    # End clip functions #
-
-    def outSite(self, s):
-        if(self.debug):
-            print("site (%d) at %f %f" % (s.sitenum, s.x, s.y))
-        elif(self.triangulate):
-            pass
-        elif(self.doPrint):
-            print("s %f %f" % (s.x, s.y))
-
-    def outVertex(self, s):
-        self.vertices.append((s.x, s.y))
-        if(self.debug):
-            print("vertex(%d) at %f %f" % (s.sitenum, s.x, s.y))
-        elif(self.triangulate):
-            pass
-        elif(self.doPrint):
-            print("v %f %f" % (s.x, s.y))
-
-    def outTriple(self, s1, s2, s3):
-        self.triangles.append((s1.sitenum, s2.sitenum, s3.sitenum))
-        if (self.debug):
-            print("circle through left=%d right=%d bottom=%d" % (s1.sitenum, s2.sitenum, s3.sitenum))
-        elif (self.triangulate and self.doPrint):
-            print("%d %d %d" % (s1.sitenum, s2.sitenum, s3.sitenum))
-
-    def outBisector(self, edge):
-        self.lines.append((edge.a, edge.b, edge.c))
-        if (self.debug):
-            print("line(%d) %gx+%gy=%g, bisecting %d %d" % (edge.edgenum, edge.a, edge.b,
-                                                            edge.c, edge.reg[0].sitenum,
-                                                            edge.reg[1].sitenum)
-                )
-        elif(self.doPrint):
-            print("l %f %f %f" % (edge.a, edge.b, edge.c))
-
-    def outEdge(self, edge):
-        sitenumL = -1
-        if edge.ep[Edge.LE] is not None:
-            sitenumL = edge.ep[Edge.LE].sitenum
-        sitenumR = -1
-        if edge.ep[Edge.RE] is not None:
-            sitenumR = edge.ep[Edge.RE].sitenum
-
-        # polygons dict add by CF
-        if edge.reg[0].sitenum not in self.polygons:
-            self.polygons[edge.reg[0].sitenum] = []
-        if edge.reg[1].sitenum not in self.polygons:
-            self.polygons[edge.reg[1].sitenum] = []
-        self.polygons[edge.reg[0].sitenum].append((edge.edgenum, sitenumL, sitenumR))
-        self.polygons[edge.reg[1].sitenum].append((edge.edgenum, sitenumL, sitenumR))
-
-        self.edges.append((edge.edgenum, sitenumL, sitenumR))
-
-        if (not self.triangulate):
-            if (self.doPrint):
-                print("e %d" % edge.edgenum)
-                print(" %d " % sitenumL)
-                print("%d" % sitenumR)
-
-
-def voronoi(siteList, context):
-    context.extent = siteList.extent
-    edgeList = EdgeList(siteList.xmin, siteList.xmax, len(siteList))
-    priorityQ = PriorityQueue(siteList.ymin, siteList.ymax, len(siteList))
-    siteIter = siteList.iterator()
-
-    bottomsite = siteIter.next()
-    context.outSite(bottomsite)
-    newsite = siteIter.next()
-    minpt = Site(-BIG_FLOAT, -BIG_FLOAT)
-    while True:
-        if not priorityQ.isEmpty():
-            minpt = priorityQ.getMinPt()
-
-        if (newsite and (priorityQ.isEmpty() or newsite < minpt)):
-            # newsite is smallest -  this is a site event
-            context.outSite(newsite)
-
-            # get first Halfedge to the LEFT and RIGHT of the new site
-            lbnd = edgeList.leftbnd(newsite)
-            rbnd = lbnd.right
-
-            # if this halfedge has no edge, bot = bottom site (whatever that is)
-            # create a new edge that bisects
-            bot = lbnd.rightreg(bottomsite)
-            edge = Edge.bisect(bot, newsite)
-            context.outBisector(edge)
-
-            # create a new Halfedge, setting its pm field to 0 and insert
-            # this new bisector edge between the left and right vectors in
-            # a linked list
-            bisector = Halfedge(edge, Edge.LE)
-            edgeList.insert(lbnd, bisector)
-
-            # if the new bisector intersects with the left edge, remove
-            # the left edge's vertex, and put in the new one
-            p = lbnd.intersect(bisector)
-            if p is not None:
-                priorityQ.delete(lbnd)
-                priorityQ.insert(lbnd, p, newsite.distance(p))
-
-            # create a new Halfedge, setting its pm field to 1
-            # insert the new Halfedge to the right of the original bisector
-            lbnd = bisector
-            bisector = Halfedge(edge, Edge.RE)
-            edgeList.insert(lbnd, bisector)
-
-            # if this new bisector intersects with the right Halfedge
-            p = bisector.intersect(rbnd)
-            if p is not None:
-                # push the Halfedge into the ordered linked list of vertices
-                priorityQ.insert(bisector, p, newsite.distance(p))
-
-            newsite = siteIter.next()
-
-        elif not priorityQ.isEmpty():
-            # intersection is smallest - this is a vector (circle) event
-            # pop the Halfedge with the lowest vector off the ordered list of
-            # vectors.  Get the Halfedge to the left and right of the above HE
-            # and also the Halfedge to the right of the right HE
-            lbnd = priorityQ.popMinHalfedge()
-            llbnd = lbnd.left
-            rbnd = lbnd.right
-            rrbnd = rbnd.right
-
-            # get the Site to the left of the left HE and to the right of
-            # the right HE which it bisects
-            bot = lbnd.leftreg(bottomsite)
-            top = rbnd.rightreg(bottomsite)
-
-            # output the triple of sites, stating that a circle goes through them
-            mid = lbnd.rightreg(bottomsite)
-            context.outTriple(bot, top, mid)
-
-            # get the vertex that caused this event and set the vertex number
-            # couldn't do this earlier since we didn't know when it would be processed
-            v = lbnd.vertex
-            siteList.setSiteNumber(v)
-            context.outVertex(v)
-
-            # set the endpoint of the left and right Halfedge to be this vector
-            if lbnd.edge.setEndpoint(lbnd.pm, v):
-                context.outEdge(lbnd.edge)
-
-            if rbnd.edge.setEndpoint(rbnd.pm, v):
-                context.outEdge(rbnd.edge)
-
-            # delete the lowest HE, remove all vertex events to do with the
-            # right HE and delete the right HE
-            edgeList.delete(lbnd)
-            priorityQ.delete(rbnd)
-            edgeList.delete(rbnd)
-
-            # if the site to the left of the event is higher than the Site
-            # to the right of it, then swap them and set 'pm' to RIGHT
-            pm = Edge.LE
-            if bot.y > top.y:
-                bot, top = top, bot
-                pm = Edge.RE
-
-            # Create an Edge (or line) that is between the two Sites.  This
-            # creates the formula of the line, and assigns a line number to it
-            edge = Edge.bisect(bot, top)
-            context.outBisector(edge)
-
-            # create a HE from the edge
-            bisector = Halfedge(edge, pm)
-
-            # insert the new bisector to the right of the left HE
-            # set one endpoint to the new edge to be the vector point 'v'
-            # If the site to the left of this bisector is higher than the right
-            # Site, then this endpoint is put in position 0; otherwise in pos 1
-            edgeList.insert(llbnd, bisector)
-            if edge.setEndpoint(Edge.RE - pm, v):
-                context.outEdge(edge)
-
-            # if left HE and the new bisector don't intersect, then delete
-            # the left HE, and reinsert it
-            p = llbnd.intersect(bisector)
-            if p is not None:
-                priorityQ.delete(llbnd)
-                priorityQ.insert(llbnd, p, bot.distance(p))
-
-            # if right HE and the new bisector don't intersect, then reinsert it
-            p = bisector.intersect(rrbnd)
-            if p is not None:
-                priorityQ.insert(bisector, p, bot.distance(p))
-        else:
-            break
-
-    he = edgeList.leftend.right
-    while he is not edgeList.rightend:
-        context.outEdge(he.edge)
-        he = he.right
-    Edge.EDGE_NUM = 0  # CF
-
-
-def isEqual(a, b, relativeError=TOLERANCE):
-    # is nearly equal to within the allowed relative error
-    norm = max(abs(a), abs(b))
-    return (norm < relativeError) or (abs(a - b) < (relativeError * norm))
-
-
-class Site(object):
-
-    def __init__(self, x=0.0, y=0.0, sitenum=0):
-        self.x = x
-        self.y = y
-        self.sitenum = sitenum
-
-    def dump(self):
-        print("Site #%d (%g, %g)" % (self.sitenum, self.x, self.y))
-
-    def __lt__(self, other):
-        if self.y < other.y:
-            return True
-        elif self.y > other.y:
-            return False
-        elif self.x < other.x:
-            return True
-        elif self.x > other.x:
-            return False
-        else:
-            return False
-
-    def __eq__(self, other):
-        if self.y == other.y and self.x == other.x:
-            return True
-
-    def distance(self, other):
-        dx = self.x - other.x
-        dy = self.y - other.y
-        return math.sqrt(dx * dx + dy * dy)
-
-
-class Edge(object):
-    LE = 0  # left end indice --> edge.ep[Edge.LE]
-    RE = 1  # right end indice
-    EDGE_NUM = 0
-    DELETED = {}  # marker value
-
-    def __init__(self):
-        self.a = 0.0  # equation of the line a*x+b*y = c
-        self.b = 0.0
-        self.c = 0.0
-        self.ep = [None, None]  # end point (2 tuples of site)
-        self.reg = [None, None]
-        self.edgenum = 0
-
-    def dump(self):
-        print("(#%d a=%g, b=%g, c=%g)" % (self.edgenum, self.a, self.b, self.c))
-        print("ep", self.ep)
-        print("reg", self.reg)
-
-    def setEndpoint(self, lrFlag, site):
-        self.ep[lrFlag] = site
-        if self.ep[Edge.RE - lrFlag] is None:
-            return False
-        return True
-
-    @staticmethod
-    def bisect(s1, s2):
-        newedge = Edge()
-        newedge.reg[0] = s1  # store the sites that this edge is bisecting
-        newedge.reg[1] = s2
-
-        # to begin with, there are no endpoints on the bisector - it goes to infinity
-        # ep[0] and ep[1] are None
-
-        # get the difference in x dist between the sites
-        dx = float(s2.x - s1.x)
-        dy = float(s2.y - s1.y)
-        adx = abs(dx)  # make sure that the difference in positive
-        ady = abs(dy)
-
-        # get the slope of the line
-        newedge.c = float(s1.x * dx + s1.y * dy + (dx * dx + dy * dy) * 0.5)
-        if adx > ady:
-            # set formula of line, with x fixed to 1
-            newedge.a = 1.0
-            newedge.b = dy / dx
-            newedge.c /= dx
-        else:
-            # set formula of line, with y fixed to 1
-            newedge.b = 1.0
-            newedge.a = dx / dy
-            newedge.c /= dy
-
-        newedge.edgenum = Edge.EDGE_NUM
-        Edge.EDGE_NUM += 1
-        return newedge
-
-
-class Halfedge(object):
-
-    def __init__(self, edge=None, pm=Edge.LE):
-        self.left = None    # left Halfedge in the edge list
-        self.right = None   # right Halfedge in the edge list
-        self.qnext = None   # priority queue linked list pointer
-        self.edge = edge    # edge list Edge
-        self.pm = pm
-        self.vertex = None  # Site()
-        self.ystar = BIG_FLOAT
-
-    def dump(self):
-        print("Halfedge--------------------------")
-        print("left: ", self.left)
-        print("right: ", self.right)
-        print("edge: ", self.edge)
-        print("pm: ", self.pm)
-        print("vertex: "),
-        if self.vertex:
-            self.vertex.dump()
-        else:
-            print("None")
-        print("ystar: ", self.ystar)
-
-    def __lt__(self, other):
-        if self.ystar < other.ystar:
-            return True
-        elif self.ystar > other.ystar:
-            return False
-        elif self.vertex.x < other.vertex.x:
-            return True
-        elif self.vertex.x > other.vertex.x:
-            return False
-        else:
-            return False
-
-    def __eq__(self, other):
-        if self.ystar == other.ystar and self.vertex.x == other.vertex.x:
-            return True
-
-    def leftreg(self, default):
-        if not self.edge:
-            return default
-        elif self.pm == Edge.LE:
-            return self.edge.reg[Edge.LE]
-        else:
-            return self.edge.reg[Edge.RE]
-
-    def rightreg(self, default):
-        if not self.edge:
-            return default
-        elif self.pm == Edge.LE:
-            return self.edge.reg[Edge.RE]
-        else:
-            return self.edge.reg[Edge.LE]
-
-    # returns True if p is to right of halfedge self
-    def isPointRightOf(self, pt):
-        e = self.edge
-        topsite = e.reg[1]
-        right_of_site = pt.x > topsite.x
-
-        if(right_of_site and self.pm == Edge.LE):
-            return True
-
-        if(not right_of_site and self.pm == Edge.RE):
-            return False
-
-        if(e.a == 1.0):
-            dyp = pt.y - topsite.y
-            dxp = pt.x - topsite.x
-            fast = 0
-            if ((not right_of_site and e.b < 0.0) or (right_of_site and e.b >= 0.0)):
-                above = dyp >= e.b * dxp
-                fast = above
-            else:
-                above = pt.x + pt.y * e.b > e.c
-                if(e.b < 0.0):
-                    above = not above
-                if (not above):
-                    fast = 1
-            if (not fast):
-                dxs = topsite.x - (e.reg[0]).x
-                above = e.b * (dxp * dxp - dyp * dyp) < dxs * dyp * (1.0 + 2.0 * dxp / dxs + e.b * e.b)
-                if(e.b < 0.0):
-                    above = not above
-        else:  # e.b == 1.0
-            yl = e.c - e.a * pt.x
-            t1 = pt.y - yl
-            t2 = pt.x - topsite.x
-            t3 = yl - topsite.y
-            above = t1 * t1 > t2 * t2 + t3 * t3
-
-        if(self.pm == Edge.LE):
-            return above
-        else:
-            return not above
-
-    # create a new site where the Halfedges el1 and el2 intersect
-    def intersect(self, other):
-        e1 = self.edge
-        e2 = other.edge
-        if (e1 is None) or (e2 is None):
-            return None
-
-        # if the two edges bisect the same parent return None
-        if e1.reg[1] is e2.reg[1]:
-            return None
-
-        d = e1.a * e2.b - e1.b * e2.a
-        if isEqual(d, 0.0):
-            return None
-
-        xint = (e1.c * e2.b - e2.c * e1.b) / d
-        yint = (e2.c * e1.a - e1.c * e2.a) / d
-        if e1.reg[1] < e2.reg[1]:
-            he = self
-            e = e1
-        else:
-            he = other
-            e = e2
-
-        rightOfSite = xint >= e.reg[1].x
-        if((rightOfSite and he.pm == Edge.LE) or
-                (not rightOfSite and he.pm == Edge.RE)):
-            return None
-
-        # create a new site at the point of intersection - this is a new
-        # vector event waiting to happen
-        return Site(xint, yint)
-
-
-class EdgeList(object):
-
-    def __init__(self, xmin, xmax, nsites):
-        if xmin > xmax:
-            xmin, xmax = xmax, xmin
-        self.hashsize = int(2 * math.sqrt(nsites + 4))
-
-        self.xmin = xmin
-        self.deltax = float(xmax - xmin)
-        self.hash = [None] * self.hashsize
-
-        self.leftend = Halfedge()
-        self.rightend = Halfedge()
-        self.leftend.right = self.rightend
-        self.rightend.left = self.leftend
-        self.hash[0] = self.leftend
-        self.hash[-1] = self.rightend
-
-    def insert(self, left, he):
-        he.left = left
-        he.right = left.right
-        left.right.left = he
-        left.right = he
-
-    def delete(self, he):
-        he.left.right = he.right
-        he.right.left = he.left
-        he.edge = Edge.DELETED
-
-    # Get entry from hash table, pruning any deleted nodes
-    def gethash(self, b):
-        if(b < 0 or b >= self.hashsize):
-            return None
-        he = self.hash[b]
-        if he is None or he.edge is not Edge.DELETED:
-            return he
-
-        #  Hash table points to deleted half edge.  Patch as necessary.
-        self.hash[b] = None
-        return None
-
-    def leftbnd(self, pt):
-        # Use hash table to get close to desired halfedge
-        bucket = int(((pt.x - self.xmin) / self.deltax * self.hashsize))
-
-        if(bucket < 0):
-            bucket = 0
-
-        if(bucket >= self.hashsize):
-            bucket = self.hashsize - 1
-
-        he = self.gethash(bucket)
-        if(he is None):
-            i = 1
-            while True:
-                he = self.gethash(bucket - i)
-                if (he is not None):
-                    break
-                he = self.gethash(bucket + i)
-                if (he is not None):
-                    break
-                i += 1
-
-        # Now search linear list of halfedges for the correct one
-        if (he is self.leftend) or (he is not self.rightend and he.isPointRightOf(pt)):
-            he = he.right
-            while he is not self.rightend and he.isPointRightOf(pt):
-                he = he.right
-            he = he.left
-        else:
-            he = he.left
-            while (he is not self.leftend and not he.isPointRightOf(pt)):
-                he = he.left
-
-        # Update hash table and reference counts
-        if(bucket > 0 and bucket < self.hashsize - 1):
-            self.hash[bucket] = he
-        return he
-
-
-class PriorityQueue(object):
-
-    def __init__(self, ymin, ymax, nsites):
-        self.ymin = ymin
-        self.deltay = ymax - ymin
-        self.hashsize = int(4 * math.sqrt(nsites))
-        self.count = 0
-        self.minidx = 0
-        self.hash = []
-        for i in range(self.hashsize):
-            self.hash.append(Halfedge())
-
-    def __len__(self):
-        return self.count
-
-    def isEmpty(self):
-        return self.count == 0
-
-    def insert(self, he, site, offset):
-        he.vertex = site
-        he.ystar = site.y + offset
-        last = self.hash[self.getBucket(he)]
-        next = last.qnext
-        while((next is not None) and he > next):
-            last = next
-            next = last.qnext
-        he.qnext = last.qnext
-        last.qnext = he
-        self.count += 1
-
-    def delete(self, he):
-        if (he.vertex is not None):
-            last = self.hash[self.getBucket(he)]
-            while last.qnext is not he:
-                last = last.qnext
-            last.qnext = he.qnext
-            self.count -= 1
-            he.vertex = None
-
-    def getBucket(self, he):
-        bucket = int(((he.ystar - self.ymin) / self.deltay) * self.hashsize)
-        if bucket < 0:
-            bucket = 0
-        if bucket >= self.hashsize:
-            bucket = self.hashsize - 1
-        if bucket < self.minidx:
-            self.minidx = bucket
-        return bucket
-
-    def getMinPt(self):
-        while(self.hash[self.minidx].qnext is None):
-            self.minidx += 1
-        he = self.hash[self.minidx].qnext
-        x = he.vertex.x
-        y = he.ystar
-        return Site(x, y)
-
-    def popMinHalfedge(self):
-        curr = self.hash[self.minidx].qnext
-        self.hash[self.minidx].qnext = curr.qnext
-        self.count -= 1
-        return curr
-
-
-class SiteList(object):
-
-    def __init__(self, pointList):
-        self.__sites = []
-        self.__sitenum = 0
-
-        self.__xmin = min([pt.x for pt in pointList])
-        self.__ymin = min([pt.y for pt in pointList])
-        self.__xmax = max([pt.x for pt in pointList])
-        self.__ymax = max([pt.y for pt in pointList])
-        self.__extent = (self.__xmin, self.__xmax, self.__ymin, self.__ymax)
-
-        for i, pt in enumerate(pointList):
-            self.__sites.append(Site(pt.x, pt.y, i))
-        self.__sites.sort()
-
-    def setSiteNumber(self, site):
-        site.sitenum = self.__sitenum
-        self.__sitenum += 1
-
-    class Iterator(object):
-
-        def __init__(this, lst):
-            this.generator = (s for s in lst)
-
-        def __iter__(this):
-            return this
-
-        def next(this):
-            try:
-                # Note: Blender is Python 3.x so no need for 2.x checks
-                return this.generator.__next__()
-            except StopIteration:
-                return None
-
-    def iterator(self):
-        return SiteList.Iterator(self.__sites)
-
-    def __iter__(self):
-        return SiteList.Iterator(self.__sites)
-
-    def __len__(self):
-        return len(self.__sites)
-
-    def _getxmin(self):
-        return self.__xmin
-
-    def _getymin(self):
-        return self.__ymin
-
-    def _getxmax(self):
-        return self.__xmax
-
-    def _getymax(self):
-        return self.__ymax
-
-    def _getextent(self):
-        return self.__extent
-
-    xmin = property(_getxmin)
-    ymin = property(_getymin)
-    xmax = property(_getxmax)
-    ymax = property(_getymax)
-    extent = property(_getextent)
-
-
-def computeVoronoiDiagram(points, xBuff=0, yBuff=0, polygonsOutput=False,
-                          formatOutput=False, closePoly=True):
-    """
-    Takes :
-    - a list of point objects (which must have x and y fields).
-    - x and y buffer values which are the expansion percentages of the bounding box
-        rectangle including all input points.
-    Returns :
-    - With default options :
-      A list of 2-tuples, representing the two points of each Voronoi diagram edge.
-      Each point contains 2-tuples which are the x,y coordinates of point.
-      if formatOutput is True, returns :
-                    - a list of 2-tuples, which are the x,y coordinates of the Voronoi diagram vertices.
-                    - and a list of 2-tuples (v1, v2) representing edges of the Voronoi diagram.
-                      v1 and v2 are the indices of the vertices at the end of the edge.
-    - If polygonsOutput option is True, returns :
-      A dictionary of polygons, keys are the indices of the input points,
-      values contains n-tuples representing the n points of each Voronoi diagram polygon.
-      Each point contains 2-tuples which are the x,y coordinates of point.
-      if formatOutput is True, returns :
-                    - A list of 2-tuples, which are the x,y coordinates of the Voronoi diagram vertices.
-                    - and a dictionary of input points indices. Values contains n-tuples representing
-                      the n points of each Voronoi diagram polygon.
-                      Each tuple contains the vertex indices of the polygon vertices.
-    - if closePoly is True then, in the list of points of a polygon, last point will be the same of first point
-    """
-    siteList = SiteList(points)
-    context = Context()
-    voronoi(siteList, context)
-    context.setClipBuffer(xBuff, yBuff)
-    if not polygonsOutput:
-        clipEdges = context.getClipEdges()
-        if formatOutput:
-            vertices, edgesIdx = formatEdgesOutput(clipEdges)
-            return vertices, edgesIdx
-        else:
-            return clipEdges
-    else:
-        clipPolygons = context.getClipPolygons(closePoly)
-        if formatOutput:
-            vertices, polyIdx = formatPolygonsOutput(clipPolygons)
-            return vertices, polyIdx
-        else:
-            return clipPolygons
-
-
-def formatEdgesOutput(edges):
-    # get list of points
-    pts = []
-    for edge in edges:
-        pts.extend(edge)
-    # get unique values
-    pts = set(pts)  # unique values (tuples are hashable)
-    # get dict {values:index}
-    valuesIdxDict = dict(zip(pts, range(len(pts))))
-    # get edges index reference
-    edgesIdx = []
-    for edge in edges:
-        edgesIdx.append([valuesIdxDict[pt] for pt in edge])
-    return list(pts), edgesIdx
-
-
-def formatPolygonsOutput(polygons):
-    # get list of points
-    pts = []
-    for poly in polygons.values():
-        pts.extend(poly)
-    # get unique values
-    pts = set(pts)  # unique values (tuples are hashable)
-    # get dict {values:index}
-    valuesIdxDict = dict(zip(pts, range(len(pts))))
-    # get polygons index reference
-    polygonsIdx = {}
-    for inPtsIdx, poly in polygons.items():
-        polygonsIdx[inPtsIdx] = [valuesIdxDict[pt] for pt in poly]
-    return list(pts), polygonsIdx
-
-
-def computeDelaunayTriangulation(points):
-    """ Takes a list of point objects (which must have x and y fields).
-            Returns a list of 3-tuples: the indices of the points that form a
-            Delaunay triangle.
-    """
-    siteList = SiteList(points)
-    context = Context()
-    context.triangulate = True
-    voronoi(siteList, context)
-    return context.triangles
diff --git a/add_advanced_objects_panels/__init__.py b/add_advanced_objects_panels/__init__.py
deleted file mode 100644
index 9e2cb0304bc23f94db234b3a31ca23ac954f4d76..0000000000000000000000000000000000000000
--- a/add_advanced_objects_panels/__init__.py
+++ /dev/null
@@ -1,515 +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, Bill Currie, Jorge Hernandez - Melenedez  Jacob Morris, Oscurart  #
-# Rebellion, Antonis Karvelas, Eleanor Howick, lijenstina, Daniel Schalla, Domlysz #
-# Unnikrishnan(kodemax), Florian Meyer, Omar ahmed, Brian Hinton (Nichod), liero   #
-# Atom, Dannyboy, Mano-Wii, Kursad Karatas, teldredge, Phil Cote #
-
-bl_info = {
-    "name": "Add Advanced Object Panels",
-    "author": "meta-androcto",
-    "version": (1, 1, 5),
-    "blender": (2, 77, 0),
-    "description": "Individual Create Panel Activation List",
-    "location": "Addons Preferences",
-    "warning": "",
-    "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6"
-                "/Py/Scripts/Object/Add_Advanced",
-    "category": "Object"
-    }
-
-import bpy
-from bpy.types import (
-        AddonPreferences,
-        PropertyGroup,
-        )
-from bpy.props import (
-        BoolProperty,
-        BoolVectorProperty,
-        EnumProperty,
-        FloatProperty,
-        FloatVectorProperty,
-        IntProperty,
-        StringProperty,
-        PointerProperty,
-        )
-
-sub_modules_names = (
-    "drop_to_ground",
-    "object_laplace_lightning",
-    "object_mangle_tools",
-    "unfold_transition",
-    "delaunay_voronoi",
-    "oscurart_constellation",
-    )
-
-
-sub_modules = [__import__(__package__ + "." + submod, {}, {}, submod) for submod in sub_modules_names]
-sub_modules.sort(key=lambda mod: (mod.bl_info['category'], mod.bl_info['name']))
-
-
-# Add-ons Preferences
-def _get_pref_class(mod):
-    import inspect
-
-    for obj in vars(mod).values():
-        if inspect.isclass(obj) and issubclass(obj, PropertyGroup):
-            if hasattr(obj, 'bl_idname') and obj.bl_idname == mod.__name__:
-                return obj
-
-
-def get_addon_preferences(name=''):
-    """Acquisition and registration"""
-    addons = bpy.context.preferences.addons
-    if __name__ not in addons:  # wm.read_factory_settings()
-        return None
-    addon_prefs = addons[__name__].preferences
-    if name:
-        if not hasattr(addon_prefs, name):
-            for mod in sub_modules:
-                if mod.__name__.split('.')[-1] == name:
-                    cls = _get_pref_class(mod)
-                    if cls:
-                        prop = PointerProperty(type=cls)
-                        setattr(AdvancedObjPreferences1, name, prop)
-                        bpy.utils.unregister_class(AdvancedObjPreferences1)
-                        bpy.utils.register_class(AdvancedObjPreferences1)
-        return getattr(addon_prefs, name, None)
-    else:
-        return addon_prefs
-
-
-def register_submodule(mod):
-    if not hasattr(mod, '__addon_enabled__'):
-        mod.__addon_enabled__ = False
-    if not mod.__addon_enabled__:
-        mod.register()
-        mod.__addon_enabled__ = True
-
-
-def unregister_submodule(mod):
-    if mod.__addon_enabled__:
-        mod.unregister()
-        mod.__addon_enabled__ = False
-
-        prefs = get_addon_preferences()
-        name = mod.__name__.split('.')[-1]
-        if hasattr(AdvancedObjPreferences1, name):
-            delattr(AdvancedObjPreferences1, name)
-            if prefs:
-                bpy.utils.unregister_class(AdvancedObjPreferences1)
-                bpy.utils.register_class(AdvancedObjPreferences1)
-                if name in prefs:
-                    del prefs[name]
-
-
-def enable_all_modules(self, context):
-    for mod in sub_modules:
-        mod_name = mod.__name__.split('.')[-1]
-        setattr(self, 'use_' + mod_name, False)
-        if not mod.__addon_enabled__:
-            setattr(self, 'use_' + mod_name, True)
-            mod.__addon_enabled__ = True
-
-    return None
-
-
-def disable_all_modules(self, context):
-    for mod in sub_modules:
-        mod_name = mod.__name__.split('.')[-1]
-
-        if mod.__addon_enabled__:
-            setattr(self, 'use_' + mod_name, False)
-            mod.__addon_enabled__ = False
-
-    return None
-
-
-class AdvancedObjPreferences1(AddonPreferences):
-    bl_idname = __name__
-
-    enable_all: BoolProperty(
-            name="Enable all",
-            description="Enable all Advanced Objects' Panels",
-            default=False,
-            update=enable_all_modules
-            )
-    disable_all: BoolProperty(
-            name="Disable all",
-            description="Disable all Advanced Objects' Panels",
-            default=False,
-            update=disable_all_modules
-            )
-
-    def draw(self, context):
-        layout = self.layout
-        split = layout.split(percentage=0.5, align=True)
-        row = split.row()
-        row.alignment = "LEFT"
-        sub_box = row.box()
-        sub_box.prop(self, "enable_all", emboss=False,
-                    icon="VISIBLE_IPO_ON", icon_only=True)
-        row.label(text="Enable All")
-
-        row = split.row()
-        row.alignment = "RIGHT"
-        row.label(text="Disable All")
-        sub_box = row.box()
-        sub_box.prop(self, "disable_all", emboss=False,
-                    icon="VISIBLE_IPO_OFF", icon_only=True)
-
-        for mod in sub_modules:
-            mod_name = mod.__name__.split('.')[-1]
-            info = mod.bl_info
-            column = layout.column()
-            box = column.box()
-
-            # first stage
-            expand = getattr(self, 'show_expanded_' + mod_name)
-            icon = 'TRIA_DOWN' if expand else 'TRIA_RIGHT'
-            col = box.column()
-            row = col.row()
-            sub = row.row()
-            sub.context_pointer_set('addon_prefs', self)
-            op = sub.operator('wm.context_toggle', text='', icon=icon,
-                              emboss=False)
-            op.data_path = 'addon_prefs.show_expanded_' + mod_name
-            sub.label(text='{}: {}'.format(info['category'], info['name']))
-            sub = row.row()
-            sub.alignment = 'RIGHT'
-            if info.get('warning'):
-                sub.label(text='', icon='ERROR')
-            sub.prop(self, 'use_' + mod_name, text='')
-
-            # The second stage
-            if expand:
-                if info.get('description'):
-                    split = col.row().split(percentage=0.15)
-                    split.label(text='Description:')
-                    split.label(text=info['description'])
-                if info.get('location'):
-                    split = col.row().split(percentage=0.15)
-                    split.label(text='Location:')
-                    split.label(text=info['location'])
-                if info.get('author'):
-                    split = col.row().split(percentage=0.15)
-                    split.label(text='Author:')
-                    split.label(text=info['author'])
-                if info.get('version'):
-                    split = col.row().split(percentage=0.15)
-                    split.label(text='Version:')
-                    split.label(text='.'.join(str(x) for x in info['version']),
-                                translate=False)
-                if info.get('warning'):
-                    split = col.row().split(percentage=0.15)
-                    split.label(text='Warning:')
-                    split.label(text='  ' + info['warning'], icon='ERROR')
-
-                tot_row = int(bool(info.get('wiki_url')))
-                if tot_row:
-                    split = col.row().split(percentage=0.15)
-                    split.label(text='Internet:')
-                    if info.get('wiki_url'):
-                        op = split.operator('wm.url_open',
-                                            text='Documentation', icon='HELP')
-                        op.url = info.get('wiki_url')
-                    for i in range(4 - tot_row):
-                        split.separator()
-
-                # Details and settings
-                if getattr(self, 'use_' + mod_name):
-                    prefs = get_addon_preferences(mod_name)
-
-                    if prefs and hasattr(prefs, 'draw'):
-                        box = box.column()
-                        prefs.layout = box
-                        try:
-                            prefs.draw(context)
-                        except:
-                            import traceback
-                            traceback.print_exc()
-                            box.label(text="Error (see console)", icon="ERROR")
-                        del prefs.layout
-
-        row = layout.row()
-        row.label(text="End of Advanced Object Panels Activations",
-                  icon="FILE_PARENT")
-
-
-for mod in sub_modules:
-    info = mod.bl_info
-    mod_name = mod.__name__.split('.')[-1]
-
-    def gen_update(mod):
-        def update(self, context):
-            if getattr(self, 'use_' + mod.__name__.split('.')[-1]):
-                if not mod.__addon_enabled__:
-                    register_submodule(mod)
-            else:
-                if mod.__addon_enabled__:
-                    unregister_submodule(mod)
-        return update
-
-    prop = BoolProperty(
-            name=info['name'],
-            description=info.get('description', ''),
-            update=gen_update(mod),
-            )
-    setattr(AdvancedObjPreferences1, 'use_' + mod_name, prop)
-    prop = BoolProperty()
-    setattr(AdvancedObjPreferences1, 'show_expanded_' + mod_name, prop)
-
-
-class AdvancedObjProperties1(PropertyGroup):
-
-    # object_laplace_lighting props
-    ORIGIN: FloatVectorProperty(
-            name="Origin charge"
-            )
-    GROUNDZ: IntProperty(
-            name="Ground Z coordinate"
-            )
-    HORDER: IntProperty(
-            name="Secondary paths orders",
-            default=1
-            )
-    # object_laplace_lighting UI props
-    TSTEPS: IntProperty(
-            name="Iterations",
-            default=350,
-            description="Number of cells to create\n"
-                        "Will end early if hits ground plane or cloud"
-            )
-    GSCALE: FloatProperty(
-            name="Grid unit size",
-            default=0.12,
-            description="scale of cells, .25 = 4 cells per blenderUnit"
-            )
-    BIGVAR: FloatProperty(
-            name="Straightness",
-            default=6.3,
-            description="Straightness/branchiness of bolt, \n"
-                        "<2 is mush, >12 is staight line, 6.3 is good"
-            )
-    GROUNDBOOL: BoolProperty(
-            name="Use Ground object",
-            description="Use ground plane or not",
-            default=True
-            )
-    GROUNDC: IntProperty(
-            name="Ground charge",
-            default=-250,
-            description="Charge of the ground plane"
-            )
-    CLOUDBOOL: BoolProperty(
-            name="Use Cloud object",
-            default=False,
-            description="Use cloud object - attracts and terminates like ground but\n"
-                        "any obj instead of z plane\n"
-                        "Can slow down loop if obj is large, overrides ground"
-            )
-    CLOUDC: IntProperty(
-            name="Cloud charge",
-            default=-1,
-            description="Charge of a cell in cloud object\n"
-                        "(so total charge also depends on obj size)"
-            )
-    VMMESH: BoolProperty(
-            name="Multi mesh",
-            default=True,
-            description="Output to multi-meshes for different materials on main/sec/side branches"
-            )
-    VSMESH: BoolProperty(
-            name="Single mesh",
-            default=False,
-            description="Output to single mesh for using build modifier and particles for effects"
-            )
-    VCUBE: BoolProperty(
-            name="Cubes",
-            default=False,
-            description="CTRL-J after run to JOIN\n"
-                        "Outputs a bunch of cube objects, mostly for testing"
-            )
-    VVOX: BoolProperty(
-            name="Voxel (experimental)",
-            default=False,
-            description="Output to a voxel file to bpy.data.filepath\FSLGvoxels.raw\n"
-                        "(doesn't work well right now)"
-            )
-    IBOOL: BoolProperty(
-            name="Use Insulator object",
-            default=False,
-            description="Use insulator mesh object to prevent growth of bolt in areas"
-            )
-    OOB: StringProperty(
-            name="Select",
-            default="",
-            description="Origin of bolt, can be an Empty\n"
-                        "if object is a mesh will use all verts as charges")
-    GOB: StringProperty(
-            name="Select",
-            default="",
-            description="Object to use as ground plane, uses z coord only"
-            )
-    COB: StringProperty(
-            name="Select",
-            default="",
-            description="Object to use as cloud, best to use a cube"
-            )
-    IOB: StringProperty(
-            name="Select",
-            default="",
-            description="Object to use as insulator, 'voxelized'\n"
-                        "before generating bolt (can be slow)"
-            )
-    # object_mangle_tools properties
-    mangle_constraint_vector = BoolVectorProperty(
-            name="Mangle Constraint",
-            default=(True, True, True),
-            subtype='XYZ',
-            description="Constrains Mangle Direction"
-            )
-    mangle_random_magnitude: IntProperty(
-            name="Mangle Severity",
-            default=5,
-            min=1, max=30,
-            description="Severity of mangling"
-            )
-    mangle_name: StringProperty(
-            name="Shape Key Name",
-            default="mangle",
-            description="Name given for mangled shape keys"
-            )
-    # unfold_transition properties
-    unfold_arm_name: StringProperty(
-            default=""
-            )
-    unfold_modo: EnumProperty(
-            name="",
-            items=[("cursor", "3D Cursor", "Use the Distance to 3D Cursor"),
-                   ("weight", "Weight Map", "Use a Painted Weight map"),
-                   ("index", "Mesh Indices", "Use Faces and Vertices index")],
-            description="How to Sort Bones for animation", default="cursor"
-            )
-    unfold_flip: BoolProperty(
-            name="Flipping Faces",
-            default=False,
-            description="Rotate faces around the Center and skip Scaling - "
-                        "keep checked for both operators"
-            )
-    unfold_fold_duration: IntProperty(
-            name="Total Time",
-            min=5, soft_min=25,
-            max=10000, soft_max=2500,
-            default=200,
-            description="Total animation length"
-            )
-    unfold_sca_time: IntProperty(
-            name="Scale Time",
-            min=1,
-            max=5000, soft_max=500,
-            default=10,
-            description="Faces scaling time"
-            )
-    unfold_rot_time: IntProperty(
-            name="Rotation Time",
-            min=1, soft_min=5,
-            max=5000, soft_max=500,
-            default=15,
-            description="Faces rotation time"
-            )
-    unfold_rot_max: IntProperty(
-            name="Angle",
-            min=-180,
-            max=180,
-            default=135,
-            description="Faces rotation angle"
-            )
-    unfold_fold_noise: IntProperty(
-            name="Noise",
-            min=0,
-            max=500, soft_max=50,
-            default=0,
-            description="Offset some faces animation"
-            )
-    unfold_bounce: FloatProperty(
-            name="Bounce",
-            min=0,
-            max=10, soft_max=2.5,
-            default=0,
-            description="Add some bounce to rotation"
-            )
-    unfold_from_point: BoolProperty(
-            name="Point",
-            default=False,
-            description="Scale faces from a Point instead of from an Edge"
-            )
-    unfold_wiggle_rot: BoolProperty(
-            name="Wiggle",
-            default=False,
-            description="Use all Axis + Random Rotation instead of X Aligned"
-            )
-    # oscurart_constellation
-    constellation_limit: FloatProperty(
-            name="Initial Threshold",
-            description="Edges will be created only if the distance\n"
-                        "between vertices is smaller than this value\n"
-                        "This is a starting value on Operator Invoke",
-            default=2,
-            min=0
-            )
-
-
-# Class list
-classes = (
-    AdvancedObjPreferences1,
-    AdvancedObjProperties1,
-    )
-
-
-def register():
-    for cls in classes:
-        bpy.utils.register_class(cls)
-
-    bpy.types.Scene.advanced_objects1 = PointerProperty(
-                                            type=AdvancedObjProperties1
-                                            )
-
-    prefs = get_addon_preferences()
-    for mod in sub_modules:
-        if not hasattr(mod, '__addon_enabled__'):
-            mod.__addon_enabled__ = False
-        name = mod.__name__.split('.')[-1]
-        if getattr(prefs, 'use_' + name):
-            register_submodule(mod)
-
-
-def unregister():
-    for mod in sub_modules:
-        if mod.__addon_enabled__:
-            unregister_submodule(mod)
-    del bpy.types.Scene.advanced_objects1
-
-    for cls in reversed(classes):
-        bpy.utils.unregister_class(cls)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_panels/delaunay_voronoi.py b/add_advanced_objects_panels/delaunay_voronoi.py
deleted file mode 100644
index fdb54a1729dc157cd2d4ce0e81dc4b12af1e7883..0000000000000000000000000000000000000000
--- a/add_advanced_objects_panels/delaunay_voronoi.py
+++ /dev/null
@@ -1,344 +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": "Delaunay Voronoi",
-    "description": "Points cloud Delaunay triangulation in 2.5D "
-                   "(suitable for terrain modelling) or Voronoi diagram in 2D",
-    "author": "Domlysz, Oscurart",
-    "version": (1, 3),
-    "blender": (2, 70, 0),
-    "location": "3D View > Toolshelf > Create > Delaunay Voronoi",
-    "warning": "",
-    "wiki_url": "https://github.com/domlysz/BlenderGIS/wiki",
-    "category": "Add Mesh"
-    }
-
-import bpy
-from .DelaunayVoronoi import (
-        computeVoronoiDiagram,
-        computeDelaunayTriangulation,
-        )
-from bpy.types import (
-        Operator,
-        Panel,
-        )
-from bpy.props import EnumProperty
-
-try:
-    from scipy.spatial import Delaunay
-    import bmesh
-    import numpy as np
-    HAS_SCIPY = True
-except:
-    HAS_SCIPY = False
-    pass
-
-
-# Globals
-# set to True to enable debug_prints
-DEBUG = False
-
-
-def debug_prints(text=""):
-    global DEBUG
-    if DEBUG and text:
-        print(text)
-
-
-class Point:
-    def __init__(self, x, y, z):
-        self.x, self.y, self.z = x, y, z
-
-
-def unique(L):
-    """Return a list of unhashable elements in s, but without duplicates.
-    [[1, 2], [2, 3], [1, 2]] >>> [[1, 2], [2, 3]]"""
-    # For unhashable objects, you can sort the sequence and
-    # then scan from the end of the list, deleting duplicates as you go
-    nDupli = 0
-    nZcolinear = 0
-    # sort() brings the equal elements together; then duplicates
-    # are easy to weed out in a single pass
-    L.sort()
-    last = L[-1]
-    for i in range(len(L) - 2, -1, -1):
-        if last[:2] == L[i][:2]:    # XY coordinates compararison
-            if last[2] == L[i][2]:  # Z coordinates compararison
-                nDupli += 1         # duplicates vertices
-            else:  # Z colinear
-                nZcolinear += 1
-            del L[i]
-        else:
-            last = L[i]
-    # list data type is mutable, input list will automatically update
-    # and doesn't need to be returned
-    return (nDupli, nZcolinear)
-
-
-def checkEqual(lst):
-    return lst[1:] == lst[:-1]
-
-
-class ToolsPanelDelaunay(Panel):
-    bl_category = "Create"
-    bl_label = "Delaunay Voronoi"
-    bl_space_type = "VIEW_3D"
-    bl_context = "objectmode"
-    bl_region_type = "TOOLS"
-    bl_options = {"DEFAULT_CLOSED"}
-
-    def draw(self, context):
-        layout = self.layout
-
-        box = layout.box()
-        col = box.column(align=True)
-        col.label(text="Point Cloud:")
-        col.operator("delaunay.triangulation")
-        col.operator("voronoi.tesselation")
-
-
-class OBJECT_OT_TriangulateButton(Operator):
-    bl_idname = "delaunay.triangulation"
-    bl_label = "Triangulation"
-    bl_description = ("Terrain points cloud Delaunay triangulation in 2.5D\n"
-                      "Needs an existing Active Mesh Object")
-    bl_options = {"REGISTER", "UNDO"}
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj is not None and obj.type == "MESH")
-
-    def execute(self, context):
-        # move the check into the poll
-        obj = context.active_object
-
-        if HAS_SCIPY:
-            # Use scipy when present (~18 x faster)
-            bpy.ops.object.mode_set(mode='EDIT')
-            bm = bmesh.from_edit_mesh(obj.data)
-            points_3D = [list(v.co) for v in bm.verts]
-            points_2D = np.array([[v[0], v[1]] for v in points_3D])
-            print("Triangulate " + str(len(points_3D)) + " points...")
-            # Triangulate
-            tri = Delaunay(points_2D)
-            faces = tri.simplices.tolist()
-            # Create new mesh structure
-            print("Create mesh...")
-            bpy.ops.object.mode_set(mode='OBJECT')
-            mesh = bpy.data.meshes.new("TIN")
-            mesh.from_pydata(points_3D, [], faces)
-            mesh.update(calc_edges=True)
-            my = bpy.data.objects.new("TIN", mesh)
-            context.collection.objects.link(my)
-            my.matrix_world = obj.matrix_world.copy()
-            obj.select_set(False)
-            my.select_set(True)
-            context.view_layer.objects.active = my
-            self.report({'INFO'}, "Mesh created (" + str(len(faces)) + " triangles)")
-            print("Total :%s faces  %s verts" % (len(faces), len(points_3D)))
-            return {'FINISHED'}
-
-        # Get points coordinates
-        r = obj.rotation_euler
-        s = obj.scale
-        mesh = obj.data
-        vertsPts = [vertex.co for vertex in mesh.vertices]
-
-        # Remove duplicate
-        verts = [[vert.x, vert.y, vert.z] for vert in vertsPts]
-        nDupli, nZcolinear = unique(verts)
-        nVerts = len(verts)
-
-        debug_prints(text=str(nDupli) + " duplicate points ignored")
-        debug_prints(str(nZcolinear) + " z colinear points excluded")
-
-        if nVerts < 3:
-            self.report({"WARNING"},
-                        "Not enough points to continue. Operation Cancelled")
-
-            return {"CANCELLED"}
-
-        # Check colinear
-        xValues = [pt[0] for pt in verts]
-        yValues = [pt[1] for pt in verts]
-
-        if checkEqual(xValues) or checkEqual(yValues):
-            self.report({'ERROR'}, "Points are colinear")
-            return {'FINISHED'}
-
-        # Triangulate
-        debug_prints(text="Triangulate " + str(nVerts) + " points...")
-
-        vertsPts = [Point(vert[0], vert[1], vert[2]) for vert in verts]
-        triangles = computeDelaunayTriangulation(vertsPts)
-        # reverse point order --> if all triangles are specified anticlockwise then all faces up
-        triangles = [tuple(reversed(tri)) for tri in triangles]
-
-        debug_prints(text=str(len(triangles)) + " triangles")
-
-        # Create new mesh structure
-        debug_prints(text="Create mesh...")
-        tinMesh = bpy.data.meshes.new("TIN")        # create a new mesh
-        tinMesh.from_pydata(verts, [], triangles)   # Fill the mesh with triangles
-        tinMesh.update(calc_edges=True)             # Update mesh with new data
-
-        # Create an object with that mesh
-        tinObj = bpy.data.objects.new("TIN", tinMesh)
-
-        # Place object
-        tinObj.location = obj.location.copy()
-        tinObj.rotation_euler = r
-        tinObj.scale = s
-
-        # Update scene
-        bpy.context.collection.objects.link(tinObj)  # Link object to collection 
-        bpy.context.view_layer.objects.active = tinObj
-        tinObj.select_set(True)
-        obj.select_set(False)
-
-        self.report({"INFO"},
-                     "Mesh created (" + str(len(triangles)) + " triangles)")
-
-        return {'FINISHED'}
-
-
-class OBJECT_OT_VoronoiButton(Operator):
-    bl_idname = "voronoi.tesselation"
-    bl_label = "Diagram"
-    bl_description = ("Points cloud Voronoi diagram in 2D\n"
-                      "Needs an existing Active Mesh Object")
-    bl_options = {"REGISTER", "UNDO"}
-
-    meshType: EnumProperty(
-            items=[('Edges', "Edges", "Edges Only - do not fill Faces"),
-                   ('Faces', "Faces", "Fill Faces in the new Object")],
-            name="Mesh type",
-            description="Type of geometry to generate"
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj is not None and obj.type == "MESH")
-
-    def execute(self, context):
-        # move the check into the poll
-        obj = context.active_object
-
-        # Get points coordinates
-        r = obj.rotation_euler
-        s = obj.scale
-        mesh = obj.data
-        vertsPts = [vertex.co for vertex in mesh.vertices]
-
-        # Remove duplicate
-        verts = [[vert.x, vert.y, vert.z] for vert in vertsPts]
-        nDupli, nZcolinear = unique(verts)
-        nVerts = len(verts)
-
-        debug_prints(text=str(nDupli) + " duplicates points ignored")
-        debug_prints(text=str(nZcolinear) + " z colinear points excluded")
-
-        if nVerts < 3:
-            self.report({"WARNING"},
-                        "Not enough points to continue. Operation Cancelled")
-
-            return {"CANCELLED"}
-
-        # Check colinear
-        xValues = [pt[0] for pt in verts]
-        yValues = [pt[1] for pt in verts]
-
-        if checkEqual(xValues) or checkEqual(yValues):
-            self.report({"WARNING"},
-                        "Points are colinear. Operation Cancelled")
-
-            return {"CANCELLED"}
-
-        # Create diagram
-        debug_prints(text="Tesselation... (" + str(nVerts) + " points)")
-
-        xbuff, ybuff = 5, 5
-        zPosition = 0
-        vertsPts = [Point(vert[0], vert[1], vert[2]) for vert in verts]
-
-        if self.meshType == "Edges":
-            pts, edgesIdx = computeVoronoiDiagram(
-                                vertsPts, xbuff, ybuff,
-                                polygonsOutput=False, formatOutput=True
-                                )
-        else:
-            pts, polyIdx = computeVoronoiDiagram(
-                                vertsPts, xbuff, ybuff, polygonsOutput=True,
-                                formatOutput=True, closePoly=False
-                                )
-
-        pts = [[pt[0], pt[1], zPosition] for pt in pts]
-
-        # Create new mesh structure
-        voronoiDiagram = bpy.data.meshes.new("VoronoiDiagram")  # create a new mesh
-
-        if self.meshType == "Edges":
-            # Fill the mesh with triangles
-            voronoiDiagram.from_pydata(pts, edgesIdx, [])
-        else:
-            # Fill the mesh with triangles
-            voronoiDiagram.from_pydata(pts, [], list(polyIdx.values()))
-
-        voronoiDiagram.update(calc_edges=True)  # Update mesh with new data
-        # create an object with that mesh
-        voronoiObj = bpy.data.objects.new("VoronoiDiagram", voronoiDiagram)
-        # place object
-        voronoiObj.location = obj.location.copy()
-        voronoiObj.rotation_euler = r
-        voronoiObj.scale = s
-
-        # update scene
-        bpy.context.collection.objects.link(voronoiObj)  # Link object to collection
-        bpy.context.view_layer.objects.active = voronoiObj
-        voronoiObj.select_set(True)
-        obj.select_set(False)
-
-        # Report
-        if self.meshType == "Edges":
-            self.report({"INFO"}, "Mesh created (" + str(len(edgesIdx)) + " edges)")
-        else:
-            self.report({"INFO"}, "Mesh created (" + str(len(polyIdx)) + " polygons)")
-
-        return {'FINISHED'}
-
-
-# Register
-def register():
-    bpy.utils.register_class(OBJECT_OT_VoronoiButton)
-    bpy.utils.register_class(OBJECT_OT_TriangulateButton)
-    bpy.utils.register_class(ToolsPanelDelaunay)
-
-
-def unregister():
-    bpy.utils.unregister_class(OBJECT_OT_VoronoiButton)
-    bpy.utils.unregister_class(OBJECT_OT_TriangulateButton)
-    bpy.utils.unregister_class(ToolsPanelDelaunay)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_panels/drop_to_ground.py b/add_advanced_objects_panels/drop_to_ground.py
deleted file mode 100644
index c9d9a7b4130bfc0d52804874322ba122d3b731e6..0000000000000000000000000000000000000000
--- a/add_advanced_objects_panels/drop_to_ground.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 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": "Drop to Ground1",
-    "author": "Unnikrishnan(kodemax), Florian Meyer(testscreenings)",
-    "blender": (2, 71, 0),
-    "location": "3D View > Toolshelf > Create > Drop To Ground",
-    "description": "Drop selected objects on active object",
-    "warning": "",
-    "category": "Object"}
-
-
-import bpy
-import bmesh
-from mathutils import (
-        Vector,
-        Matrix,
-        )
-from bpy.types import (
-        Operator,
-        Panel,
-        )
-from bpy.props import BoolProperty
-
-
-def test_ground_object(ground):
-    if ground.type in {'MESH', 'FONT', 'META', 'CURVE', 'SURFACE'}:
-        return True
-    return False
-
-
-def get_align_matrix(location, normal):
-    up = Vector((0, 0, 1))
-    angle = normal.angle(up)
-    axis = up.cross(normal)
-    mat_rot = Matrix.Rotation(angle, 4, axis)
-    mat_loc = Matrix.Translation(location)
-    mat_align = mat_rot * mat_loc
-    return mat_align
-
-
-def transform_ground_to_world(sc, ground):
-    tmpMesh = ground.to_mesh(sc, True, 'PREVIEW')
-    tmpMesh.transform(ground.matrix_world)
-    tmp_ground = bpy.data.objects.new('tmpGround', tmpMesh)
-    sc.objects.link(tmp_ground)
-    sc.update()
-
-    return tmp_ground
-
-
-def get_lowest_world_co_from_mesh(ob, mat_parent=None):
-    bme = bmesh.new()
-    bme.from_mesh(ob.data)
-    mat_to_world = ob.matrix_world.copy()
-    if mat_parent:
-        mat_to_world = mat_parent * mat_to_world
-    lowest = None
-    for v in bme.verts:
-        if not lowest:
-            lowest = v
-        if (mat_to_world * v.co).z < (mat_to_world * lowest.co).z:
-            lowest = v
-    lowest_co = mat_to_world * lowest.co
-    bme.free()
-
-    return lowest_co
-
-
-def get_lowest_world_co(context, ob, mat_parent=None):
-    if ob.type == 'MESH':
-        return get_lowest_world_co_from_mesh(ob)
-
-    elif ob.type == 'EMPTY' and ob.instance_type == 'COLLECTION':
-        if not ob.instance_collection:
-            return None
-
-        else:
-            lowest_co = None
-            for ob_l in ob.instance_collection.objects:
-                if ob_l.type == 'MESH':
-                    lowest_ob_l = get_lowest_world_co_from_mesh(ob_l, ob.matrix_world)
-                    if not lowest_co:
-                        lowest_co = lowest_ob_l
-                    if lowest_ob_l.z < lowest_co.z:
-                        lowest_co = lowest_ob_l
-
-            return lowest_co
-
-
-def drop_objectsall(self, context):
-    ground = context.active_object
-    name = ground.name
-
-    for obs in bpy.context.scene.objects:
-        obs.select_set(True)
-        if obs.name == name:
-            obs.select_set(False)
-
-    obs2 = context.selected_objects
-
-    tmp_ground = transform_ground_to_world(context.scene, ground)
-    down = Vector((0, 0, -10000))
-
-    for ob in obs2:
-        if self.use_origin:
-            lowest_world_co = ob.location
-        else:
-            lowest_world_co = get_lowest_world_co(context, ob)
-
-        if not lowest_world_co:
-            message = "Object {} is of type {} works only with Use Center option " \
-                      "checked".format(ob.name, ob.type)
-            self.reported.append(message)
-            continue
-        is_hit, hit_location, hit_normal, hit_index = tmp_ground.ray_cast(lowest_world_co, down)
-
-        if not is_hit:
-            message = ob.name + " did not hit the Ground"
-            self.reported.append(message)
-            continue
-
-        # simple drop down
-        to_ground_vec = hit_location - lowest_world_co
-        ob.location += to_ground_vec
-
-        # drop with align to hit normal
-        if self.align:
-            to_center_vec = ob.location - hit_location  # vec: hit_loc to origin
-            # rotate object to align with face normal
-            mat_normal = get_align_matrix(hit_location, hit_normal)
-            rot_euler = mat_normal.to_euler()
-            mat_ob_tmp = ob.matrix_world.copy().to_3x3()
-            mat_ob_tmp.rotate(rot_euler)
-            mat_ob_tmp = mat_ob_tmp.to_4x4()
-            ob.matrix_world = mat_ob_tmp
-            # move_object to hit_location
-            ob.location = hit_location
-            # move object above surface again
-            to_center_vec.rotate(rot_euler)
-            ob.location += to_center_vec
-
-    # cleanup
-    bpy.ops.object.select_all(action='DESELECT')
-    tmp_ground.select_set(True)
-    bpy.ops.object.delete('EXEC_DEFAULT')
-    for ob in obs2:
-        ob.select_set(True)
-    ground.select_set(True)
-
-
-def drop_objects(self, context):
-    ground = context.active_object
-
-    obs = context.selected_objects
-    if ground in obs:
-        obs.remove(ground)
-
-    tmp_ground = transform_ground_to_world(context.scene, ground)
-    down = Vector((0, 0, -10000))
-
-    for ob in obs:
-        if self.use_origin:
-            lowest_world_co = ob.location
-        else:
-            lowest_world_co = get_lowest_world_co(context, ob)
-
-        if not lowest_world_co:
-            message = "Object {} is of type {} works only with Use Center option " \
-                      "checked".format(ob.name, ob.type)
-            self.reported.append(message)
-            continue
-
-        is_hit, hit_location, hit_normal, hit_index = tmp_ground.ray_cast(lowest_world_co, down)
-        if not is_hit:
-            message = ob.name + " did not hit the Active Object"
-            self.reported.append(message)
-            continue
-
-        # simple drop down
-        to_ground_vec = hit_location - lowest_world_co
-        ob.location += to_ground_vec
-
-        # drop with align to hit normal
-        if self.align:
-            to_center_vec = ob.location - hit_location  # vec: hit_loc to origin
-            # rotate object to align with face normal
-            mat_normal = get_align_matrix(hit_location, hit_normal)
-            rot_euler = mat_normal.to_euler()
-            mat_ob_tmp = ob.matrix_world.copy().to_3x3()
-            mat_ob_tmp.rotate(rot_euler)
-            mat_ob_tmp = mat_ob_tmp.to_4x4()
-            ob.matrix_world = mat_ob_tmp
-            # move_object to hit_location
-            ob.location = hit_location
-            # move object above surface again
-            to_center_vec.rotate(rot_euler)
-            ob.location += to_center_vec
-
-    # cleanup
-    bpy.ops.object.select_all(action='DESELECT')
-    tmp_ground.select_set(True)
-    bpy.ops.object.delete('EXEC_DEFAULT')
-    for ob in obs:
-        ob.select_set(True)
-    ground.select_set(True)
-
-
-# define base dummy class for inheritance
-class DropBaseAtributes:
-    align: BoolProperty(
-            name="Align to ground",
-            description="Aligns the objects' rotation to the ground",
-            default=True)
-    use_origin: BoolProperty(
-            name="Use Origins",
-            description="Drop to objects' origins\n"
-                        "Use this option for dropping all types of Objects",
-            default=False)
-
-
-class OBJECT_OT_drop_to_ground(Operator, DropBaseAtributes):
-    bl_idname = "object.drop_on_active"
-    bl_label = "Drop to Ground"
-    bl_description = ("Drop selected objects on the Active object\n"
-                      "Active Object has to be of following the types:\n"
-                      "Mesh, Font, Metaball, Curve, Surface")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    reported = []
-
-    @classmethod
-    def poll(cls, context):
-        act_obj = context.active_object
-        return (len(context.selected_objects) >= 2 and
-                act_obj and test_ground_object(act_obj))
-
-    def execute(self, context):
-        drop_objects(self, context)
-
-        if self.reported:
-            self.report({"INFO"},
-                        "Some objects could not be dropped (See the Console for more Info)")
-            report_items = "  \n".join(self.reported)
-            print("\n[Drop to Ground Report]\n{}\n".format(report_items))
-
-        self.reported[:] = []
-
-        return {'FINISHED'}
-
-
-class OBJECT_OT_drop_all_ground(Operator, DropBaseAtributes):
-    bl_idname = "object.drop_all_active"
-    bl_label = "Drop All to Ground (Active Object)"
-    bl_description = ("Drop all other objects onto Active Object\n"
-                      "Active Object has to be of following the types:\n"
-                      "Mesh, Font, Metaball, Curve, Surface")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    reported = []
-
-    @classmethod
-    def poll(cls, context):
-        act_obj = context.active_object
-        return act_obj and test_ground_object(act_obj)
-
-    def execute(self, context):
-        drop_objectsall(self, context)
-
-        if self.reported:
-            self.report({"INFO"},
-                        "Some objects could not be dropped (See the Console for more Info)")
-            report_items = "  \n".join(self.reported)
-            print("\n[Drop All to Ground Report]\n{}\n".format(report_items))
-
-        self.reported[:] = []
-
-        return {'FINISHED'}
-
-
-class Drop_help(Operator):
-    bl_idname = "help.drop"
-    bl_label = "Drop to Ground Help"
-    bl_description = "Clik for some information about Drop to Ground"
-    bl_options = {"REGISTER", "INTERNAL"}
-
-    is_all: BoolProperty(
-            default=True,
-            options={"HIDDEN"}
-            )
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.label(text="General Info:")
-        layout.label(text="The Active Object has to be of a Mesh, Font,")
-        layout.label(text="Metaball, Curve or Surface type and")
-        layout.label(text="be at the lowest Z location")
-        layout.label(text="The option Use Origins must be enabled to drop")
-        layout.label(text="objects that are not of a Mesh or DupliGroup type")
-        layout.label(text="The Active Object has to be big enough to catch them")
-        layout.label(text="To check that, use the Orthographic Top View")
-        layout.separator()
-
-        layout.label(text="To use:")
-
-        if self.is_all is False:
-            layout.label(text="Select objects to drop")
-            layout.label(text="Then Shift Select the object to be the ground")
-            layout.label(text="Drops Selected Object to the Active one")
-        else:
-            layout.label(text="Select the ground Mesh and press Drop all")
-            layout.label(text="The unselected Objects will be moved straight")
-            layout.label(text="down the Z axis, so they have to be above")
-            layout.label(text="the Selected / Active one to fall")
-
-    def execute(self, context):
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        return context.window_manager.invoke_popup(self, width=300)
-
-
-class Drop_Operator_Panel(Panel):
-    bl_label = "Drop To Ground"
-    bl_region_type = "TOOLS"
-    bl_space_type = "VIEW_3D"
-    bl_options = {'DEFAULT_CLOSED'}
-    bl_context = "objectmode"
-    bl_category = "Create"
-
-    def draw(self, context):
-        layout = self.layout
-
-        row = layout.split(percentage=0.8, align=True)
-        row.operator(OBJECT_OT_drop_to_ground.bl_idname,
-                     text="Drop Selected")
-        row.operator("help.drop", text="", icon="LAYER_USED").is_all = False
-
-        row = layout.split(percentage=0.8, align=True)
-        row.operator(OBJECT_OT_drop_all_ground.bl_idname,
-                     text="Drop All")
-        row.operator("help.drop", text="", icon="LAYER_USED").is_all = True
-
-
-# Register
-def register():
-    bpy.utils.register_class(OBJECT_OT_drop_all_ground)
-    bpy.utils.register_class(OBJECT_OT_drop_to_ground)
-    bpy.utils.register_class(Drop_Operator_Panel)
-    bpy.utils.register_class(Drop_help)
-
-
-def unregister():
-    bpy.utils.unregister_class(OBJECT_OT_drop_all_ground)
-    bpy.utils.unregister_class(OBJECT_OT_drop_to_ground)
-    bpy.utils.unregister_class(Drop_Operator_Panel)
-    bpy.utils.unregister_class(Drop_help)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_panels/object_laplace_lightning.py b/add_advanced_objects_panels/object_laplace_lightning.py
deleted file mode 100644
index ece0640dd44445d2d0247883bd11df3b33ebf9ce..0000000000000000000000000000000000000000
--- a/add_advanced_objects_panels/object_laplace_lightning.py
+++ /dev/null
@@ -1,1446 +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 #####
-
-# NOTE: moved the winmgr properties to __init__ and scene
-# search for context.scene.advanced_objects1
-
-bl_info = {
-    "name": "Laplacian Lightning",
-    "author": "teldredge",
-    "blender": (2, 78, 0),
-    "location": "3D View > Toolshelf > Create > Laplacian Lightning",
-    "description": "Lightning mesh generator using laplacian growth algorithm",
-    "warning": "",
-    "category": "Object"}
-
-# BLENDER LAPLACIAN LIGHTNING
-# teldredge
-# www.funkboxing.com
-# https://developer.blender.org/T27189
-
-# using algorithm from
-# FAST SIMULATION OF LAPLACIAN GROWTH (FSLG)
-# http://gamma.cs.unc.edu/FRAC/
-
-# and a few ideas ideas from
-# FAST ANIMATION OF LIGHTNING USING AN ADAPTIVE MESH (FALUAM)
-# http://gamma.cs.unc.edu/FAST_LIGHTNING/
-
-
-"""
------ RELEASE LOG/NOTES/PONTIFICATIONS -----
-v0.1.0 - 04.11.11
-    basic generate functions and UI
-    object creation report (Custom Properties: FSLG_REPORT)
-v0.2.0 - 04.15.11
-    started spelling laplacian right.
-    add curve function (not in UI) ...twisting problem
-    classify stroke by MAIN path, h-ORDER paths, TIP paths
-    jitter cells for mesh creation
-    add materials if present
-v0.2.1 - 04.16.11
-    mesh classification speedup
-v0.2.2 - 04.21.11
-    fxns to write/read array to file
-    restrict growth to insulator cells (object bounding box)
-    origin/ground defineable by object
-    gridunit more like 'resolution'
-v0.2.3 - 04.24.11
-    cloud attractor object (termintates loop if hit)
-    secondary path orders (hOrder) disabled in UI (set to 1)
-v0.2.4 - 04.26.11
-    fixed object selection in UI
-    will not run if required object not selected
-    moved to view 3d > toolbox
-v0.2.5 - 05.08.11
-    testing for 2.57b
-    single mesh output (for build modifier)
-    speedups (dist fxn)
-v0.2.6 - 06.20.11
-    scale/pos on 'write to cubes' works now
-    if origin obj is mesh, uses all verts as initial charges
-    semi-helpful tooltips
-    speedups, faster dedupe fxn, faster classification
-    use any shape mesh obj as insulator mesh
-        must have rot=0, scale=1, origin set to geometry
-        often fails to block bolt with curved/complex shapes
-    separate single and multi mesh creation
-v0.2.7 - 01.05.13
-    fixed the issue that prevented enabling the add-on
-    fixed makeMeshCube fxn
-    disabled visualization for voxels
-
-v0.x -
-    -prevent create_setup_objects from generating duplicates
-    -fix vis fxn to only buildCPGraph once for VM or VS
-    -improve list fxns (rid of ((x,y,z),w) and use (x,y,z,w)), use 'sets'
-    -create python cmodule for a few of most costly fxns
-        i have pretty much no idea how to do this yet
-    -cloud and insulator can be groups of MESH objs
-    -text output, possibly to save on interrupt, allow continue from text
-    -?hook modifiers from tips->sides->main, weight w/ vert groups
-    -user defined 'attractor' path
-    -fix add curve function
-    -animated arcs via. ionization path
-    -environment map boundary conditions - requires Eqn. 15 from FSLG.
-    -assign wattage at each segment for HDRI
-    -?default settings for -lightning, -teslacoil, -spark/arc
-    -fix hOrder functionality
-    -multiple 'MAIN' brances for non-lightning discharges
-    -n-symmetry option, create mirror images, snowflakes, etc...
-"""
-
-import bpy
-import time
-import random
-from bpy.types import (
-        Operator,
-        Panel,
-        )
-# from math import sqrt
-from mathutils import Vector
-import struct
-import bisect
-import os.path
-
-# -- Globals --
-notZero = 0.0000000001
-# set to True to enable debug prints
-DEBUG = False
-
-
-# Utility Functions
-
-# func - function name, text - message, var - variable to print
-# it can have one variable to observe
-def debug_prints(func="", text="Message", var=None):
-    global DEBUG
-    if DEBUG:
-        print("\n[{}]\nmessage: {}".format(func, text))
-        if var:
-            print("variable: ", var)
-
-
-# pass variables just like for the regular prints
-def debug_print_vars(*args, **kwargs):
-    global DEBUG
-    if DEBUG:
-        print(*args, **kwargs)
-
-
-def within(x, y, d):
-    # CHECK IF x - d <= y <= x + d
-    if x - d <= y and x + d >= y:
-        return True
-    else:
-        return False
-
-
-def dist(ax, ay, az, bx, by, bz):
-    dv = Vector((ax, ay, az)) - Vector((bx, by, bz))
-    d = dv.length
-    return d
-
-
-def splitList(aList, idx):
-    ll = []
-    for x in aList:
-        ll.append(x[idx])
-    return ll
-
-
-def splitListCo(aList):
-    ll = []
-    for p in aList:
-        ll.append((p[0], p[1], p[2]))
-    return ll
-
-
-def getLowHigh(aList):
-    tLow = aList[0]
-    tHigh = aList[0]
-    for a in aList:
-        if a < tLow:
-            tLow = a
-        if a > tHigh:
-            tHigh = a
-    return tLow, tHigh
-
-
-def weightedRandomChoice(aList):
-    tL = []
-    tweight = 0
-    for a in range(len(aList)):
-        idex = a
-        weight = aList[a]
-        if weight > 0.0:
-            tweight += weight
-            tL.append((tweight, idex))
-    i = bisect.bisect(tL, (random.uniform(0, tweight), None))
-    r = tL[i][1]
-    return r
-
-
-def getStencil3D_26(x, y, z):
-    nL = []
-    for xT in range(x - 1, x + 2):
-        for yT in range(y - 1, y + 2):
-            for zT in range(z - 1, z + 2):
-                nL.append((xT, yT, zT))
-    nL.remove((x, y, z))
-    return nL
-
-
-def jitterCells(aList, jit):
-    j = jit / 2
-    bList = []
-    for a in aList:
-        ax = a[0] + random.uniform(-j, j)
-        ay = a[1] + random.uniform(-j, j)
-        az = a[2] + random.uniform(-j, j)
-        bList.append((ax, ay, az))
-    return bList
-
-
-def deDupe(seq, idfun=None):
-    # Thanks to this guy - http://www.peterbe.com/plog/uniqifiers-benchmark
-    if idfun is None:
-        def idfun(x):
-            return x
-    seen = {}
-    result = []
-    for item in seq:
-        marker = idfun(item)
-        if marker in seen:
-            continue
-        seen[marker] = 1
-        result.append(item)
-    return result
-
-
-# Visulization functions
-
-def writeArrayToVoxel(arr, filename):
-    gridS = 64
-    half = int(gridS / 2)
-    bitOn = 255
-    aGrid = [[[0 for z in range(gridS)] for y in range(gridS)] for x in range(gridS)]
-    for a in arr:
-        try:
-            aGrid[a[0] + half][a[1] + half][a[2] + half] = bitOn
-        except:
-            debug_prints(func="writeArrayToVoxel", text="Particle beyond voxel domain")
-
-    file = open(filename, "wb")
-    for z in range(gridS):
-        for y in range(gridS):
-            for x in range(gridS):
-                file.write(struct.pack('B', aGrid[x][y][z]))
-    file.flush()
-    file.close()
-
-
-def writeArrayToFile(arr, filename):
-    file = open(filename, "w")
-    for a in arr:
-        tstr = str(a[0]) + ',' + str(a[1]) + ',' + str(a[2]) + '\n'
-        file.write(tstr)
-    file.close
-
-
-def readArrayFromFile(filename):
-    file = open(filename, "r")
-    arr = []
-    for f in file:
-        pt = f[0:-1].split(',')
-        arr.append((int(pt[0]), int(pt[1]), int(pt[2])))
-    return arr
-
-
-def makeMeshCube_OLD(msize):
-    msize = msize / 2
-    mmesh = bpy.data.meshes.new('q')
-    mmesh.vertices.add(8)
-    mmesh.vertices[0].co = [-msize, -msize, -msize]
-    mmesh.vertices[1].co = [-msize, msize, -msize]
-    mmesh.vertices[2].co = [msize, msize, -msize]
-    mmesh.vertices[3].co = [msize, -msize, -msize]
-    mmesh.vertices[4].co = [-msize, -msize, msize]
-    mmesh.vertices[5].co = [-msize, msize, msize]
-    mmesh.vertices[6].co = [msize, msize, msize]
-    mmesh.vertices[7].co = [msize, -msize, msize]
-    mmesh.faces.add(6)
-    mmesh.faces[0].vertices_raw = [0, 1, 2, 3]
-    mmesh.faces[1].vertices_raw = [0, 4, 5, 1]
-    mmesh.faces[2].vertices_raw = [2, 1, 5, 6]
-    mmesh.faces[3].vertices_raw = [3, 2, 6, 7]
-    mmesh.faces[4].vertices_raw = [0, 3, 7, 4]
-    mmesh.faces[5].vertices_raw = [5, 4, 7, 6]
-    mmesh.update(calc_edges=True)
-
-    return(mmesh)
-
-
-def makeMeshCube(msize):
-    m2 = msize / 2
-    # verts = [(0,0,0),(0,5,0),(5,5,0),(5,0,0),(0,0,5),(0,5,5),(5,5,5),(5,0,5)]
-    verts = [(-m2, -m2, -m2), (-m2, m2, -m2), (m2, m2, -m2), (m2, -m2, -m2),
-             (-m2, -m2, m2), (-m2, m2, m2), (m2, m2, m2), (m2, -m2, m2)]
-    faces = [
-        (0, 1, 2, 3), (4, 5, 6, 7), (0, 4, 5, 1),
-        (1, 5, 6, 2), (2, 6, 7, 3), (3, 7, 4, 0)
-        ]
-    # Define mesh and object
-    mmesh = bpy.data.meshes.new("Cube")
-
-    # Create mesh
-    mmesh.from_pydata(verts, [], faces)
-    mmesh.update(calc_edges=True)
-    return(mmesh)
-
-
-def writeArrayToCubes(arr, gridBU, orig, cBOOL=False, jBOOL=True):
-    for a in arr:
-        x = a[0]
-        y = a[1]
-        z = a[2]
-        me = makeMeshCube(gridBU)
-        ob = bpy.data.objects.new('xCUBE', me)
-        ob.location.x = (x * gridBU) + orig[0]
-        ob.location.y = (y * gridBU) + orig[1]
-        ob.location.z = (z * gridBU) + orig[2]
-
-        if cBOOL:  # mostly unused
-            # pos + blue, neg - red, zero: black
-            col = (1.0, 1.0, 1.0, 1.0)
-            if a[3] == 0:
-                col = (0.0, 0.0, 0.0, 1.0)
-            if a[3] < 0:
-                col = (-a[3], 0.0, 0.0, 1.0)
-            if a[3] > 0:
-                col = (0.0, 0.0, a[3], 1.0)
-            ob.color = col
-        bpy.context.collection.objects.link(ob)
-        bpy.context.scene.update()
-
-    if jBOOL:
-        # Selects all cubes w/ ?bpy.ops.object.join() b/c
-        # Can't join all cubes to a single mesh right... argh...
-        for q in bpy.context.scene.objects:
-            q.select_set(False)
-            if q.name[0:5] == 'xCUBE':
-                q.select_set(True)
-                bpy.context.view_layer.objects.active = q
-
-
-def addVert(ob, pt, conni=-1):
-    mmesh = ob.data
-    mmesh.vertices.add(1)
-    vcounti = len(mmesh.vertices) - 1
-    mmesh.vertices[vcounti].co = [pt[0], pt[1], pt[2]]
-    if conni > -1:
-        mmesh.edges.add(1)
-        ecounti = len(mmesh.edges) - 1
-        mmesh.edges[ecounti].vertices = [conni, vcounti]
-        mmesh.update()
-
-
-def addEdge(ob, va, vb):
-    mmesh = ob.data
-    mmesh.edges.add(1)
-    ecounti = len(mmesh.edges) - 1
-    mmesh.edges[ecounti].vertices = [va, vb]
-    mmesh.update()
-
-
-def newMesh(mname):
-    mmesh = bpy.data.meshes.new(mname)
-    omesh = bpy.data.objects.new(mname, mmesh)
-    bpy.context.collection.objects.link(omesh)
-    return omesh
-
-
-def writeArrayToMesh(mname, arr, gridBU, rpt=None):
-    mob = newMesh(mname)
-    mob.scale = (gridBU, gridBU, gridBU)
-    if rpt:
-        addReportProp(mob, rpt)
-    addVert(mob, arr[0], -1)
-    for ai in range(1, len(arr)):
-        a = arr[ai]
-        addVert(mob, a, ai - 1)
-    return mob
-
-
-# out of order - some problem with it adding (0,0,0)
-def writeArrayToCurves(cname, arr, gridBU, bd=.05, rpt=None):
-    cur = bpy.data.curves.new('fslg_curve', 'CURVE')
-    cur.use_fill_front = False
-    cur.use_fill_back = False
-    cur.bevel_depth = bd
-    cur.bevel_resolution = 2
-    cob = bpy.data.objects.new(cname, cur)
-    cob.scale = (gridBU, gridBU, gridBU)
-
-    if rpt:
-        addReportProp(cob, rpt)
-    bpy.context.collection.objects.link(cob)
-    cur.splines.new('BEZIER')
-    cspline = cur.splines[0]
-    div = 1  # spacing for handles (2 - 1/2 way, 1 - next bezier)
-
-    for a in range(len(arr)):
-        cspline.bezier_points.add(1)
-        bp = cspline.bezier_points[len(cspline.bezier_points) - 1]
-        if a - 1 < 0:
-            hL = arr[a]
-        else:
-            hx = arr[a][0] - ((arr[a][0] - arr[a - 1][0]) / div)
-            hy = arr[a][1] - ((arr[a][1] - arr[a - 1][1]) / div)
-            hz = arr[a][2] - ((arr[a][2] - arr[a - 1][2]) / div)
-            hL = (hx, hy, hz)
-
-        if a + 1 > len(arr) - 1:
-            hR = arr[a]
-        else:
-            hx = arr[a][0] + ((arr[a + 1][0] - arr[a][0]) / div)
-            hy = arr[a][1] + ((arr[a + 1][1] - arr[a][1]) / div)
-            hz = arr[a][2] + ((arr[a + 1][2] - arr[a][2]) / div)
-            hR = (hx, hy, hz)
-        bp.co = arr[a]
-        bp.handle_left = hL
-        bp.handle_right = hR
-
-
-def addArrayToMesh(mob, arr):
-    addVert(mob, arr[0], -1)
-    mmesh = mob.data
-    vcounti = len(mmesh.vertices) - 1
-    for ai in range(1, len(arr)):
-        a = arr[ai]
-        addVert(mob, a, len(mmesh.vertices) - 1)
-
-
-def addMaterial(ob, matname):
-    mat = bpy.data.materials[matname]
-    ob.active_material = mat
-
-
-def writeStokeToMesh(arr, jarr, MAINi, HORDERi, TIPSi, orig, gs, rpt=None):
-    # main branch
-    debug_prints(func="writeStokeToMesh", text='Writing main branch')
-    llmain = []
-
-    for x in MAINi:
-        llmain.append(jarr[x])
-    mob = writeArrayToMesh('la0MAIN', llmain, gs)
-    mob.location = orig
-
-    # horder branches
-    for hOi in range(len(HORDERi)):
-        debug_prints(func="writeStokeToMesh", text="Writing order", var=hOi)
-        hO = HORDERi[hOi]
-        hob = newMesh('la1H' + str(hOi))
-
-        for y in hO:
-            llHO = []
-            for x in y:
-                llHO.append(jarr[x])
-            addArrayToMesh(hob, llHO)
-        hob.scale = (gs, gs, gs)
-        hob.location = orig
-
-    # tips
-    debug_prints(func="writeStokeToMesh", text="Writing tip paths")
-    tob = newMesh('la2TIPS')
-    for y in TIPSi:
-        llt = []
-        for x in y:
-            llt.append(jarr[x])
-        addArrayToMesh(tob, llt)
-    tob.scale = (gs, gs, gs)
-    tob.location = orig
-
-    # add materials to objects (if they exist)
-    try:
-        addMaterial(mob, 'edgeMAT-h0')
-        addMaterial(hob, 'edgeMAT-h1')
-        addMaterial(tob, 'edgeMAT-h2')
-        debug_prints(func="writeStokeToMesh", text="Added materials")
-
-    except:
-        debug_prints(func="writeStokeToMesh", text="Materials not found")
-
-    # add generation report to all meshes
-    if rpt:
-        addReportProp(mob, rpt)
-        addReportProp(hob, rpt)
-        addReportProp(tob, rpt)
-
-
-def writeStokeToSingleMesh(arr, jarr, orig, gs, mct, rpt=None):
-    sgarr = buildCPGraph(arr, mct)
-    llALL = []
-
-    Aob = newMesh('laALL')
-    for pt in jarr:
-        addVert(Aob, pt)
-    for cpi in range(len(sgarr)):
-        ci = sgarr[cpi][0]
-        pi = sgarr[cpi][1]
-        addEdge(Aob, pi, ci)
-    Aob.location = orig
-    Aob.scale = ((gs, gs, gs))
-
-    if rpt:
-        addReportProp(Aob, rpt)
-
-
-def visualizeArray(cg, oob, gs, vm, vs, vc, vv, rst):
-    winmgr = bpy.context.scene.advanced_objects1
-    # IN: (cellgrid, origin, gridscale,
-    # mulimesh, single mesh, cubes, voxels, report string)
-    origin = oob.location
-
-    # deal with vert multi-origins
-    oct = 2
-    if oob.type == 'MESH':
-        oct = len(oob.data.vertices)
-
-    # jitter cells
-    if vm or vs:
-        cjarr = jitterCells(cg, 1)
-
-    if vm:  # write array to multi mesh
-
-        aMi, aHi, aTi = classifyStroke(cg, oct, winmgr.HORDER)
-        debug_prints(func="visualizeArray", text="Writing to multi-mesh")
-        writeStokeToMesh(cg, cjarr, aMi, aHi, aTi, origin, gs, rst)
-        debug_prints(func="visualizeArray", text="Multi-mesh written")
-
-    if vs:  # write to single mesh
-        debug_prints(func="visualizeArray", text="Writing to single mesh")
-        writeStokeToSingleMesh(cg, cjarr, origin, gs, oct, rst)
-        debug_prints(func="visualizeArray", text="Single mesh written")
-
-    if vc:  # write array to cube objects
-        debug_prints(func="visualizeArray", text="Writing to cubes")
-        writeArrayToCubes(cg, gs, origin)
-        debug_prints(func="visualizeArray", text="Cubes written")
-
-    if vv:  # write array to voxel data file
-        debug_prints(func="visualizeArray", text="Writing to voxels")
-        fname = "FSLGvoxels.raw"
-        path = os.path.dirname(bpy.data.filepath)
-        writeArrayToVoxel(cg, path + "\\" + fname)
-
-        debug_prints(func="visualizeArray",
-                     text="Voxel data written to:", var=path + "\\" + fname)
-
-    # read/write array to file (might not be necessary)
-    # tfile = 'c:\\testarr.txt'
-    # writeArrayToFile(cg, tfile)
-    # cg = readArrayFromFile(tfile)
-
-    # read/write array to curves (out of order)
-    # writeArrayToCurves('laMAIN', llmain, .10, .25)
-
-
-# Algorithm functions
-# from faluam paper
-# plus some stuff i made up
-
-def buildCPGraph(arr, sti=2):
-    # in -xyz array as built by generator
-    # out -[(childindex, parentindex)]
-    # sti - start index, 2 for empty, len(me.vertices) for mesh
-    sgarr = []
-    sgarr.append((1, 0))
-
-    for ai in range(sti, len(arr)):
-        cs = arr[ai]
-        cpts = arr[0:ai]
-        cslap = getStencil3D_26(cs[0], cs[1], cs[2])
-
-        for nc in cslap:
-            ct = cpts.count(nc)
-            if ct > 0:
-                cti = cpts.index(nc)
-        sgarr.append((ai, cti))
-
-    return sgarr
-
-
-def buildCPGraph_WORKINPROGRESS(arr, sti=2):
-    # in -xyz array as built by generator
-    # out -[(childindex, parentindex)]
-    # sti - start index, 2 for empty, len(me.vertices) for mesh
-    sgarr = []
-    sgarr.append((1, 0))
-    ctix = 0
-    for ai in range(sti, len(arr)):
-        cs = arr[ai]
-        # cpts = arr[0:ai]
-        cpts = arr[ctix:ai]
-        cslap = getStencil3D_26(cs[0], cs[1], cs[2])
-        for nc in cslap:
-            ct = cpts.count(nc)
-            if ct > 0:
-                # cti = cpts.index(nc)
-                cti = ctix + cpts.index(nc)
-                ctix = cpts.index(nc)
-
-        sgarr.append((ai, cti))
-
-    return sgarr
-
-
-def findChargePath(oc, fc, ngraph, restrict=[], partial=True):
-    # oc -origin charge index, fc -final charge index
-    # ngraph -node graph, restrict- index of sites cannot traverse
-    # partial -return partial path if restriction encountered
-    cList = splitList(ngraph, 0)
-    pList = splitList(ngraph, 1)
-    aRi = []
-    cNODE = fc
-    for x in range(len(ngraph)):
-        pNODE = pList[cList.index(cNODE)]
-        aRi.append(cNODE)
-        cNODE = pNODE
-        npNODECOUNT = cList.count(pNODE)
-        if cNODE == oc:             # stop if origin found
-            aRi.append(cNODE)       # return path
-            return aRi
-        if npNODECOUNT == 0:        # stop if no parents
-            return []               # return []
-        if pNODE in restrict:       # stop if parent is in restriction
-            if partial:             # return partial or []
-                aRi.append(cNODE)
-                return aRi
-            else:
-                return []
-
-
-def findTips(arr):
-    lt = []
-    for ai in arr[0: len(arr) - 1]:
-        a = ai[0]
-        cCOUNT = 0
-        for bi in arr:
-            b = bi[1]
-            if a == b:
-                cCOUNT += 1
-        if cCOUNT == 0:
-            lt.append(a)
-
-    return lt
-
-
-def findChannelRoots(path, ngraph, restrict=[]):
-    roots = []
-    for ai in range(len(ngraph)):
-        chi = ngraph[ai][0]
-        par = ngraph[ai][1]
-        if par in path and chi not in path and chi not in restrict:
-            roots.append(par)
-    droots = deDupe(roots)
-
-    return droots
-
-
-def findChannels(roots, tips, ngraph, restrict):
-    cPATHS = []
-    for ri in range(len(roots)):
-        r = roots[ri]
-        sL = 1
-        sPATHi = []
-        for ti in range(len(tips)):
-            t = tips[ti]
-            if t < r:
-                continue
-            tPATHi = findChargePath(r, t, ngraph, restrict, False)
-            tL = len(tPATHi)
-            if tL > sL:
-                if countChildrenOnPath(tPATHi, ngraph) > 1:
-                    sL = tL
-                    sPATHi = tPATHi
-                    tTEMP = t
-                    tiTEMP = ti
-        if len(sPATHi) > 0:
-            debug_print_vars(
-                    "\n[findChannels]\n",
-                    "found path/idex from", ri, 'of',
-                    len(roots), "possible | tips:", tTEMP, tiTEMP
-                    )
-            cPATHS.append(sPATHi)
-            tips.remove(tTEMP)
-
-    return cPATHS
-
-
-def findChannels_WORKINPROGRESS(roots, ttips, ngraph, restrict):
-    cPATHS = []
-    tips = list(ttips)
-    for ri in range(len(roots)):
-        r = roots[ri]
-        sL = 1
-        sPATHi = []
-        tipREMOVE = []  # checked tip indexes, to be removed for next loop
-        for ti in range(len(tips)):
-            t = tips[ti]
-            if ti < ri:
-                continue
-
-            tPATHi = findChargePath(r, t, ngraph, restrict, False)
-            tL = len(tPATHi)
-            if tL > sL:
-                if countChildrenOnPath(tPATHi, ngraph) > 1:
-                    sL = tL
-                    sPATHi = tPATHi
-                    tTEMP = t
-                    tiTEMP = ti
-            if tL > 0:
-                tipREMOVE.append(t)
-        if len(sPATHi) > 0:
-            debug_print_vars(
-                    "\n[findChannels_WORKINPROGRESS]\n",
-                    "found path from root idex", ri, 'of',
-                    len(roots), "possible roots | of tips= ", len(tips)
-                    )
-            cPATHS.append(sPATHi)
-
-        for q in tipREMOVE:
-            tips.remove(q)
-
-    return cPATHS
-
-
-def countChildrenOnPath(aPath, ngraph, quick=True):
-    # return how many branches
-    # count when node is a parent >1 times
-    # quick -stop and return after first
-    cCOUNT = 0
-    pList = splitList(ngraph, 1)
-
-    for ai in range(len(aPath) - 1):
-        ap = aPath[ai]
-        pc = pList.count(ap)
-
-        if quick and pc > 1:
-            return pc
-
-    return cCOUNT
-
-
-# classify channels into 'main', 'hORDER/secondary' and 'side'
-def classifyStroke(sarr, mct, hORDER=1):
-    debug_prints(func="classifyStroke", text="Classifying stroke")
-    # build child/parent graph (indexes of sarr)
-    sgarr = buildCPGraph(sarr, mct)
-
-    # find main channel
-    debug_prints(func="classifyStroke", text="Finding MAIN")
-    oCharge = sgarr[0][1]
-    fCharge = sgarr[len(sgarr) - 1][0]
-    aMAINi = findChargePath(oCharge, fCharge, sgarr)
-
-    # find tips
-    debug_prints(func="classifyStroke", text="Finding TIPS")
-    aTIPSi = findTips(sgarr)
-
-    # find horder channel roots
-    # hcount = orders between main and side/tips
-    # !!!still buggy!!!
-    hRESTRICT = list(aMAINi)    # add to this after each time
-    allHPATHSi = []             # all ho paths: [[h0], [h1]...]
-    curPATHSi = [aMAINi]        # list of paths find roots on
-
-    for h in range(hORDER):
-        allHPATHSi.append([])
-        for pi in range(len(curPATHSi)):     # loop through all paths in this order
-            p = curPATHSi[pi]
-            # get roots for this path
-            aHROOTSi = findChannelRoots(p, sgarr, hRESTRICT)
-            debug_print_vars(
-                    "\n[classifyStroke]\n",
-                    "found", len(aHROOTSi), "roots in ORDER", h, ":paths:", len(curPATHSi)
-                    )
-            # get channels for these roots
-            if len(aHROOTSi) == 0:
-                debug_prints(func="classifyStroke", text="No roots for found for channel")
-                aHPATHSi = []
-                continue
-            else:
-                aHPATHSiD = findChannels(aHROOTSi, aTIPSi, sgarr, hRESTRICT)
-                aHPATHSi = aHPATHSiD
-                allHPATHSi[h] += aHPATHSi
-                # set these channels as restrictions for next iterations
-                for hri in aHPATHSi:
-                    hRESTRICT += hri
-        curPATHSi = aHPATHSi
-
-    # side branches, final order of hierarchy
-    # from tips that are not in an existing path
-    # back to any other point that is already on a path
-    aDRAWNi = []
-    aDRAWNi += aMAINi
-    for oH in allHPATHSi:
-        for o in oH:
-            aDRAWNi += o
-    aTPATHSi = []
-    for a in aTIPSi:
-        if a not in aDRAWNi:
-            aPATHi = findChargePath(oCharge, a, sgarr, aDRAWNi)
-            aDRAWNi += aPATHi
-            aTPATHSi.append(aPATHi)
-
-    return aMAINi, allHPATHSi, aTPATHSi
-
-
-def voxelByVertex(ob, gs):
-    # 'voxelizes' verts in a mesh to list [(x,y,z),(x,y,z)]
-    # w/ respect gscale and ob origin (b/c should be origin obj)
-    # orig = ob.location
-    ll = []
-    for v in ob.data.vertices:
-        x = int(v.co.x / gs)
-        y = int(v.co.y / gs)
-        z = int(v.co.z / gs)
-        ll.append((x, y, z))
-
-    return ll
-
-
-def voxelByRays(ob, orig, gs):
-    # mesh into a 3dgrid w/ respect gscale and bolt origin
-    # - does not take object rotation/scale into account
-    # - this is a horrible, inefficient function
-    # maybe the raycast/grid thing are a bad idea. but i
-    # have to 'voxelize the object w/ resct to gscale/origin
-    bbox = ob.bound_box
-    bbxL = bbox[0][0]
-    bbxR = bbox[4][0]
-    bbyL = bbox[0][1]
-    bbyR = bbox[2][1]
-    bbzL = bbox[0][2]
-    bbzR = bbox[1][2]
-    xct = int((bbxR - bbxL) / gs)
-    yct = int((bbyR - bbyL) / gs)
-    zct = int((bbzR - bbzL) / gs)
-    xs = int(xct / 2)
-    ys = int(yct / 2)
-    zs = int(zct / 2)
-
-    debug_print_vars(
-            "\n[voxelByRays]\n",
-            "Casting", xct, '/', yct, '/', zct, 'cells, total:',
-            xct * yct * zct, 'in obj-', ob.name
-            )
-    ll = []
-    rc = 100    # distance to cast from
-    # raycast top/bottom
-    debug_prints(func="voxelByRays", text="Raycasting top/bottom")
-
-    for x in range(xct):
-        for y in range(yct):
-            xco = bbxL + (x * gs)
-            yco = bbyL + (y * gs)
-            v1 = ((xco, yco, rc))
-            v2 = ((xco, yco, -rc))
-            vz1 = ob.ray_cast(v1, v2)
-            vz2 = ob.ray_cast(v2, v1)
-
-            debug_print_vars(
-                        "\n[voxelByRays]\n", "vz1 is: ", vz1, "\nvz2 is: ", vz2
-                        )
-            # Note: the API raycast return has changed now it is
-            # (result, location, normal, index) - result is a boolean
-            if vz1[0] is True:
-                ll.append((x - xs, y - ys, int(vz1[1][2] * (1 / gs))))
-            if vz2[0] is True:
-                ll.append((x - xs, y - ys, int(vz2[1][2] * (1 / gs))))
-
-    # raycast front/back
-    debug_prints(func="voxelByRays", text="Raycasting front/back")
-
-    for x in range(xct):
-        for z in range(zct):
-            xco = bbxL + (x * gs)
-            zco = bbzL + (z * gs)
-            v1 = ((xco, rc, zco))
-            v2 = ((xco, -rc, zco))
-            vy1 = ob.ray_cast(v1, v2)
-            vy2 = ob.ray_cast(v2, v1)
-            if vy1[0] is True:
-                ll.append((x - xs, int(vy1[1][1] * (1 / gs)), z - zs))
-            if vy2[0] is True:
-                ll.append((x - xs, int(vy2[1][1] * (1 / gs)), z - zs))
-
-    # raycast left/right
-    debug_prints(func="voxelByRays", text="Raycasting left/right")
-
-    for y in range(yct):
-        for z in range(zct):
-            yco = bbyL + (y * gs)
-            zco = bbzL + (z * gs)
-            v1 = ((rc, yco, zco))
-            v2 = ((-rc, yco, zco))
-            vx1 = ob.ray_cast(v1, v2)
-            vx2 = ob.ray_cast(v2, v1)
-            if vx1[0] is True:
-                ll.append((int(vx1[1][0] * (1 / gs)), y - ys, z - zs))
-            if vx2[0] is True:
-                ll.append((int(vx2[1][0] * (1 / gs)), y - ys, z - zs))
-
-    # add in neighbors so bolt wont go through
-    nlist = []
-    for l in ll:
-        nl = getStencil3D_26(l[0], l[1], l[2])
-        nlist += nl
-
-    # dedupe
-    debug_prints(func="voxelByRays", text="Added neighbors, deduping...")
-    rlist = deDupe(ll + nlist)
-    qlist = []
-
-    # relocate grid w/ respect gscale and bolt origin
-    # !!!need to add in obj rot/scale here somehow...
-    od = Vector(
-            ((ob.location[0] - orig[0]) / gs,
-             (ob.location[1] - orig[1]) / gs,
-             (ob.location[2] - orig[2]) / gs)
-            )
-    for r in rlist:
-        qlist.append((r[0] + int(od[0]), r[1] + int(od[1]), r[2] + int(od[2])))
-
-    return qlist
-
-
-def fakeGroundChargePlane(z, charge):
-    eCL = []
-    xy = abs(z) / 2
-    eCL += [(0, 0, z, charge)]
-    eCL += [(xy, 0, z, charge)]
-    eCL += [(0, xy, z, charge)]
-    eCL += [(-xy, 0, z, charge)]
-    eCL += [(0, -xy, z, charge)]
-
-    return eCL
-
-
-def addCharges(ll, charge):
-    # in: ll - [(x,y,z), (x,y,z)], charge - w
-    # out clist - [(x,y,z,w), (x,y,z,w)]
-    clist = []
-    for l in ll:
-        clist.append((l[0], l[1], l[2], charge))
-    return clist
-
-
-# algorithm functions #
-# from fslg #
-
-def getGrowthProbability_KEEPFORREFERENCE(uN, aList):
-    # in: un -user term, clist -candidate sites, olist -candidate site charges
-    # out: list of [(xyz), pot, prob]
-    cList = splitList(aList, 0)
-    oList = splitList(aList, 1)
-    Omin, Omax = getLowHigh(oList)
-    if Omin == Omax:
-        Omax += notZero
-        Omin -= notZero
-    PdL = []
-    E = 0
-    E = notZero   # divisor for (fslg - eqn. 12)
-
-    for o in oList:
-        Uj = (o - Omin) / (Omax - Omin)  # (fslg - eqn. 13)
-        E += pow(Uj, uN)
-
-    for oi in range(len(oList)):
-        o = oList[oi]
-        Ui = (o - Omin) / (Omax - Omin)
-        Pd = (pow(Ui, uN)) / E  # (fslg - eqn. 12)
-        PdINT = Pd * 100
-        PdL.append(Pd)
-
-    return PdL
-
-
-# work in progress, trying to speed these up
-def fslg_e13(x, min, max, u):
-    return pow((x - min) / (max - min), u)
-
-
-def addit(x, y):
-    return x + y
-
-
-def fslg_e12(x, min, max, u, e):
-    return (fslg_e13(x, min, max, u) / e) * 100
-
-
-def getGrowthProbability(uN, aList):
-    # In: uN - user_term, cList - candidate sites, oList - candidate site charges
-    # Out: list of prob
-    cList = splitList(aList, 0)
-    oList = splitList(aList, 1)
-    Omin, Omax = getLowHigh(oList)
-
-    if Omin == Omax:
-        Omax += notZero
-        Omin -= notZero
-
-    PdL = []
-    E = notZero
-    minL = [Omin for q in range(len(oList))]
-    maxL = [Omax for q in range(len(oList))]
-    uNL = [uN for q in range(len(oList))]
-    E = sum(map(fslg_e13, oList, minL, maxL, uNL))
-    EL = [E for q in range(len(oList))]
-    mp = map(fslg_e12, oList, minL, maxL, uNL, EL)
-
-    for m in mp:
-        PdL.append(m)
-
-    return PdL
-
-
-def updatePointCharges(p, cList, eList=[]):
-    # In: pNew - new growth cell
-    # cList - old candidate sites, eList -SAME
-    # Out: list of new charge at candidate sites
-    r1 = 1 / 2        # (FSLG - Eqn. 10)
-    nOiL = []
-
-    for oi in range(len(cList)):
-        o = cList[oi][1]
-        c = cList[oi][0]
-        iOe = 0
-        rit = dist(c[0], c[1], c[2], p[0], p[1], p[2])
-        iOe += (1 - (r1 / rit))
-        Oit = o + iOe
-        nOiL.append((c, Oit))
-
-    return nOiL
-
-
-def initialPointCharges(pList, cList, eList=[]):
-    # In: p -CHARGED CELL (XYZ), cList -candidate sites (XYZ, POT, PROB)
-    # Out: cList -with potential calculated
-    r1 = 1 / 2        # (FSLG - Eqn. 10)
-    npList = []
-
-    for p in pList:
-        npList.append(((p[0], p[1], p[2]), 1.0))
-
-    for e in eList:
-        npList.append(((e[0], e[1], e[2]), e[3]))
-
-    OiL = []
-    for i in cList:
-        Oi = 0
-        for j in npList:
-            if i != j[0]:
-                rij = dist(i[0], i[1], i[2], j[0][0], j[0][1], j[0][2])
-                Oi += (1 - (r1 / rij)) * j[1]  # charge influence
-        OiL.append(((i[0], i[1], i[2]), Oi))
-
-    return OiL
-
-
-def getCandidateSites(aList, iList=[]):
-    # In: aList -(X,Y,Z) of charged cell sites, iList - insulator sites
-    # Out: candidate list of growth sites [(X,Y,Z)]
-    cList = []
-    for c in aList:
-        tempList = getStencil3D_26(c[0], c[1], c[2])
-        for t in tempList:
-            if t not in aList and t not in iList:
-                cList.append(t)
-    ncList = deDupe(cList)
-
-    return ncList
-
-
-# Setup functions
-
-def setupObjects():
-    winmgr = bpy.context.scene.advanced_objects1
-    oOB = bpy.data.objects.new('ELorigin', None)
-    oOB.location = ((0, 0, 10))
-    bpy.context.collection.objects.link(oOB)
-
-    gOB = bpy.data.objects.new('ELground', None)
-    gOB.empty_display_type = 'ARROWS'
-    bpy.context.collection.objects.link(gOB)
-
-    cME = makeMeshCube(1)
-    cOB = bpy.data.objects.new('ELcloud', cME)
-    cOB.location = ((-2, 8, 12))
-    cOB.hide_render = True
-    bpy.context.collection.objects.link(cOB)
-
-    iME = makeMeshCube(1)
-    for v in iME.vertices:
-        xyl = 6.5
-        zl = .5
-        v.co[0] = v.co[0] * xyl
-        v.co[1] = v.co[1] * xyl
-        v.co[2] = v.co[2] * zl
-    iOB = bpy.data.objects.new('ELinsulator', iME)
-    iOB.location = ((0, 0, 5))
-    iOB.hide_render = True
-    bpy.context.collection.objects.link(iOB)
-
-    try:
-        winmgr.OOB = 'ELorigin'
-        winmgr.GOB = 'ELground'
-        winmgr.COB = 'ELcloud'
-        winmgr.IOB = 'ELinsulator'
-    except:
-        pass
-
-
-def checkSettings():
-    check = True
-    winmgr = bpy.context.scene.advanced_objects1
-    message = ""
-    if winmgr.OOB == "":
-        message = "Error: no origin object selected"
-        check = False
-
-    if winmgr.GROUNDBOOL and winmgr.GOB == "":
-        message = "Error: no ground object selected"
-        check = False
-
-    if winmgr.CLOUDBOOL and winmgr.COB == "":
-        message = "Error: no cloud object selected"
-        check = False
-
-    if winmgr.IBOOL and winmgr.IOB == "":
-        message = "Error: no insulator object selected"
-        check = False
-
-    if check is False:
-        debug_prints(func="checkSettings", text=message)
-
-    # return state and the message for the operator report
-    return check, message
-
-
-# Main
-
-def FSLG():
-    winmgr = bpy.context.scene.advanced_objects1
-    # fast simulation of laplacian growth
-    debug_prints(func="FSLG",
-                 text="Go go gadget: fast simulation of laplacian growth")
-    tc1 = time.clock()
-    TSTEPS = winmgr.TSTEPS
-
-    obORIGIN = bpy.context.scene.objects[winmgr.OOB]
-    obGROUND = bpy.context.scene.objects[winmgr.GOB]
-    winmgr.ORIGIN = obORIGIN.location
-    winmgr.GROUNDZ = int((obGROUND.location[2] - winmgr.ORIGIN[2]) / winmgr.GSCALE)
-
-    # 1) insert initial charge(s) point (uses verts if mesh)
-    cgrid = [(0, 0, 0)]
-
-    if obORIGIN.type == 'MESH':
-        debug_prints(
-                func="FSLG",
-                text="Origin object is mesh, 'voxelizing' initial charges from verts"
-                )
-        cgrid = voxelByVertex(obORIGIN, winmgr.GSCALE)
-
-        if winmgr.VMMESH:
-            debug_prints(
-                func="FSLG",
-                text="Cannot classify stroke from vert origins yet, no multi-mesh output"
-                )
-            winmgr.VMMESH = False
-            winmgr.VSMESH = True
-
-    # ground charge cell / insulator lists (echargelist/iclist)
-    eChargeList = []
-    icList = []
-    if winmgr.GROUNDBOOL:
-        eChargeList = fakeGroundChargePlane(winmgr.GROUNDZ, winmgr.GROUNDC)
-
-    if winmgr.CLOUDBOOL:
-        debug_prints(
-                func="FSLG",
-                text="'Voxelizing' cloud object (could take some time)"
-                )
-        obCLOUD = bpy.context.scene.objects[winmgr.COB]
-        eChargeListQ = voxelByRays(obCLOUD, winmgr.ORIGIN, winmgr.GSCALE)
-        eChargeList = addCharges(eChargeListQ, winmgr.CLOUDC)
-        debug_prints(
-                func="FSLG",
-                text="cloud object cell count", var=len(eChargeList)
-                )
-
-    if winmgr.IBOOL:
-        debug_prints(
-                func="FSLG",
-                text="'Voxelizing' insulator object (could take some time)"
-                )
-        obINSULATOR = bpy.context.scene.objects[winmgr.IOB]
-        icList = voxelByRays(obINSULATOR, winmgr.ORIGIN, winmgr.GSCALE)
-
-        debug_prints(
-                func="FSLG",
-                text="Insulator object cell count", var=len(icList)
-                )
-
-    # 2) locate candidate sites around charge
-    cSites = getCandidateSites(cgrid, icList)
-
-    # 3) calc potential at each site (eqn. 10)
-    cSites = initialPointCharges(cgrid, cSites, eChargeList)
-
-    ts = 1
-    while ts <= TSTEPS:
-        # 1) select new growth site (eqn. 12)
-        # get probabilities at candidate sites
-        gProbs = getGrowthProbability(winmgr.BIGVAR, cSites)
-        # choose new growth site based on probabilities
-        gSitei = weightedRandomChoice(gProbs)
-        gsite = cSites[gSitei][0]
-
-        # 2) add new point charge at growth site
-        # add new growth cell to grid
-        cgrid.append(gsite)
-        # remove new growth cell from candidate sites
-        cSites.remove(cSites[gSitei])
-
-        # 3) update potential at candidate sites (eqn. 11)
-        cSites = updatePointCharges(gsite, cSites, eChargeList)
-
-        # 4) add new candidates surrounding growth site
-        # get candidate 'stencil'
-        ncSitesT = getCandidateSites([gsite], icList)
-        # remove candidates already in candidate list or charge grid
-        ncSites = []
-        cSplit = splitList(cSites, 0)
-        for cn in ncSitesT:
-            if cn not in cSplit and cn not in cgrid:
-                ncSites.append((cn, 0))
-
-        # 5) calc potential at new candidate sites (eqn. 10)
-        ncSplit = splitList(ncSites, 0)
-        ncSites = initialPointCharges(cgrid, ncSplit, eChargeList)
-
-        # add new candidate sites to candidate list
-        for ncs in ncSites:
-            cSites.append(ncs)
-
-        # iteration complete
-        istr1 = ':::T-STEP: ' + str(ts) + '/' + str(TSTEPS)
-        istr12 = ' | GROUNDZ: ' + str(winmgr.GROUNDZ) + ' | '
-        istr2 = 'CANDS: ' + str(len(cSites)) + ' | '
-        istr3 = 'GSITE: ' + str(gsite)
-        debug_prints(
-                func="FSLG",
-                text="Iteration complete",
-                var=istr1 + istr12 + istr2 + istr3
-                )
-        ts += 1
-
-        # early termination for ground/cloud strike
-        if winmgr.GROUNDBOOL:
-            if gsite[2] == winmgr.GROUNDZ:
-                ts = TSTEPS + 1
-                debug_prints(
-                        func="FSLG",
-                        text="Early termination due to groundstrike"
-                        )
-                continue
-
-        if winmgr.CLOUDBOOL:
-            if gsite in splitListCo(eChargeList):
-                ts = TSTEPS + 1
-                debug_prints(
-                        func="FSLG",
-                        text="Early termination due to cloudstrike"
-                        )
-                continue
-
-    tc2 = time.clock()
-    tcRUN = tc2 - tc1
-    debug_prints(
-            func="FSLG",
-            text="Laplacian growth loop completed",
-            var=str(len(cgrid)) + " / " + str(tcRUN)[0:5] + " Seconds"
-            )
-    debug_prints(func="FSLG", text="Visualizing data")
-
-    reportSTRING = getReportString(tcRUN)
-
-    # Visualize array
-    visualizeArray(
-            cgrid, obORIGIN, winmgr.GSCALE,
-            winmgr.VMMESH, winmgr.VSMESH,
-            winmgr.VCUBE, winmgr.VVOX, reportSTRING
-            )
-
-    debug_prints(func="FSLG", text="COMPLETE")
-
-
-# GUI #
-
-class runFSLGLoopOperator(Operator):
-    bl_idname = "object.runfslg_operator"
-    bl_label = "run FSLG Loop Operator"
-    bl_description = "By The Mighty Hammer Of Thor!!!"
-
-    def execute(self, context):
-        # tuple - state, report text
-        is_conditions, message = checkSettings()
-
-        if is_conditions:
-            FSLG()
-        else:
-            self.report({'WARNING'}, message + " Operation Cancelled")
-
-            return {'CANCELLED'}
-
-        return {'FINISHED'}
-
-
-class setupObjectsOperator(Operator):
-    bl_idname = "object.setup_objects_operator"
-    bl_label = "Setup Objects Operator"
-    bl_description = "Create origin/ground/cloud/insulator objects"
-
-    def execute(self, context):
-        setupObjects()
-
-        return {'FINISHED'}
-
-
-class OBJECT_PT_fslg(Panel):
-    bl_label = "Laplacian Lightning"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_context = "objectmode"
-    bl_category = "Create"
-    bl_options = {'DEFAULT_CLOSED'}
-
-    def draw(self, context):
-        layout = self.layout
-        winmgr = context.scene.advanced_objects1
-
-        col = layout.column(align=True)
-        col.prop(winmgr, "TSTEPS")
-        col.prop(winmgr, "GSCALE")
-        col.prop(winmgr, "BIGVAR")
-
-        col = layout.column()
-        col.operator("object.setup_objects_operator", text="Create Setup objects")
-        col.label(text="Origin object")
-        col.prop_search(winmgr, "OOB", context.scene, "objects")
-
-        box = layout.box()
-        col = box.column()
-        col.prop(winmgr, "GROUNDBOOL")
-        if winmgr.GROUNDBOOL:
-            col.prop_search(winmgr, "GOB", context.scene, "objects")
-            col.prop(winmgr, "GROUNDC")
-
-        box = layout.box()
-        col = box.column()
-        col.prop(winmgr, "CLOUDBOOL")
-        if winmgr.CLOUDBOOL:
-            col.prop_search(winmgr, "COB", context.scene, "objects")
-            col.prop(winmgr, "CLOUDC")
-
-        box = layout.box()
-        col = box.column()
-        col.prop(winmgr, "IBOOL")
-        if winmgr.IBOOL:
-            col.prop_search(winmgr, "IOB", context.scene, "objects")
-
-        col = layout.column()
-        col.operator("object.runfslg_operator",
-                     text="Generate Lightning", icon="RNDCURVE")
-
-        row = layout.row(align=True)
-        row.prop(winmgr, "VMMESH", toggle=True)
-        row.prop(winmgr, "VSMESH", toggle=True)
-        row.prop(winmgr, "VCUBE", toggle=True)
-
-
-def getReportString(rtime):
-    winmgr = bpy.context.scene.advanced_objects1
-    rSTRING1 = 't:' + str(winmgr.TSTEPS) + ',sc:' + str(winmgr.GSCALE)[0:4] + ',uv:' + str(winmgr.BIGVAR)[0:4] + ','
-    rSTRING2 = 'ori:' + str(winmgr. ORIGIN[0]) + '/' + str(winmgr. ORIGIN[1]) + '/' + str(winmgr. ORIGIN[2]) + ','
-    rSTRING3 = 'gz:' + str(winmgr.GROUNDZ) + ',gc:' + str(winmgr.GROUNDC) + ',rtime:' + str(int(rtime))
-    return rSTRING1 + rSTRING2 + rSTRING3
-
-
-def addReportProp(ob, str):
-    bpy.types.Object.FSLG_REPORT = bpy.props.StringProperty(
-        name='fslg_report', default='')
-    ob.FSLG_REPORT = str
-
-
-def register():
-    bpy.utils.register_class(runFSLGLoopOperator)
-    bpy.utils.register_class(setupObjectsOperator)
-    bpy.utils.register_class(OBJECT_PT_fslg)
-
-
-def unregister():
-    bpy.utils.unregister_class(runFSLGLoopOperator)
-    bpy.utils.unregister_class(setupObjectsOperator)
-    bpy.utils.unregister_class(OBJECT_PT_fslg)
-
-
-if __name__ == "__main__":
-    register()
-    pass
-
-
-# Benchmarks Function
-
-def BENCH():
-    debug_prints(func="BENCH", text="BEGIN BENCHMARK")
-    bt0 = time.clock()
-    # make a big list
-    tsize = 25
-    tlist = []
-    for x in range(tsize):
-        for y in range(tsize):
-            for z in range(tsize):
-                tlist.append((x, y, z))
-                tlist.append((x, y, z))
-
-    # function to test
-    bt1 = time.clock()
-    bt2 = time.clock()
-    btRUNb = bt2 - bt1
-    btRUNa = bt1 - bt0
-
-    debug_prints(func="BENCH", text="SETUP TIME", var=btRUNa)
-    debug_prints(func="BENCH", text="BENCHMARK TIME", var=btRUNb)
-    debug_print_vars(
-            "\n[BENCH]\n",
-            "GRIDSIZE: ", tsize, ' - ', tsize * tsize * tsize
-            )
diff --git a/add_advanced_objects_panels/object_mangle_tools.py b/add_advanced_objects_panels/object_mangle_tools.py
deleted file mode 100644
index 4631f82dc9ddfbe7f1f9276d76c2d761867e8b4b..0000000000000000000000000000000000000000
--- a/add_advanced_objects_panels/object_mangle_tools.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# mangle_tools.py (c) 2011 Phil Cote (cotejrp1)
-
-# ###### 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 LICENCE BLOCK ######
-
-# Note: properties are moved into __init__
-
-bl_info = {
-    "name": "Mangle Tools",
-    "author": "Phil Cote",
-    "blender": (2, 71, 0),
-    "location": "3D View > Toolshelf > Create > Mangle Tools",
-    "description": "Set of tools to mangle curves, meshes, and shape keys",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Object"}
-
-
-import bpy
-import random
-from bpy.types import (
-        Operator,
-        Panel,
-        )
-import time
-from math import pi
-import bmesh
-
-
-def move_coordinate(context, co, is_curve=False):
-    advanced_objects = context.scene.advanced_objects1
-    xyz_const = advanced_objects.mangle_constraint_vector
-    random.seed(time.time())
-    multiplier = 1
-
-    # For curves, we base the multiplier on the circumference formula.
-    # This helps make curve changes more noticeable.
-    if is_curve:
-        multiplier = 2 * pi
-    random_mag = advanced_objects.mangle_random_magnitude
-    if xyz_const[0]:
-        co.x += .01 * random.randrange(-random_mag, random_mag) * multiplier
-    if xyz_const[1]:
-        co.y += .01 * random.randrange(-random_mag, random_mag) * multiplier
-    if xyz_const[2]:
-        co.z += .01 * random.randrange(-random_mag, random_mag) * multiplier
-
-
-class MeshManglerOperator(Operator):
-    bl_idname = "ba.mesh_mangler"
-    bl_label = "Mangle Mesh"
-    bl_description = ("Push vertices on the selected object around in random\n"
-                      "directions to create a crumpled look")
-    bl_options = {"REGISTER", "UNDO"}
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return ob is not None and ob.type == 'MESH'
-
-    def execute(self, context):
-        mesh = context.active_object.data
-        bm = bmesh.new()
-        bm.from_mesh(mesh)
-        verts = bm.verts
-        advanced_objects = context.scene.advanced_objects1
-        randomMag = advanced_objects.mangle_random_magnitude
-        random.seed(time.time())
-
-        if mesh.shape_keys is not None:
-            self.report({'INFO'},
-                        "Cannot mangle mesh: Shape keys present. Operation Cancelled")
-            return {'CANCELLED'}
-
-        for vert in verts:
-            xVal = .01 * random.randrange(-randomMag, randomMag)
-            yVal = .01 * random.randrange(-randomMag, randomMag)
-            zVal = .01 * random.randrange(-randomMag, randomMag)
-
-            vert.co.x = vert.co.x + xVal
-            vert.co.y = vert.co.y + yVal
-            vert.co.z = vert.co.z + zVal
-
-        del verts
-
-        bm.to_mesh(mesh)
-        mesh.update()
-
-        return {'FINISHED'}
-
-
-class AnimanglerOperator(Operator):
-    bl_idname = "ba.ani_mangler"
-    bl_label = "Mangle Shape Key"
-    bl_description = ("Make a shape key and pushes the verts around on it\n"
-                      "to set up for random pulsating animation")
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return ob is not None and ob.type in ['MESH', 'CURVE']
-
-    def execute(self, context):
-        scn = context.scene.advanced_objects1
-        mangleName = scn.mangle_name
-        ob = context.object
-        shapeKey = ob.shape_key_add(name=mangleName)
-        verts = shapeKey.data
-
-        for vert in verts:
-            move_coordinate(context, vert.co, is_curve=ob.type == 'CURVE')
-
-        return {'FINISHED'}
-
-
-class CurveManglerOp(Operator):
-    bl_idname = "ba.curve_mangler"
-    bl_label = "Mangle Curve"
-    bl_description = "Mangle a curve to the degree the user specifies"
-    bl_options = {'REGISTER', 'UNDO'}
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return ob is not None and ob.type == "CURVE"
-
-    def execute(self, context):
-        ob = context.active_object
-        if ob.data.shape_keys is not None:
-            self.report({'INFO'},
-                        "Cannot mangle curve. Shape keys present. Operation Cancelled")
-            return {'CANCELLED'}
-
-        splines = context.object.data.splines
-
-        for spline in splines:
-            if spline.type == 'BEZIER':
-                points = spline.bezier_points
-            elif spline.type in {'POLY', 'NURBS'}:
-                points = spline.points
-
-            for point in points:
-                move_coordinate(context, point.co, is_curve=True)
-
-        return {'FINISHED'}
-
-
-class MangleToolsPanel(Panel):
-    bl_label = "Mangle Tools"
-    bl_space_type = "VIEW_3D"
-    bl_context = "objectmode"
-    bl_region_type = "TOOLS"
-    bl_category = "Create"
-    bl_options = {'DEFAULT_CLOSED'}
-
-    def draw(self, context):
-        scn = context.scene.advanced_objects1
-        obj = context.object
-
-        if obj and obj.type in ['MESH']:
-            layout = self.layout
-
-            row = layout.row(align=True)
-            row.prop(scn, "mangle_constraint_vector", toggle=True)
-
-            col = layout.column()
-            col.prop(scn, "mangle_random_magnitude")
-            col.operator("ba.mesh_mangler")
-            col.separator()
-
-            col.prop(scn, "mangle_name")
-            col.operator("ba.ani_mangler")
-        else:
-            layout = self.layout
-            layout.label(text="Please select a Mesh Object", icon="INFO")
-
-
-def register():
-    bpy.utils.register_class(AnimanglerOperator)
-    bpy.utils.register_class(MeshManglerOperator)
-    bpy.utils.register_class(CurveManglerOp)
-    bpy.utils.register_class(MangleToolsPanel)
-
-
-def unregister():
-    bpy.utils.unregister_class(AnimanglerOperator)
-    bpy.utils.unregister_class(MeshManglerOperator)
-    bpy.utils.unregister_class(MangleToolsPanel)
-    bpy.utils.unregister_class(CurveManglerOp)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_panels/oscurart_constellation.py b/add_advanced_objects_panels/oscurart_constellation.py
deleted file mode 100644
index a07f78f2e0886d31c52db795ee3419211c239165..0000000000000000000000000000000000000000
--- a/add_advanced_objects_panels/oscurart_constellation.py
+++ /dev/null
@@ -1,145 +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": "Constellation",
-    "author": "Oscurart",
-    "blender": (2, 67, 0),
-    "location": "3D View > Toolshelf > Create > Constellation",
-    "description": "Create a new Mesh From Selected",
-    "warning": "",
-    "wiki_url": "",
-    "category": "Add Mesh"}
-
-# Note the setting is moved to __init__ search for
-# the adv_obj and advanced_objects patterns
-
-import bpy
-from bpy.props import FloatProperty
-from math import sqrt
-from bpy.types import (
-        Operator,
-        Panel,
-        )
-
-
-def VertDis(a, b):
-    dst = sqrt(pow(a.co.x - b.co.x, 2) +
-               pow(a.co.y - b.co.y, 2) +
-               pow(a.co.z - b.co.z, 2))
-    return(dst)
-
-
-def OscConstellation(limit):
-    actobj = bpy.context.object
-    vertlist = []
-    edgelist = []
-    edgei = 0
-
-    for ind, verta in enumerate(actobj.data.vertices[:]):
-        for vertb in actobj.data.vertices[ind:]:
-            if VertDis(verta, vertb) <= limit:
-                vertlist.append(verta.co[:])
-                vertlist.append(vertb.co[:])
-                edgelist.append((edgei, edgei + 1))
-                edgei += 2
-
-    mesh = bpy.data.meshes.new("rsdata")
-    obj = bpy.data.objects.new("rsObject", mesh)
-    bpy.context.collection.objects.link(obj)
-    mesh.from_pydata(vertlist, edgelist, [])
-
-
-class Oscurart_Constellation(Operator):
-    bl_idname = "mesh.constellation"
-    bl_label = "Constellation"
-    bl_description = ("Create a Constellation Mesh - Cloud of Vertices\n"
-                      "Note: can produce a lot of geometry\n"
-                      "Needs an existing Active Mesh Object")
-    bl_options = {'REGISTER', 'UNDO'}
-
-    limit: FloatProperty(
-            name="Threshold",
-            description="Edges will be created only if the distance\n"
-                        "between vertices is smaller than this value",
-            default=2,
-            min=0
-            )
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj and obj.type == "MESH")
-
-    def invoke(self, context, event):
-        adv_obj = context.scene.advanced_objects1
-        self.limit = adv_obj.constellation_limit
-
-        return self.execute(context)
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.prop(self, "limit")
-
-    def execute(self, context):
-        try:
-            OscConstellation(self.limit)
-        except Exception as e:
-            print("\n[Add Advanced Objects]\nOperator: mesh.constellation\n{}".format(e))
-
-            self.report({"WARNING"},
-                        "Constellation Operation could not be Completed (See Console for more Info)")
-
-            return {"CANCELLED"}
-
-        return {'FINISHED'}
-
-
-class Constellation_Operator_Panel(Panel):
-    bl_label = "Constellation"
-    bl_region_type = "TOOLS"
-    bl_space_type = "VIEW_3D"
-    bl_options = {'DEFAULT_CLOSED'}
-    bl_context = "objectmode"
-    bl_category = "Create"
-
-    def draw(self, context):
-        layout = self.layout
-        adv_obj = context.scene.advanced_objects1
-
-        box = layout.box()
-        col = box.column(align=True)
-        col.label(text="Constellation:")
-        col.operator("mesh.constellation", text="Cross Section")
-        col.prop(adv_obj, "constellation_limit")
-
-
-# Register
-def register():
-    bpy.utils.register_class(Oscurart_Constellation)
-    bpy.utils.register_class(Constellation_Operator_Panel)
-
-
-def unregister():
-    bpy.utils.unregister_class(Oscurart_Constellation)
-    bpy.utils.unregister_class(Constellation_Operator_Panel)
-
-
-if __name__ == "__main__":
-    register()
diff --git a/add_advanced_objects_panels/unfold_transition.py b/add_advanced_objects_panels/unfold_transition.py
deleted file mode 100644
index 726a49429e3340fca422e4f5b11048346607c546..0000000000000000000000000000000000000000
--- a/add_advanced_objects_panels/unfold_transition.py
+++ /dev/null
@@ -1,348 +0,0 @@
-# gpl: authors Liero, Atom
-
-bl_info = {
-    "name": "Unfold transition",
-    "author": "Liero, Atom",
-    "location": "3D View > Toolshelf > Create > Unfold Transition",
-    "description": "Simple unfold transition / animation, will "
-                   "separate faces and set up an armature",
-    "category": "Animation"}
-
-# Note the properties are moved to __init__
-# search for patterns advanced_objects, adv_obj
-
-import bpy
-from bpy.types import (
-        Operator,
-        Panel,
-        )
-from random import (
-        randint,
-        uniform,
-        )
-from mathutils import Vector
-from mathutils.geometry import intersect_point_line
-
-
-class Set_Up_Fold(Operator):
-    bl_idname = "object.set_up_fold"
-    bl_label = "Set Up Unfold"
-    bl_description = ("Set up Faces and Bones for animation\n"
-                      "Needs an existing Active Mesh Object")
-    bl_options = {"REGISTER", "UNDO"}
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj is not None and obj.type == "MESH")
-
-    def execute(self, context):
-        bpy.ops.object.mode_set()
-        scn = bpy.context.scene
-        adv_obj = scn.advanced_objects1
-        obj = bpy.context.object
-        dat = obj.data
-        fac = dat.polygons
-        ver = dat.vertices
-
-        # try to cleanup traces of previous actions
-        bpy.ops.object.mode_set(mode="EDIT")
-        bpy.ops.mesh.remove_doubles(threshold=0.0001, use_unselected=True)
-        bpy.ops.object.mode_set()
-        old_vg = [vg for vg in obj.vertex_groups if vg.name.startswith("bone.")]
-        for vg in old_vg:
-            obj.vertex_groups.remove(vg)
-
-        if "UnFold" in obj.modifiers:
-            arm = obj.modifiers["UnFold"].object
-            rig = arm.data
-            try:
-                scn.objects.unlink(arm)
-                bpy.data.objects.remove(arm)
-                bpy.data.armatures.remove(rig)
-            except:
-                pass
-            obj.modifiers.remove(obj.modifiers["UnFold"])
-
-        # try to obtain the face sequence from the vertex weights
-        if adv_obj.unfold_modo == "weight":
-            if len(obj.vertex_groups):
-                i = obj.vertex_groups.active.index
-                W = []
-                for f in fac:
-                    v_data = []
-                    for v in f.vertices:
-                        try:
-                            w = ver[v].groups[i].weight
-                            v_data.append((w, v))
-                        except:
-                            v_data.append((0, v))
-                    v_data.sort(reverse=True)
-                    v1 = ver[v_data[0][1]].co
-                    v2 = ver[v_data[1][1]].co
-                    cen = Vector(f.center)
-                    its = intersect_point_line(cen, v2, v1)
-                    head = v2.lerp(v1, its[1])
-                    peso = sum([x[0] for x in v_data])
-                    W.append((peso, f.index, cen, head))
-                W.sort(reverse=True)
-                S = [x[1:] for x in W]
-            else:
-                self.report({"INFO"}, "First paint a Weight Map for this object")
-
-                return {"FINISHED"}
-
-        # separate the faces and sort them
-        bpy.ops.object.mode_set(mode="EDIT")
-        bpy.ops.mesh.select_all(action="SELECT")
-        bpy.ops.mesh.edge_split()
-        bpy.ops.mesh.select_all(action="SELECT")
-
-        if adv_obj.unfold_modo == "cursor":
-            bpy.context.tool_settings.mesh_select_mode = [True, True, True]
-            bpy.ops.mesh.sort_elements(
-                    type="CURSOR_DISTANCE", elements={"VERT", "EDGE", "FACE"}
-                    )
-        bpy.context.tool_settings.mesh_select_mode = [False, False, True]
-        bpy.ops.object.mode_set()
-
-        # Get sequence of faces and edges from the face / vertex indices
-        if adv_obj.unfold_modo != "weight":
-            S = []
-            for f in fac:
-                E = list(f.edge_keys)
-                E.sort()
-                v1 = ver[E[0][0]].co
-                v2 = ver[E[0][1]].co
-                cen = Vector(f.center)
-                its = intersect_point_line(cen, v2, v1)
-                head = v2.lerp(v1, its[1])
-                S.append((f.index, f.center, head))
-
-        # create the armature and the modifier
-        arm = bpy.data.armatures.new("arm")
-        rig = bpy.data.objects.new("rig_" + obj.name, arm)
-
-        # store the name for checking the right rig
-        adv_obj.unfold_arm_name = rig.name
-        rig.matrix_world = obj.matrix_world
-        scn.objects.link(rig)
-        scn.objects.active = rig
-        bpy.ops.object.mode_set(mode="EDIT")
-        arm.display_type = "WIRE"
-        rig.show_in_front = True
-        mod = obj.modifiers.new("UnFold", "ARMATURE")
-        mod.show_in_editmode = True
-        mod.object = rig
-
-        # create bones and vertex groups
-        root = arm.edit_bones.new("bone.000")
-        root.tail = (0, 0, 0)
-        root.head = (0, 0, 1)
-        root.select = True
-        vis = [False, True] + [False] * 30
-
-        for fb in S:
-            f = fac[fb[0]]
-            b = arm.edit_bones.new("bone.000")
-            if adv_obj.unfold_flip:
-                b.tail, b.head = fb[2], fb[1]
-            else:
-                b.tail, b.head = fb[1], fb[2]
-
-            b.align_roll(f.normal)
-            b.select_set(False)
-            b.layers = vis
-            b.parent = root
-            vg = obj.vertex_groups.new(name=b.name)
-            vg.add(f.vertices, 1, "ADD")
-
-        bpy.ops.object.mode_set()
-
-        if adv_obj.unfold_modo == "weight":
-            obj.vertex_groups.active_index = 0
-        scn.objects.active = rig
-        obj.select_set(False)
-
-        return {"FINISHED"}
-
-
-class Animate_Fold(Operator):
-    bl_idname = "object.animate_fold"
-    bl_label = "Animate Unfold"
-    bl_description = ("Animate bones to simulate unfold. Starts on current frame\n"
-                      "Needs an existing Active Armature Object created in the previous step")
-    bl_options = {"REGISTER", "UNDO"}
-
-    is_not_undo = False
-
-    @classmethod
-    def poll(cls, context):
-        obj = context.active_object
-        return (obj is not None and obj.type == "ARMATURE" and obj.is_visible(bpy.context.scene))
-
-    def draw(self, context):
-        layout = self.layout
-        adv_obj = context.scene.advanced_objects1
-
-        if self.is_not_undo is True:
-            layout.label(text="Warning:", icon="INFO")
-            layout.label(text="The generated Armature was not selected or it was renamed")
-            layout.label(text="The animation can fail if it is not generated by the previous step")
-            layout.separator()
-            layout.label(text="Expected Armature name:", icon="BONE_DATA")
-            layout.label(text=str(adv_obj.unfold_arm_name), icon="TRIA_RIGHT")
-            layout.label(text="To Continue press OK, to Cancel click Outside the Pop-up")
-            layout.separator()
-        else:
-            return
-
-    def invoke(self, context, event):
-        obj = bpy.context.object
-        scn = bpy.context.scene
-        adv_obj = scn.advanced_objects1
-
-        if obj.name != adv_obj.unfold_arm_name:
-            self.is_not_undo = True
-            return context.window_manager.invoke_props_dialog(self, width=400)
-        else:
-            return self.execute(context)
-
-    def execute(self, context):
-        obj = bpy.context.object
-        scn = bpy.context.scene
-        adv_obj = scn.advanced_objects1
-        fra = scn.frame_current
-        if obj.name != adv_obj.unfold_arm_name:
-            self.report({"INFO"},
-                        "The generated rig was not selected or renamed. The animation can fail")
-        # clear the animation and get the list of bones
-        if obj.animation_data:
-            obj.animation_data_clear()
-        bpy.ops.object.mode_set(mode="POSE")
-        bones = obj.pose.bones[0].children_recursive
-
-        if adv_obj.unfold_flip:
-            rot = -3.141592
-        else:
-            rot = adv_obj.unfold_rot_max / 57.3
-
-        extra = adv_obj.unfold_rot_time * adv_obj.unfold_bounce
-        ruido = max(adv_obj.unfold_rot_time + extra,
-                    adv_obj.unfold_sca_time) + adv_obj.unfold_fold_noise
-
-        len_bones = len(bones) if len(bones) != 0 else 1  # possible division by zero
-        vel = (adv_obj.unfold_fold_duration - ruido) / len_bones
-
-        # introduce scale and rotation keyframes
-        for a, b in enumerate(bones):
-            t = fra + a * vel + randint(0, adv_obj.unfold_fold_noise)
-
-            if adv_obj.unfold_flip:
-                b.scale = (1, 1, 1)
-            elif adv_obj.unfold_from_point:
-                b.scale = (0, 0, 0)
-            else:
-                b.scale = (1, 0, 0)
-
-            if not adv_obj.unfold_flip:
-                b.keyframe_insert("scale", frame=t)
-                b.scale = (1, 1, 1)
-                b.keyframe_insert("scale", frame=t + adv_obj.unfold_sca_time)
-
-            if adv_obj.unfold_rot_max:
-                b.rotation_mode = "XYZ"
-                if adv_obj.unfold_wiggle_rot:
-                    euler = (uniform(-rot, rot), uniform(-rot, rot), uniform(-rot, rot))
-                else:
-                    euler = (rot, 0, 0)
-
-                b.rotation_euler = euler
-                b.keyframe_insert("rotation_euler", frame=t)
-
-            if adv_obj.unfold_bounce:
-                val = adv_obj.unfold_bounce * -.10
-                b.rotation_euler = (val * euler[0], val * euler[1], val * euler[2])
-                b.keyframe_insert(
-                        "rotation_euler", frame=t + adv_obj.unfold_rot_time + .25 * extra
-                        )
-
-                val = adv_obj.unfold_bounce * .05
-                b.rotation_euler = (val * euler[0], val * euler[1], val * euler[2])
-                b.keyframe_insert(
-                        "rotation_euler", frame=t + adv_obj.unfold_rot_time + .50 * extra
-                        )
-
-                val = adv_obj.unfold_bounce * -.025
-                b.rotation_euler = (val * euler[0], val * euler[1], val * euler[2])
-                b.keyframe_insert(
-                        "rotation_euler", frame=t + adv_obj.unfold_rot_time + .75 * extra
-                        )
-
-            b.rotation_euler = (0, 0, 0)
-            b.keyframe_insert(
-                        "rotation_euler", frame=t + adv_obj.unfold_rot_time + extra
-                        )
-        self.is_not_undo = False
-
-        return {"FINISHED"}
-
-
-class PanelFOLD(Panel):
-    bl_label = "Unfold Transition"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
-    bl_category = "Create"
-    bl_context = "objectmode"
-    bl_options = {"DEFAULT_CLOSED"}
-
-    def draw(self, context):
-        layout = self.layout
-        adv_obj = context.scene.advanced_objects1
-
-        box = layout.box()
-        col = box.column()
-        col.operator("object.set_up_fold", text="1. Set Up Unfold")
-        col.separator()
-        col.label(text="Unfold Mode:")
-        col.prop(adv_obj, "unfold_modo")
-        col.prop(adv_obj, "unfold_flip")
-
-        box = layout.box()
-        col = box.column(align=True)
-        col.operator("object.animate_fold", text="2. Animate Unfold")
-        col.separator()
-        col.prop(adv_obj, "unfold_fold_duration")
-        col.prop(adv_obj, "unfold_sca_time")
-        col.prop(adv_obj, "unfold_rot_time")
-        col.prop(adv_obj, "unfold_rot_max")
-
-        row = col.row(align=True)
-        row.prop(adv_obj, "unfold_fold_noise")
-        row.prop(adv_obj, "unfold_bounce")
-        row = col.row(align=True)
-        row.prop(adv_obj, "unfold_wiggle_rot")
-
-        if not adv_obj.unfold_flip:
-            row.prop(adv_obj, "unfold_from_point")
-
-
-classes = (
-    Set_Up_Fold,
-    Animate_Fold,
-    PanelFOLD,
-    )
-
-
-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()