diff --git a/add_advanced_objects/__init__.py b/add_advanced_objects/__init__.py
index 3c15d1b4cf2849ada09cf4fa782f1d58bb6cfa0d..cad3c077ac1e5f442961ea5004c6e956c0edd003 100644
--- a/add_advanced_objects/__init__.py
+++ b/add_advanced_objects/__init__.py
@@ -20,19 +20,18 @@
 # 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   #
-# Dannyboy, Mano-Wii, Kursad Karatas, teldredge
+# Atom, Dannyboy, Mano-Wii, Kursad Karatas, teldredge, Phil Cote #
 
 bl_info = {
     "name": "Add Advanced Objects",
     "author": "Meta Androcto,",
-    "version": (0, 1, 1),
+    "version": (0, 1, 3),
     "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",
-    "tracker_url": "",
     "category": "Object"}
 
 if "bpy" in locals():
@@ -64,46 +63,54 @@ if "bpy" in locals():
     importlib.reload(oscurart_chain_maker)
 
 else:
-    from . import (
-        add_light_template,
-        scene_objects_bi,
-        scene_objects_cycles,
-        scene_texture_render,
-        trilighting,
-        pixelate_3d,
-        object_add_chain,
-        oscurart_chain_maker,
-        drop_to_ground,
-        circle_array,
-        unfold_transition,
-        copy2,
-        make_struts,
-        random_box_structure,
-        cubester,
-        rope_alpha,
-        add_mesh_aggregate,
-        object_mangle_tools,
-        arrange_on_curve,
-        object_laplace_lightning,
-        mesh_easylattice
-        )
-    from .delaunay_voronoi import (
-        DelaunayVoronoi,
-        delaunayVoronoiBlender,
-        oscurart_constellation
-        )
+    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 drop_to_ground
+    from . import circle_array
+    from . import unfold_transition
+    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 object_mangle_tools
+    from . import arrange_on_curve
+    from . import object_laplace_lightning
+    from . import mesh_easylattice
+
+    from .delaunay_voronoi import DelaunayVoronoi
+    from .delaunay_voronoi import delaunayVoronoiBlender
+    from .delaunay_voronoi import oscurart_constellation
 
 import bpy
 from bpy.types import (
         Menu,
         AddonPreferences,
+        PropertyGroup,
+        )
+from bpy.props import (
+        BoolProperty,
+        BoolVectorProperty,
+        EnumProperty,
+        FloatProperty,
+        FloatVectorProperty,
+        IntProperty,
+        StringProperty,
+        PointerProperty,
         )
 
 
+# Define the "Scenes" menu
 class INFO_MT_scene_elements_add(Menu):
-    # Define the "scenes" menu
     bl_idname = "INFO_MT_scene_elements"
-    bl_label = "Test scenes"
+    bl_label = "Test Scenes"
 
     def draw(self, context):
         layout = self.layout
@@ -116,8 +123,8 @@ class INFO_MT_scene_elements_add(Menu):
                         text="Scene_Textures_Cycles")
 
 
+# Define the "Lights" menu
 class INFO_MT_mesh_lamps_add(Menu):
-    # Define the "lights" menu
     bl_idname = "INFO_MT_scene_lamps"
     bl_label = "Lighting Sets"
 
@@ -130,8 +137,8 @@ class INFO_MT_mesh_lamps_add(Menu):
                         text="Add Tri Lighting")
 
 
+# Define the "Chains" menu
 class INFO_MT_mesh_chain_add(Menu):
-    # Define the "Chains" menu
     bl_idname = "INFO_MT_mesh_chain"
     bl_label = "Chains"
 
@@ -142,47 +149,45 @@ class INFO_MT_mesh_chain_add(Menu):
         layout.operator("mesh.primitive_oscurart_chain_add", icon="LINKED")
 
 
+# Define the "Array" Menu
 class INFO_MT_array_mods_add(Menu):
-    # Define the "array" menu
     bl_idname = "INFO_MT_array_mods"
     bl_label = "Array Mods"
 
     def draw(self, context):
         layout = self.layout
         layout.operator_context = 'INVOKE_REGION_WIN'
-        self.layout.menu("INFO_MT_mesh_chain", icon="LINKED")
+
+        layout.menu("INFO_MT_mesh_chain", icon="LINKED")
+
         layout.operator("objects.circle_array_operator",
-                        text="Circle Array", icon='MOD_ARRAY')
+                        text="Circle Array", icon="MOD_ARRAY")
         layout.operator("object.agregate_mesh",
-                        text="Aggregate Mesh", icon='MOD_ARRAY')
-        obj = context.object
-        if obj.type in ['MESH',]:  
-            layout.operator("mesh.copy2",
-                        text="Copy To Vert/Edge", icon='MOD_ARRAY')
-
+                        text="Aggregate Mesh", icon="MOD_ARRAY")
+        layout.operator("mesh.copy2",
+                text="Copy To Vert/Edge", icon="MOD_ARRAY")
 
 
+# Define the "Blocks" Menu
 class INFO_MT_quick_blocks_add(Menu):
-    # Define the "Blocks" menu
     bl_idname = "INFO_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')
-        obj = context.object
-        if obj.type in ['MESH',]:  
-            layout.operator("mesh.generate_struts",
-                        text="Struts", icon='GRID')
-            layout.operator("object.easy_lattice",
-                        text="Easy Lattice", icon='MOD_LATTICE')
-            layout.operator("object.make_structure",
-                        text="Random Boxes", icon='SEQ_SEQUENCER')
 
+        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 INFO_MT_Physics_tools_add(Menu):
-    # Define the "mesh objects" menu
     bl_idname = "INFO_MT_physics_tools"
     bl_label = "Physics Tools"
 
@@ -190,7 +195,7 @@ class INFO_MT_Physics_tools_add(Menu):
         layout = self.layout
         layout.operator_context = 'INVOKE_REGION_WIN'
         layout.operator("object.drop_on_active",
-                        text="Drop To Ground")
+                        text="Drop To Ground", icon="SORTSIZE")
         layout.operator("ball.rope",
                         text="Wrecking Ball", icon='PHYSICS')
         layout.operator("clot.rope",
@@ -211,22 +216,551 @@ def menu(self, context):
 
 
 # Addons Preferences
-class AddonPreferences(AddonPreferences):
+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
-        layout.label(text="----Add Menu Advanced----")
-        layout.label(text="Quick Tools:")
-        layout.label(text="Drop, Pixelate & Wrecking Ball")
-        layout.label(text="Array Mods:")
-        layout.label(text="Circle Array, Chains, Vert to Edge, Aggregate")
+
+        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="Drop to Ground, 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="Drop to Ground", icon="LAYER_USED")
+            box.label(text="Unfold Transition", icon="LAYER_USED")
+            box.label(text="CubeSter", icon="LAYER_USED")
+            box.label(text="Mangle tools", icon="LAYER_USED")
+            box.label(text="Laplacian Lighting", icon="LAYER_USED")
+            box.label(text="Delaunay Voronoi", icon="LAYER_USED")
+            box.label(text="Duplicate 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
+            )
+
+    # pixelate_3d properties
+    pixelate_3d_size = FloatProperty(
+            name="Size",
+            min=.05, max=5,
+            default=.25,
+            description="Size of the cube / grid"
+            )
+    pixelate_3d_gap = IntProperty(
+            name="Gap",
+            min=0, max=90,
+            default=10,
+            subtype='PERCENTAGE',
+            description="Separation - percent of size"
+            )
+    pixelate_3d_smooth = FloatProperty(
+            name="Smooth",
+            min=0, max=1,
+            default=.0,
+            description="Smooth factor when subdividing mesh"
+            )
+    # 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',
+            )
+    # 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="Inital 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
+            )
 
 
 def register():
-    object_mangle_tools.register()
-    arrange_on_curve.register()
     bpy.utils.register_module(__name__)
+
+    bpy.types.Scene.advanced_objects = PointerProperty(
+                                            type=AdvancedObjProperties
+                                            )
+
     # Add "Extras" menu to the "Add" menu
     bpy.types.INFO_MT_add.append(menu)
     try:
@@ -236,8 +770,6 @@ def register():
 
 
 def unregister():
-    object_mangle_tools.unregister()
-    arrange_on_curve.unregister()
     # Remove "Extras" menu from the "Add" menu.
     bpy.types.INFO_MT_add.remove(menu)
     try:
@@ -246,6 +778,11 @@ def unregister():
         pass
 
     bpy.utils.unregister_module(__name__)
+    del bpy.types.Scene.advanced_objects
+
+    # cleanup Easy Lattice Scene Property if it was created
+    if hasattr(bpy.types.Scene, "activelatticeobject"):
+        del bpy.types.Scene.activelatticeobject
 
 
 if __name__ == "__main__":
diff --git a/add_advanced_objects/add_light_template.py b/add_advanced_objects/add_light_template.py
index 312b2d9e648249a3677bcb2142fcd36da9d42294..9e2c139fa8451ba53b35cf8496f801221c4ddbdf 100644
--- a/add_advanced_objects/add_light_template.py
+++ b/add_advanced_objects/add_light_template.py
@@ -6,120 +6,129 @@ from bpy.props import BoolProperty
 
 
 def add_lamps(self, context):
-    try:
-        if self.bKeyLight:
-            keyLight = bpy.data.lamps.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.scene.objects.link(ob)
-            ob.rotation_euler[2] = -0.785398
-
-        if self.bFillLight:
-            fillLight = bpy.data.lamps.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.scene.objects.link(ob)
-            ob.rotation_euler[2] = 0.785398
-            ob.data.energy = 0.3
-
-        if self.bBackLight:
-            backLight = bpy.data.lamps.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.scene.objects.link(ob)
-            ob.rotation_euler[2] = 3.14159
-            ob.data.energy = 0.2
-
-        if self.camera_constraint:
-            constraint = self.camera.constraints.new(type='TRACK_TO')
-            constraint.target = self.target
-            constraint.track_axis = 'TRACK_NEGATIVE_Z'
-            constraint.up_axis = 'UP_Y'
-
-    except Exception as e:
-        self.report({'WARNING'},
-                    "Some operations could not be performed (See Console for more info)")
-
-        print("\n[object.add_light_template]\nError: {}".format(e))
+
+    if self.bKeyLight:
+        keyLight = bpy.data.lamps.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.scene.objects.link(ob)
+        ob.rotation_euler[2] = -0.785398
+
+    if self.bFillLight:
+        fillLight = bpy.data.lamps.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.scene.objects.link(ob)
+        ob.rotation_euler[2] = 0.785398
+        ob.data.energy = 0.3
+
+    if self.bBackLight:
+        backLight = bpy.data.lamps.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.scene.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 & Back Lights"
+    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",
-                    default=True
-                    )
+            name="Key Light",
+            description="Enable Key Light in the Scene",
+            default=True
+            )
     bFillLight = BoolProperty(
-                    name="Fill Light",
-                    default=True
-                    )
+            name="Fill Light",
+            description="Enable Fill Light in the Scene",
+            default=True
+            )
     bBackLight = BoolProperty(
-                    name="Back Light",
-                    default=True
-                    )
+            name="Back Light",
+            description="Enable Back Light in the Scene",
+            default=True
+            )
     camera_constraint = BoolProperty(
-                    name="Camera Constraint",
-                    default=False
-                    )
+            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):
-        objects = context.selected_objects
-
-        if len(objects) == 2:
-            for ob in objects:
-                if ob.type == 'CAMERA':
-                    self.camera = ob
+        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.target = ob
-        elif len(objects) == 1:
-            if objects[0].type == 'CAMERA':
-                self.camera = objects[0]
+                    self.camera = context.scene.camera
+                    self.target = context.active_object
+            elif len(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_lamps(self, context)
+            add_lamps(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'}
 
diff --git a/add_advanced_objects/add_mesh_aggregate.py b/add_advanced_objects/add_mesh_aggregate.py
index e2ac5f07ad07653cba10691cf6c18c9df1d65fd2..6072cb9c447c5b972c9e25ad403d816c5fd3df50 100644
--- a/add_advanced_objects/add_mesh_aggregate.py
+++ b/add_advanced_objects/add_mesh_aggregate.py
@@ -72,107 +72,108 @@ class OBJECT_OT_agregate_mesh(Operator):
     bl_options = {'REGISTER', 'UNDO', 'PRESET'}
 
     volX = FloatProperty(
-                name="Volume X",
-                min=0.1, max=25,
-                default=3,
-                description="The cloud around cursor"
-                )
+            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"
-                )
+            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"
-                 )
+            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"
-                )
+            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"
-                )
+            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"
-                )
+            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"
-                )
+            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"
-                )
+            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"
-                )
+            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"
-                )
+            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"
-                )
+            name="Normal Oriented",
+            default=False,
+            description="Align Z axis with Faces normals"
+            )
     cent = BoolProperty(
-                name="Use Face Center",
-                default=False,
-                description="Center on Faces"
-                )
+            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"
-                )
+            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 = bpy.props.BoolProperty(
-                name="Update",
-                default=False
-                )
-    auto_refresh = bpy.props.BoolProperty(
-                name="Auto",
-                description="Auto update spline",
-                default=False
-                )
+            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')
+
+        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()
@@ -194,18 +195,20 @@ class OBJECT_OT_agregate_mesh(Operator):
 
         col = layout.column(align=True)
         col.prop(self, "rSeed", slider=False)
+        col.prop(self, "numP")
 
-        col = layout.column(align=True)
-        col.prop(self, "nor")
-        col.prop(self, "cent")
-        col.prop(self, "track")
-        col.prop(self, "anim")
+        row = layout.row(align=True)
+        row.prop(self, "nor")
+        row.prop(self, "cent")
 
-        col.prop(self, 'numP')
+        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')
+        return (len(bpy.context.selected_objects) > 1 and
+                bpy.context.object.type == 'MESH')
 
     def invoke(self, context, event):
         self.refresh = True
@@ -227,8 +230,10 @@ class OBJECT_OT_agregate_mesh(Operator):
                 (0, 0, 0, 1))
                 )
         if obj.matrix_world != mat:
-            self.report({'WARNING'}, "Apply transformations to Active Object first!")
+            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'}
@@ -296,9 +301,8 @@ class OBJECT_OT_agregate_mesh(Operator):
 
                 bme.to_mesh(obj.data)
                 remover(True)
-
-                newobj.data.user_clear()
-                bpy.data.meshes.remove(newobj.data)
+                # 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
@@ -318,8 +322,6 @@ class OBJECT_OT_agregate_mesh(Operator):
 
         if self.auto_refresh is False:
             self.refresh = False
-        #elif self.auto_refresh is True:
-        #    self.refresh = True
 
         return{'FINISHED'}
 
@@ -333,4 +335,4 @@ def unregister():
 
 
 if __name__ == '__main__':
- register()
\ No newline at end of file
+    register()
diff --git a/add_advanced_objects/arrange_on_curve.py b/add_advanced_objects/arrange_on_curve.py
index 9894de126435c84ab9de14142ab1c238cd093a00..1401748039e3a27cd3a18b2da78ea11322e84551 100644
--- a/add_advanced_objects/arrange_on_curve.py
+++ b/add_advanced_objects/arrange_on_curve.py
@@ -9,10 +9,12 @@ bl_info = {
     "description": "Arrange objects along a curve",
     "warning": "Select curve",
     "wiki_url": "",
-    "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
     "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 (
@@ -20,11 +22,9 @@ from bpy.types import (
         Panel,
         )
 from bpy.props import (
-        BoolProperty,
         EnumProperty,
         FloatProperty,
         IntProperty,
-        StringProperty,
         )
 
 FLT_MIN = 0.004
@@ -44,82 +44,90 @@ class PanelDupliCurve(Panel):
 
     def draw(self, context):
         layout = self.layout
-        layout.prop(context.scene, "use_selected")
-        if not context.scene.use_selected:
-            layout.prop(context.scene, "select_type", expand=True)
-            if context.scene.select_type == 'O':
+        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(
-                                context.scene, "objeto_arranjar",
-                                bpy.data, "objects"
-                                )
-            elif context.scene.select_type == 'G':
+                              adv_obj, "arrange_c_obj_arranjar",
+                              bpy.data, "objects"
+                              )
+            elif adv_obj.arrange_c_select_type == 'G':
                 layout.column(align=True).prop_search(
-                                context.scene, "objeto_arranjar",
-                                bpy.data, "groups"
-                                )
+                              adv_obj, "arrange_c_obj_arranjar",
+                              bpy.data, "groups"
+                              )
         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"
+    bl_label = "Arrange Objects along a Curve"
+    bl_description = "Arange chosen / selected objects along the Active Curve"
     bl_options = {'REGISTER', 'UNDO'}
 
     use_distance = EnumProperty(
-        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)
-            ]
-        )
+            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="Distancia entre objetos",
-                default=1.0,
-                min=FLT_MIN,
-                soft_min=0.1,
-                unit='LENGTH',
-                )
+            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,
-                )
+            name="Quantity",
+            description="Object amount",
+            default=2,
+            min=0,
+            )
     scale = FloatProperty(
-                name="Scale",
-                description="Object Scale",
-                default=1.0,
-                min=FLT_MIN,
-                unit='LENGTH',
+            name="Scale",
+            description="Object Scale",
+            default=1.0,
+            min=FLT_MIN,
+            unit='LENGTH',
                 )
     Yaw = FloatProperty(
-                default=0.0,
-                name="X",
-                unit='ROTATION'
-                )
+            name="X",
+            description="Rotate around the X axis (Yaw)",
+            default=0.0,
+            unit='ROTATION'
+            )
     Pitch = FloatProperty(
-                default=0.0,
-                name="Y",
-                unit='ROTATION'
-                )
+            default=0.0,
+            description="Rotate around the Y axis (Pitch)",
+            name="Y",
+            unit='ROTATION'
+            )
     Roll = FloatProperty(
-                default=0.0,
-                name="Z",
-                unit='ROTATION'
-                )
+            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'
-                )
+            default=1.57079,
+            max=3.141592,
+            name="Angle",
+            unit='ROTATION'
+            )
     offset = FloatProperty(
-                default=0.0,
-                name="offset",
-                unit='LENGTH'
-                )
+            default=0.0,
+            name="Offset",
+            unit='LENGTH'
+            )
 
     @classmethod
     def poll(cls, context):
@@ -191,7 +199,8 @@ class DupliCurve(Operator):
                             tmp_Gpoints.append(tuple(sp2))
                             sp2 = [lp]
                     except Exception as e:
-                        print(e)
+                        print("\n[Add Advanced  Objects]\nOperator: "
+                              "object.arranjar_numa_curva\nError: {}".format(e))
                         pass
                     sp2.append(p)
                     v1 = v2
@@ -216,21 +225,25 @@ class DupliCurve(Operator):
 
         curve = context.active_object
         Gpoints, lengs = self.Glpoints(curve)
+        adv_obj = context.scene.advanced_objects
 
-        if context.scene.use_selected:
+        if adv_obj.arrange_c_use_selected:
             G_Objeto = context.selected_objects
             G_Objeto.remove(curve)
+
             if not G_Objeto:
                 return {'CANCELLED'}
-        elif context.scene.select_type == 'O':
-            G_Objeto = bpy.data.objects[context.scene.objeto_arranjar],
-        elif context.scene.select_type == 'G':
-            G_Objeto = bpy.data.groups[context.scene.objeto_arranjar].objects
+
+        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.groups[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  # is this used?
+        max_angle = self.max_angle  # max_angle is called in Glpoints
 
         if self.use_distance == "D":
             dist = self.distance
@@ -331,31 +344,11 @@ class DupliCurve(Operator):
 def register():
     bpy.utils.register_class(PanelDupliCurve)
     bpy.utils.register_class(DupliCurve)
-    bpy.types.Scene.use_selected = BoolProperty(
-                        name='Use Selected',
-                        description='Use the selected objects to duplicate',
-                        default=True,
-                        )
-    bpy.types.Scene.objeto_arranjar = StringProperty(
-                        name=""
-                        )
-    bpy.types.Scene.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 unregister():
     bpy.utils.unregister_class(PanelDupliCurve)
     bpy.utils.unregister_class(DupliCurve)
-    del bpy.types.Scene.objeto_arranjar
-    del bpy.types.Scene.use_selected
-    del bpy.types.Scene.select_type
 
 
 if __name__ == "__main__":
diff --git a/add_advanced_objects/circle_array.py b/add_advanced_objects/circle_array.py
index 170ea7a6768227e75edd384395f78ab095f8d35f..af5a6a0aefa3a39fc6e14939b4d391597743ee8c 100644
--- a/add_advanced_objects/circle_array.py
+++ b/add_advanced_objects/circle_array.py
@@ -5,14 +5,13 @@
 bl_info = {
     "name": "Circle Array",
     "author": "Antonis Karvelas",
-    "version": (1, 0),
+    "version": (1, 0, 1),
     "blender": (2, 6, 7),
     "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": "",
-    "tracker_url": "",
     "category": "Mesh"
     }
 
@@ -26,7 +25,10 @@ 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 & Surface")
+                      "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):
@@ -53,27 +55,52 @@ class Circle_Array(Operator):
             return None
 
     def execute(self, context):
+        is_allowed = True
         try:
             allowed_obj = ['MESH', 'CURVE', 'SURFACE', 'FONT']
-            if context.active_object.type not in allowed_obj:
+            for obj in context.selected_objects:
+                if obj.type not in allowed_obj:
+                    is_allowed = False
+                    break
+
+            if not is_allowed:
                 self.report(
                     {"WARNING"},
-                    "Operation Cancelled. The active object is not of "
-                    "Mesh, Curve, Surface or Font type"
+                    "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(bpy.context.selected_objects) == 2:
-                list = bpy.context.selected_objects
-                active = list[0]
+            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.scene.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 = False
-                bpy.context.scene.objects.active = list[0]
+                bpy.context.scene.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
@@ -98,6 +125,7 @@ class Circle_Array(Operator):
                 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
@@ -116,6 +144,7 @@ class Circle_Array(Operator):
                 active.select = True
 
                 return {'FINISHED'}
+
         except Exception as e:
             self.report({'WARNING'},
                         "Circle Array operator could not be executed (See the console for more info)")
@@ -125,18 +154,12 @@ class Circle_Array(Operator):
 
 
 # Register
-def circle_array_menu(self, context):
-    self.layout.operator(Circle_Array.bl_idname, text="Circle_Array")
-
-
 def register():
     bpy.utils.register_class(Circle_Array)
-    bpy.types.VIEW3D_MT_object.append(circle_array_menu)
 
 
 def unregister():
     bpy.utils.unregister_class(Circle_Array)
-    bpy.types.VIEW3D_MT_object.remove(circle_array_menu)
 
 
 if __name__ == "__main__":
diff --git a/add_advanced_objects/copy2.py b/add_advanced_objects/copy2.py
index 3afdef22fcf4f2ea8f673f229e9ff2e9b04224c0..489f6deeb339704322410f051f5f8c90c55e56e5 100644
--- a/add_advanced_objects/copy2.py
+++ b/add_advanced_objects/copy2.py
@@ -1,4 +1,4 @@
-#  ***** BEGIN GPL LICENSE BLOCK *****
+# ##### 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
@@ -15,12 +15,12 @@
 #  or write to the Free Software Foundation, Inc., 51 Franklin Street,
 #  Fifth Floor, Boston, MA 02110-1301, USA.
 #
-#  ***** END GPL LICENSE BLOCK *****
+# ##### END GPL LICENSE BLOCK #####
 
 bl_info = {
-    "name": "Copy2 vertices, edges or faces",
+    "name": "Copy2 Vertices, Edges or Faces",
     "author": "Eleanor Howick (elfnor.com)",
-    "version": (0, 1),
+    "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",
@@ -29,13 +29,23 @@ bl_info = {
 }
 
 import bpy
-
-from mathutils import Vector, Matrix
-
-
-class Copy2(bpy.types.Operator):
+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
@@ -45,84 +55,126 @@ class Copy2(bpy.types.Operator):
 
     def sec_axes_list_cb(self, context):
         if self.priaxes == 'X':
-            sec_list = [('Y', 'Y', 'Y'), ('Z', 'Z', 'Z')]
+            sec_list = [('Y', "Y", "Secondary axis Y"),
+                        ('Z', "Z", "Secondary axis Z")]
 
         if self.priaxes == 'Y':
-            sec_list = [('X', 'X', 'X'), ('Z', 'Z', 'Z')]
+            sec_list = [('X', "X", "Secondary axis X"),
+                        ('Z', "Z", "Secondary axis Z")]
 
         if self.priaxes == 'Z':
-            sec_list = [('X', 'X', 'X'), ('Y', 'Y', 'Y')]
+            sec_list = [('X', "X", "Secondary axis X"),
+                        ('Y', "Y", "Secondary axis Y")]
         return sec_list
 
-    copytype = bpy.props.EnumProperty(items=(('V', '', 'paste to vertices', 'VERTEXSEL', 0),
-                                             ('E', '', 'paste to edges', 'EDGESEL', 1),
-                                             ('F', '', 'paste to faces', 'FACESEL', 2)),
-                                      description='where to paste to')
-
-    copyfromobject = bpy.props.EnumProperty(items=obj_list_cb, name='Copy from:')
-
-    priaxes = bpy.props.EnumProperty(items=(('X', 'X', 'along X'),
-                                            ('Y', 'Y', 'along Y'),
-                                            ('Z', 'Z', 'along Z')),
-                                     )
-
-    edgescale = bpy.props.BoolProperty(name='Scale to fill edge?')
-
-    secaxes = bpy.props.EnumProperty(items=sec_axes_list_cb, name='Secondary Axis')
-
-    scale = bpy.props.FloatProperty(default=1.0, min=0.0, name='Scale')
+    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.prop(self, "copyfromobject")
         layout.label("to:")
-        layout.prop(self, 'copytype', expand=True)
-        layout.label("primary axis:")
-        layout.prop(self, 'priaxes', expand=True)
-        layout.label("secondary axis:")
-        layout.prop(self, 'secaxes', expand=True)
-        if self.copytype == 'E':
-            layout.prop(self, 'edgescale')
+        layout.prop(self, "copytype", expand=True)
+        layout.label("Primary axis:")
+        layout.prop(self, "priaxes", expand=True)
+        layout.label("Secondary axis:")
+        layout.prop(self, "secaxes", expand=True)
+        if self.copytype == "E":
+            layout.prop(self, "edgescale")
             if self.edgescale:
-                layout.prop(self, 'scale')
+                layout.prop(self, "scale")
         return
 
     def execute(self, context):
         copytoobject = context.active_object.name
         axes = self.priaxes + self.secaxes
-        copy_list = copy_to_from(context.scene,
-                                 bpy.data.objects[copytoobject],
-                                 bpy.data.objects[self.copyfromobject],
-                                 self.copytype,
-                                 axes,
-                                 self.edgescale,
-                                 self.scale)
+
+        # 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.scene,
+                    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"}
-# end Copy2 class
-
-#---------------------------------------------------------------------------------------
-
-
-def add_to_menu(self, context):
-    self.layout.operator(Copy2.bl_idname)
-    return
 
+        return {"FINISHED"}
 
-#-----------------------------------------------------------------
 
 def copy_to_from(scene, to_obj, from_obj, copymode, axes, edgescale, scale):
     if copymode == 'V':
-        copy_list = vertex_copy(scene, to_obj, from_obj, axes)
+        vertex_copy(scene, to_obj, from_obj, axes)
+
     if copymode == 'E':
-        copy_list = edge_copy(scene, to_obj, from_obj, axes, edgescale, scale)
+        # don't pass edgescalling to object types that cannot be scaled
+        if from_obj.type in ["CAMERA", "LAMP", "EMPTY", "ARMATURE", "SPEAKER", "META"]:
+            edgescale = False
+        edge_copy(scene, to_obj, from_obj, axes, edgescale, scale)
+
     if copymode == 'F':
-        copy_list = face_copy(scene, to_obj, from_obj, axes)
-    return copy_list
+        face_copy(scene, to_obj, from_obj, axes)
+
 
 axes_dict = {'XY': (1, 2, 0),
              'XZ': (2, 1, 0),
@@ -133,9 +185,9 @@ axes_dict = {'XY': (1, 2, 0),
 
 
 def copyto(scene, 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 the source_obj to pos, so its primary axis points in zdir and its
+    secondary axis points in xdir
     """
     copy_obj = source_obj.copy()
     scene.objects.link(copy_obj)
@@ -161,7 +213,7 @@ def copyto(scene, source_obj, pos, xdir, zdir, axes, scale=None):
     copy_obj.location = pos
 
     # scale object
-    if scale != None:
+    if scale is not None:
         copy_obj.scale = scale
 
     return copy_obj
@@ -171,8 +223,9 @@ def vertex_copy(scene, obj, source_obj, axes):
     # vertex select mode
     sel_verts = []
     copy_list = []
+
     for v in obj.data.vertices:
-        if v.select == True:
+        if v.select is True:
             sel_verts.append(v)
 
     # make a set for each vertex. The set contains all the connected vertices
@@ -198,20 +251,22 @@ def vertex_copy(scene, obj, source_obj, axes):
 
         copy = copyto(scene, source_obj, pos, xdir, zdir, axes)
         copy_list.append(copy)
+
     # select all copied objects
     for copy in copy_list:
         copy.select = True
     obj.select = False
-    return copy_list
 
 
 def edge_copy(scene, obj, source_obj, axes, es, scale):
     # edge select mode
     sel_edges = []
     copy_list = []
+
     for e in obj.data.edges:
-        if e.select == True:
+        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()
@@ -222,10 +277,10 @@ def edge_copy(scene, obj, source_obj, axes, es, scale):
         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
+        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
@@ -239,20 +294,22 @@ def edge_copy(scene, obj, source_obj, axes, es, scale):
 
         copy = copyto(scene, source_obj, pos, xdir, zdir, axes, scale=escale)
         copy_list.append(copy)
+
     # select all copied objects
     for copy in copy_list:
         copy.select = True
     obj.select = False
-    return copy_list
 
 
 def face_copy(scene, obj, source_obj, axes):
     # face select mode
     sel_faces = []
     copy_list = []
+
     for f in obj.data.polygons:
-        if f.select == True:
+        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
@@ -263,25 +320,19 @@ def face_copy(scene, obj, source_obj, axes):
 
         copy = copyto(scene, source_obj, fco, vco - fco, fn, axes)
         copy_list.append(copy)
+
     # select all copied objects
     for copy in copy_list:
         copy.select = True
     obj.select = False
-    return copy_list
-
-#-------------------------------------------------------------------
 
 
 def register():
-
-    bpy.utils.register_module(__name__)
-    bpy.types.VIEW3D_MT_object.append(add_to_menu)
+    bpy.utils.register_class(Copy2)
 
 
 def unregister():
-
-    bpy.types.VIEW3D_MT_object.remove(add_to_menu)
-    bpy.utils.unregister_module(__name__)
+    bpy.utils.unregister_class(Copy2)
 
 
 if __name__ == "__main__":
diff --git a/add_advanced_objects/cubester.py b/add_advanced_objects/cubester.py
index 83053ad1f5217d35aceda82b314d1070487930eb..1a516bd07f658a57dfdd2109d505b7279f1fbb55 100644
--- a/add_advanced_objects/cubester.py
+++ b/add_advanced_objects/cubester.py
@@ -19,10 +19,13 @@
 # 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),
+    "version": (0, 7, 1),
     "blender": (2, 78, 0),
     "location": "View 3D > Toolbar > CubeSter",
     "description": "Takes image, image sequence, or audio file and converts it "
@@ -32,13 +35,6 @@ bl_info = {
 
 import bpy
 import bmesh
-from bpy.props import (
-        BoolProperty,
-        IntProperty,
-        FloatProperty,
-        StringProperty,
-        EnumProperty,
-        )
 from bpy.types import (
         Operator,
         Panel,
@@ -53,29 +49,9 @@ from os import (
         )
 
 
-# load image if possible
-def adjust_selected_image(self, context):
-    scene = context.scene
-    try:
-        image = bpy.data.images.load(scene.cubester_load_image)
-        scene.cubester_image = image.name
-    except RuntimeError:
-        self.report({"ERROR"}, "CubeSter: '{}' could not be loaded".format(scene.cubester_load_image))
-
-
-# load color image if possible
-def adjust_selected_color_image(self, context):
-    scene = context.scene
-    try:
-        image = bpy.data.images.load(scene.cubester_load_color_image)
-        scene.cubester_color_image = image.name
-    except RuntimeError:
-        self.report({"ERROR"}, "CubeSter: '{}' could not be loaded".format(scene.cubester_load_color_image))
-
-
-# crate block at center position x, y with block width 2 * hx and 2 * hy and height of h
+# 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.cubester_block_style == "size":
+    if bpy.context.scene.advanced_objects.cubester_block_style == "size":
         z = 0.0
     else:
         z = h
@@ -134,12 +110,20 @@ def create_f_curves(mesh, frames, frame_step_size, style):
 # 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 scene.cubester_use_image_color and scene.cubester_color_image in bpy.data.images:
-        image = bpy.data.images[scene.cubester_color_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:
-        image = bpy.data.images[scene.cubester_image]
+        try:
+            image = bpy.data.images[adv_obj.cubester_image]
+        except:
+            pass
 
     if scene.render.engine == "CYCLES":
         mat.use_nodes = True
@@ -150,16 +134,17 @@ def create_material(scene, ob, name):
         att.location = (-200, 300)
 
         att = nodes.new("ShaderNodeTexImage")
-        att.image = image
+        if image:
+            att.image = image
 
-        if scene.cubester_load_type == "multiple":
+        if adv_obj.cubester_load_type == "multiple":
             att.image.source = "SEQUENCE"
         att.location = (-200, 700)
 
         att = nodes.new("ShaderNodeTexCoord")
         att.location = (-450, 600)
 
-        if scene.cubester_materials == "image":
+        if adv_obj.cubester_materials == "image":
             mat.node_tree.links.new(
                             nodes["Image Texture"].outputs[0],
                             nodes["Diffuse BSDF"].inputs[0]
@@ -174,9 +159,10 @@ def create_material(scene, ob, name):
                             nodes["Diffuse BSDF"].inputs[0]
                             )
     else:
-        if scene.cubester_materials == "image" or scene.render.engine != "BLENDER_RENDER":
+        if adv_obj.cubester_materials == "image" or scene.render.engine != "BLENDER_RENDER":
             tex = bpy.data.textures.new("CubeSter_" + name, "IMAGE")
-            tex.image = image
+            if image:
+                tex.image = image
             slot = mat.texture_slots.add()
             slot.texture = tex
         else:
@@ -187,10 +173,11 @@ def create_material(scene, ob, name):
 
 # generate mesh from audio
 def create_mesh_from_audio(self, scene, verts, faces):
-    audio_filepath = scene.cubester_audio_path
-    width = scene.cubester_audio_width_blocks
-    length = scene.cubester_audio_length_blocks
-    size_per_hundred = scene.cubester_size_per_hundred_pixels
+    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
 
@@ -213,8 +200,8 @@ def create_mesh_from_audio(self, scene, verts, faces):
     ob.select = True
 
     # inital vertex colors
-    if scene.cubester_materials == "image":
-        picture = bpy.data.images[scene.cubester_color_image]
+    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 = []
 
@@ -228,22 +215,25 @@ def create_mesh_from_audio(self, scene, verts, faces):
                 vert_colors += [(r, g, b) 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:
-            c.color = vert_colors[i]
-            i += 1
+            if i < vert_colors_size:
+                c.color = vert_colors[i]
+                i += 1
 
         # image sequence handling
-        if scene.cubester_load_type == "multiple":
+        if adv_obj.cubester_load_type == "multiple":
             images = find_sequence_images(self, bpy.context)
 
             frames_vert_colors = []
 
-            max_images = scene.cubester_max_images + 1 if \
-                        len(images[0]) > scene.cubester_max_images else len(images[0])
+            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, scene.cubester_skip_images):
+            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)
@@ -258,9 +248,10 @@ def create_mesh_from_audio(self, scene, verts, faces):
 
                 frames_vert_colors.append(frame_colors)
 
-            scene.cubester_vertex_colors[ob.name] = {"type": "vertex", "frames": frames_vert_colors,
-                                                     "frame_skip": scene.cubester_frame_step,
-                                                     "total_images": max_images}
+            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:
@@ -285,14 +276,14 @@ def create_mesh_from_audio(self, scene, verts, faces):
     for i in fcurves:
         i.select = False
 
-    max_images = scene.cubester_audio_max_freq
-    min_freq = scene.cubester_audio_min_freq
-    freq_frame = scene.cubester_audio_offset_type
+    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 = scene.cubester_audio_frame_offset
+    frame_step = adv_obj.cubester_audio_frame_offset
 
     # animate each block with a portion of the frequency
     for c in range(length):
@@ -314,8 +305,10 @@ def create_mesh_from_audio(self, scene, verts, faces):
             for i in range(index, index + 4):
                 curve = i * 3 + 2  # fcurve location
                 fcurves[curve].select = True
-
-            bpy.ops.graph.sound_bake(filepath=bpy.path.abspath(audio_filepath), low=l, high=h)
+            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):
@@ -328,7 +321,7 @@ def create_mesh_from_audio(self, scene, verts, faces):
     create_uv_map(bpy.context, width, length)
 
     # if radial apply needed modifiers
-    if scene.cubester_audio_block_layout == "radial":
+    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
@@ -358,14 +351,15 @@ def create_mesh_from_audio(self, scene, verts, faces):
 # generate mesh from image(s)
 def create_mesh_from_image(self, scene, verts, faces):
     context = bpy.context
-    picture = bpy.data.images[scene.cubester_image]
+    adv_obj = scene.advanced_objects
+    picture = bpy.data.images[adv_obj.cubester_image]
     pixels = list(picture.pixels)
 
-    x_pixels = picture.size[0] / (scene.cubester_skip_pixels + 1)
-    y_pixels = picture.size[1] / (scene.cubester_skip_pixels + 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 * scene.cubester_size_per_hundred_pixels
-    height = y_pixels / 100 * scene.cubester_size_per_hundred_pixels
+    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
@@ -376,18 +370,18 @@ def create_mesh_from_image(self, scene, verts, faces):
     weights = [uniform(0.0, 1.0) for i in range(4)]  # random weights
     rows = 0
 
-    # go through each row of pixels stepping by scene.cubester_skip_pixels + 1
-    for row in range(0, picture.size[1], scene.cubester_skip_pixels + 1):
+    # 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 + scene.cubester_skip_pixels * 4):
+        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)
             h = find_point_height(r, g, b, a, scene)
 
             # if not transparent
             if h != -1:
-                if scene.cubester_mesh_style == "blocks":
+                if adv_obj.cubester_mesh_style == "blocks":
                     create_block(x, y, half_width, h, verts, faces)
                     vert_colors += [(r, g, b) for i in range(24)]
                 else:
@@ -399,11 +393,11 @@ def create_mesh_from_image(self, scene, verts, faces):
 
         # if plane not blocks, then remove last 4 items from vertex_colors
         # as the faces have already wrapped around
-        if scene.cubester_mesh_style == "plane":
+        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 scene.cubester_mesh_style == "plane":
+    if adv_obj.cubester_mesh_style == "plane":
         off = int(len(verts) / rows)
         for r in range(rows - 1):
             for c in range(off - 1):
@@ -417,20 +411,21 @@ def create_mesh_from_image(self, scene, verts, faces):
     ob.select = True
 
     # uv unwrap
-    if scene.cubester_mesh_style == "blocks":
+    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 scene.cubester_materials == "vertex":  # vertex color
+    if adv_obj.cubester_materials == "vertex":  # vertex color
         image_name = "Vertex"
-    elif not scene.cubester_use_image_color and scene.cubester_color_image in bpy.data.images and \
-            scene.cubester_materials == "image":  # replaced image
-        image_name = scene.cubester_color_image
+    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 = scene.cubester_image
+        image_name = adv_obj.cubester_image
 
     # either add material or create
     if ("CubeSter_" + image_name) in bpy.data.materials:
@@ -449,15 +444,15 @@ def create_mesh_from_image(self, scene, verts, faces):
 
     frames = []
     # image sequence handling
-    if scene.cubester_load_type == "multiple":
+    if adv_obj.cubester_load_type == "multiple":
         images = find_sequence_images(self, context)
         frames_vert_colors = []
 
-        max_images = scene.cubester_max_images + 1 if \
-                    len(images[0]) > scene.cubester_max_images else len(images[0])
+        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, scene.cubester_skip_images):
+        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)
@@ -466,45 +461,50 @@ def create_mesh_from_image(self, scene, verts, faces):
             frame_heights = []
             frame_colors = []
 
-            for row in range(0, picture.size[1], scene.cubester_skip_pixels + 1):
-                for column in range(0, picture.size[0] * 4, 4 + scene.cubester_skip_pixels * 4):
+            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)
                     h = find_point_height(r, g, b, a, scene)
 
                     if h != -1:
                         frame_heights.append(h)
-                        if scene.cubester_mesh_style == "blocks":
+                        if adv_obj.cubester_mesh_style == "blocks":
                             frame_colors += [(r, g, b) for i in range(24)]
                         else:
                             frame_colors += [(r, g, b) for i in range(4)]
 
-            if scene.cubester_mesh_style == "plane":
+            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 scene.cubester_materials == "vertex" or scene.render.engine == "BLENDER_ENGINE":
-            scene.cubester_vertex_colors[ob.name] = {
-                                            "type": "vertex", "frames": frames_vert_colors,
-                                            "frame_skip": scene.cubester_frame_step,
-                                            "total_images": max_images
-                                            }
+        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:
-            scene.cubester_vertex_colors[ob.name] = {
-                                            "type": "image", "frame_skip": scene.cubester_frame_step,
-                                            "total_images": max_images
-                                            }
+            adv_obj.cubester_vertex_colors[ob.name] = {
+                                    "type": "image", "frame_skip": scene.cubester_frame_step,
+                                    "total_images": max_images
+                                    }
             att = get_image_node(ob.data.materials[0])
-            att.image_user.frame_duration = len(frames) * scene.cubester_frame_step
+            att.image_user.frame_duration = len(frames) * adv_obj.cubester_frame_step
 
         # animate mesh
-        create_f_curves(mesh, frames, scene.cubester_frame_step, scene.cubester_mesh_style)
+        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()
@@ -521,7 +521,7 @@ def create_uv_map(context, rows, columns):
     count = columns - 1  # hold current count to compare to if need to go to next row
 
     # if blocks
-    if context.scene.cubester_mesh_style == "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
@@ -555,33 +555,6 @@ def create_uv_map(context, rows, columns):
     bm.to_mesh(mesh)
 
 
-# returns length in frames
-def find_audio_length(self, context):
-    audio_file = context.scene.cubester_audio_path
-    length = 0
-
-    if audio_file != "":
-        # confirm that strip hasn't been loaded yet
-        for strip in context.scene.sequence_editor.sequences_all:
-            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"
-
-            bpy.ops.sequencer.sound_strip_add(filepath=audio_file)
-            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:
-                length = strip.frame_final_duration
-
-    context.scene.cubester_audio_file_length = str(length)
-
-
 # if already loaded return image, else load and return
 def fetch_image(self, name, load_path):
     if name in bpy.data.images:
@@ -597,19 +570,20 @@ def fetch_image(self, name, load_path):
 
 # 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 scene.cubester_advanced:
+        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 scene.cubester_random_weights:
-                composed = scene.cubester_weight_r * r + scene.cubester_weight_g * g + \
-                        scene.cubester_weight_b * b + scene.cubester_weight_a * a
-                total = scene.cubester_weight_r + scene.cubester_weight_g + scene.cubester_weight_b + \
-                        scene.cubester_weight_a
+            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
@@ -619,10 +593,10 @@ def find_point_height(r, g, b, a, scene):
                 total = weights[0] + weights[1] + weights[2] + weights[3]
                 normalize = 1 / total
 
-        if scene.cubester_invert:
-            h = (1 - composed) * scene.cubester_height_scale * normalize
+        if adv_obj.cubester_invert:
+            h = (1 - composed) * adv_obj.cubester_height_scale * normalize
         else:
-            h = composed * scene.cubester_height_scale * normalize
+            h = composed * adv_obj.cubester_height_scale * normalize
 
         return h
     else:
@@ -634,8 +608,8 @@ def find_sequence_images(self, context):
     scene = context.scene
     images = [[], []]
 
-    if scene.cubester_image in bpy.data.images:
-        image = bpy.data.images[scene.cubester_image]
+    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
@@ -685,15 +659,16 @@ def get_pixel_values(picture, pixels, row, column):
 # frame change handler for materials
 def material_frame_handler(scene):
     frame = scene.frame_current
+    adv_obj = scene.advanced_objects
 
-    keys = list(scene.cubester_vertex_colors.keys())
+    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 = scene.cubester_vertex_colors[ob.name]
+            data = adv_obj.advanced_objects.cubester_vertex_colors[ob.name]
             skip_frames = data["frame_skip"]
 
             # update materials using vertex colors
@@ -716,183 +691,7 @@ def material_frame_handler(scene):
 
         # if the object is no longer in the scene then delete then entry
         else:
-            del scene.cubester_vertex_colors[i]
-
-
-# main properties
-bpy.types.Scene.cubester_audio_image = EnumProperty(
-                            name="Input Type",
-                            items=(("image", "Image", ""),
-                                   ("audio", "Audio", ""))
-                                   )
-bpy.types.Scene.cubester_audio_file_length = StringProperty(
-                            default=""
-                            )
-# audio
-bpy.types.Scene.cubester_audio_path = StringProperty(
-                            default="",
-                            name="Audio File",
-                            subtype="FILE_PATH",
-                            update=find_audio_length
-                            )
-bpy.types.Scene.cubester_audio_min_freq = IntProperty(
-                            name="Minimum Frequency",
-                            min=20, max=100000,
-                            default=20
-                            )
-bpy.types.Scene.cubester_audio_max_freq = IntProperty(
-                            name="Maximum Frequency",
-                            min=21, max=999999,
-                            default=5000
-                            )
-bpy.types.Scene.cubester_audio_offset_type = EnumProperty(
-                            name="Offset Type",
-                            items=(("freq", "Frequency Offset", ""),
-                                   ("frame", "Frame Offset", "")),
-                            description="Type of offset per row of mesh"
-                            )
-bpy.types.Scene.cubester_audio_frame_offset = IntProperty(
-                            name="Frame Offset",
-                            min=0, max=10,
-                            default=2
-                            )
-bpy.types.Scene.cubester_audio_block_layout = EnumProperty(
-                            name="Block Layout",
-                            items=(("rectangle", "Rectangular", ""),
-                                  ("radial", "Radial", ""))
-                            )
-bpy.types.Scene.cubester_audio_width_blocks = IntProperty(
-                            name="Width Block Count",
-                            min=1, max=10000,
-                            default=5
-                            )
-bpy.types.Scene.cubester_audio_length_blocks = IntProperty(
-                            name="Length Block Count",
-                            min=1, max=10000,
-                            default=50
-                            )
-# image
-bpy.types.Scene.cubester_load_type = EnumProperty(
-                            name="Image Input Type",
-                            items=(("single", "Single Image", ""),
-                                  ("multiple", "Image Sequence", ""))
-                            )
-bpy.types.Scene.cubester_image = StringProperty(
-                            default="",
-                            name=""
-                            )
-bpy.types.Scene.cubester_load_image = StringProperty(
-                            default="",
-                            name="Load Image",
-                            subtype="FILE_PATH",
-                            update=adjust_selected_image
-                            )
-bpy.types.Scene.cubester_skip_images = IntProperty(
-                            name="Image Step",
-                            min=1, max=30,
-                            default=1,
-                            description="Step from image to image by this number"
-                            )
-bpy.types.Scene.cubester_max_images = IntProperty(
-                            name="Max Number Of Images",
-                            min=2, max=1000,
-                            default=10,
-                            description="Maximum number of images to be used"
-                            )
-bpy.types.Scene.cubester_frame_step = IntProperty(
-                            name="Frame Step Size",
-                            min=1, max=10,
-                            default=4,
-                            description="The number of frames each picture is used"
-                            )
-bpy.types.Scene.cubester_skip_pixels = IntProperty(
-                            name="Skip # Pixels",
-                            min=0, max=256,
-                            default=64,
-                            description="Skip this number of pixels before placing the next"
-                            )
-bpy.types.Scene.cubester_mesh_style = EnumProperty(
-                            name="Mesh Type",
-                            items=(("blocks", "Blocks", ""),
-                                   ("plane", "Plane", "")),
-                            description="Compose mesh of multiple blocks or of a single plane"
-                            )
-bpy.types.Scene.cubester_block_style = EnumProperty(
-                            name="Block Style",
-                            items=(("size", "Vary Size", ""),
-                                   ("position", "Vary Position", "")),
-                            description="Vary Z-size of block, or vary Z-position"
-                            )
-bpy.types.Scene.cubester_height_scale = FloatProperty(
-                            name="Height Scale",
-                            subtype="DISTANCE",
-                            min=0.1, max=2,
-                            default=0.2
-                            )
-bpy.types.Scene.cubester_invert = BoolProperty(
-                            name="Invert Height?",
-                            default=False
-                            )
-# general adjustments
-bpy.types.Scene.cubester_size_per_hundred_pixels = FloatProperty(
-                            name="Size Per 100 Blocks/Points",
-                            subtype="DISTANCE",
-                            min=0.001, max=5,
-                            default=1
-                            )
-# material based stuff
-bpy.types.Scene.cubester_materials = EnumProperty(
-                            name="Material",
-                            items=(("vertex", "Vertex Colors", ""),
-                                   ("image", "Image", "")),
-                            description="Color with vertex colors, or uv unwrap and use an image"
-                            )
-bpy.types.Scene.cubester_use_image_color = BoolProperty(
-                            name="Use Original Image Colors'?",
-                            default=True,
-                            description="Use original image colors, or replace with other"
-                            )
-bpy.types.Scene.cubester_color_image = StringProperty(
-                            default="", name=""
-                            )
-bpy.types.Scene.cubester_load_color_image = StringProperty(
-                            default="",
-                            name="Load Color Image",
-                            subtype="FILE_PATH",
-                            update=adjust_selected_color_image
-                            )
-bpy.types.Scene.cubester_vertex_colors = {}
-# advanced
-bpy.types.Scene.cubester_advanced = BoolProperty(
-                            name="Advanced Options?"
-                            )
-bpy.types.Scene.cubester_random_weights = BoolProperty(
-                            name="Random Weights?"
-                            )
-bpy.types.Scene.cubester_weight_r = FloatProperty(
-                            name="Red",
-                            subtype="FACTOR",
-                            min=0.01, max=1.0,
-                            default=0.25
-                            )
-bpy.types.Scene.cubester_weight_g = FloatProperty(
-                            name="Green",
-                            subtype="FACTOR",
-                            min=0.01, max=1.0,
-                            default=0.25
-                            )
-bpy.types.Scene.cubester_weight_b = FloatProperty(
-                            name="Blue",
-                            subtype="FACTOR",
-                            min=0.01, max=1.0,
-                            default=0.25
-                            )
-bpy.types.Scene.cubester_weight_a = FloatProperty(
-                            name="Alpha",
-                            subtype="FACTOR",
-                            min=0.01, max=1.0,
-                            default=0.25
-                            )
+            del adv_obj.advanced_objects.cubester_vertex_colors[i]
 
 
 class CubeSterPanel(Panel):
@@ -907,127 +706,123 @@ class CubeSterPanel(Panel):
     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(scene, "cubester_audio_image", icon="IMAGE_COL")
-        layout.separator()
+        layout.prop(adv_obj, "cubester_audio_image")
 
-        if scene.cubester_audio_image == "image":
+        if adv_obj.cubester_audio_image == "image":
             box = layout.box()
-            box.prop(scene, "cubester_load_type")
+            box.prop(adv_obj, "cubester_load_type")
             box.label("Image To Convert:")
-            box.prop_search(scene, "cubester_image", bpy.data, "images")
-            box.prop(scene, "cubester_load_image")
-            layout.separator()
+            box.prop_search(adv_obj, "cubester_image", bpy.data, "images")
+            box.prop(adv_obj, "cubester_load_image")
 
             # find number of approriate images if sequence
-            if scene.cubester_load_type == "multiple":
+            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]) <= scene.cubester_max_images \
-                    else scene.cubester_max_images
+                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(scene, "cubester_max_images")
-                box.prop(scene, "cubester_skip_images")
-                box.prop(scene, "cubester_frame_step")
-
-                layout.separator()
+                box.prop(adv_obj, "cubester_max_images")
+                box.prop(adv_obj, "cubester_skip_images")
+                box.prop(adv_obj, "cubester_frame_step")
 
             box = layout.box()
-            box.prop(scene, "cubester_skip_pixels")
-            box.prop(scene, "cubester_size_per_hundred_pixels")
-            box.prop(scene, "cubester_height_scale")
-            box.prop(scene, "cubester_invert", icon="FILE_REFRESH")
+            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")
 
-            layout.separator()
             box = layout.box()
-            box.prop(scene, "cubester_mesh_style", icon="MESH_GRID")
+            box.prop(adv_obj, "cubester_mesh_style", icon="MESH_GRID")
 
-            if scene.cubester_mesh_style == "blocks":
-                box.prop(scene, "cubester_block_style")
-
-        # audio file
+            if adv_obj.cubester_mesh_style == "blocks":
+                box.prop(adv_obj, "cubester_block_style")
         else:
-            layout.prop(scene, "cubester_audio_path")
-            layout.separator()
+            # 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.prop(scene, "cubester_audio_min_freq")
-            box.prop(scene, "cubester_audio_max_freq")
             box.separator()
-            box.prop(scene, "cubester_audio_offset_type")
+            box.prop(adv_obj, "cubester_audio_offset_type")
 
-            if scene.cubester_audio_offset_type == "frame":
-                box.prop(scene, "cubester_audio_frame_offset")
+            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()
 
-            box.prop(scene, "cubester_audio_block_layout")
-            box.prop(scene, "cubester_audio_width_blocks")
-            box.prop(scene, "cubester_audio_length_blocks")
+            col = box.column(align=True)
+            col.prop(adv_obj, "cubester_audio_width_blocks")
+            col.prop(adv_obj, "cubester_audio_length_blocks")
 
-            rows = scene.cubester_audio_width_blocks
-            columns = scene.cubester_audio_length_blocks
+            rows = adv_obj.cubester_audio_width_blocks
+            columns = adv_obj.cubester_audio_length_blocks
 
-            box.prop(scene, "cubester_size_per_hundred_pixels")
+            col.prop(adv_obj, "cubester_size_per_hundred_pixels")
 
         # materials
-        layout.separator()
         box = layout.box()
+        box.prop(adv_obj, "cubester_materials", icon="MATERIAL")
 
-        box.prop(scene, "cubester_materials", icon="MATERIAL")
-
-        if scene.cubester_materials == "image":
-            box.prop(scene, "cubester_load_type")
+        if adv_obj.cubester_materials == "image":
+            box.prop(adv_obj, "cubester_load_type")
 
             # find number of approriate images if sequence
-            if scene.cubester_load_type == "multiple":
+            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]) <= scene.cubester_max_images \
-                    else scene.cubester_max_images
+                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(scene, "cubester_max_images")
-                box.prop(scene, "cubester_skip_images")
-                box.prop(scene, "cubester_frame_step")
+                box.prop(adv_obj, "cubester_max_images")
+                box.prop(adv_obj, "cubester_skip_images")
+                box.prop(adv_obj, "cubester_frame_step")
 
             box.separator()
 
-            if scene.cubester_audio_image == "image":
-                box.prop(scene, "cubester_use_image_color", icon="COLOR")
+            if adv_obj.cubester_audio_image == "image":
+                box.prop(adv_obj, "cubester_use_image_color", icon="COLOR")
 
-            if not scene.cubester_use_image_color or scene.cubester_audio_image == "audio":
+            if not adv_obj.cubester_use_image_color or adv_obj.cubester_audio_image == "audio":
                 box.label("Image To Use For Colors:")
-                box.prop_search(scene, "cubester_color_image", bpy.data, "images")
-                box.prop(scene, "cubester_load_color_image")
+                box.prop_search(adv_obj, "cubester_color_image", bpy.data, "images")
+                box.prop(adv_obj, "cubester_load_color_image")
 
-            if scene.cubester_image in bpy.data.images:
-                rows = int(bpy.data.images[scene.cubester_image].size[1] / (scene.cubester_skip_pixels + 1))
-                columns = int(bpy.data.images[scene.cubester_image].size[0] / (scene.cubester_skip_pixels + 1))
+            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))
 
-        layout.separator()
         box = layout.box()
 
-        if scene.cubester_mesh_style == "blocks":
+        if adv_obj.cubester_mesh_style == "blocks":
             box.label("Approximate Cube Count: " + str(rows * columns))
-            box.label("Expected # Verts/Faces: " + str(rows * columns * 8) + " / " + str(rows * columns * 6))
+            box.label("Expected Verts/Faces: " + str(rows * columns * 8) + " / " + str(rows * columns * 6))
         else:
             box.label("Approximate Point Count: " + str(rows * columns))
-            box.label("Expected # Verts/Faces: " + str(rows * columns) + " / " + str(rows * (columns - 1)))
+            box.label("Expected Verts/Faces: " + str(rows * columns) + " / " + str(rows * (columns - 1)))
 
         # blocks and plane generation time values
-        if scene.cubester_mesh_style == "blocks":
+        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
@@ -1035,21 +830,22 @@ class CubeSterPanel(Panel):
 
         # if creating image based mesh
         points = rows * columns
-        if scene.cubester_audio_image == "image":
-            if scene.cubester_load_type == "single":
+        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 / scene.cubester_skip_images * frame_infl) + intercept2
+                       (images_found / adv_obj.cubester_skip_images * frame_infl) + intercept2
 
-                box.label("Images To Be Used: " + str(int(images_found / scene.cubester_skip_images)))
-
-        # audio based mesh
+                box.label("Images To Be Used: " + str(int(images_found / adv_obj.cubester_skip_images)))
         else:
-            box.label("Audio Track Length: " + scene.cubester_audio_file_length + " frames")
+            # audio based mesh
+            box.label("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) + (int(scene.cubester_audio_file_length) * frame_infl) + intercept
+            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
@@ -1060,29 +856,31 @@ class CubeSterPanel(Panel):
         box.label("Expected Time: " + str(time) + " " + time_mod)
 
         # advanced
-        if scene.cubester_audio_image == "image":
-            layout.separator()
+        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(scene, "cubester_advanced", icon="TRIA_DOWN")
-            if bpy.context.scene.cubester_advanced:
-                box.prop(scene, "cubester_random_weights", icon="RNDCURVE")
-                box.separator()
+            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 bpy.context.scene.cubester_random_weights:
+                if not adv_obj.cubester_random_weights:
                     box.label("RGBA Channel Weights", icon="COLOR")
-                    box.prop(scene, "cubester_weight_r")
-                    box.prop(scene, "cubester_weight_g")
-                    box.prop(scene, "cubester_weight_b")
-                    box.prop(scene, "cubester_weight_a")
+                    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.separator()
         layout.operator("mesh.cubester", icon="OBJECT_DATA")
 
 
 class CubeSter(Operator):
     bl_idname = "mesh.cubester"
     bl_label = "Generate Mesh"
+    bl_description = "Generate a mesh from an Image or Sound File"
     bl_options = {"REGISTER", "UNDO"}
 
     def execute(self, context):
@@ -1090,18 +888,31 @@ class CubeSter(Operator):
 
         start = timeit.default_timer()
         scene = bpy.context.scene
+        adv_obj = scene.advanced_objects
 
-        if scene.cubester_audio_image == "image":
-            create_mesh_from_image(self, scene, verts, faces)
-            frames = find_sequence_images(self, context)
-            created = len(frames[0])
+        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:
-            create_mesh_from_audio(self, scene, verts, faces)
-            created = int(scene.cubester_audio_file_length)
+            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, scene, 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 scene.cubester_mesh_style == "blocks" or scene.cubester_audio_image == "audio":
+        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)),
diff --git a/add_advanced_objects/delaunay_voronoi/DelaunayVoronoi.py b/add_advanced_objects/delaunay_voronoi/DelaunayVoronoi.py
index 18d7f38f1764923d1a06e9082bfa778770d7c92a..dcce7f689eac85de28656a57d6baa5a8275bf33b 100644
--- a/add_advanced_objects/delaunay_voronoi/DelaunayVoronoi.py
+++ b/add_advanced_objects/delaunay_voronoi/DelaunayVoronoi.py
@@ -61,13 +61,11 @@
 
 import bpy
 import math
-import sys
-import getopt
+
+# Globals
 TOLERANCE = 1e-9
 BIG_FLOAT = 1e38
 
-# TODO : Licence, prints, imports, autorship
-
 
 class Context(object):
 
@@ -295,14 +293,14 @@ class Context(object):
 
     def outTriple(self, s1, s2, s3):
         self.triangles.append((s1.sitenum, s2.sitenum, s3.sitenum))
-        if(self.debug):
+        if (self.debug):
             print("circle through left=%d right=%d bottom=%d" % (s1.sitenum, s2.sitenum, s3.sitenum))
-        elif(self.triangulate and self.doPrint):
+        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):
+        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)
@@ -328,8 +326,8 @@ class Context(object):
 
         self.edges.append((edge.edgenum, sitenumL, sitenumR))
 
-        if(not self.triangulate):
-            if(self.doPrint):
+        if (not self.triangulate):
+            if (self.doPrint):
                 print("e %d" % edge.edgenum)
                 print(" %d " % sitenumL)
                 print("%d" % sitenumR)
diff --git a/add_advanced_objects/delaunay_voronoi/__init__.py b/add_advanced_objects/delaunay_voronoi/__init__.py
index 1d210a2a60c7d7dedfc8a4086040d63341d5fdee..c32eb37487fc4c72b23fd6ad1553edb7b785c1c6 100644
--- a/add_advanced_objects/delaunay_voronoi/__init__.py
+++ b/add_advanced_objects/delaunay_voronoi/__init__.py
@@ -21,14 +21,13 @@
 bl_info = {
     "name": "Delaunay Voronoi",
     "description": "Points cloud Delaunay triangulation in 2.5D "
-                  "(suitable for terrain modelling) or Voronoi diagram in 2D",
+                   "(suitable for terrain modelling) or Voronoi diagram in 2D",
     "author": "Domlysz, Oscurart",
     "version": (1, 3),
     "blender": (2, 7, 0),
     "location": "View3D > Tools > GIS",
     "warning": "",
     "wiki_url": "https://github.com/domlysz/BlenderGIS/wiki",
-    "tracker_url": "",
     "category": ""
     }
 
diff --git a/add_advanced_objects/delaunay_voronoi/delaunayVoronoiBlender.py b/add_advanced_objects/delaunay_voronoi/delaunayVoronoiBlender.py
index e937e7a138c59376e76612e42755f579cd7598b3..707c45b4b1f2d430c61f6f490b1506b7732cea16 100644
--- a/add_advanced_objects/delaunay_voronoi/delaunayVoronoiBlender.py
+++ b/add_advanced_objects/delaunay_voronoi/delaunayVoronoiBlender.py
@@ -2,9 +2,9 @@
 
 import bpy
 from .DelaunayVoronoi import (
-            computeVoronoiDiagram,
-            computeDelaunayTriangulation,
-            )
+        computeVoronoiDiagram,
+        computeDelaunayTriangulation,
+        )
 from bpy.types import (
         Operator,
         Panel,
@@ -12,6 +12,17 @@ from bpy.types import (
 from bpy.props import EnumProperty
 
 
+# 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
@@ -56,45 +67,56 @@ class ToolsPanelDelaunay(Panel):
 
     def draw(self, context):
         layout = self.layout
-        layout.label('Constellation')
-        self.layout.operator("delaunay.triangulation")
-        self.layout.operator("voronoi.tesselation")
-        layout.label('Constellation')
-        layout.operator("mesh.constellation", text="Cross Section")
+        adv_obj = context.scene.advanced_objects
+
+        box = layout.box()
+        col = box.column(align=True)
+        col.label("Point Cloud:")
+        col.operator("delaunay.triangulation")
+        col.operator("voronoi.tesselation")
+
+        box = layout.box()
+        col = box.column(align=True)
+        col.label("Constellation:")
+        col.operator("mesh.constellation", text="Cross Section")
+        col.prop(adv_obj, "constellation_limit")
 
 
 class OBJECT_OT_TriangulateButton(Operator):
     bl_idname = "delaunay.triangulation"
     bl_label = "Triangulation"
-    bl_description = "Terrain points cloud Delaunay triangulation in 2.5D"
-    bl_options = {"UNDO"}
+    bl_description = ("Terrain points cloud Delaunay triangulation in 2.5D\n"
+                      "Needs an existing Active Mesh Object")
+    bl_options = {"REGISTER", "UNDO"}
 
-    def execute(self, context):
-        # Get selected obj
-        objs = bpy.context.selected_objects
-        if len(objs) == 0 or len(objs) > 1:
-            self.report({'INFO'}, "Selection is empty or too much object selected")
-            return {'FINISHED'}
+    @classmethod
+    def poll(cls, context):
+        obj = context.active_object
+        return (obj is not None and obj.type == "MESH")
 
-        obj = objs[0]
-        if obj.type != 'MESH':
-            self.report({'INFO'}, "Selection isn't a mesh")
-            return {'FINISHED'}
+    def execute(self, context):
+        # move the check into the poll
+        obj = context.active_object
 
         # Get points coodinates
         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)
-        print(str(nDupli) + " duplicates points ignored")
-        print(str(nZcolinear) + " z colinear points excluded")
+
+        debug_prints(text=str(nDupli) + " duplicate points ignored")
+        debug_prints(str(nZcolinear) + " z colinear points excluded")
+
         if nVerts < 3:
-            self.report({'ERROR'}, "Not enough points")
-            return {'FINISHED'}
+            self.report({"WARNING"},
+                        "Not enough points to continue. Operation Cancelled")
+
+            return {"CANCELLED"}
 
         # Check colinear
         xValues = [pt[0] for pt in verts]
@@ -105,59 +127,63 @@ class OBJECT_OT_TriangulateButton(Operator):
             return {'FINISHED'}
 
         # Triangulate
-        print("Triangulate " + str(nVerts) + " points...")
+        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]
 
-        print(str(len(triangles)) + " triangles")
+        debug_prints(text=str(len(triangles)) + " triangles")
 
         # Create new mesh structure
-        print("Create mesh...")
+        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.scene.objects.link(tinObj)  # Link object to scene
         bpy.context.scene.objects.active = tinObj
         tinObj.select = True
         obj.select = False
-        # Report
-        self.report({'INFO'}, "Mesh created (" + str(len(triangles)) + " triangles)")
+
+        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"
+    bl_description = ("Points cloud Voronoi diagram in 2D\n"
+                      "Needs an existing Active Mesh Object")
     bl_options = {"REGISTER", "UNDO"}
 
     meshType = EnumProperty(
-                    items=[("Edges", "Edges", ""), ("Faces", "Faces", "")],
-                    name="Mesh type",
-                    description=""
-                    )
+            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"
+            )
 
-    def execute(self, context):
-        # Get selected obj
-        objs = bpy.context.selected_objects
-        if len(objs) == 0 or len(objs) > 1:
-            self.report({'INFO'}, "Selection is empty or too much object selected")
-            return {'FINISHED'}
+    @classmethod
+    def poll(cls, context):
+        obj = context.active_object
+        return (obj is not None and obj.type == "MESH")
 
-        obj = objs[0]
-        if obj.type != 'MESH':
-            self.report({'INFO'}, "Selection isn't a mesh")
-            return {'FINISHED'}
+    def execute(self, context):
+        # move the check into the poll
+        obj = context.active_object
 
         # Get points coodinates
         r = obj.rotation_euler
@@ -170,28 +196,36 @@ class OBJECT_OT_VoronoiButton(Operator):
         nDupli, nZcolinear = unique(verts)
         nVerts = len(verts)
 
-        print(str(nDupli) + " duplicates points ignored")
-        print(str(nZcolinear) + " z colinear points excluded")
+        debug_prints(text=str(nDupli) + " duplicates points ignored")
+        debug_prints(text=str(nZcolinear) + " z colinear points excluded")
 
         if nVerts < 3:
-            self.report({'ERROR'}, "Not enough points")
-            return {'FINISHED'}
+            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'}
+            self.report({"WARNING"},
+                        "Points are colinear. Operation Cancelled")
+
+            return {"CANCELLED"}
 
         # Create diagram
-        print("Tesselation... (" + str(nVerts) + " points)")
+        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
+                                vertsPts, xbuff, ybuff,
+                                polygonsOutput=False, formatOutput=True
                                 )
         else:
             pts, polyIdx = computeVoronoiDiagram(
@@ -227,8 +261,8 @@ class OBJECT_OT_VoronoiButton(Operator):
 
         # Report
         if self.meshType == "Edges":
-            self.report({'INFO'}, "Mesh created (" + str(len(edgesIdx)) + " edges)")
+            self.report({"INFO"}, "Mesh created (" + str(len(edgesIdx)) + " edges)")
         else:
-            self.report({'INFO'}, "Mesh created (" + str(len(polyIdx)) + " polygons)")
+            self.report({"INFO"}, "Mesh created (" + str(len(polyIdx)) + " polygons)")
 
         return {'FINISHED'}
diff --git a/add_advanced_objects/delaunay_voronoi/oscurart_constellation.py b/add_advanced_objects/delaunay_voronoi/oscurart_constellation.py
index babbfdc503a93298a5dc3e497df979d85e4b2d58..adde96c0430ac5f1591c52ac9f0c5ab05e288f9a 100644
--- a/add_advanced_objects/delaunay_voronoi/oscurart_constellation.py
+++ b/add_advanced_objects/delaunay_voronoi/oscurart_constellation.py
@@ -19,15 +19,17 @@
 bl_info = {
     "name": "Mesh: Constellation",
     "author": "Oscurart",
-    "version": (1, 0),
+    "version": (1, 1, 1),
     "blender": (2, 67, 0),
     "location": "Add > Mesh > Constellation",
-    "description": "Adds a new Mesh From Selected",
+    "description": "Create a new Mesh From Selected",
     "warning": "",
     "wiki_url": "",
-    "tracker_url": "",
     "category": "Add Mesh"}
 
+# Note the setting is moved to __init__ search for
+# the adv_obj and advanced_objects patterns
+
 import bpy
 from bpy.types import Operator
 from bpy.props import FloatProperty
@@ -56,51 +58,66 @@ def OscConstellation(limit):
                 edgei += 2
 
     mesh = bpy.data.meshes.new("rsdata")
-    object = bpy.data.objects.new("rsObject", mesh)
-    bpy.context.scene.objects.link(object)
+    obj = bpy.data.objects.new("rsObject", mesh)
+    bpy.context.scene.objects.link(obj)
     mesh.from_pydata(vertlist, edgelist, [])
 
 
-class Oscurart_Constellation (Operator):
+class Oscurart_Constellation(Operator):
     bl_idname = "mesh.constellation"
     bl_label = "Constellation"
-    bl_description = "Create a Constellation Mesh"
+    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='Limit',
-                default=2,
-                min=0
-                )
+            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):
-        return(bpy.context.active_object.type == "MESH")
+        obj = context.active_object
+        return (obj and obj.type == "MESH")
+
+    def invoke(self, context, event):
+        adv_obj = context.scene.advanced_objects
+        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):
-        OscConstellation(self.limit)
+        try:
+            OscConstellation(self.limit)
+        except Exception as e:
+            print("\n[Add Advanced Objects]\nOperator: mesh.constellation\n{}".format(e))
 
-        return {'FINISHED'}
+            self.report({"WARNING"},
+                        "Constellation Operation could not be Completed (See Console for more Info)")
 
+            return {"CANCELLED"}
 
-# Register
+        return {'FINISHED'}
 
-def add_osc_constellation_button(self, context):
-    self.layout.operator(
-        Oscurart_Constellation.bl_idname,
-        text="Constellation",
-        icon="PLUGIN")
 
+# Register
 
 def register():
     bpy.utils.register_class(Oscurart_Constellation)
-    bpy.types.INFO_MT_mesh_add.append(add_osc_constellation_button)
 
 
 def unregister():
     bpy.utils.unregister_class(Oscurart_Constellation)
-    bpy.types.INFO_MT_mesh_add.remove(add_osc_constellation_button)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     register()
diff --git a/add_advanced_objects/drop_to_ground.py b/add_advanced_objects/drop_to_ground.py
index 801b7e94c6556305da4bc25910107bdd2dec6dce..744a2d6b71cfbd8b6a96103a127ad9a1575bb315 100644
--- a/add_advanced_objects/drop_to_ground.py
+++ b/add_advanced_objects/drop_to_ground.py
@@ -19,14 +19,13 @@
 bl_info = {
     "name": "Drop to Ground1",
     "author": "Unnikrishnan(kodemax), Florian Meyer(testscreenings)",
-    "version": (1, 2),
+    "version": (1, 2, 1),
     "blender": (2, 71, 0),
     "location": "3D View > Toolshelf > Tools Tab",
     "description": "Drop selected objects on active object",
     "warning": "",
     "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
                 "Scripts/Object/Drop_to_ground",
-    "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
     "category": "Object"}
 
 
@@ -59,6 +58,7 @@ def transform_ground_to_world(sc, ground):
     tmp_ground = bpy.data.objects.new('tmpGround', tmpMesh)
     sc.objects.link(tmp_ground)
     sc.update()
+
     return tmp_ground
 
 
@@ -120,12 +120,16 @@ def drop_objectsall(self, context):
             lowest_world_co = ob.location
         else:
             lowest_world_co = get_lowest_world_co(context, ob)
+
         if not lowest_world_co:
-            print(ob.type, 'is not supported. Failed to drop', ob.name)
+            message = "Type {} is not supported. Failed to drop {}".format(ob.type, ob.name)
+            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:
-            print(ob.name, 'didn\'t hit the ground')
+            message = ob.name + " did not hit the Ground"
+            self.reported.append(message)
             continue
 
         # simple drop down
@@ -169,12 +173,16 @@ def drop_objects(self, context):
             lowest_world_co = ob.location
         else:
             lowest_world_co = get_lowest_world_co(context, ob)
+
         if not lowest_world_co:
-            print(ob.type, 'is not supported. Failed to drop', ob.name)
+            message = "Type {} is not supported. Failed to drop {}".format(ob.type, ob.name)
+            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:
-            print(ob.name, 'didn\'t hit the ground')
+            message = ob.name + " did not hit the Ground"
+            self.reported.append(message)
             continue
 
         # simple drop down
@@ -209,8 +217,8 @@ def drop_objects(self, context):
 class OBJECT_OT_drop_to_ground(Operator):
     bl_idname = "object.drop_on_active"
     bl_label = "Drop to Ground"
+    bl_description = "Drop selected objects on the active object"
     bl_options = {'REGISTER', 'UNDO'}
-    bl_description = "Drop selected objects on active object"
 
     align = BoolProperty(
             name="Align to ground",
@@ -220,22 +228,31 @@ class OBJECT_OT_drop_to_ground(Operator):
             name="Use Center",
             description="Drop to objects origins",
             default=False)
+    reported = []
 
     @classmethod
     def poll(cls, context):
         return len(context.selected_objects) >= 2
 
     def execute(self, context):
-        print('\nDropping Objects')
         drop_objects(self, context)
+
+        if self.reported:
+            self.report({"INFO"},
+                        "Operation failed on some objects. 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):
     bl_idname = "object.drop_all_active"
-    bl_label = "Drop to Ground"
-    bl_options = {'REGISTER', 'UNDO'}
+    bl_label = "Drop All to Ground (Active Object)"
     bl_description = "Drop selected objects on active object"
+    bl_options = {'REGISTER', 'UNDO'}
 
     align = BoolProperty(
             name="Align to ground",
@@ -245,33 +262,45 @@ class OBJECT_OT_drop_all_ground(Operator):
             name="Use Center",
             description="Drop to objects origins",
             default=False)
+    reported = []
+
+    @classmethod
+    def poll(cls, context):
+        return context.active_object is not None
 
     def execute(self, context):
-        print('\nDropping Objects')
         drop_objectsall(self, context)
 
+        if self.reported:
+            self.report({"INFO"},
+                        "Operation failed on some objects. 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):
+class Drop_help(Operator):
     bl_idname = "help.drop"
     bl_label = ""
 
+    is_all = BoolProperty(
+            default=True,
+            options={"HIDDEN"}
+            )
+
     def draw(self, context):
         layout = self.layout
         layout.label("To use:")
-        layout.label("___________________________")
 
-        layout.label("Drop selected :-")
-
-        layout.label("Name the base object 'Ground'")
-        layout.label("Select the object/s to drop")
-        layout.label("Then Shift Select 'Ground'")
-        layout.label("___________________________")
-
-        layout.label("Drop all :-")
-
-        layout.label("select the ground mesh , and press Drop all")
+        if self.is_all is False:
+            layout.label("Name the base object 'Ground'")
+            layout.label("Select the object's to drop")
+            layout.label("Then Shift Select 'Ground'")
+        else:
+            layout.label("Select the ground mesh and press Drop all")
 
     def execute(self, context):
         return {'FINISHED'}
@@ -290,25 +319,31 @@ class Drop_Operator_Panel(Panel):
 
     def draw(self, context):
         layout = self.layout
-        row = layout.row()
-        row = layout.split(0.80)
+
+        row = layout.split(percentage=0.8, align=True)
         row.operator(OBJECT_OT_drop_to_ground.bl_idname,
                      text="Drop Selected")
-        row = layout.row()
+        row.operator("help.drop", 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', icon='INFO')
+        row.operator("help.drop", icon="LAYER_USED").is_all = True
 
 
 # Register
 def register():
-    bpy.utils.register_module(__name__)
-    pass
+    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_module(__name__)
-    pass
+    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__":
diff --git a/add_advanced_objects/make_struts.py b/add_advanced_objects/make_struts.py
index 7f754ea8a60129e1e673912a61658fc71c4aa870..58e149abaefa31dcc4ade447f490889f75b34ea1 100644
--- a/add_advanced_objects/make_struts.py
+++ b/add_advanced_objects/make_struts.py
@@ -21,22 +21,9 @@
 
 # <pep8 compliant>
 
-"""
-bl_info = {
-    "name": "Strut Generator",
-    "author": "Bill Currie",
-    "blender": (2, 6, 3),
-    "api": 35622,
-    "location": "View3D > Add > Mesh > Struts",
-    "description": "Add struts meshes based on selected truss meshes",
-    "warning": "can get very high-poly",
-    "wiki_url": "",
-    "tracker_url": "",
-    "category": "Add Mesh"}
-"""
-
 import bpy
 import bmesh
+from bpy.types import Operator
 from bpy.props import (
         FloatProperty,
         IntProperty,
@@ -48,8 +35,7 @@ from mathutils import (
         Quaternion,
         )
 from math import (
-        pi,
-        cos,
+        pi, cos,
         sin,
         )
 
@@ -71,6 +57,7 @@ def build_cossin(n):
 
 
 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:
@@ -109,21 +96,21 @@ def select_up(axis):
 #                   vertices for the created strut.
 
 
-def make_strut(v1, v2, id, od, n, solid, loops):
+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 - id) / 2, od / 2),
-                (axis.length - (od - id) / 2, od / 2)]
+        pos += [((od - ind) / 2, od / 2),
+                (axis.length - (od - ind) / 2, od / 2)]
     pos += [(axis.length, od / 2)]
     if solid:
-        pos += [(axis.length, id / 2)]
+        pos += [(axis.length, ind / 2)]
         if loops:
-            pos += [(axis.length - (od - id) / 2, id / 2),
-                    ((od - id) / 2, id / 2)]
-        pos += [(0, id / 2)]
+            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:
@@ -156,7 +143,7 @@ def make_strut(v1, v2, id, od, n, solid, loops):
     for j in range(fps):
         f = (i - 1) * fps + j
         faces[f] = [base + j, j, (j + 1) % vps, base + (j + 1) % vps]
-    # print(verts,faces)
+
     return verts, faces
 
 
@@ -452,7 +439,7 @@ def make_manifold_struts(truss_obj, od, segments):
     return verts, faces
 
 
-def make_simple_struts(truss_mesh, id, od, segments, solid, loops):
+def make_simple_struts(truss_mesh, ind, od, segments, solid, loops):
     vps = 2
     if solid:
         vps *= 2
@@ -466,10 +453,11 @@ def make_simple_struts(truss_mesh, id, od, segments, solid, loops):
     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, id, od, segments, solid, loops)
+        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
@@ -481,14 +469,13 @@ def make_simple_struts(truss_mesh, id, od, segments, solid, loops):
         #    print (base * 100 / len(verts))
         vbase += vps * segments
         fbase += fps * segments
-    # print(verts,faces)
+
     return verts, faces
 
 
-def create_struts(self, context, id, od, segments, solid, loops, manifold):
+def create_struts(self, context, ind, od, segments, solid, loops, manifold):
     build_cossin(segments)
 
-    bpy.context.user_preferences.edit.use_global_undo = False
     for truss_obj in bpy.context.scene.objects:
         if not truss_obj.select:
             continue
@@ -499,7 +486,7 @@ def create_struts(self, context, id, od, segments, solid, loops, manifold):
         if manifold:
             verts, faces = make_manifold_struts(truss_obj, od, segments)
         else:
-            verts, faces = make_simple_struts(truss_mesh, id, od, segments,
+            verts, faces = make_simple_struts(truss_mesh, ind, od, segments,
                                               solid, loops)
         mesh = bpy.data.meshes.new("Struts")
         mesh.from_pydata(verts, [], faces)
@@ -509,58 +496,92 @@ def create_struts(self, context, id, od, segments, solid, loops, manifold):
         obj.location = truss_obj.location
         bpy.context.scene.objects.active = obj
         mesh.update()
-    bpy.context.user_preferences.edit.use_global_undo = True
-    return {'FINISHED'}
 
 
-class Struts(bpy.types.Operator):
-    """Add one or more struts meshes based on selected truss meshes"""
+class Struts(Operator):
     bl_idname = "mesh.generate_struts"
     bl_label = "Struts"
-    bl_description = """Add one or more struts meshes based on selected truss meshes"""
+    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'}
 
-    id = 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)
+    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.user_preferences.edit.use_global_undo
+        bpy.context.user_preferences.edit.use_global_undo = False
         keywords = self.as_keywords()
-        return create_struts(self, context, **keywords)
 
+        try:
+            create_struts(self, context, **keywords)
+            bpy.context.user_preferences.edit.use_global_undo = store_undo
+
+            return {"FINISHED"}
 
-def menu_func(self, context):
-    self.layout.operator(Struts.bl_idname, text="Struts", icon='PLUGIN')
+        except Exception as e:
+            bpy.context.user_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__)
-    bpy.types.INFO_MT_mesh_add.append(menu_func)
 
 
 def unregister():
diff --git a/add_advanced_objects/mesh_easylattice.py b/add_advanced_objects/mesh_easylattice.py
index 13512adf5151f013c2f66ac6b42813a8f80fee3e..91a167dce668092eeee6e5845816da6675390e14 100644
--- a/add_advanced_objects/mesh_easylattice.py
+++ b/add_advanced_objects/mesh_easylattice.py
@@ -16,11 +16,12 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+# TODO: find a better solution for allowing more than one lattice per scene
 
 bl_info = {
     "name": "Easy Lattice Object",
     "author": "Kursad Karatas",
-    "version": (0, 5),
+    "version": (0, 5, 1),
     "blender": (2, 66, 0),
     "location": "View3D > Easy Lattice",
     "description": "Create a lattice for shape editing",
@@ -35,9 +36,11 @@ from mathutils import (
         Matrix,
         Vector,
         )
+from bpy.types import Operator
 from bpy.props import (
         EnumProperty,
         IntProperty,
+        StringProperty,
         )
 
 
@@ -86,7 +89,8 @@ def createLattice(obj, size, pos, props):
     # the size  from bbox
     ob.scale = size
 
-    # the rotation comes from the combined obj world matrix which was converted to euler pairs
+    # the rotation comes from the combined obj world
+    # matrix which was converted to euler pairs
     ob.rotation_euler = buildRot_World(obj)
 
     ob.show_x_ray = True
@@ -263,10 +267,11 @@ def run(lat_props):
 
     if obj.type == "MESH":
         # set global property for the currently active latticed object
-        bpy.types.Scene.activelatticeobject = bpy.props.StringProperty(
-                                                    name="currentlatticeobject",
-                                                    default=""
-                                                    )
+        # removed in __init__ on unregister if created
+        bpy.types.Scene.activelatticeobject = StringProperty(
+                name="currentlatticeobject",
+                default=""
+                )
         bpy.types.Scene.activelatticeobject = obj.name
 
         modifiersDelete(obj)
@@ -311,70 +316,85 @@ def main(context, latticeprops):
     run(latticeprops)
 
 
-class EasyLattice(bpy.types.Operator):
-    """Adds a Lattice modifier ready to edit"""
+class EasyLattice(Operator):
     bl_idname = "object.easy_lattice"
     bl_label = "Easy Lattice Creator"
-    bl_space_type = "VIEW_3D"
-    bl_region_type = "TOOLS"
+    bl_description = ("Create a Lattice modifier ready to edit\n"
+                      "Needs an existing Active Mesh Object\n"
+                      "Note: Works only with one lattice per scene")
 
     lat_u = IntProperty(
-                name="Lattice u",
-                default=3
-                )
+            name="Lattice u",
+            description="Points in u direction",
+            default=3
+            )
     lat_w = IntProperty(
-                name="Lattice w",
-                default=3
-                )
+            name="Lattice w",
+            description="Points in w direction",
+            default=3
+            )
     lat_m = IntProperty(
-                name="Lattice m",
-                default=3
+            name="Lattice m",
+            description="Points in m direction",
+            default=3
+            )
+    lat_types = (('KEY_LINEAR', "Linear", "Linear Interpolation type"),
+                 ('KEY_CARDINAL', "Cardinal", "Cardinal Interpolation type"),
+                 ('KEY_BSPLINE', "BSpline", "Key BSpline Interpolation Type")
                 )
-    lat_types = (('0', 'KEY_LINEAR', '0'),
-                 ('1', 'KEY_CARDINAL', '1'),
-                 ('2', 'KEY_BSPLINE', '2'))
     lat_type = EnumProperty(
-                name="Lattice Type",
-                items=lat_types,
-                default='0'
-                )
+            name="Lattice Type",
+            description="Choose Lattice Type",
+            items=lat_types,
+            default='KEY_LINEAR'
+            )
 
     @classmethod
     def poll(cls, context):
-        return context.active_object is not None
+        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_w")
+        col.prop(self, "lat_m")
+
+        layout.prop(self, "lat_type")
 
     def execute(self, context):
         lat_u = self.lat_u
         lat_w = self.lat_w
         lat_m = self.lat_m
 
-        # this is a reference to the "items" used to generate the
-        # enum property
-        lat_type = self.lat_types[int(self.lat_type)][1]
+        # enum property no need to complicate things
+        lat_type = self.lat_type
         lat_props = [lat_u, lat_w, lat_m, lat_type]
+        try:
+            main(context, lat_props)
+
+        except Exception as e:
+            print("\n[Add Advanced Objects]\nOperator:object.easy_lattice\n{}\n".format(e))
+            self.report({'WARNING'},
+                         "Easy Lattice Creator could not be completed (See Console for more info)")
 
-        main(context, lat_props)
+            return {"CANCELLED"}
 
-        return {'FINISHED'}
+        return {"FINISHED"}
 
     def invoke(self, context, event):
         wm = context.window_manager
         return wm.invoke_props_dialog(self)
 
 
-def menu_draw(self, context):
-    self.layout.operator_context = 'INVOKE_REGION_WIN'
-    self.layout.operator(EasyLattice.bl_idname, "Easy Lattice")
-
-
 def register():
     bpy.utils.register_class(EasyLattice)
-    bpy.types.VIEW3D_MT_edit_mesh_specials.append(menu_draw)
 
 
 def unregister():
     bpy.utils.unregister_class(EasyLattice)
-    bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_draw)
 
 
 if __name__ == "__main__":
diff --git a/add_advanced_objects/object_add_chain.py b/add_advanced_objects/object_add_chain.py
index 57babfd6f9315e17a0ee2a700958bd23f76d94b8..8b182c822f6d6a75329439adce161ce0238874a4 100644
--- a/add_advanced_objects/object_add_chain.py
+++ b/add_advanced_objects/object_add_chain.py
@@ -30,20 +30,18 @@ bl_info = {
 }
 
 import bpy
-from bpy.types import (
-        Operator,
-        Panel,
-        )
+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),
-                       )
+    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
@@ -53,24 +51,26 @@ def Add_Chain():
     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),
-                                           )
+    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,
-                                     )
+    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
@@ -98,22 +98,23 @@ def Add_Chain():
     # Toggle into editmode
     bpy.ops.object.editmode_toggle()
 
-    # TODO, may be better to move objects directly.
+    # TODO, may be better to move objects directly
     # Translate curve object
-    bpy.ops.transform.translate(value=(2, 0, 0),
-                                constraint_axis=(True, False, False),
-                                constraint_orientation='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,
-                                )
+    bpy.ops.transform.translate(
+            value=(2, 0, 0),
+            constraint_axis=(True, False, False),
+            constraint_orientation='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()
@@ -151,19 +152,27 @@ class AddChain(Operator):
     bl_options = {'REGISTER', 'UNDO'}
 
     def execute(self, context):
-        Add_Chain()
+        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_module(__name__)
-    pass
+    bpy.utils.register_class(AddChain)
 
 
 def unregister():
-    bpy.utils.unregister_module(__name__)
-    pass
+    bpy.utils.unregister_class(AddChain)
 
 
 if __name__ == "__main__":
diff --git a/add_advanced_objects/object_laplace_lightning.py b/add_advanced_objects/object_laplace_lightning.py
index ceaf6cd6ff92197847e1ce62814a87346a738308..857682b025a92bd31c859b6fdf2f6ee211345914 100644
--- a/add_advanced_objects/object_laplace_lightning.py
+++ b/add_advanced_objects/object_laplace_lightning.py
@@ -16,18 +16,18 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-# NOTE Needs cleanup, reorganizing, make prints optional
+# NOTE: moved the winmgr properties to __init__ and scene
+# search for context.scene.advanced_objects
 
 bl_info = {
     "name": "Laplacian Lightning",
     "author": "teldredge",
-    "version": (0, 2, 7),
-    "blender": (2, 71, 0),
+    "version": (0, 2, 9),
+    "blender": (2, 78, 0),
     "location": "View3D > Toolshelf > Create Tab",
     "description": "Lightning mesh generator using laplacian growth algorithm",
-    "warning": "Beta",
+    "warning": "",
     "wiki_url": "http://www.funkboxing.com/wordpress/?p=301",
-    "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
     "category": "Object"}
 
 # BLENDER LAPLACIAN LIGHTNING
@@ -110,19 +110,43 @@ v0.x -
 import bpy
 import time
 import random
-from math import sqrt
+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
-winmgr = bpy.context.window_manager
+# 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)
 
-# UTILITY FXNS #
 
 def within(x, y, d):
-    # CHECK IF x-d <= y <= x+d
+    # CHECK IF x - d <= y <= x + d
     if x - d <= y and x + d >= y:
         return True
     else:
@@ -196,7 +220,7 @@ def jitterCells(aList, jit):
 
 
 def deDupe(seq, idfun=None):
-    # THANKS TO THIS GUY - http://www.peterbe.com/plog/uniqifiers-benchmark
+    # Thanks to this guy - http://www.peterbe.com/plog/uniqifiers-benchmark
     if idfun is None:
         def idfun(x):
             return x
@@ -211,7 +235,7 @@ def deDupe(seq, idfun=None):
     return result
 
 
-# VISUALIZATION FXNS #
+# Visulization functions
 
 def writeArrayToVoxel(arr, filename):
     gridS = 64
@@ -222,7 +246,8 @@ def writeArrayToVoxel(arr, filename):
         try:
             aGrid[a[0] + half][a[1] + half][a[2] + half] = bitOn
         except:
-            print('Particle beyond voxel domain')
+            debug_prints(func="writeArrayToVoxel", text="Particle beyond voxel domain")
+
     file = open(filename, "wb")
     for z in range(gridS):
         for y in range(gridS):
@@ -278,15 +303,12 @@ def makeMeshCube(msize):
     # 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)]
-
+    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")
-    # mobject = bpy.data.objects.new("Cube", mmesh)
-
-    # Set location and scene of object
-    # mobject.location = bpy.context.scene.cursor_location
-    # bpy.context.scene.objects.link(mobject)
 
     # Create mesh
     mmesh.from_pydata(verts, [], faces)
@@ -304,8 +326,9 @@ def writeArrayToCubes(arr, gridBU, orig, cBOOL=False, jBOOL=True):
         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
+
+        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)
@@ -316,9 +339,10 @@ def writeArrayToCubes(arr, gridBU, orig, cBOOL=False, jBOOL=True):
             ob.color = col
         bpy.context.scene.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...
+        # 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 = False
             if q.name[0:5] == 'xCUBE':
@@ -365,7 +389,7 @@ def writeArrayToMesh(mname, arr, gridBU, rpt=None):
     return mob
 
 
-# OUT OF ORDER - SOME PROBLEM WITH IT ADDING (0,0,0)
+# 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
@@ -374,12 +398,14 @@ def writeArrayToCurves(cname, arr, gridBU, bd=.05, rpt=None):
     cur.bevel_resolution = 2
     cob = bpy.data.objects.new(cname, cur)
     cob.scale = (gridBU, gridBU, gridBU)
+
     if rpt:
         addReportProp(cob, rpt)
     bpy.context.scene.objects.link(cob)
     cur.splines.new('BEZIER')
     cspline = cur.splines[0]
-    div = 1  # SPACING FOR HANDLES (2 - 1/2 WAY, 1 - NEXT BEZIER)
+    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]
@@ -418,17 +444,18 @@ def addMaterial(ob, matname):
 
 
 def writeStokeToMesh(arr, jarr, MAINi, HORDERi, TIPSi, orig, gs, rpt=None):
-    # MAIN BRANCH
-    print('   WRITING MAIN BRANCH')
+    # 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
+    # horder branches
     for hOi in range(len(HORDERi)):
-        print('   WRITING ORDER', hOi)
+        debug_prints(func="writeStokeToMesh", text="Writing order", var=hOi)
         hO = HORDERi[hOi]
         hob = newMesh('la1H' + str(hOi))
 
@@ -440,8 +467,8 @@ def writeStokeToMesh(arr, jarr, MAINi, HORDERi, TIPSi, orig, gs, rpt=None):
         hob.scale = (gs, gs, gs)
         hob.location = orig
 
-    # TIPS
-    print('   WRITING TIP PATHS')
+    # tips
+    debug_prints(func="writeStokeToMesh", text="Writing tip paths")
     tob = newMesh('la2TIPS')
     for y in TIPSi:
         llt = []
@@ -451,16 +478,17 @@ def writeStokeToMesh(arr, jarr, MAINi, HORDERi, TIPSi, orig, gs, rpt=None):
     tob.scale = (gs, gs, gs)
     tob.location = orig
 
-    # ADD MATERIALS TO OBJECTS (IF THEY EXIST)
+    # add materials to objects (if they exist)
     try:
         addMaterial(mob, 'edgeMAT-h0')
         addMaterial(hob, 'edgeMAT-h1')
         addMaterial(tob, 'edgeMAT-h2')
-        print('   ADDED MATERIALS')
+        debug_prints(func="writeStokeToMesh", text="Added materials")
+
     except:
-        print('   MATERIALS NOT FOUND')
+        debug_prints(func="writeStokeToMesh", text="Materials not found")
 
-    # ADD GENERATION REPORT TO ALL MESHES
+    # add generation report to all meshes
     if rpt:
         addReportProp(mob, rpt)
         addReportProp(hob, rpt)
@@ -486,62 +514,66 @@ def writeStokeToSingleMesh(arr, jarr, orig, gs, mct, rpt=None):
 
 
 def visualizeArray(cg, oob, gs, vm, vs, vc, vv, rst):
+    winmgr = bpy.context.scene.advanced_objects
     # IN: (cellgrid, origin, gridscale,
     # mulimesh, single mesh, cubes, voxels, report sting)
     origin = oob.location
 
-    # DEAL WITH VERT MULTI-ORIGINS
+    # deal with vert multi-origins
     oct = 2
     if oob.type == 'MESH':
         oct = len(oob.data.vertices)
 
-    # JITTER CELLS
+    # jitter cells
     if vm or vs:
         cjarr = jitterCells(cg, 1)
 
-    if vm:  # WRITE ARRAY TO MULTI MESH
+    if vm:  # write array to multi mesh
 
         aMi, aHi, aTi = classifyStroke(cg, oct, winmgr.HORDER)
-        print(':::WRITING TO MULTI-MESH')
+        debug_prints(func="visualizeArray", text="Writing to multi-mesh")
         writeStokeToMesh(cg, cjarr, aMi, aHi, aTi, origin, gs, rst)
-        print(':::MULTI-MESH WRITTEN')
+        debug_prints(func="visualizeArray", text="Multi-mesh written")
 
-    if vs:  # WRITE TO SINGLE MESH
-        print(':::WRITING TO SINGLE MESH')
+    if vs:  # write to single mesh
+        debug_prints(func="visualizeArray", text="Writing to single mesh")
         writeStokeToSingleMesh(cg, cjarr, origin, gs, oct, rst)
-        print(':::SINGLE MESH WRITTEN')
+        debug_prints(func="visualizeArray", text="Single mesh written")
 
-    if vc:  # WRITE ARRAY TO CUBE OBJECTS
-        print(':::WRITING TO CUBES')
+    if vc:  # write array to cube objects
+        debug_prints(func="visualizeArray", text="Writing to cubes")
         writeArrayToCubes(cg, gs, origin)
-        print(':::CUBES WRITTEN')
+        debug_prints(func="visualizeArray", text="Cubes written")
 
-    if vv:  # WRITE ARRAY TO VOXEL DATA FILE
-        print(':::WRITING TO VOXELS')
+    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)
-        print(':::VOXEL DATA WRITTEN TO - ', path + "\\" + fname)
 
-    # READ/WRITE ARRAY TO FILE (MIGHT NOT BE NECESSARY)
+        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)
+    # read/write array to curves (out of order)
     # writeArrayToCurves('laMAIN', llmain, .10, .25)
 
 
-# ALGORITHM FXNS #
-# FROM FALUAM PAPER #
-# PLUS SOME STUFF I MADE UP #
+# 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
+    # 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]
@@ -552,13 +584,14 @@ def buildCPGraph(arr, sti=2):
             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
+    # 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
@@ -575,13 +608,14 @@ def buildCPGraph_WORKINPROGRESS(arr, sti=2):
                 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 ENCOUNTERD
+    # oc -origin charge index, fc -final charge index
+    # ngraph -node graph, restrict- index of sites cannot traverse
+    # partial -return partial path if restriction encounterd
     cList = splitList(ngraph, 0)
     pList = splitList(ngraph, 1)
     aRi = []
@@ -591,13 +625,13 @@ def findChargePath(oc, fc, ngraph, restrict=[], partial=True):
         aRi.append(cNODE)
         cNODE = pNODE
         npNODECOUNT = cList.count(pNODE)
-        if cNODE == oc:             # STOP IF ORIGIN FOUND
-            aRi.append(cNODE)       # RETURN PATH
+        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 []
+        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:
@@ -615,6 +649,7 @@ def findTips(arr):
                 cCOUNT += 1
         if cCOUNT == 0:
             lt.append(a)
+
     return lt
 
 
@@ -626,6 +661,7 @@ def findChannelRoots(path, ngraph, restrict=[]):
         if par in path and chi not in path and chi not in restrict:
             roots.append(par)
     droots = deDupe(roots)
+
     return droots
 
 
@@ -648,10 +684,14 @@ def findChannels(roots, tips, ngraph, restrict):
                     tTEMP = t
                     tiTEMP = ti
         if len(sPATHi) > 0:
-            print('   found path/idex from', ri, 'of',
-                  len(roots), 'possible | tips:', tTEMP, tiTEMP)
+            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
 
 
@@ -662,13 +702,12 @@ def findChannels_WORKINPROGRESS(roots, ttips, ngraph, restrict):
         r = roots[ri]
         sL = 1
         sPATHi = []
-        tipREMOVE = []  # CHECKED TIP INDEXES, TO BE REMOVED FOR NEXT LOOP
+        tipREMOVE = []  # checked tip indexes, to be removed for next loop
         for ti in range(len(tips)):
             t = tips[ti]
-            # print('-CHECKING RT/IDEX:', r, ri, 'AGAINST TIP', t, ti)
-            # if t < r: continue
             if ti < ri:
                 continue
+
             tPATHi = findChargePath(r, t, ngraph, restrict, False)
             tL = len(tPATHi)
             if tL > sL:
@@ -680,9 +719,13 @@ def findChannels_WORKINPROGRESS(roots, ttips, ngraph, restrict):
             if tL > 0:
                 tipREMOVE.append(t)
         if len(sPATHi) > 0:
-            print('   found path from root idex', ri, 'of',
-                   len(roots), 'possible roots | #oftips=', len(tips))
+            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)
 
@@ -690,65 +733,72 @@ def findChannels_WORKINPROGRESS(roots, ttips, ngraph, restrict):
 
 
 def countChildrenOnPath(aPath, ngraph, quick=True):
-    # RETURN HOW MANY BRANCHES
-    # COUNT WHEN NODE IS A PARENT >1 TIMES
-    # quick -STOP AND RETURN AFTER FIRST
+    # 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'
+# classify channels into 'main', 'hORDER/secondary' and 'side'
 def classifyStroke(sarr, mct, hORDER=1):
-    print(':::CLASSIFYING STROKE')
-    # BUILD CHILD/PARENT GRAPH (INDEXES OF sarr)
+    debug_prints(func="classifyStroke", text="Classifying stroke")
+    # build child/parent graph (indexes of sarr)
     sgarr = buildCPGraph(sarr, mct)
 
-    # FIND MAIN CHANNEL
-    print('   finding MAIN')
+    # 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
-    print('   finding TIPS')
+    # find tips
+    debug_prints(func="classifyStroke", text="Finding TIPS")
     aTIPSi = findTips(sgarr)
 
-    # FIND hORDER CHANNEL ROOTS
-    # hCOUNT = ORDERS BEWTEEN 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
+    # find horder channel roots
+    # hcount = orders bewteen 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
+        for pi in range(len(curPATHSi)):     # loop through all paths in this order
             p = curPATHSi[pi]
-            # GET ROOTS FOR THIS PATH
+            # get roots for this path
             aHROOTSi = findChannelRoots(p, sgarr, hRESTRICT)
-            print('   found', len(aHROOTSi), 'roots in ORDER', h, ':#paths:', len(curPATHSi))
-            # GET CHANNELS FOR THESE ROOTS
+            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:
-                print('NO ROOTS FOR FOUND FOR CHANNEL')
+                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
+                # set these channels as restrictions for next iterations
                 for hri in aHPATHSi:
                     hRESTRICT += hri
         curPATHSi = aHPATHSi
 
-    # SIDE BRANCHES, FINAL ORDER OF HEIRARCHY
-    # FROM TIPS THAT ARE NOT IN AN EXISTING PATH
-    # BACK TO ANY OTHER POINT THAT IS ALREADY ON A PATH
+    # side branches, final order of heirarchy
+    # 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:
@@ -765,24 +815,25 @@ def classifyStroke(sarr, mct, hORDER=1):
 
 
 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
+    # '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
+    # 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]
@@ -796,11 +847,17 @@ def voxelByRays(ob, orig, gs):
     xs = int(xct / 2)
     ys = int(yct / 2)
     zs = int(zct / 2)
-    print('  CASTING', xct, '/', yct, '/', zct, 'cells, total:', xct * yct * zct, 'in obj-', ob.name)
+
+    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
-    print('  RAYCASTING TOP/BOTTOM')
+    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)
@@ -809,12 +866,20 @@ def voxelByRays(ob, orig, gs):
             v2 = ((xco, yco, -rc))
             vz1 = ob.ray_cast(v1, v2)
             vz2 = ob.ray_cast(v2, v1)
-            if vz1[2] != -1:
-                ll.append((x - xs, y - ys, int(vz1[0][2] * (1 / gs))))
-            if vz2[2] != -1:
-                ll.append((x - xs, y - ys, int(vz2[0][2] * (1 / gs))))
-    # RAYCAST FRONT/BACK
-    print('  RAYCASTING FRONT/BACK')
+
+            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)
@@ -823,12 +888,14 @@ def voxelByRays(ob, orig, gs):
             v2 = ((xco, -rc, zco))
             vy1 = ob.ray_cast(v1, v2)
             vy2 = ob.ray_cast(v2, v1)
-            if vy1[2] != -1:
-                ll.append((x - xs, int(vy1[0][1] * (1 / gs)), z - zs))
-            if vy2[2] != -1:
-                ll.append((x - xs, int(vy2[0][1] * (1 / gs)), z - zs))
-    # RAYCAST LEFT/RIGHT
-    print('  RAYCASTING LEFT/RIGHT')
+            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)
@@ -837,24 +904,24 @@ def voxelByRays(ob, orig, gs):
             v2 = ((-rc, yco, zco))
             vx1 = ob.ray_cast(v1, v2)
             vx2 = ob.ray_cast(v2, v1)
-            if vx1[2] != -1:
-                ll.append((int(vx1[0][0] * (1 / gs)), y - ys, z - zs))
-            if vx2[2] != -1:
-                ll.append((int(vx2[0][0] * (1 / gs)), y - ys, z - zs))
+            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 THRU
+    # 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
-    print('  ADDED NEIGHBORS, DEDUPING...')
+    # 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...
+    # 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,
@@ -874,24 +941,25 @@ def fakeGroundChargePlane(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)]
+    # 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 FXNS #
-# FROM FSLG #
+# 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]
+    # 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)
@@ -900,20 +968,21 @@ def getGrowthProbability_KEEPFORREFERENCE(uN, aList):
         Omin -= notZero
     PdL = []
     E = 0
-    E = notZero   # DIVISOR FOR (FSLG - Eqn. 12)
+    E = notZero   # divisor for (fslg - eqn. 12)
     for o in oList:
-        Uj = (o - Omin) / (Omax - Omin)  # (FSLG - Eqn. 13)
+        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)
+        Pd = (pow(Ui, uN)) / E  # (fslg - eqn. 12)
         PdINT = Pd * 100
         PdL.append(Pd)
+
     return PdL
 
 
-# WORK IN PROGRESS, TRYING TO SPEED THESE UP
+# work in progress, trying to speed these up
 def fslg_e13(x, min, max, u):
     return pow((x - min) / (max - min), u)
 
@@ -927,14 +996,16 @@ def fslg_e12(x, min, max, u, e):
 
 
 def getGrowthProbability(uN, aList):
-    # IN: uN -USER TERM, cList -CANDIDATE SITES, oList -CANDIDATE SITE CHARGES
-    # OUT: LIST OF PROB
+    # 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))]
@@ -943,15 +1014,17 @@ def getGrowthProbability(uN, aList):
     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
+    # 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)):
@@ -962,12 +1035,13 @@ def updatePointCharges(p, cList, eList=[]):
         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
+    # 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:
@@ -980,15 +1054,15 @@ def initialPointCharges(pList, cList, eList=[]):
         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
+                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)]
-    tt1 = time.clock()
+    # 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])
@@ -996,14 +1070,14 @@ def getCandidateSites(aList, iList=[]):
             if t not in aList and t not in iList:
                 cList.append(t)
     ncList = deDupe(cList)
-    tt2 = time.clock()
 
     return ncList
 
 
-# SETUP FXNS #
+# Setup functions
 
 def setupObjects():
+    winmgr = bpy.context.scene.advanced_objects
     oOB = bpy.data.objects.new('ELorigin', None)
     oOB.location = ((0, 0, 10))
     bpy.context.scene.objects.link(oOB)
@@ -1041,27 +1115,38 @@ def setupObjects():
 
 def checkSettings():
     check = True
+    winmgr = bpy.context.scene.advanced_objects
+    message = ""
     if winmgr.OOB == "":
-        print('ERROR: NO ORIGIN OBJECT SELECTED')
+        message = "Error: no origin object selected"
         check = False
+
     if winmgr.GROUNDBOOL and winmgr.GOB == "":
-        print('ERROR: NO GROUND OBJECT SELECTED')
+        message = "Error: no ground object selected"
         check = False
+
     if winmgr.CLOUDBOOL and winmgr.COB == "":
-        print('ERROR: NO CLOUD OBJECT SELECTED')
+        message = "Error: no cloud object selected"
         check = False
+
     if winmgr.IBOOL and winmgr.IOB == "":
-        print('ERROR: NO INSULATOR OBJECT SELECTED')
+        message = "Error: no insulator object selected"
         check = False
-    # should make a popup here
-    return check
 
+    if check is False:
+        debug_prints(func="checkSettings", text=message)
 
-# MAIN #
+    # return state and the message for the operator report
+    return check, message
+
+
+# Main
 
 def FSLG():
-    # FAST SIMULATION OF LAPLACIAN GROWTH #
-    print('\n<<<<<<------GO GO GADGET: FAST SIMULATION OF LAPLACIAN GROWTH!')
+    winmgr = bpy.context.scene.advanced_objects
+    # fast simulation of laplacian growth
+    debug_prints(func="FSLG",
+                 text="Go go gadget: fast simulation of laplacian growth")
     tc1 = time.clock()
     TSTEPS = winmgr.TSTEPS
 
@@ -1070,214 +1155,183 @@ def FSLG():
     winmgr.ORIGIN = obORIGIN.location
     winmgr.GROUNDZ = int((obGROUND.location[2] - winmgr.ORIGIN[2]) / winmgr.GSCALE)
 
-    # 1) INSERT INTIAL CHARGE(S) POINT (USES VERTS IF MESH)
+    # 1) insert intial charge(s) point (uses verts if mesh)
     cgrid = [(0, 0, 0)]
+
     if obORIGIN.type == 'MESH':
-        print("<<<<<<------ORIGIN OBJECT IS MESH, 'VOXELIZING' INTIAL CHARGES FROM VERTS")
+        debug_prints(
+                func="FSLG",
+                text="Origin object is mesh, 'voxelizing' intial charges from verts"
+                )
         cgrid = voxelByVertex(obORIGIN, winmgr.GSCALE)
+
         if winmgr.VMMESH:
-            print("<<<<<<------CANNOT CLASSIFY STROKE FROM VERT ORIGINS YET, NO MULTI-MESH OUTPUT")
+            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)
+    # ground charge cell / insulator lists (echargelist/iclist)
     eChargeList = []
     icList = []
     if winmgr.GROUNDBOOL:
         eChargeList = fakeGroundChargePlane(winmgr.GROUNDZ, winmgr.GROUNDC)
+
     if winmgr.CLOUDBOOL:
-        print("<<<<<<------'VOXELIZING' CLOUD OBJECT (COULD TAKE SOME TIME)")
+        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)
-        print('<<<<<<------CLOUD OBJECT CELL COUNT = ', len(eChargeList))
+        debug_prints(
+                func="FSLG",
+                text="cloud object cell count", var=len(eChargeList)
+                )
+
     if winmgr.IBOOL:
-        print("<<<<<<------'VOXELIZING' INSULATOR OBJECT (COULD TAKE SOME TIME)")
+        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)
-        print('<<<<<<------INSULATOR OBJECT CELL COUNT = ', len(icList))
 
-    # 2) LOCATE CANDIDATE SITES AROUND CHARGE
+        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)
+    # 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
+        # 1) select new growth site (eqn. 12)
+        # get probabilities at candidate sites
         gProbs = getGrowthProbability(winmgr.BIGVAR, cSites)
-        # CHOOSE NEW GROWTH SITE BASED ON PROBABILITIES
+        # 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
+        # 2) add new point charge at growth site
+        # add new growth cell to grid
         cgrid.append(gsite)
-        # REMOVE NEW GROWTH CELL FROM CANDIDATE SITES
+        # remove new growth cell from candidate sites
         cSites.remove(cSites[gSitei])
 
-        # 3) UPDATE POTENTIAL AT CANDIDATE SITES (Eqn. 11)
+        # 3) update potential at candidate sites (eqn. 11)
         cSites = updatePointCharges(gsite, cSites, eChargeList)
 
-        # 4) ADD NEW CANDIDATES SURROUNDING GROWTH SITE
-        # GET CANDIDATE 'STENCIL'
+        # 4) add new candidates surrounding growth site
+        # get candidate 'stencil'
         ncSitesT = getCandidateSites([gsite], icList)
-        # REMOVE CANDIDATES ALREADY IN CANDIDATE LIST OR CHARGE GRID
+        # 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)
+        # 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
+        # add new candidate sites to candidate list
         for ncs in ncSites:
             cSites.append(ncs)
 
-        # ITERATION COMPLETE
+        # iteration complete
         istr1 = ':::T-STEP: ' + str(ts) + '/' + str(TSTEPS)
         istr12 = ' | GROUNDZ: ' + str(winmgr.GROUNDZ) + ' | '
         istr2 = 'CANDS: ' + str(len(cSites)) + ' | '
         istr3 = 'GSITE: ' + str(gsite)
-        print(istr1 + istr12 + istr2 + istr3)
+        debug_prints(
+                func="FSLG",
+                text="Iteration complete",
+                var=istr1 + istr12 + istr2 + istr3
+                )
         ts += 1
 
-        # EARLY TERMINATION FOR GROUND/CLOUD STRIKE
+        # early termination for ground/cloud strike
         if winmgr.GROUNDBOOL:
             if gsite[2] == winmgr.GROUNDZ:
                 ts = TSTEPS + 1
-                print('<<<<<<------EARLY TERMINATION DUE TO GROUNDSTRIKE')
+                debug_prints(
+                        func="FSLG",
+                        text="Early termination due to groundstrike"
+                        )
                 continue
+
         if winmgr.CLOUDBOOL:
             if gsite in splitListCo(eChargeList):
                 ts = TSTEPS + 1
-                print('<<<<<<------EARLY TERMINATION DUE TO CLOUDSTRIKE')
+                debug_prints(
+                        func="FSLG",
+                        text="Early termination due to cloudstrike"
+                        )
                 continue
 
     tc2 = time.clock()
     tcRUN = tc2 - tc1
-    print('<<<<<<------LAPLACIAN GROWTH LOOP COMPLETED: ' + str(len(cgrid)) + ' / ' + str(tcRUN)[0:5] + ' SECONDS')
-    print('<<<<<<------VISUALIZING DATA')
+    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
-                )
-    print('<<<<<<------COMPLETE')
-
 
-# GUI #
+    # Visualize array
+    visualizeArray(
+            cgrid, obORIGIN, winmgr.GSCALE,
+            winmgr.VMMESH, winmgr.VSMESH,
+            winmgr.VCUBE, winmgr.VVOX, reportSTRING
+            )
 
-# NOT IN UI
-bpy.types.WindowManager.ORIGIN = bpy.props.FloatVectorProperty(name="origin charge")
-bpy.types.WindowManager.GROUNDZ = bpy.props.IntProperty(name="ground Z coordinate")
-bpy.types.WindowManager.HORDER = bpy.props.IntProperty(name="secondary paths orders")
-# IN UI
-bpy.types.WindowManager.TSTEPS = bpy.props.IntProperty(
-    name="iterations",
-    description="number of cells to create, will end early if hits ground plane or cloud")
-bpy.types.WindowManager.GSCALE = bpy.props.FloatProperty(
-    name="grid unit size",
-    description="scale of cells, .25 = 4 cells per blenderUnit")
-bpy.types.WindowManager.BIGVAR = bpy.props.FloatProperty(
-    name="straightness",
-    description="straightness/branchiness of bolt, <2 is mush, >12 is staight line, 6.3 is good")
-bpy.types.WindowManager.GROUNDBOOL = bpy.props.BoolProperty(
-    name="use ground object", description="use ground plane or not")
-bpy.types.WindowManager.GROUNDC = bpy.props.IntProperty(
-    name="ground charge", description="charge of ground plane")
-bpy.types.WindowManager.CLOUDBOOL = bpy.props.BoolProperty(
-    name="use cloud object",
-    description="use cloud obj, attracts and terminates like ground but "
-                "any obj instead of z plane, can slow down loop if obj is large, overrides ground")
-bpy.types.WindowManager.CLOUDC = bpy.props.IntProperty(
-    name="cloud charge",
-    description="charge of a cell in cloud object (so total charge also depends on obj size)")
-
-bpy.types.WindowManager.VMMESH = bpy.props.BoolProperty(
-    name="multi mesh",
-    description="output to multi-meshes for different materials on main/sec/side branches")
-bpy.types.WindowManager.VSMESH = bpy.props.BoolProperty(
-    name="single mesh",
-    description="output to single mesh for using build modifier and particles for effects")
-bpy.types.WindowManager.VCUBE = bpy.props.BoolProperty(
-    name="cubes", description="CTRL-J after run to JOIN, outputs a bunch of cube objest, mostly for testing")
-bpy.types.WindowManager.VVOX = bpy.props.BoolProperty(
-    name="voxel (experimental)",
-    description="output to a voxel file to bpy.data.filepath\FSLGvoxels.raw - doesn't work well right now")
-bpy.types.WindowManager.IBOOL = bpy.props.BoolProperty(
-    name="use insulator object", description="use insulator mesh object to prevent growth of bolt in areas")
-bpy.types.WindowManager.OOB = bpy.props.StringProperty(
-    description="origin of bolt, can be an Empty, if obj is mesh will use all verts as charges")
-bpy.types.WindowManager.GOB = bpy.props.StringProperty(
-    description="object to use as ground plane, uses z coord only")
-bpy.types.WindowManager.COB = bpy.props.StringProperty(
-    description="object to use as cloud, best to use a cube")
-bpy.types.WindowManager.IOB = bpy.props.StringProperty(
-    description="object to use as insulator, 'voxelized' before generating bolt, can be slow")
-
-# DEFAULT USER SETTINGS
-winmgr.TSTEPS = 350
-winmgr.HORDER = 1
-winmgr.GSCALE = 0.12
-winmgr.BIGVAR = 6.3
-winmgr.GROUNDBOOL = True
-winmgr.GROUNDC = -250
-winmgr.CLOUDBOOL = False
-winmgr.CLOUDC = -1
-winmgr.VMMESH = True
-winmgr.VSMESH = False
-winmgr.VCUBE = False
-winmgr.VVOX = False
-winmgr.IBOOL = False
-try:
-    winmgr.OOB = "ELorigin"
-    winmgr.GOB = "ELground"
-    winmgr.COB = "ELcloud"
-    winmgr.IOB = "ELinsulator"
-except:
-    pass
+    debug_prints(func="FSLG", text="COMPLETE")
 
-# TESTING USER SETTINGS
-if False:
-    winmgr.TSTEPS = 40
-    winmgr.GROUNDBOOL = True
-    winmgr.CLOUDBOOL = True
-    winmgr.IBOOL = True
 
+# GUI #
 
-class runFSLGLoopOperator(bpy.types.Operator):
-    '''By The Mighty Hammer Of Thor!!!'''
+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):
-        if checkSettings():
+        # tuple - state, report text
+        is_conditions, message = checkSettings()
+
+        if is_conditions:
             FSLG()
         else:
-            pass
+            self.report({'WARNING'}, message + " Operation Cancelled")
+
+            return {'CANCELLED'}
+
         return {'FINISHED'}
 
 
-class setupObjectsOperator(bpy.types.Operator):
-    '''create origin/ground/cloud/insulator objects'''
+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(bpy.types.Panel):
+class OBJECT_PT_fslg(Panel):
     bl_label = "Laplacian Lightning"
     bl_space_type = "VIEW_3D"
     bl_region_type = "TOOLS"
@@ -1287,30 +1341,50 @@ class OBJECT_PT_fslg(bpy.types.Panel):
 
     def draw(self, context):
         layout = self.layout
-        colR = layout.column()
-        colR.label('-for progress open console-')
-        colR.label('Help > Toggle System Console')
-        colR.prop(winmgr, 'TSTEPS')
-        colR.prop(winmgr, 'GSCALE')
-        colR.prop(winmgr, 'BIGVAR')
-        colR.operator('object.setup_objects_operator', text='create setup objects')
-        colR.label('origin object')
-        colR.prop_search(winmgr, "OOB", context.scene, "objects")
-        colR.prop(winmgr, 'GROUNDBOOL')
-        colR.prop_search(winmgr, "GOB", context.scene, "objects")
-        colR.prop(winmgr, 'GROUNDC')
-        colR.prop(winmgr, 'CLOUDBOOL')
-        colR.prop_search(winmgr, "COB", context.scene, "objects")
-        colR.prop(winmgr, 'CLOUDC')
-        colR.prop(winmgr, 'IBOOL')
-        colR.prop_search(winmgr, "IOB", context.scene, "objects")
-        colR.operator('object.runfslg_operator', text='generate lightning')
-        colR.prop(winmgr, 'VMMESH')
-        colR.prop(winmgr, 'VSMESH')
-        colR.prop(winmgr, 'VCUBE')
+        winmgr = context.scene.advanced_objects
+
+        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("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_objects
     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))
@@ -1336,20 +1410,16 @@ def unregister():
 
 
 if __name__ == "__main__":
-    # RUN FOR TESTING
-    # FSLG()
-
-    # UI
     register()
     pass
 
 
-# FXN BENCHMARKS #
+# Benchmarks Function
 
 def BENCH():
-    print('\n\n\n--->BEGIN BENCHMARK')
+    debug_prints(func="BENCH", text="BEGIN BENCHMARK")
     bt0 = time.clock()
-    # MAKE A BIG LIST
+    # make a big list
     tsize = 25
     tlist = []
     for x in range(tsize):
@@ -1358,13 +1428,15 @@ def BENCH():
                 tlist.append((x, y, z))
                 tlist.append((x, y, z))
 
-    # FUNCTION TO TEST
+    # function to test
     bt1 = time.clock()
-    # print('LENS - ', len(tlist), len(ll))
-
     bt2 = time.clock()
     btRUNb = bt2 - bt1
     btRUNa = bt1 - bt0
-    print('--->SETUP TIME    : ', btRUNa)
-    print('--->BENCHMARK TIME: ', btRUNb)
-    print('--->GRIDSIZE: ', tsize, ' - ', tsize * tsize * tsize)
+
+    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/object_mangle_tools.py b/add_advanced_objects/object_mangle_tools.py
index 81110ad3b42a7018531fa329d0f4d0974b54bcb3..9f5b44ee7c2f3c32a5f1850db6e81b3e44809721 100644
--- a/add_advanced_objects/object_mangle_tools.py
+++ b/add_advanced_objects/object_mangle_tools.py
@@ -1,7 +1,6 @@
 # mangle_tools.py (c) 2011 Phil Cote (cotejrp1)
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
+
+# ###### 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
@@ -10,36 +9,43 @@
 #
 # 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
+# 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 *****
+# ###### END GPL LICENCE BLOCK ######
+
+# Note: properties are moved into __init__
 
 bl_info = {
     "name": "Mangle Tools",
     "author": "Phil Cote",
-    "version": (0, 2),
+    "version": (0, 2, 2),
     "blender": (2, 71, 0),
     "location": "View3D > Toolshelf > Tools Tab",
     "description": "Set of tools to mangle curves, meshes, and shape keys",
-    "warning": "", # used for warning icon and text in addons panel
+    "warning": "",
     "wiki_url": "",
-    "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
     "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):
-    xyz_const = context.scene.constraint_vector
+    advanced_objects = context.scene.advanced_objects
+    xyz_const = advanced_objects.mangle_constraint_vector
     random.seed(time.time())
     multiplier = 1
 
@@ -47,95 +53,100 @@ def move_coordinate(context, co, is_curve=False):
     # This helps make curve changes more noticable.
     if is_curve:
         multiplier = 2 * pi
-    random_mag = context.scene.random_magnitude
+    random_mag = advanced_objects.mangle_random_magnitude
     if xyz_const[0]:
-        co.x += .01 * random.randrange( -random_mag, random_mag ) * multiplier
+        co.x += .01 * random.randrange(-random_mag, random_mag) * multiplier
     if xyz_const[1]:
-        co.y += .01 * random.randrange( -random_mag, random_mag )  * multiplier
+        co.y += .01 * random.randrange(-random_mag, random_mag) * multiplier
     if xyz_const[2]:
-        co.z += .01 * random.randrange( -random_mag, random_mag ) * multiplier
+        co.z += .01 * random.randrange(-random_mag, random_mag) * multiplier
 
 
-class MeshManglerOperator(bpy.types.Operator):
-    """Push vertices on the selected object around in random """ \
-    """directions to create a crumpled look"""
+class MeshManglerOperator(Operator):
     bl_idname = "ba.mesh_mangler"
     bl_label = "Mangle Mesh"
-    bl_options = { "REGISTER", "UNDO" }
+    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 != None and ob.type == 'MESH'
+        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, faces = bm.verts, bm.faces
-        randomMag = context.scene.random_magnitude
-        random.seed( time.time() )
-
-        if mesh.shape_keys != None:
-            self.report({'INFO'}, "Cannot mangle mesh: Shape keys present")
+        verts = bm.verts
+        advanced_objects = context.scene.advanced_objects
+        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 )
+            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(bpy.types.Operator):
-    """Make a shape key and pushes the verts around on it """ \
-    """to set up for random pulsating animation"""
+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 != None and ob.type in [ 'MESH', 'CURVE' ]
+        return ob is not None and ob.type in ['MESH', 'CURVE']
 
     def execute(self, context):
-        scn = context.scene
+        scn = context.scene.advanced_objects
         mangleName = scn.mangle_name
         ob = context.object
-        shapeKey = ob.shape_key_add( name=mangleName )
+        shapeKey = ob.shape_key_add(name=mangleName)
         verts = shapeKey.data
 
         for vert in verts:
-            move_coordinate(context, vert.co, is_curve=ob.type=='CURVE')
+            move_coordinate(context, vert.co, is_curve=ob.type == 'CURVE')
 
         return {'FINISHED'}
 
 
-class CurveManglerOp(bpy.types.Operator):
-    """Mangle a curve to the degree the user specifies"""
+class CurveManglerOp(Operator):
     bl_idname = "ba.curve_mangler"
     bl_label = "Mangle Curve"
-    bl_options = { 'REGISTER', 'UNDO' }
+    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 != None and ob.type == "CURVE"
-
+        return ob is not None and ob.type == "CURVE"
 
     def execute(self, context):
-
         ob = context.active_object
-        if ob.data.shape_keys != None:
-            self.report({'INFO'}, "Cannot mangle curve.  Shape keys present")
+        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:
@@ -150,56 +161,43 @@ class CurveManglerOp(bpy.types.Operator):
         return {'FINISHED'}
 
 
-class MangleToolsPanel(bpy.types.Panel):
+class MangleToolsPanel(Panel):
     bl_label = "Mangle Tools"
     bl_space_type = "VIEW_3D"
     bl_context = "objectmode"
-    bl_region_type="TOOLS"
+    bl_region_type = "TOOLS"
     bl_category = "Create"
     bl_options = {'DEFAULT_CLOSED'}
 
-
     def draw(self, context):
-        scn = context.scene
+        scn = context.scene.advanced_objects
         obj = context.object
-        if obj.type in ['MESH',]:  
+
+        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, "constraint_vector")
-            col.prop(scn, "random_magnitude")
+            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
-            col = layout.column()
-            col.label("Please Select Mesh Object")
+            layout.label(text="Please select a Mesh Object", icon="INFO")
 
-IntProperty = bpy.props.IntProperty
-StringProperty = bpy.props.StringProperty
-BoolVectorProperty = bpy.props.BoolVectorProperty
 
 def register():
     bpy.utils.register_class(AnimanglerOperator)
     bpy.utils.register_class(MeshManglerOperator)
     bpy.utils.register_class(CurveManglerOp)
     bpy.utils.register_class(MangleToolsPanel)
-    scnType = bpy.types.Scene
-
-
-    scnType.constraint_vector = BoolVectorProperty(name="Mangle Constraint",
-                                default=(True,True,True),
-                                subtype='XYZ',
-                                description="Constrains Mangle Direction")
 
-    scnType.random_magnitude = IntProperty( name = "Mangle Severity",
-                              default = 5, min = 1, max = 30,
-                              description = "Severity of mangling")
 
-    scnType.mangle_name = StringProperty(name="Shape Key Name",
-                             default="mangle",
-                             description="Name given for mangled shape keys")
 def unregister():
     bpy.utils.unregister_class(AnimanglerOperator)
     bpy.utils.unregister_class(MeshManglerOperator)
diff --git a/add_advanced_objects/oscurart_chain_maker.py b/add_advanced_objects/oscurart_chain_maker.py
index c336e44d27618363ae5a83a2656daff8672d8bf3..6dcd6f808e8f2d9f8a2807c3566e1e66f559ac4c 100644
--- a/add_advanced_objects/oscurart_chain_maker.py
+++ b/add_advanced_objects/oscurart_chain_maker.py
@@ -16,7 +16,7 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-# TODO: translate the comments into English
+# TODO: find English versions of created object names
 
 bl_info = {
     "name": "Oscurart Chain Maker",
@@ -27,7 +27,6 @@ bl_info = {
     "description": "Create chain links from armatures",
     "warning": "",
     "wiki_url": "oscurart.blogspot.com",
-    "tracker_url": "",
     "category": "Object"}
 
 
@@ -52,7 +51,7 @@ def makeChain(self, context, mult, curverig):
     def creahuesocero(hueso):
         # create data to link
         mesh = bpy.data.meshes.new("objectData" + str(hueso.name))
-        object = bpy.data.objects.new("EslabonCero" + str(hueso.name), mesh)
+        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),
@@ -93,18 +92,18 @@ def makeChain(self, context, mult, curverig):
         mesh.validate()
         bpy.context.scene.objects.link(object)
         # scale to the bone
-        bpy.data.objects['EslabonCero' + str(hueso.name)].scale = (hueso.length * mult,
-                                                                   hueso.length * mult,
-                                                                   hueso.length * mult)
+        bpy.data.objects["HardLink" + str(hueso.name)].scale = (hueso.length * mult,
+                                                                hueso.length * mult,
+                                                                hueso.length * mult)
         # Parent Objects
-        bpy.data.objects['EslabonCero' + str(hueso.name)].parent = ARMATURE
-        bpy.data.objects['EslabonCero' + str(hueso.name)].parent_type = 'BONE'
-        bpy.data.objects['EslabonCero' + str(hueso.name)].parent_bone = hueso.name
+        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("EslabonNov" + str(hueso.name), mesh)
+        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),
@@ -145,13 +144,13 @@ def makeChain(self, context, mult, curverig):
         mesh.validate()
         bpy.context.scene.objects.link(object)
         # scale to the bone
-        bpy.data.objects['EslabonNov' + str(hueso.name)].scale = (hueso.length * mult,
+        bpy.data.objects["NewLink" + str(hueso.name)].scale = (hueso.length * mult,
                                                                   hueso.length * mult,
                                                                   hueso.length * mult)
         # Parent objects
-        bpy.data.objects['EslabonNov' + str(hueso.name)].parent = ARMATURE
-        bpy.data.objects['EslabonNov' + str(hueso.name)].parent_type = 'BONE'
-        bpy.data.objects['EslabonNov' + str(hueso.name)].parent_bone = hueso.name
+        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:
@@ -182,18 +181,16 @@ def makeChain(self, context, mult, curverig):
 
         # 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
-                    ))
+                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
+                    hueso.tail_local[2], 1
                     ))
 
         # create the Spline
@@ -249,14 +246,14 @@ class MESH_OT_primitive_oscurart_chain_add(Operator):
     bl_options = {'REGISTER', 'UNDO'}
 
     curverig = BoolProperty(
-                    name="Curve Rig",
-                    default=False
-                    )
+            name="Curve Rig",
+            default=False
+            )
     multiplier = FloatProperty(
-                    name="Scale",
-                    default=1,
-                    min=0.01, max=100.0
-                    )
+            name="Scale",
+            default=1,
+            min=0.01, max=100.0
+            )
 
     @classmethod
     def poll(cls, context):
@@ -264,7 +261,18 @@ class MESH_OT_primitive_oscurart_chain_add(Operator):
         return (obj is not None and obj.type == "ARMATURE")
 
     def execute(self, context):
-        makeChain(self, context, self.multiplier, self.curverig)
+        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'}
 
 
diff --git a/add_advanced_objects/pixelate_3d.py b/add_advanced_objects/pixelate_3d.py
index 90e129daba712b7a8a0fd76d1e8dac45366ce98b..d2b289715f4bd1811858b700df80c04d5ca545ea 100644
--- a/add_advanced_objects/pixelate_3d.py
+++ b/add_advanced_objects/pixelate_3d.py
@@ -1,28 +1,25 @@
-#######################################################
+# gpl author: liero
 # very simple 'pixelization' or 'voxelization' engine #
-#######################################################
 
 bl_info = {
-    "name": "3D Pix",
+    "name": "3D Pixelate",
     "author": "liero",
-    "version": (0, 5, 1),
+    "version": (0, 5, 2),
     "blender": (2, 74, 0),
     "location": "View3D > Tool Shelf",
-    "description": "Creates a 3d pixelated version of the object.",
+    "description": "Creates a 3d pixelated version of the object",
     "category": "Object"}
 
-import bpy
-import mathutils
-from mathutils import Vector
+# Note: winmgr properties are moved into __init__
+# search for patterns advanced_objects and adv_obj
 
-bpy.types.WindowManager.size = bpy.props.FloatProperty(name='Size', min=.05, max=5, default=.25, description='Size of the cube / grid')
-bpy.types.WindowManager.gap = bpy.props.IntProperty(name='Gap', min=0, max=90, default=10, subtype='PERCENTAGE', description='Separation - percent of size')
-bpy.types.WindowManager.smooth = bpy.props.FloatProperty(name='Smooth', min=0, max=1, default=.0, description='Smooth factor when subdividing mesh')
+import bpy
+from bpy.types import Operator
 
 
 def pix(obj):
     sce = bpy.context.scene
-    wm = bpy.context.window_manager
+    props = sce.advanced_objects
     obj.hide = obj.hide_render = True
     mes = obj.to_mesh(sce, True, 'RENDER')
     mes.transform(obj.matrix_world)
@@ -37,12 +34,12 @@ def pix(obj):
         fin = True
         for i in dup.data.edges:
             d = ver[i.vertices[0]].co - ver[i.vertices[1]].co
-            if d.length > wm.size:
+            if d.length > props.pixelate_3d_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=wm.smooth)
+        bpy.ops.mesh.subdivide(number_cuts=1, smoothness=props.pixelate_3d_smooth)
         bpy.ops.mesh.select_all(action='DESELECT')
         bpy.ops.object.editmode_toggle()
         if fin:
@@ -50,55 +47,68 @@ def pix(obj):
 
     for i in ver:
         for n in range(3):
-            i.co[n] -= (.001 + i.co[n]) % wm.size
+            i.co[n] -= (.001 + i.co[n]) % props.pixelate_3d_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 = wm.size * (100 - wm.gap) * .005
+    sca = props.pixelate_3d_size * (100 - props.pixelate_3d_gap) * .005
     bpy.ops.mesh.primitive_cube_add(layers=[True] + [False] * 19)
     bpy.ops.transform.resize(value=[sca] * 3)
     bpy.context.scene.objects.active = dup
     bpy.ops.object.parent_set(type='OBJECT')
 
 
-class Pixelate(bpy.types.Operator):
-    bl_idname = 'object.pixelate'
-    bl_label = 'Pixelate Object'
-    bl_description = 'Create a 3d pixelated version of the 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'}
 
     @classmethod
     def poll(cls, context):
-        return (context.active_object and context.active_object.type == 'MESH' and context.mode == 'OBJECT')
+        return (context.active_object and
+                context.active_object.type == 'MESH' and
+                context.mode == 'OBJECT')
 
     def draw(self, context):
         layout = self.layout
+        adv_obj = context.scene.advanced_objects
 
-        column = layout.column(align=True)
-        column.prop(context.window_manager, "size")
-        column.prop(context.window_manager, "gap")
-        layout.prop(context.window_manager, "smooth")
+        col = layout.column(align=True)
+        col.prop(adv_obj, "pixelate_size")
+        col.prop(adv_obj, "pixelate_gap")
+        layout.prop(adv_obj, "pixelate_smooth")
 
     def execute(self, context):
-        objeto = bpy.context.object
-        pix(objeto)
+        objeto = context.active_object
+        try:
+            pix(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'}
 
-classes = (
-    Pixelate,
-)
 
 def register():
-    for cls in classes:
-        bpy.utils.register_class(cls)
+    bpy.utils.register_class(Pixelate)
 
 
 def unregister():
-    for cls in classes:
-        bpy.utils.unregister_class(cls)
+    bpy.utils.unregister_class(Pixelate)
+
 
 if __name__ == '__main__':
     register()
diff --git a/add_advanced_objects/random_box_structure.py b/add_advanced_objects/random_box_structure.py
index 5440b8b0739aaae221fb2b640c7c22ded6eb2d63..fa4b6497f6c8f059e5ffd2c3ff87032d8a9d2d12 100644
--- a/add_advanced_objects/random_box_structure.py
+++ b/add_advanced_objects/random_box_structure.py
@@ -1,9 +1,11 @@
+# gpl: author Dannyboy
+
 bl_info = {
     "name": "Add Random Box Structure",
     "author": "Dannyboy",
-    "version": (1, 0),
+    "version": (1, 0, 1),
     "location": "View3D > Add > Make Box Structure",
-    "description": "Fill selected box shaped meshes with randomly sized cubes.",
+    "description": "Fill selected box shaped meshes with randomly sized cubes",
     "warning": "",
     "wiki_url": "",
     "tracker_url": "dannyboypython.blogspot.com",
@@ -23,45 +25,70 @@ from bpy.props import (
 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(s)?",
-                default=True
-                )
+            name="Delete Base Mesh(es)",
+            default=True
+            )
     wh = BoolProperty(
-                name="Stay Within Base Mesh(s)?",
-                description="Keeps cubes from exceeding base mesh bounds",
-                default=True
-                )
+            name="Stay Within Bounds",
+            description="Keeps cubes from exceeding base mesh bounds",
+            default=True
+            )
     uf = BoolProperty(
-                name="Uniform Cube Quantity",
-                default=False
-                )
+            name="Uniform Cube Quantity",
+            default=False
+            )
     qn = IntProperty(
-                name="Cube Quantity",
-                default=10,
-                min=1, max=1500
-                )
+            name="Cube Quantity",
+            default=10,
+            min=1, max=1500
+            )
     mn = FloatVectorProperty(
-                name="Min Scales",
-                default=(0.1, 0.1, 0.1),
-                subtype='XYZ'
-                )
+            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'
-                )
+            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'
-                )
+            name="XYZ Offset",
+            default=(0.0, 0.0, 0.0),
+            subtype='XYZ'
+            )
     rsd = FloatProperty(
-                name="Random Seed",
-                default=1
-                )
+            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
@@ -69,8 +96,10 @@ class makestructure(Operator):
         uvyes = 0
         bpy.ops.group.create(name='Cubagrouper')
         bpy.ops.group.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.scene.objects.active = obj
@@ -85,18 +114,19 @@ class makestructure(Operator):
                 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.
+                    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.
+                if 0.0 > pmn.x:  # Keeping things from going under zero
                     pmn.x = 0.0
                 if 0.0 > pmn.y:
                     pmn.y = 0.0
@@ -105,7 +135,7 @@ class makestructure(Operator):
                 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.
+                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
@@ -119,74 +149,52 @@ class makestructure(Operator):
                 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),
-                            constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED',
-                            proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
-                            )
+                    value=(sx, sy, sz), constraint_axis=(True, True, True),
+                    constraint_orientation='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().
+                select = bpy.context.object  # This is used to keep something selected for poll()
                 bpy.ops.object.group_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),
-                            constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED',
-                            proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
-                            )
+                    value=rot[0], axis=(1, 0, 0), constraint_axis=(False, False, False),
+                    constraint_orientation='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),
-                            constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED',
-                            proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
-                            )
+                    value=rot[1], axis=(0, 1, 0), constraint_axis=(False, False, False),
+                    constraint_orientation='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),
-                            constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED',
-                            proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
-                            )
-            bpy.context.scene.objects.active = obj  # Again needed to avoid poll() taking me down.
+                    value=rot[2], axis=(0, 0, 1), constraint_axis=(False, False, False),
+                    constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED',
+                    proportional_edit_falloff='SMOOTH', proportional_size=1, release_confirm=True
+                    )
+            bpy.context.scene.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.group.objects_remove()
             bpy.context.scene.objects.active = select
+
             if self.dc is True:
                 bpy.context.scene.objects.unlink(obj)
-        return {'FINISHED'}
-
-    @classmethod
-    def poll(cls, context):
-        ob = context.active_object
-        return ob is not None and ob.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 add_object_button(self, context):
-    self.layout.operator(makestructure.bl_idname, text="Add Random Box structure", icon='PLUGIN')
+        return {'FINISHED'}
 
 
 def register():
     bpy.utils.register_class(makestructure)
-    bpy.types.INFO_MT_add.append(add_object_button)
 
 
 def unregister():
     bpy.utils.unregister_class(makestructure)
-    bpy.types.INFO_MT_add.remove(add_object_button)
 
 
 if __name__ == "__main__":
diff --git a/add_advanced_objects/rope_alpha.py b/add_advanced_objects/rope_alpha.py
index f040614855e02c62d6fd0ab1942c551915deb39b..904168a1ed24a0158439b9b841307231f353e80b 100644
--- a/add_advanced_objects/rope_alpha.py
+++ b/add_advanced_objects/rope_alpha.py
@@ -18,18 +18,17 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-# TODO : translate comments, prop names into English, add missing tooltips
+# 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),
+    "version": (0, 2, 2),
     "blender": (2, 7, 3),
     "location": "Left Toolbar > ClothRope",
     "warning": "",
     "wiki_url": "",
-    "tracker_url": "",
     "category": "Add Mesh"
 }
 
@@ -60,29 +59,34 @@ def seleccionar_todo():
 
 
 def salir_de_editmode():
-    if bpy.context.mode == "EDIT" or bpy.context.mode == "EDIT_CURVE" or bpy.context.mode == "EDIT_MESH":
+    if bpy.context.mode in ["EDIT", "EDIT_MESH", "EDIT_CURVE"]:
         bpy.ops.object.mode_set(mode='OBJECT')
 
-# Clear scene:
-
 
+# Clear scene:
 def reset_scene():
     desocultar("todo")
-    # el play back al principio
+    # playback to the start
     bpy.ops.screen.frame_jump(end=False)
     try:
         salir_de_editmode()
     except:
         pass
-    area = bpy.context.area
-    # en el outliner expando todo para poder seleccionar los emptys hijos
-    old_type = area.type
-    area.type = 'OUTLINER'
-    bpy.ops.outliner.expanded_toggle()
-    area.type = old_type
-    # vuelvo al contexto donde estaba
-    seleccionar_todo()
-    bpy.ops.object.delete(use_global=False)
+    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():
@@ -100,7 +104,6 @@ def select_all_in_edit_mode(ob):
         if not v.select:
             v.select = True
     entrar_en_editmode()
-    # bpy.ops.mesh.select_all(action="SELECT")
 
 
 def deselect_all_in_edit_mode(ob):
@@ -119,17 +122,17 @@ def which_vertex_are_selected(ob):
     for v in ob.data.vertices:
         if v.select:
             print(str(v.index))
-            print("el vertice " + str(v.index) + " esta seleccionado")
+            print("Vertex " + str(v.index) + " is selected")
 
 
 def seleccionar_por_nombre(nombre):
     scn = bpy.context.scene
     bpy.data.objects[nombre].select = True
+
     scn.objects.active = bpy.data.objects[nombre]
 
 
 def deseleccionar_por_nombre(nombre):
-    # scn = bpy.context.scene
     bpy.data.objects[nombre].select = False
 
 
@@ -143,14 +146,9 @@ def borrar_elementos_seleccionados(tipo):
         bpy.ops.mesh.delete(type='VERT')
 
 
-def tab_editmode():
-    bpy.ops.object.editmode_toggle()
-
-
 def obtener_coords_vertex_seleccionados():
     coordenadas_de_vertices = []
     for ob in bpy.context.selected_objects:
-        print(ob.name)
         if ob.type == 'MESH':
             for v in ob.data.vertices:
                 if v.select:
@@ -160,28 +158,28 @@ def obtener_coords_vertex_seleccionados():
 
 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)
-                )
+            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),
-                        "constraint_orientation": '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
-                        }
-                )
+            MESH_OT_extrude_region={"mirror": False},
+            TRANSFORM_OT_translate={
+                    "value": (longitud / cuantos_segmentos, 0, 0),
+                    "constraint_axis": (True, False, False),
+                    "constraint_orientation": '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):
@@ -203,135 +201,154 @@ def ocultar_relationships():
 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")
 
     ropelenght = IntProperty(
-                    name="longitud",
-                    default=5
-                    )
+            name="Rope Length",
+            description="Length of the generated Rope",
+            default=5
+            )
     ropesegments = IntProperty(
-                    name="rsegments",
-                    default=5
-                    )
+            name="Rope Segments",
+            description="Number of the Rope Segments",
+            default=5
+            )
     qcr = IntProperty(
-                    name="qualcolr",
-                    min=1, max=20,
-                    default=20
-                    )
+            name="Collision Quality",
+            description="Rope's Cloth modifier collsion quality",
+            min=1, max=20,
+            default=20
+            )
     substeps = IntProperty(
-                    name="rsubsteps",
-                    min=4, max=80,
-                    default=50
-                    )
+            name="Rope Substeps",
+            description="Rope's Cloth modifier quality",
+            min=4, max=80,
+            default=50
+            )
     resrope = IntProperty(
-                    name="resr",
-                    default=5
-                    )
+            name="Rope Resolution",
+            description="Rope's Bevel resolution",
+            default=5
+            )
     radiusrope = FloatProperty(
-                    name="radius",
-                    min=0.04, max=1,
-                    default=0.04
-                    )
+            name="Radius",
+            description="Rope's Radius",
+            min=0.04, max=1,
+            default=0.04
+            )
     hide_emptys = BoolProperty(
-                    name="hemptys",
-                    default=False
-                    )
+            name="Hide Empties",
+            description="Hide Helper Objects",
+            default=False
+            )
 
     def execute(self, context):
-        # add new scene
+        # add a new scene
         bpy.ops.scene.new(type="NEW")
         scene = bpy.context.scene
         scene.name = "Test Rope"
         seleccionar_todo()
         longitud = self.ropelenght
-        # para que desde el primer punto hasta el ultimo, entre
-        # medias tenga x segmentos debo sumarle 1 a la cantidad:
+
+        # 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()
-        # creamos el empty que sera el padre de 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)
-                        )
+                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()
-        # creamos un plano y lo borramos
+
+        # 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)
-                            )
+                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]
-        # renombrar:
+        # rename:
         ob.name = "cuerda"
-        entrar_en_editmode()  # entramos en edit mode
+        # .001 and friends
+        cuerda_1_name = ob.name
+
+        entrar_en_editmode()  # enter edit mode
         select_all_in_edit_mode(ob)
-        # seleccionar_todo() # ya viene por default seleccionado
+
         borrar_elementos_seleccionados("vertices")
-        salir_de_editmode()  # salimos de edit mode
-        crear_vertices(ob)  # creamos un vertex
-        # creando el grupo Group para el PIN
-        # Group contiene los vertices del pin y Group.001 contiene la linea unica principal
-        entrar_en_editmode()  # entramos en edit mode
-        bpy.ops.object.vertex_group_add()  # creamos un grupo
+        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()  # y lo asignamos
-        # los hooks van a la curva no a la guia poligonal...
-        # creo el primer hook sin necesidad de crear luego el locator a mano:
-        # bpy.ops.object.hook_add_newob()
-        salir_de_editmode()  # salimos de edit mode
+        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")
-        # hago los extrudes del vertice:
+        seleccionar_por_nombre(cuerda_1_name)
+
+        # extrude vertices:
         for i in range(cuantos_segmentos):
             entrar_en_editmode()
             extruir_vertices(longitud, cuantos_segmentos)
-            # y los ELIMINO del grupo PIN
+            # delete the PIN group
             bpy.ops.object.vertex_group_remove_from()
-            # obtengo la direccion para lego crear el locator en su posicion
+            # get the direction to create the locator on it's position
             pos = obtener_coords_vertex_seleccionados()
-            # los hooks van a la curva no a la guia poligonal...
-            # creo el hook sin necesidad de crear el locator a mano:
-            # bpy.ops.object.hook_add_newob()
-            salir_de_editmode()  # salimos de edit mode
-            # creo el locator en su sitio
+
+            salir_de_editmode()  # leave edit mode
+            # create locator at position
             crear_locator(pos)
             deseleccionar_todo()
-            seleccionar_por_nombre("cuerda")
+            seleccionar_por_nombre(cuerda_1_name)
         deseleccionar_todo()
-        seleccionar_por_nombre("cuerda")
-        # vuelvo a seleccionar la cuerda
+
+        seleccionar_por_nombre(cuerda_1_name)  # select the rope
         entrar_en_editmode()
-        pos = obtener_coords_vertex_seleccionados()  # y obtenemos su posicion
+
+        pos = obtener_coords_vertex_seleccionados()  # get their positions
         salir_de_editmode()
-        # creamos el ultimo locator
+        # create the last locator
         crear_locator(pos)
         deseleccionar_todo()
-        seleccionar_por_nombre("cuerda")
-        entrar_en_editmode()  # entramos en edit mode
-        bpy.ops.object.vertex_group_add()  # CREANDO GRUPO GUIA MAESTRA
+        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()  # y lo asignamos
+        bpy.ops.object.vertex_group_assign()  # and assing it
         ob.vertex_groups[1].name = "Guide_rope"
-        # extruimos la curva para que tenga un minimo grosor para colisionar
+
+        # extrude the Curve so it has a minumum 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),
-                                "constraint_orientation": '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
-                                }
-                        )
+                MESH_OT_extrude_region={"mirror": False},
+                TRANSFORM_OT_translate={
+                        "value": (0, 0.005, 0), "constraint_axis": (False, True, False),
+                        "constraint_orientation": '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()
@@ -340,54 +357,70 @@ class ClothRope(Operator):
         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
-        # DUPLICAMOS para convertir a curva:
-        # selecciono los vertices que forman parte del grupo Group.001
-        seleccionar_por_nombre("cuerda")
+
+        # 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()
-        # ya tenemos la guia seleccionada:
-        # la duplicamos:
+
+        # 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),
-                                "constraint_orientation": '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
-                                }
-                        )
-        # separamos por seleccion:
+                MESH_OT_duplicate={"mode": 1},
+                TRANSFORM_OT_translate={
+                        "value": (0, 0, 0), "constraint_axis": (False, False, False),
+                        "constraint_orientation": '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()
-        seleccionar_por_nombre("cuerda.001")
-        # a la nueva curva copiada le quitamos el cloth:
+
+        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")
-        # la convertimos en curva:
+        # convert the Curve:
         bpy.ops.object.convert(target='CURVE')
-        # todos los emptys:
+
+        # all Empties that are not previously present
         emptys = []
         for eo in bpy.data.objects:
-            if eo.type == 'EMPTY':
-                if eo.name != "Rope":
+            if eo.type == 'EMPTY' and eo.name not in empties_prev:
+                if eo.name != rope_name:
                     emptys.append(eo)
-        # print(emptys)
-        # cuantos puntos tiene la becier:
-        # len(bpy.data.objects['cuerda.001'].data.splines[0].points)
-        # seleccionar y deseleccionar:
-        bc = bpy.data.objects['cuerda.001']
+
+        # select and deselect:
+        bc = bpy.data.objects[cuerda_2_name]
         n = 0
+
         for e in emptys:
             deseleccionar_todo()
             seleccionar_por_nombre(e.name)
@@ -398,9 +431,10 @@ class ClothRope(Operator):
             bpy.ops.object.hook_add_selob(use_bone=False)
             salir_de_editmode()
             n = n + 1
-        # entrar_en_editmode()
-        ob = bpy.data.objects['cuerda']
+
+        ob = bpy.data.objects[cuerda_1_name]
         n = 0
+
         for e in emptys:
             deseleccionar_todo()
             seleccionar_por_nombre(e.name)
@@ -409,29 +443,32 @@ class ClothRope(Operator):
             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()
-            # deselect_all_in_edit_mode(ob)
+
             salir_de_editmode()
             n = n + 1
 
-        # ocultar los emptys:
-        # for e in emptys:
+            # hide the Empties:
             deseleccionar_todo()
-        # emparentando todo al empty esferico:
-        seleccionar_por_nombre("cuerda.001")
-        seleccionar_por_nombre("cuerda")
-        seleccionar_por_nombre("Rope")
+
+        # 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()
-        # display que no muestre las relaciones
+
+        # do not display the relations
         ocultar_relationships()
-        seleccionar_por_nombre("cuerda.001")
-        # cuerda curva settings:
+        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
@@ -439,82 +476,97 @@ class ClothRope(Operator):
         return {'FINISHED'}
 
     def invoke(self, context, event):
-        return context.window_manager.invoke_props_dialog(self, width=310)
+        return context.window_manager.invoke_props_dialog(self, width=350)
 
     def draw(self, context):
         layout = self.layout
         box = layout.box()
-        col = box.column()
+        col = box.column(align=True)
+
         col.label("Rope settings:")
         rowsub0 = col.row()
-        rowsub0.prop(self, "ropelenght", text='Length')
-        rowsub0.prop(self, "ropesegments", text='Segments')
-        rowsub0.prop(self, "radiusrope", text='Radius')
+        rowsub0.prop(self, "ropelenght", text="Length")
+        rowsub0.prop(self, "ropesegments", text="Segments")
+        rowsub0.prop(self, "radiusrope", text="Radius")
 
         col.label("Quality Settings:")
-        col.prop(self, "resrope", text='Resolution curve')
-        col.prop(self, "qcr", text='Quality Collision')
-        col.prop(self, "substeps", text='Substeps')
+        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 = "Rope Ball"
+    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
     ropelenght2 = IntProperty(
-                    name="longitud",
-                    default=10
-                    )
+            name="Rope Length",
+            description="Length of the Wrecking Ball rope",
+            default=10
+            )
     ropesegments2 = IntProperty(
-                    name="rsegments",
-                    min=0, max=999,
-                    default=6
-                    )
+            name="Rope Segments",
+            description="Number of the Wrecking Ball rope segments",
+            min=0, max=999,
+            default=6
+            )
     radiuscubes = FloatProperty(
-                    name="radius",
-                    default=0.5
-                    )
+            name="Cube Radius",
+            description="Size of the Linked Cubes helpers",
+            default=0.5
+            )
     radiusrope = FloatProperty(
-                    name="radius",
-                    default=0.4
-                    )
+            name="Rope Radius",
+            description="Radius of the Rope",
+            default=0.4
+            )
     worldsteps = IntProperty(
-                    name="worldsteps",
-                    min=60, max=1000,
-                    default=250
-                    )
+            name="World Steps",
+            description="Rigid Body Solver world steps per second (update)",
+            min=60, max=1000,
+            default=250
+            )
     solveriterations = IntProperty(
-                    name="solveriterations",
-                    min=10, max=100,
-                    default=50
-                    )
+            name="Solver Iterations",
+            description="How many times the Rigid Body Solver should run",
+            min=10, max=100,
+            default=50
+            )
     massball = IntProperty(
-                    name="massball",
-                    default=1
-                    )
+            name="Ball Mass",
+            description="Mass of the Wrecking Ball",
+            default=1
+            )
     resrope = IntProperty(
-                    name="resolucion",
-                    default=4
-                    )
+            name="Resolution",
+            description="Rope resolution",
+            default=4
+            )
     grados = FloatProperty(
-                    name="grados",
-                    default=45
-                    )
+            name="Degrees",
+            description="Angle of the Wrecking Ball compared to the Ground Plane",
+            default=45
+            )
     separacion = FloatProperty(
-                    name="separacion",
-                    default=0.1
-                    )
+            name="Link Cubes Gap",
+            description="Space between the Rope's Linked Cubes",
+            default=0.1
+            )
     hidecubes = BoolProperty(
-                    name="hidecubes",
-                    default=False
-                    )
+            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.ropelenght2
-        # hago un + 2 para que los segmentos sean los que hay entre los dos extremos...
+
+        # 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)
@@ -525,39 +577,48 @@ class BallRope(Operator):
         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"
-        # suelo:
+
+        # 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)
-                            )
+                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')
-        # creamos el primer cubo:
+
+        # create the first cube:
         cuboslink = []
         n = 0
         for i in range(segmentos):
-            # si es 0 le digo que empieza desde 1
+            # if 0 start from 1
             if i == 0:
                 i = offset_del_suelo
-            else:  # si no es 0 les tengo que sumar uno para que no se pisen al empezar el primero desde 1
+            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  # distancia entre los cubos link
+            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)
-                        )
+                    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:
@@ -568,6 +629,7 @@ class BallRope(Operator):
             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:
@@ -576,111 +638,115 @@ class BallRope(Operator):
                 seleccionar_por_nombre(nombre1.name)
                 seleccionar_por_nombre(nombre2.name)
                 bpy.ops.rigidbody.connect()
-        seleccionar_por_nombre
-        for i in range(segmentos - 1):
-            if i == 0:
-                seleccionar_por_nombre("Constraint")
-            else:
-                if i <= 9 and i > 0:
-                    seleccionar_por_nombre("Constraint.00" + str(i))
-                else:
-                    if i <= 99 and i > 9:
-                        seleccionar_por_nombre("Constraint.0" + str(i))
-                    else:
-                        if i <= 999 and i > 99:
-                            seleccionar_por_nombre("Constraint." + str(i))
-            for c in bpy.context.selected_objects:
-                c.rigid_body_constraint.type = 'POINT'
+
+        # 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()
 
-        # creamos la curva bezier:
+        # 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)
-                        )
+                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("Cuerda")
+            seleccionar_por_nombre(real_name)
             x = cuboslink[i].location[0]
             y = cuboslink[i].location[1]
             z = cuboslink[i].location[2]
-            # si es 0 le digo que empieza desde 1 es el offset desde el suelo...
+
+            # if it is 0 make it start from 1 as the offset from the ground...
             if i == 0:
                 i = offset_del_suelo
-            else:  # si no es 0 les tengo que sumar uno para que no se pisen al empezar el primero desde 1
+            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()
-            tab_editmode()
+            entrar_en_editmode()
+
             if i == 1:
-                # selecciono todos los vertices y los  borro
-                select_all_vertex_in_curve_bezier(bpy.data.objects["Cuerda"])
+                # select all the vertices and delete them
+                select_all_vertex_in_curve_bezier(bpy.data.objects[real_name])
                 bpy.ops.curve.delete(type='VERT')
-                # creamos el primer vertice:
+                # create the first vertex:
                 bpy.ops.curve.vertex_add(location=(x, y, z))
             else:
-                # extruimos el resto:
+                # 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),
-                                "constraint_orientation": '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
-                                }
-                            )
+                        CURVE_OT_extrude={"mode": 'TRANSLATION'},
+                        TRANSFORM_OT_translate={
+                            "value": (0, 0, z / i),
+                            "constraint_axis": (False, False, True),
+                            "constraint_orientation": '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()
 
-        # creando la esfera ball:
+        # 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)
-                        )
+                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),
-                        constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED',
-                        proportional_edit_falloff='SMOOTH', proportional_size=1
-                        )
+                value=(0, 0, -z + 2), constraint_axis=(False, False, True),
+                constraint_orientation='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),
-                        constraint_orientation='GLOBAL',
-                        mirror=False, proportional='DISABLED',
-                        proportional_edit_falloff='SMOOTH', proportional_size=1
-                        )
+                value=(longitud / 2, longitud / 2, longitud / 2),
+                constraint_axis=(False, False, False),
+                constraint_orientation='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')
 
-        # lo subo todo para arriba un poco mas:
+        # move it all up a bit more:
         seleccionar_todo()
-        deseleccionar_por_nombre("groundplane")
+        deseleccionar_por_nombre(groundplane_name)
         bpy.ops.transform.translate(
-                        value=(0, 0, offset_del_suelo_real),
-                        constraint_axis=(False, False, True),
-                        constraint_orientation='GLOBAL', mirror=False,
-                        proportional='DISABLED', proportional_edit_falloff='SMOOTH',
-                        proportional_size=1
-                        )
+                value=(0, 0, offset_del_suelo_real),
+                constraint_axis=(False, False, True),
+                constraint_orientation='GLOBAL', mirror=False,
+                proportional='DISABLED', proportional_edit_falloff='SMOOTH',
+                proportional_size=1
+                )
 
         deseleccionar_todo()
         seleccionar_por_nombre(cuboslink[-1].name)
@@ -689,25 +755,25 @@ class BallRope(Operator):
         bpy.context.scene.rigidbody_world.steps_per_second = world_steps
         bpy.context.scene.rigidbody_world.solver_iterations = solver_iterations
 
-        # para mover todo desde el primero de arriba:
+        # 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")
+        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),
-                            constraint_orientation='GLOBAL',
-                            mirror=False, proportional='DISABLED',
-                            proportional_edit_falloff='SMOOTH',
-                            proportional_size=1
-                            )
+                value=rotrope, axis=(1, 0, 0),
+                constraint_axis=(True, False, False),
+                constraint_orientation='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("Cuerda")
+        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:
@@ -722,30 +788,34 @@ class BallRope(Operator):
         return {'FINISHED'}
 
     def invoke(self, context, event):
-        return context.window_manager.invoke_props_dialog(self, width=310)
+        return context.window_manager.invoke_props_dialog(self, width=350)
 
     def draw(self, context):
         layout = self.layout
         box = layout.box()
-        col = box.column()
+        col = box.column(align=True)
+
         col.label("Rope settings:")
         rowsub0 = col.row()
-        rowsub0.prop(self, "hidecubes", text='Hide Link Cubes')
-        rowsub1 = col.row()
-        rowsub1.prop(self, "ropelenght2", text='Length')
-        rowsub1.prop(self, "ropesegments2", text='Segments')
-        rowsub2 = col.row()
-        rowsub2.prop(self, "radiuscubes", text='Radius Link Cubes')
-        rowsub2.prop(self, "radiusrope", text='Radius Rope')
-        rowsub3 = col.row()
-        rowsub3.prop(self, "grados", text='Degrees')
-        rowsub3.prop(self, "separacion", text='Separation Link Cubes')
+        rowsub0.prop(self, "hidecubes", text="Hide Link Cubes")
+
+        rowsub1 = col.row(align=True)
+        rowsub1.prop(self, "ropelenght2", 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("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')
+        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
diff --git a/add_advanced_objects/scene_objects_bi.py b/add_advanced_objects/scene_objects_bi.py
index db3ec9cdd83e5d0cfcdcbdb60bc6e2796f11b8e4..f189bb1189b9580c8807031a3e84ad9be78af24c 100644
--- a/add_advanced_objects/scene_objects_bi.py
+++ b/add_advanced_objects/scene_objects_bi.py
@@ -7,179 +7,189 @@ from bpy.types import Operator
 class add_BI_scene(Operator):
     bl_idname = "bi.add_scene"
     bl_label = "Create test scene"
-    bl_description = "BI Scene with Objects"
+    bl_description = "Blender Internal renderer Scene with Objects"
     bl_options = {'REGISTER', 'UNDO'}
 
     def execute(self, context):
-        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(
+        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.draw_size = 0.1
-        bpy.ops.view3d.viewnumpad(type='CAMERA')
+            cam = bpy.context.active_object.data
+            cam.lens = 35
+            cam.draw_size = 0.1
+            bpy.ops.view3d.viewnumpad(type='CAMERA')
 
-        # add point lamp
-        bpy.ops.object.lamp_add(
+            # add point lamp
+            bpy.ops.object.lamp_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.lamp_add(
+            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.lamp_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),
-                        constraint_orientation='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
+            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),
+                    constraint_orientation='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/scene_objects_cycles.py b/add_advanced_objects/scene_objects_cycles.py
index 1e07b3e572bc47647e441bb525fce3d74bd0a5e6..85e85867b0d7b0e8ee680b2c8c4eb5068580f4df 100644
--- a/add_advanced_objects/scene_objects_cycles.py
+++ b/add_advanced_objects/scene_objects_cycles.py
@@ -7,124 +7,136 @@ from bpy.types import Operator
 class add_cycles_scene(Operator):
     bl_idname = "objects_cycles.add_scene"
     bl_label = "Create test scene"
-    bl_description = "Cycles Scene with Objects"
+    bl_description = "Cycles renderer Scene with Objects"
     bl_options = {'REGISTER'}
 
     def execute(self, context):
-        blend_data = context.blend_data
-        # ob = bpy.context.active_object
-
-        # 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.draw_size = 0.1
-        bpy.ops.view3d.viewnumpad(type='CAMERA')
-
-        # add point lamp
-        bpy.ops.object.lamp_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.lamp_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
+        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.draw_size = 0.1
+            bpy.ops.view3d.viewnumpad(type='CAMERA')
+
+            # add point lamp
+            bpy.ops.object.lamp_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.lamp_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/scene_texture_render.py b/add_advanced_objects/scene_texture_render.py
index 2025b979dff1734fad1481bbc25d1cd62935b4ac..02d6490bbec822358cdc7d389108a022f567b24b 100644
--- a/add_advanced_objects/scene_texture_render.py
+++ b/add_advanced_objects/scene_texture_render.py
@@ -7,60 +7,72 @@ from bpy.types import Operator
 class add_texture_scene(Operator):
     bl_idname = "objects_texture.add_scene"
     bl_label = "Create test scene"
-    bl_description = "Cycles Scene: Camera aligned to plane"
+    bl_description = "Cycles renderer Scene: Camera aligned to a plane"
     bl_options = {'REGISTER', 'UNDO'}
 
     def execute(self, context):
-        blend_data = context.blend_data
-        # ob = bpy.context.active_object
+        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"
+            # 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
+            # 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 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.draw_size = 0.1
+            # 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.draw_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
+            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
+            # 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'}
 
-        # Back to Scene
-        sc = bpy.context.scene
-        bpy.ops.view3d.viewnumpad(type='CAMERA')
         return {'FINISHED'}
diff --git a/add_advanced_objects/trilighting.py b/add_advanced_objects/trilighting.py
index d23b4dbc3a953d82e0e77ae0728ee98016c96574..e0068e66d267b2a120464b354d396675e0c2e526 100644
--- a/add_advanced_objects/trilighting.py
+++ b/add_advanced_objects/trilighting.py
@@ -8,8 +8,7 @@ from bpy.props import (
         IntProperty,
         )
 from math import (
-        sin,
-        cos,
+        sin, cos,
         radians,
         sqrt,
         )
@@ -19,67 +18,69 @@ 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 active object in the scene")
+                      "Needs an existing Active Object")
     bl_options = {'REGISTER', 'UNDO'}
 
     height = FloatProperty(
-                    name="Height",
-                    default=5
-                    )
+            name="Height",
+            default=5
+            )
     distance = FloatProperty(
-                    name="Distance",
-                    default=5,
-                    min=0.1,
-                    subtype="DISTANCE"
-                    )
+            name="Distance",
+            default=5,
+            min=0.1,
+            subtype="DISTANCE"
+            )
     energy = IntProperty(
-                    name="Base Energy",
-                    default=3,
-                    min=1
-                    )
+            name="Base Energy",
+            default=3,
+            min=1
+            )
     contrast = IntProperty(
-                    name="Contrast",
-                    default=50,
-                    min=-100, max=100,
-                    subtype="PERCENTAGE"
-                    )
+            name="Contrast",
+            default=50,
+            min=-100, max=100,
+            subtype="PERCENTAGE"
+            )
     leftangle = IntProperty(
-                    name="Left Angle",
-                    default=26,
-                    min=1, max=90,
-                    subtype="ANGLE"
-                    )
+            name="Left Angle",
+            default=26,
+            min=1, max=90,
+            subtype="ANGLE"
+            )
     rightangle = IntProperty(
-                    name="Right Angle",
-                    default=45,
-                    min=1, max=90,
-                    subtype="ANGLE"
-                    )
+            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')]
+            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 type off Key Light you would like",
-                    items=Light_Type_List,
-                    default='HEMI'
-                    )
+            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 type off secondary Light you would like",
-                    items=Light_Type_List,
-                    default="POINT"
-                    )
+            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):
@@ -111,115 +112,127 @@ class TriLighting(Operator):
         col.prop(self, "secondarytype", text="")
 
     def execute(self, context):
-        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)
-            scene.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.scene.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'}
+        try:
+            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)
+                scene.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.scene.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.lamps.new(name="TriLamp-Back", type=self.secondarytype)
+            backData.energy = backEnergy
+
+            backLamp = bpy.data.objects.new(name="TriLamp-Back", object_data=backData)
+            scene.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.lamps.new(name="TriLamp-Fill", type=self.secondarytype)
+            rightData.energy = fillEnergy
+            rightLamp = bpy.data.objects.new(name="TriLamp-Fill", object_data=rightData)
+            scene.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.lamps.new(name="TriLamp-Key", type=self.primarytype)
+            leftData.energy = keyEnergy
+
+            leftLamp = bpy.data.objects.new(name="TriLamp-Key", object_data=leftData)
+            scene.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))
 
-        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.lamps.new(name="TriLamp-Back", type=self.secondarytype)
-        backData.energy = backEnergy
-
-        backLamp = bpy.data.objects.new(name="TriLamp-Back", object_data=backData)
-        scene.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.lamps.new(name="TriLamp-Fill", type=self.secondarytype)
-        rightData.energy = fillEnergy
-        rightLamp = bpy.data.objects.new(name="TriLamp-Fill", object_data=rightData)
-        scene.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.lamps.new(name="TriLamp-Key", type=self.primarytype)
-        leftData.energy = keyEnergy
-
-        leftLamp = bpy.data.objects.new(name="TriLamp-Key", object_data=leftData)
-        scene.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"
+            return {'CANCELLED'}
 
         return {'FINISHED'}
diff --git a/add_advanced_objects/unfold_transition.py b/add_advanced_objects/unfold_transition.py
index a621ca546622f214a77c8aeeafbaaeb10621d9da..769386f532a03c6468caac950e4617734c310b5d 100644
--- a/add_advanced_objects/unfold_transition.py
+++ b/add_advanced_objects/unfold_transition.py
@@ -1,18 +1,18 @@
+# gpl: authors Liero, Atom
+
 bl_info = {
     "name": "Unfold transition",
-    "version": (0, 1, 0),
+    "author": "Liero, Atom",
+    "version": (0, 1, 2),
     "location": "Tool bar > Animation tab > UnFold Transition",
-    "description": "Simple unfold transition / animation, will separate faces and set up an armature",
+    "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.props import (
-        BoolProperty,
-        EnumProperty,
-        FloatProperty,
-        IntProperty,
-        # PointerProperty,
-        )
 from bpy.types import (
         Operator,
         Panel,
@@ -25,87 +25,22 @@ from mathutils import Vector
 from mathutils.geometry import intersect_point_line
 
 
-bpy.types.WindowManager.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"
-            )
-bpy.types.WindowManager.flip = BoolProperty(
-            name="Flipping Faces",
-            default=False,
-            description="Rotate faces around the Center & skip Scaling - "
-                        "keep checked for both operators"
-            )
-bpy.types.WindowManager.fold_duration = IntProperty(
-            name="Total Time",
-            min=5, soft_min=25,
-            max=10000, soft_max=2500,
-            default=200,
-            description="Total animation length"
-            )
-bpy.types.WindowManager.sca_time = IntProperty(
-            name="Scale Time",
-            min=1,
-            max=5000, soft_max=500,
-            default=10,
-            description="Faces scaling time"
-            )
-bpy.types.WindowManager.rot_time = IntProperty(
-            name="Rotation Time",
-            min=1, soft_min=5,
-            max=5000, soft_max=500,
-            default=15,
-            description="Faces rotation time"
-            )
-bpy.types.WindowManager.rot_max = IntProperty(
-            name="Angle",
-            min=-180,
-            max=180,
-            default=135,
-            description="Faces rotation angle"
-            )
-bpy.types.WindowManager.fold_noise = IntProperty(
-            name="Noise",
-            min=0,
-            max=500, soft_max=50,
-            default=0,
-            description="Offset some faces animation"
-            )
-bpy.types.WindowManager.bounce = FloatProperty(
-            name="Bounce",
-            min=0,
-            max=10, soft_max=2.5,
-            default=0,
-            description="Add some bounce to rotation"
-            )
-bpy.types.WindowManager.from_point = BoolProperty(
-            name="Point",
-            default=False,
-            description="Scale faces from a Point instead of from an Edge"
-            )
-bpy.types.WindowManager.wiggle_rot = BoolProperty(
-            name="Wiggle",
-            default=False,
-            description="Use all Axis + Random Rotation instead of X Aligned"
-            )
-
-
 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"
+    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):
-        return (bpy.context.object.type == "MESH")
+        obj = context.active_object
+        return (obj is not None and obj.type == "MESH")
 
     def execute(self, context):
         bpy.ops.object.mode_set()
-        wm = context.window_manager
         scn = bpy.context.scene
+        adv_obj = scn.advanced_objects
         obj = bpy.context.object
         dat = obj.data
         fac = dat.polygons
@@ -118,6 +53,7 @@ class Set_Up_Fold(Operator):
         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
@@ -130,7 +66,7 @@ class Set_Up_Fold(Operator):
             obj.modifiers.remove(obj.modifiers["UnFold"])
 
         # try to obtain the face sequence from the vertex weights
-        if wm.modo == "weight":
+        if adv_obj.unfold_modo == "weight":
             if len(obj.vertex_groups):
                 i = obj.vertex_groups.active.index
                 W = []
@@ -154,6 +90,7 @@ class Set_Up_Fold(Operator):
                 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
@@ -161,14 +98,17 @@ class Set_Up_Fold(Operator):
         bpy.ops.mesh.select_all(action="SELECT")
         bpy.ops.mesh.edge_split()
         bpy.ops.mesh.select_all(action="SELECT")
-        if wm.modo == "cursor":
+
+        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.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 wm.modo != "weight":
+        if adv_obj.unfold_modo != "weight":
             S = []
             for f in fac:
                 E = list(f.edge_keys)
@@ -183,6 +123,9 @@ class Set_Up_Fold(Operator):
         # 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
@@ -203,10 +146,11 @@ class Set_Up_Fold(Operator):
         for fb in S:
             f = fac[fb[0]]
             b = arm.edit_bones.new("bone.000")
-            if wm.flip:
+            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 = False
             b.layers = vis
@@ -215,7 +159,8 @@ class Set_Up_Fold(Operator):
             vg.add(f.vertices, 1, "ADD")
 
         bpy.ops.object.mode_set()
-        if wm.modo == "weight":
+
+        if adv_obj.unfold_modo == "weight":
             obj.vertex_groups.active_index = 0
         scn.objects.active = rig
         obj.select = False
@@ -226,66 +171,120 @@ class Set_Up_Fold(Operator):
 class Animate_Fold(Operator):
     bl_idname = "object.animate_fold"
     bl_label = "Animate Unfold"
-    bl_description = "Animate bones to simulate unfold... Starts on current frame"
+    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_objects
+
+        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
-        return (obj.type == "ARMATURE" and obj.is_visible(bpy.context.scene))
+        scn = bpy.context.scene
+        adv_obj = scn.advanced_objects
+
+        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_objects
         fra = scn.frame_current
-        wm = context.window_manager
-
+        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 wm.flip:
+
+        if adv_obj.unfold_flip:
             rot = -3.141592
         else:
-            rot = wm.rot_max / 57.3
-        extra = wm.rot_time * wm.bounce
-        ruido = max(wm.rot_time + extra, wm.sca_time) + wm.fold_noise
-        vel = (wm.fold_duration - ruido) / len(bones)
+            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, wm.fold_noise)
-            if wm.flip:
+            t = fra + a * vel + randint(0, adv_obj.unfold_fold_noise)
+
+            if adv_obj.unfold_flip:
                 b.scale = (1, 1, 1)
-            elif wm.from_point:
+            elif adv_obj.unfold_from_point:
                 b.scale = (0, 0, 0)
             else:
                 b.scale = (1, 0, 0)
-            if not wm.flip:
+
+            if not adv_obj.unfold_flip:
                 b.keyframe_insert("scale", frame=t)
                 b.scale = (1, 1, 1)
-                b.keyframe_insert("scale", frame=t + wm.sca_time)
-            if wm.rot_max:
+                b.keyframe_insert("scale", frame=t + adv_obj.unfold_sca_time)
+
+            if adv_obj.unfold_rot_max:
                 b.rotation_mode = "XYZ"
-                if wm.wiggle_rot:
+                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 wm.bounce:
-                val = wm.bounce * -.10
+
+            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 + wm.rot_time + .25 * extra)
-                val = wm.bounce * .05
+                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 + wm.rot_time + .50 * extra)
-                val = wm.bounce * -.025
+                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 + wm.rot_time + .75 * extra)
+                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 + wm.rot_time + extra)
+            b.keyframe_insert(
+                        "rotation_euler", frame=t + adv_obj.unfold_rot_time + extra
+                        )
+        self.is_not_undo = False
 
         return {"FINISHED"}
 
@@ -299,26 +298,34 @@ class PanelFOLD(Panel):
     bl_options = {"DEFAULT_CLOSED"}
 
     def draw(self, context):
-        wm = context.window_manager
         layout = self.layout
-        column = layout.column()
-        column.operator("object.set_up_fold", text="1. Set Up Unfold")
-        column.prop(wm, "modo")
-        column.prop(wm, "flip")
-        layout.separator()
-        column = layout.column()
-        column.operator("object.animate_fold", text="2. Animate Unfold")
-        column.prop(wm, "fold_duration")
-        column.prop(wm, "sca_time")
-        column.prop(wm, "rot_time")
-        column.prop(wm, "rot_max")
-        row = column.row(align=True)
-        row.prop(wm, "fold_noise")
-        row.prop(wm, "bounce")
-        row = column.row(align=True)
-        row.prop(wm, "wiggle_rot")
-        if not wm.flip:
-            row.prop(wm, "from_point")
+        adv_obj = context.scene.advanced_objects
+
+        box = layout.box()
+        col = box.column()
+        col.operator("object.set_up_fold", text="1. Set Up Unfold")
+        col.separator()
+        col.label("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")
 
 
 def register():