diff --git a/measureit/__init__.py b/measureit/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3401a6a63e78058ed24af188ce4327917e618be4
--- /dev/null
+++ b/measureit/__init__.py
@@ -0,0 +1,403 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# ----------------------------------------------------------
+# Author: Antonio Vazquez (antonioya)
+# ----------------------------------------------------------
+
+# ----------------------------------------------
+# Define Addon info
+# ----------------------------------------------
+bl_info = {
+    "name": "MeasureIt",
+    "author": "Antonio Vazquez (antonioya)",
+    "location": "View3D > Tools Panel /Properties panel",
+    "version": (1, 6, 6),
+    "blender": (2, 7, 4),
+    "description": "Tools for measuring objects.",
+    'warning': 'Temporary: pending review fixes T48704',
+    "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
+    "category": "3D View"}
+
+import sys
+import os
+
+# ----------------------------------------------
+# Add to Phyton path (once only)
+# ----------------------------------------------
+path = sys.path
+flag = False
+for item in path:
+    if "measureit" in item:
+        flag = True
+if flag is False:
+    sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'measureit'))
+    print("measureit: added to phytonpath")
+
+# ----------------------------------------------
+# Import modules
+# ----------------------------------------------
+if "bpy" in locals():
+    import imp
+
+    imp.reload(measureit_main)
+    print("measureit: Reloaded multifiles")
+else:
+    import measureit_main
+
+    print("measureit: Imported multifiles")
+
+# noinspection PyUnresolvedReferences
+import bpy
+# noinspection PyUnresolvedReferences
+from bpy.props import *
+
+
+# --------------------------------------------------------------
+# Register all operators and panels
+# --------------------------------------------------------------
+def register():
+    bpy.utils.register_class(measureit_main.RunHintDisplayButton)
+    bpy.utils.register_class(measureit_main.AddSegmentButton)
+    bpy.utils.register_class(measureit_main.AddAreaButton)
+    bpy.utils.register_class(measureit_main.AddSegmentOrtoButton)
+    bpy.utils.register_class(measureit_main.AddAngleButton)
+    bpy.utils.register_class(measureit_main.AddArcButton)
+    bpy.utils.register_class(measureit_main.AddLabelButton)
+    bpy.utils.register_class(measureit_main.AddNoteButton)
+    bpy.utils.register_class(measureit_main.AddLinkButton)
+    bpy.utils.register_class(measureit_main.AddOriginButton)
+    bpy.utils.register_class(measureit_main.DeleteSegmentButton)
+    bpy.utils.register_class(measureit_main.DeleteAllSegmentButton)
+    bpy.utils.register_class(measureit_main.DeleteAllSumButton)
+    bpy.utils.register_class(measureit_main.MeasureitEditPanel)
+    bpy.utils.register_class(measureit_main.MeasureitMainPanel)
+    bpy.utils.register_class(measureit_main.MeasureitConfPanel)
+    bpy.utils.register_class(measureit_main.MeasureitRenderPanel)
+    bpy.utils.register_class(measureit_main.RenderSegmentButton)
+
+    # Define properties
+    bpy.types.Scene.measureit_default_color = bpy.props.FloatVectorProperty(
+        name="Default color",
+        description="Default Color",
+        default=(0.173, 0.545, 1.0, 1.0),
+        min=0.1,
+        max=1,
+        subtype='COLOR',
+        size=4)
+    bpy.types.Scene.measureit_font_size = bpy.props.IntProperty(name="Text Size",
+                                                                description="Default text size",
+                                                                default=14, min=10, max=150)
+    bpy.types.Scene.measureit_hint_space = bpy.props.FloatProperty(name='Separation', min=0, max=100, default=0.1,
+                                                                   precision=3,
+                                                                   description="Default distance to display measure")
+    bpy.types.Scene.measureit_gl_ghost = bpy.props.BoolProperty(name="All",
+                                                                description="Display measures for all objects,"
+                                                                            " not only selected",
+                                                                default=True)
+    bpy.types.Scene.measureit_gl_txt = bpy.props.StringProperty(name="Text", maxlen=256,
+                                                                description="Short description (use | for line break)")
+
+    bpy.types.Scene.measureit_gl_precision = bpy.props.IntProperty(name='Precision', min=0, max=5, default=2,
+                                                                   description="Number of decimal precision")
+    bpy.types.Scene.measureit_gl_show_d = bpy.props.BoolProperty(name="ShowDist",
+                                                                 description="Display distances",
+                                                                 default=True)
+    bpy.types.Scene.measureit_gl_show_n = bpy.props.BoolProperty(name="ShowName",
+                                                                 description="Display texts",
+                                                                 default=False)
+    bpy.types.Scene.measureit_scale = bpy.props.BoolProperty(name="Scale",
+                                                             description="Use scale factor",
+                                                             default=False)
+    bpy.types.Scene.measureit_scale_factor = bpy.props.FloatProperty(name='Factor', min=0.001, max=9999999,
+                                                                     default=1.0,
+                                                                     precision=3,
+                                                                     description="Scale factor 1:x")
+    bpy.types.Scene.measureit_scale_color = bpy.props.FloatVectorProperty(name="Scale color",
+                                                                          description="Scale Color",
+                                                                          default=(1, 1, 0, 1.0),
+                                                                          min=0.1,
+                                                                          max=1,
+                                                                          subtype='COLOR',
+                                                                          size=4)
+    bpy.types.Scene.measureit_scale_font = bpy.props.IntProperty(name="Font",
+                                                                 description="Text size",
+                                                                 default=14, min=10, max=150)
+    bpy.types.Scene.measureit_scale_pos_x = bpy.props.IntProperty(name="Position X",
+                                                                  description="Margin on the X axis",
+                                                                  default=5,
+                                                                  min=0,
+                                                                  max=100)
+    bpy.types.Scene.measureit_scale_pos_y = bpy.props.IntProperty(name="Position Y",
+                                                                  description="Margin on the Y axis",
+                                                                  default=5,
+                                                                  min=0,
+                                                                  max=100)
+    bpy.types.Scene.measureit_gl_scaletxt = bpy.props.StringProperty(name="ScaleText", maxlen=48,
+                                                                     description="Scale title",
+                                                                     default="Scale:")
+    bpy.types.Scene.measureit_scale_precision = bpy.props.IntProperty(name='Precision', min=0, max=5, default=0,
+                                                                      description="Number of decimal precision")
+
+    bpy.types.Scene.measureit_ovr = bpy.props.BoolProperty(name="Override",
+                                                           description="Override colors and fonts",
+                                                           default=False)
+    bpy.types.Scene.measureit_ovr_font = bpy.props.IntProperty(name="Font",
+                                                               description="Override text size",
+                                                               default=14, min=10, max=150)
+    bpy.types.Scene.measureit_ovr_color = bpy.props.FloatVectorProperty(name="Override color",
+                                                                        description="Override Color",
+                                                                        default=(1, 0, 0, 1.0),
+                                                                        min=0.1,
+                                                                        max=1,
+                                                                        subtype='COLOR',
+                                                                        size=4)
+    bpy.types.Scene.measureit_ovr_width = bpy.props.IntProperty(name='Override width', min=1, max=10, default=1,
+                                                                description='override line width')
+
+    bpy.types.Scene.measureit_units = bpy.props.EnumProperty(items=(('1', "Automatic", "Use scene units"),
+                                                                    ('2', "Meters", ""),
+                                                                    ('3', "Centimeters", ""),
+                                                                    ('4', "Milimiters", ""),
+                                                                    ('5', "Feet", ""),
+                                                                    ('6', "Inches", "")),
+                                                             name="Units",
+                                                             default="2",
+                                                             description="Units")
+    bpy.types.Scene.measureit_render = bpy.props.BoolProperty(name="Render",
+                                                              description="Save an image with measures over"
+                                                                          " render image",
+                                                              default=False)
+    bpy.types.Scene.measureit_render_type = bpy.props.EnumProperty(items=(('1', "*Current", "Use current render"),
+                                                                          ('2', "OpenGL", ""),
+                                                                          ('3', "Animation OpenGL", ""),
+                                                                          ('4', "Image", ""),
+                                                                          ('5', "Animation", "")),
+                                                                   name="Render type",
+                                                                   description="Type of render image")
+    bpy.types.Scene.measureit_sum = bpy.props.EnumProperty(items=(('99', "-", "Select a group for sum"),
+                                                                  ('0', "A", ""),
+                                                                  ('1', "B", ""),
+                                                                  ('2', "C", ""),
+                                                                  ('3', "D", ""),
+                                                                  ('4', "E", ""),
+                                                                  ('5', "F", ""),
+                                                                  ('6', "G", ""),
+                                                                  ('7', "H", ""),
+                                                                  ('8', "I", ""),
+                                                                  ('9', "J", ""),
+                                                                  ('10', "K", ""),
+                                                                  ('11', "L", ""),
+                                                                  ('12', "M", ""),
+                                                                  ('13', "N", ""),
+                                                                  ('14', "O", ""),
+                                                                  ('15', "P", ""),
+                                                                  ('16', "Q", ""),
+                                                                  ('17', "R", ""),
+                                                                  ('18', "S", ""),
+                                                                  ('19', "T", ""),
+                                                                  ('20', "U", ""),
+                                                                  ('21', "V", ""),
+                                                                  ('22', "W", ""),
+                                                                  ('23', "X", ""),
+                                                                  ('24', "Y", ""),
+                                                                  ('25', "Z", "")),
+                                                           name="Sum in Group",
+                                                           description="Add segment length in selected group")
+
+    bpy.types.Scene.measureit_rf = bpy.props.BoolProperty(name="render_frame",
+                                                          description="Add a frame in render output",
+                                                          default=False)
+    bpy.types.Scene.measureit_rf_color = bpy.props.FloatVectorProperty(name="Fcolor",
+                                                                       description="Frame Color",
+                                                                       default=(0.9, 0.9, 0.9, 1.0),
+                                                                       min=0.1,
+                                                                       max=1,
+                                                                       subtype='COLOR',
+                                                                       size=4)
+    bpy.types.Scene.measureit_rf_border = bpy.props.IntProperty(name='fborder ', min=1, max=1000, default=10,
+                                                                description='Frame space from border')
+    bpy.types.Scene.measureit_rf_line = bpy.props.IntProperty(name='fline', min=1, max=10, default=1,
+                                                              description='Line width for border')
+
+    bpy.types.Scene.measureit_glarrow_a = bpy.props.EnumProperty(items=(('99', "--", "No arrow"),
+                                                                        ('1', "Line",
+                                                                         "The point of the arrow are lines"),
+                                                                        ('2', "Triangle",
+                                                                         "The point of the arrow is triangle"),
+                                                                        ('3', "TShape",
+                                                                         "The point of the arrow is a T")),
+                                                                 name="A end",
+                                                                 description="Add arrows to point A")
+    bpy.types.Scene.measureit_glarrow_b = bpy.props.EnumProperty(items=(('99', "--", "No arrow"),
+                                                                        ('1', "Line",
+                                                                         "The point of the arrow are lines"),
+                                                                        ('2', "Triangle",
+                                                                         "The point of the arrow is triangle"),
+                                                                        ('3', "TShape",
+                                                                         "The point of the arrow is a T")),
+                                                                 name="B end",
+                                                                 description="Add arrows to point B")
+    bpy.types.Scene.measureit_glarrow_s = bpy.props.IntProperty(name="Size",
+                                                                description="Arrow size",
+                                                                default=15, min=6, max=500)
+
+    bpy.types.Scene.measureit_debug = bpy.props.BoolProperty(name="Debug",
+                                                             description="Display information for debuging"
+                                                                         " (expand/collapse for enabling or disabling)"
+                                                                         " this information is only renderered for "
+                                                                         "selected objects",
+                                                             default=False)
+    bpy.types.Scene.measureit_debug_select = bpy.props.BoolProperty(name="Selected",
+                                                                    description="Display information "
+                                                                                "for selected vertices/faces",
+                                                                    default=False)
+    bpy.types.Scene.measureit_debug_vertices = bpy.props.BoolProperty(name="Vertices",
+                                                                      description="Display vertex number",
+                                                                      default=True)
+    bpy.types.Scene.measureit_debug_location = bpy.props.BoolProperty(name="Location",
+                                                                      description="Display vertex location",
+                                                                      default=False)
+    bpy.types.Scene.measureit_debug_faces = bpy.props.BoolProperty(name="Faces",
+                                                                   description="Display face number",
+                                                                   default=False)
+    bpy.types.Scene.measureit_debug_normals = bpy.props.BoolProperty(name="Normals",
+                                                                     description="Display face normal "
+                                                                                 "vector and creation order",
+                                                                     default=False)
+    bpy.types.Scene.measureit_debug_normal_details = bpy.props.BoolProperty(name="Details",
+                                                                            description="Display face normal details",
+                                                                            default=True)
+    bpy.types.Scene.measureit_debug_font = bpy.props.IntProperty(name="Font",
+                                                                 description="Debug text size",
+                                                                 default=14, min=10, max=150)
+    bpy.types.Scene.measureit_debug_color = bpy.props.FloatVectorProperty(name="Debug color",
+                                                                          description="Debug Color",
+                                                                          default=(1, 0, 0, 1.0),
+                                                                          min=0.1,
+                                                                          max=1,
+                                                                          subtype='COLOR',
+                                                                          size=4)
+    bpy.types.Scene.measureit_debug_color2 = bpy.props.FloatVectorProperty(name="Debug face color",
+                                                                           description="Debug face Color",
+                                                                           default=(0, 1, 0, 1.0),
+                                                                           min=0.1,
+                                                                           max=1,
+                                                                           subtype='COLOR',
+                                                                           size=4)
+    bpy.types.Scene.measureit_debug_color3 = bpy.props.FloatVectorProperty(name="Debug vector color",
+                                                                           description="Debug vector Color",
+                                                                           default=(1.0, 1.0, 0.1, 1.0),
+                                                                           min=0.1,
+                                                                           max=1,
+                                                                           subtype='COLOR',
+                                                                           size=4)
+    bpy.types.Scene.measureit_debug_normal_size = bpy.props.FloatProperty(name='Len', min=0.001, max=9,
+                                                                          default=0.5,
+                                                                          precision=2,
+                                                                          description="Normal arrow size")
+    bpy.types.Scene.measureit_debug_width = bpy.props.IntProperty(name='Debug width', min=1, max=10, default=2,
+                                                                  description='Vector line thickness')
+    bpy.types.Scene.measureit_debug_precision = bpy.props.IntProperty(name='Precision', min=0, max=5, default=1,
+                                                                      description="Number of decimal precision")
+
+    # OpenGL flag
+    wm = bpy.types.WindowManager
+    # register internal property
+    wm.measureit_run_opengl = bpy.props.BoolProperty(default=False)
+
+
+def unregister():
+    bpy.utils.unregister_class(measureit_main.RunHintDisplayButton)
+    bpy.utils.unregister_class(measureit_main.AddSegmentButton)
+    bpy.utils.unregister_class(measureit_main.AddAreaButton)
+    bpy.utils.unregister_class(measureit_main.AddSegmentOrtoButton)
+    bpy.utils.unregister_class(measureit_main.AddAngleButton)
+    bpy.utils.unregister_class(measureit_main.AddArcButton)
+    bpy.utils.unregister_class(measureit_main.AddLabelButton)
+    bpy.utils.unregister_class(measureit_main.AddNoteButton)
+    bpy.utils.unregister_class(measureit_main.AddLinkButton)
+    bpy.utils.unregister_class(measureit_main.AddOriginButton)
+    bpy.utils.unregister_class(measureit_main.DeleteSegmentButton)
+    bpy.utils.unregister_class(measureit_main.DeleteAllSegmentButton)
+    bpy.utils.unregister_class(measureit_main.DeleteAllSumButton)
+    bpy.utils.unregister_class(measureit_main.MeasureitEditPanel)
+    bpy.utils.unregister_class(measureit_main.MeasureitMainPanel)
+    bpy.utils.unregister_class(measureit_main.MeasureitConfPanel)
+    bpy.utils.unregister_class(measureit_main.MeasureitRenderPanel)
+    bpy.utils.unregister_class(measureit_main.RenderSegmentButton)
+
+    # Remove properties
+    del bpy.types.Scene.measureit_default_color
+    del bpy.types.Scene.measureit_font_size
+    del bpy.types.Scene.measureit_hint_space
+    del bpy.types.Scene.measureit_gl_ghost
+    del bpy.types.Scene.measureit_gl_txt
+    del bpy.types.Scene.measureit_gl_precision
+    del bpy.types.Scene.measureit_gl_show_d
+    del bpy.types.Scene.measureit_gl_show_n
+    del bpy.types.Scene.measureit_scale
+    del bpy.types.Scene.measureit_scale_factor
+    del bpy.types.Scene.measureit_scale_color
+    del bpy.types.Scene.measureit_scale_font
+    del bpy.types.Scene.measureit_scale_pos_x
+    del bpy.types.Scene.measureit_scale_pos_y
+    del bpy.types.Scene.measureit_gl_scaletxt
+    del bpy.types.Scene.measureit_scale_precision
+    del bpy.types.Scene.measureit_ovr
+    del bpy.types.Scene.measureit_ovr_font
+    del bpy.types.Scene.measureit_ovr_color
+    del bpy.types.Scene.measureit_ovr_width
+    del bpy.types.Scene.measureit_units
+    del bpy.types.Scene.measureit_render
+    del bpy.types.Scene.measureit_render_type
+    del bpy.types.Scene.measureit_sum
+    del bpy.types.Scene.measureit_rf
+    del bpy.types.Scene.measureit_rf_color
+    del bpy.types.Scene.measureit_rf_border
+    del bpy.types.Scene.measureit_rf_line
+    del bpy.types.Scene.measureit_glarrow_a
+    del bpy.types.Scene.measureit_glarrow_b
+    del bpy.types.Scene.measureit_glarrow_s
+    del bpy.types.Scene.measureit_debug
+    del bpy.types.Scene.measureit_debug_select
+    del bpy.types.Scene.measureit_debug_vertices
+    del bpy.types.Scene.measureit_debug_faces
+    del bpy.types.Scene.measureit_debug_normals
+    del bpy.types.Scene.measureit_debug_normal_details
+    del bpy.types.Scene.measureit_debug_font
+    del bpy.types.Scene.measureit_debug_color
+    del bpy.types.Scene.measureit_debug_color2
+    del bpy.types.Scene.measureit_debug_color3
+    del bpy.types.Scene.measureit_debug_normal_size
+    del bpy.types.Scene.measureit_debug_width
+    del bpy.types.Scene.measureit_debug_precision
+    del bpy.types.Scene.measureit_debug_location
+
+    # remove OpenGL data
+    measureit_main.RunHintDisplayButton.handle_remove(measureit_main.RunHintDisplayButton, bpy.context)
+    wm = bpy.context.window_manager
+    p = 'measureit_run_opengl'
+    if p in wm:
+        del wm[p]
+
+
+if __name__ == '__main__':
+    register()
diff --git a/measureit/measureit_geometry.py b/measureit/measureit_geometry.py
new file mode 100644
index 0000000000000000000000000000000000000000..c8c6170d913db7dc9b5a5c4e24a4197e745a4ed2
--- /dev/null
+++ b/measureit/measureit_geometry.py
@@ -0,0 +1,1350 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# ----------------------------------------------------------
+# support routines for OpenGL
+# Author: Antonio Vazquez (antonioya)
+#
+# ----------------------------------------------------------
+# noinspection PyUnresolvedReferences
+import bpy
+# noinspection PyUnresolvedReferences
+import bgl
+# noinspection PyUnresolvedReferences
+import blf
+import math
+# noinspection PyUnresolvedReferences
+import mathutils
+# noinspection PyUnresolvedReferences
+import bmesh
+# noinspection PyUnresolvedReferences
+from bpy_extras import view3d_utils, mesh_utils
+# noinspection PyUnresolvedReferences
+import bpy_extras.object_utils as object_utils
+import sys
+
+
+# -------------------------------------------------------------
+# Draw segments
+#
+# rgb: Color
+# fsize: Font size
+# -------------------------------------------------------------
+# noinspection PyUnresolvedReferences,PyUnboundLocalVariable
+def draw_segments(context, myobj, op, region, rv3d):
+    if op.measureit_num > 0:
+        a_code = "\u00b0"  # degree
+        scale = bpy.context.scene.unit_settings.scale_length
+        scene = bpy.context.scene
+        pr = scene.measureit_gl_precision
+        fmt = "%1." + str(pr) + "f"
+        ovr = scene.measureit_ovr
+        ovrcolor = scene.measureit_ovr_color
+        ovrfsize = scene.measureit_ovr_font
+        ovrline = scene.measureit_ovr_width
+        units = scene.measureit_units
+        # --------------------
+        # Scene Scale
+        # --------------------
+        if scene.measureit_scale is True:
+            prs = scene.measureit_scale_precision
+            fmts = "%1." + str(prs) + "f"
+            pos_x, pos_y = get_scale_txt_location(context)
+            tx_dsp = fmts % scene.measureit_scale_factor
+            tx_scale = scene.measureit_gl_scaletxt + " 1:" + tx_dsp
+            draw_text(myobj, pos_x, pos_y,
+                      tx_scale, scene.measureit_scale_color, scene.measureit_scale_font)
+        # --------------------
+        # Loop
+        # --------------------
+        for idx in range(0, op.measureit_num):
+            ms = op.measureit_segments[idx]
+            if ovr is False:
+                fsize = ms.glfont_size
+            else:
+                fsize = ovrfsize
+            # ------------------------------
+            # only active and visible
+            # ------------------------------
+            if ms.glview is True and ms.glfree is False:
+                # Arrow data
+                a_size = ms.glarrow_s
+                a_type = ms.glarrow_a
+                b_type = ms.glarrow_b
+                # noinspection PyBroadException
+                try:
+                    if ovr is False:
+                        rgb = ms.glcolor
+                    else:
+                        rgb = ovrcolor
+                    # ----------------------
+                    # Segment or Label
+                    # ----------------------
+                    if ms.gltype == 1 or ms.gltype == 2:
+                        obverts = get_mesh_vertices(myobj)
+
+                        if ms.glpointa <= len(obverts) and ms.glpointb <= len(obverts):
+                            a_p1 = get_point(obverts[ms.glpointa].co, myobj)
+                            b_p1 = get_point(obverts[ms.glpointb].co, myobj)
+                    # ----------------------
+                    # Segment or Label
+                    # ----------------------
+                    if ms.gltype == 12 or ms.gltype == 13 or ms.gltype == 14:
+                        obverts = get_mesh_vertices(myobj)
+                        if ms.glpointa <= len(obverts):
+                            a_p1 = get_point(obverts[ms.glpointa].co, myobj)
+                            if ms.gltype == 12:  # X
+                                b_p1 = get_point((0.0,
+                                                  obverts[ms.glpointa].co[1],
+                                                  obverts[ms.glpointa].co[2]), myobj)
+                            elif ms.gltype == 13:  # Y
+                                b_p1 = get_point((obverts[ms.glpointa].co[0],
+                                                  0.0,
+                                                  obverts[ms.glpointa].co[2]), myobj)
+                            else:  # Z
+                                b_p1 = get_point((obverts[ms.glpointa].co[0],
+                                                  obverts[ms.glpointa].co[1],
+                                                  0.0), myobj)
+                    # ----------------------
+                    # Vertex to Vertex (link)
+                    # ----------------------
+                    if ms.gltype == 3:
+                        obverts = get_mesh_vertices(myobj)
+                        linkverts = bpy.data.objects[ms.gllink].data.vertices
+                        a_p1 = get_point(obverts[ms.glpointa].co, myobj)
+                        b_p1 = get_point(linkverts[ms.glpointb].co, bpy.data.objects[ms.gllink])
+                    # ----------------------
+                    # Vertex to Object (link)
+                    # ----------------------
+                    if ms.gltype == 4:
+                        obverts = get_mesh_vertices(myobj)
+                        a_p1 = get_point(obverts[ms.glpointa].co, myobj)
+                        b_p1 = get_location(bpy.data.objects[ms.gllink])
+                    # ----------------------
+                    # Object to Vertex (link)
+                    # ----------------------
+                    if ms.gltype == 5:
+                        linkverts = bpy.data.objects[ms.gllink].data.vertices
+                        a_p1 = get_location(myobj)
+                        b_p1 = get_point(linkverts[ms.glpointb].co, bpy.data.objects[ms.gllink])
+                    # ----------------------
+                    # Object to Object (link)
+                    # ----------------------
+                    if ms.gltype == 8:
+                        a_p1 = get_location(myobj)
+                        b_p1 = get_location(bpy.data.objects[ms.gllink])
+                    # ----------------------
+                    # Vertex to origin
+                    # ----------------------
+                    if ms.gltype == 6:
+                        obverts = get_mesh_vertices(myobj)
+                        a_p1 = (0, 0, 0)
+                        b_p1 = get_point(obverts[ms.glpointa].co, myobj)
+                    # ----------------------
+                    # Object to origin
+                    # ----------------------
+                    if ms.gltype == 7:
+                        a_p1 = (0, 0, 0)
+                        b_p1 = get_location(myobj)
+                    # ----------------------
+                    # Angle
+                    # ----------------------
+                    if ms.gltype == 9:
+                        obverts = get_mesh_vertices(myobj)
+                        if ms.glpointa <= len(obverts) and ms.glpointb <= len(obverts) and ms.glpointc <= len(obverts):
+                            an_p1 = get_point(obverts[ms.glpointa].co, myobj)
+                            an_p2 = get_point(obverts[ms.glpointb].co, myobj)
+                            an_p3 = get_point(obverts[ms.glpointc].co, myobj)
+
+                            ang_1 = mathutils.Vector((an_p1[0] - an_p2[0], an_p1[1] - an_p2[1], an_p1[2] - an_p2[2]))
+                            ang_2 = mathutils.Vector((an_p3[0] - an_p2[0], an_p3[1] - an_p2[1], an_p3[2] - an_p2[2]))
+
+                            ang_3 = ang_1 + ang_2  # Result vector
+
+                        a_p1 = (an_p2[0], an_p2[1], an_p2[2])
+                        b_p1 = (0, 0, 0)
+                    # ----------------------
+                    # Annotation
+                    # ----------------------
+                    if ms.gltype == 10:
+                        a_p1 = get_location(myobj)
+                        b_p1 = get_location(myobj)
+
+                    # ----------------------
+                    # Arc
+                    # ----------------------
+                    if ms.gltype == 11:
+                        obverts = get_mesh_vertices(myobj)
+                        if ms.glpointa <= len(obverts) and ms.glpointb <= len(obverts) and ms.glpointc <= len(obverts):
+                            an_p1 = get_point(obverts[ms.glpointa].co, myobj)
+                            an_p2 = get_point(obverts[ms.glpointb].co, myobj)
+                            an_p3 = get_point(obverts[ms.glpointc].co, myobj)
+                            # reference for maths: http://en.wikipedia.org/wiki/Circumscribed_circle
+                            an_p12 = mathutils.Vector((an_p1[0] - an_p2[0], an_p1[1] - an_p2[1], an_p1[2] - an_p2[2]))
+                            an_p13 = mathutils.Vector((an_p1[0] - an_p3[0], an_p1[1] - an_p3[1], an_p1[2] - an_p3[2]))
+                            an_p21 = mathutils.Vector((an_p2[0] - an_p1[0], an_p2[1] - an_p1[1], an_p2[2] - an_p1[2]))
+                            an_p23 = mathutils.Vector((an_p2[0] - an_p3[0], an_p2[1] - an_p3[1], an_p2[2] - an_p3[2]))
+                            an_p31 = mathutils.Vector((an_p3[0] - an_p1[0], an_p3[1] - an_p1[1], an_p3[2] - an_p1[2]))
+                            an_p32 = mathutils.Vector((an_p3[0] - an_p2[0], an_p3[1] - an_p2[1], an_p3[2] - an_p2[2]))
+                            an_p12xp23 = an_p12.copy().cross(an_p23)
+
+                            # radius = an_p12.length * an_p23.length * an_p31.length / (2 * an_p12xp23.length)
+
+                            alpha = pow(an_p23.length, 2) * an_p12.dot(an_p13) / (2 * pow(an_p12xp23.length, 2))
+                            beta = pow(an_p13.length, 2) * an_p21.dot(an_p23) / (2 * pow(an_p12xp23.length, 2))
+                            gamma = pow(an_p12.length, 2) * an_p31.dot(an_p32) / (2 * pow(an_p12xp23.length, 2))
+
+                        a_p1 = (alpha * an_p1[0] + beta * an_p2[0] + gamma * an_p3[0],
+                                alpha * an_p1[1] + beta * an_p2[1] + gamma * an_p3[1],
+                                alpha * an_p1[2] + beta * an_p2[2] + gamma * an_p3[2])
+
+                        b_p1 = (an_p2[0], an_p2[1], an_p2[2])
+                        a_n = an_p12.cross(an_p23)
+                        a_n.normalize()  # normal vector
+                        arc_angle, arc_length = get_arc_data(an_p1, a_p1, an_p2, an_p3)
+                        # Apply scale to arc_length
+                        arc_length *= scene.measureit_scale_factor
+
+                    # ----------------------
+                    # Area
+                    # ----------------------
+                    if ms.gltype == 20:
+                        a_p1 = get_location(myobj)  # Not used
+                        b_p1 = get_location(myobj)  # Not used
+
+                    # Calculate distance
+                    dist, distloc = distance(a_p1, b_p1, ms.glocx, ms.glocy, ms.glocz)
+                    # ------------------------------------
+                    # get normal vector
+                    # ------------------------------------
+                    if ms.gldefault is True:
+                        if ms.gltype == 9:
+                            vn = ang_3  # if angle, vector is angle position
+                        elif ms.gltype == 11:
+                            vn = a_n  # if arc, vector is perpendicular to surface of the three vertices
+                        else:
+                            loc = get_location(myobj)
+                            midpoint3d = interpolate3d(a_p1, b_p1, math.fabs(dist / 2))
+                            vn = mathutils.Vector((midpoint3d[0] - loc[0],
+                                                   midpoint3d[1] - loc[1],
+                                                   midpoint3d[2] - loc[2]))
+                    else:
+                        vn = mathutils.Vector((ms.glnormalx, ms.glnormaly, ms.glnormalz))
+
+                    vn.normalize()
+                    # ------------------------------------
+                    # position vector
+                    # ------------------------------------
+                    vi = vn * ms.glspace
+                    s = (14 / 200)
+                    if s > ms.glspace:
+                        s = ms.glspace / 5
+                    vi2 = vn * (ms.glspace + s)
+                    # ------------------------------------
+                    # apply vector
+                    # ------------------------------------
+                    v1 = [a_p1[0] + vi[0], a_p1[1] + vi[1], a_p1[2] + vi[2]]
+                    v2 = [b_p1[0] + vi[0], b_p1[1] + vi[1], b_p1[2] + vi[2]]
+
+                    # Segment extreme
+                    v11 = [a_p1[0] + vi2[0], a_p1[1] + vi2[1], a_p1[2] + vi2[2]]
+                    v22 = [b_p1[0] + vi2[0], b_p1[1] + vi2[1], b_p1[2] + vi2[2]]
+
+                    # Labeling
+                    v11a = (a_p1[0] + vi2[0], a_p1[1] + vi2[1], a_p1[2] + vi2[2] + s / 30)
+                    v11b = (a_p1[0] + vi2[0], a_p1[1] + vi2[1], a_p1[2] + vi2[2] - s / 40)
+
+                    # Annotation
+                    vn1 = (a_p1[0], a_p1[1], a_p1[2])
+
+                    # -------------------------------------------
+                    # Orthogonal
+                    # -------------------------------------------
+                    if ms.gltype == 1 and ms.glorto != "99":
+                        if ms.glorto == "0":  # A
+                            if ms.glorto_x is True:
+                                v1[0] = v2[0]
+                                v11[0] = v22[0]
+                            if ms.glorto_y is True:
+                                v1[1] = v2[1]
+                                v11[1] = v22[1]
+                            if ms.glorto_z is True:
+                                v1[2] = v2[2]
+                                v11[2] = v22[2]
+
+                        if ms.glorto == "1":  # B
+                            if ms.glorto_x is True:
+                                v2[0] = v1[0]
+                                v22[0] = v11[0]
+                            if ms.glorto_y is True:
+                                v2[1] = v1[1]
+                                v22[1] = v11[1]
+                            if ms.glorto_z is True:
+                                v2[2] = v1[2]
+                                v22[2] = v11[2]
+
+                    # ------------------------------------
+                    # converting to screen coordinates
+                    # ------------------------------------
+                    screen_point_ap1 = get_2d_point(region, rv3d, a_p1)
+                    screen_point_bp1 = get_2d_point(region, rv3d, b_p1)
+
+                    screen_point_v1 = get_2d_point(region, rv3d, v1)
+                    screen_point_v2 = get_2d_point(region, rv3d, v2)
+                    screen_point_v11 = get_2d_point(region, rv3d, v11)
+                    screen_point_v22 = get_2d_point(region, rv3d, v22)
+                    screen_point_v11a = get_2d_point(region, rv3d, v11a)
+                    screen_point_v11b = get_2d_point(region, rv3d, v11b)
+                    # ------------------------------------
+                    # colour + line setup
+                    # ------------------------------------
+                    if ovr is False:
+                        bgl.glLineWidth(ms.glwidth)
+                    else:
+                        bgl.glLineWidth(ovrline)
+
+                    bgl.glColor4f(rgb[0], rgb[1], rgb[2], rgb[3])
+
+                    # ------------------------------------
+                    # Text (distance)
+                    # ------------------------------------
+                    # noinspection PyBroadException
+                    if ms.gltype != 2 and ms.gltype != 9 and ms.gltype != 10 and ms.gltype != 11 and ms.gltype != 20:
+                        # noinspection PyBroadException
+                        try:
+                            midpoint3d = interpolate3d(v1, v2, math.fabs(dist / 2))
+                            gap3d = (midpoint3d[0], midpoint3d[1], midpoint3d[2] + s / 2)
+                            txtpoint2d = get_2d_point(region, rv3d, gap3d)
+                            # Scale
+                            if scene.measureit_scale is True:
+                                dist = dist * scene.measureit_scale_factor
+                                distloc = distloc * scene.measureit_scale_factor
+
+                            # decide dist to use
+                            if dist == distloc:
+                                locflag = False
+                                usedist = dist
+                            else:
+                                usedist = distloc
+                                locflag = True
+                            # Apply scene scale
+                            usedist *= scale
+                            tx_dist = str(format_distance(fmt, units, usedist))
+                            # -----------------------------------
+                            # Draw text
+                            # -----------------------------------
+                            if scene.measureit_gl_show_d is True and ms.gldist is True:
+                                msg = tx_dist + " "
+                            else:
+                                msg = " "
+                            if scene.measureit_gl_show_n is True and ms.glnames is True:
+                                msg += ms.gltxt
+                            if scene.measureit_gl_show_d is True or scene.measureit_gl_show_n is True:
+                                draw_text(myobj, txtpoint2d[0] + ms.glfontx, txtpoint2d[1] + ms.glfonty,
+                                          msg, rgb, fsize)
+
+                            # ------------------------------
+                            # if axis loc, show a indicator
+                            # ------------------------------
+                            if locflag is True and ms.glocwarning is True:
+                                txtpoint2d = get_2d_point(region, rv3d, (v2[0], v2[1], v2[2]))
+                                txt = "["
+                                if ms.glocx is True:
+                                    txt += "X"
+                                if ms.glocy is True:
+                                    txt += "Y"
+                                if ms.glocz is True:
+                                    txt += "Z"
+                                txt += "]"
+                                draw_text(myobj, txtpoint2d[0], txtpoint2d[1], txt, rgb, fsize - 1)
+
+                        except:
+                            pass
+                    # ------------------------------------
+                    # Text (label) and Angles
+                    # ------------------------------------
+                    # noinspection PyBroadException
+                    if ms.gltype == 2 or ms.gltype == 9 or ms.gltype == 11:
+                        right = False
+                        tx_dist = ""
+                        # noinspection PyBroadException
+                        try:
+                            if ms.gltype == 2:
+                                tx_dist = ms.gltxt
+                                right = False
+                            if ms.gltype == 9:  # Angles
+                                ang = ang_1.angle(ang_2)
+                                right = True
+                                if bpy.context.scene.unit_settings.system_rotation == "DEGREES":
+                                    ang = math.degrees(ang)
+
+                                tx_dist = " " + fmt % ang
+                                # Add degree symbol
+                                if bpy.context.scene.unit_settings.system_rotation == "DEGREES":
+                                    tx_dist += a_code
+
+                                if scene.measureit_gl_show_n is True:
+                                    tx_dist += " " + ms.gltxt
+                            if ms.gltype == 11:  # arc
+                                right = True
+                                # print length or arc and angle
+                                if ms.glarc_len is True:
+                                    tx_dist = ms.glarc_txlen + format_distance(fmt, units, arc_length)
+                                else:
+                                    tx_dist = " "
+
+                                if bpy.context.scene.unit_settings.system_rotation == "DEGREES":
+                                    arc_d = math.degrees(arc_angle)
+                                else:
+                                    arc_d = arc_angle
+
+                                if ms.glarc_ang is True:
+                                    tx_dist += " " + ms.glarc_txang + format_distance(fmt, 9, arc_d)
+                                    # Add degree symbol
+                                    if bpy.context.scene.unit_settings.system_rotation == "DEGREES":
+                                        tx_dist += a_code
+
+                                if scene.measureit_gl_show_d is True and ms.gldist is True:
+                                    msg = tx_dist + " "
+                                else:
+                                    msg = " "
+                                if scene.measureit_gl_show_n is True and ms.glnames is True:
+                                    msg += ms.gltxt
+
+                                if scene.measureit_gl_show_d is True or scene.measureit_gl_show_n is True:
+                                    # Normal vector
+                                    vna = mathutils.Vector((b_p1[0] - a_p1[0],
+                                                            b_p1[1] - a_p1[1],
+                                                            b_p1[2] - a_p1[2]))
+                                    vna.normalize()
+                                    via = vna * ms.glspace
+
+                                    gap3d = (b_p1[0] + via[0], b_p1[1] + via[1], b_p1[2] + via[2])
+                                    txtpoint2d = get_2d_point(region, rv3d, gap3d)
+                                    draw_text(myobj, txtpoint2d[0] + ms.glfontx, txtpoint2d[1] + ms.glfonty, msg, rgb,
+                                              fsize, right)
+                                # Radius
+                                if scene.measureit_gl_show_d is True and ms.gldist is True and ms.glarc_rad is True:
+                                    tx_dist = ms.glarc_txradio + format_distance(fmt, units,
+                                                                                 dist * scene.measureit_scale_factor)
+                                else:
+                                    tx_dist = " "
+                            if ms.gltype == 2:
+                                gap3d = (v11a[0], v11a[1], v11a[2])
+                            else:
+                                gap3d = (a_p1[0], a_p1[1], a_p1[2])
+
+                            txtpoint2d = get_2d_point(region, rv3d, gap3d)
+                            draw_text(myobj, txtpoint2d[0] + ms.glfontx, txtpoint2d[1] + ms.glfonty, tx_dist, rgb,
+                                      fsize, right)
+                        except:
+                            pass
+                    # ------------------------------------
+                    # Annotation
+                    # ------------------------------------
+                    # noinspection PyBroadException
+                    if ms.gltype == 10:
+                        # noinspection PyBroadException
+                        try:
+                            tx_dist = ms.gltxt
+                            gap3d = (vn1[0], vn1[1], vn1[2])
+                            txtpoint2d = get_2d_point(region, rv3d, gap3d)
+                            draw_text(myobj, txtpoint2d[0] + ms.glfontx, txtpoint2d[1] + ms.glfonty,
+                                      tx_dist, rgb, fsize)
+                        except:
+                            pass
+                    # ------------------------------------
+                    # Draw lines
+                    # ------------------------------------
+                    bgl.glEnable(bgl.GL_BLEND)
+                    bgl.glColor4f(rgb[0], rgb[1], rgb[2], rgb[3])
+
+                    if ms.gltype == 1:  # Segment
+                        draw_line(screen_point_ap1, screen_point_v11)
+                        draw_line(screen_point_bp1, screen_point_v22)
+                        draw_arrow(screen_point_v1, screen_point_v2, a_size, a_type, b_type)
+
+                    if ms.gltype == 12 or ms.gltype == 13 or ms.gltype == 14:  # Segment to origin
+                        draw_line(screen_point_ap1, screen_point_v11)
+                        draw_line(screen_point_bp1, screen_point_v22)
+                        draw_arrow(screen_point_v1, screen_point_v2, a_size, a_type, b_type)
+
+                    if ms.gltype == 2:  # Label
+                        draw_line(screen_point_v11a, screen_point_v11b)
+                        draw_arrow(screen_point_ap1, screen_point_v11, a_size, a_type, b_type)
+
+                    if ms.gltype == 3 or ms.gltype == 4 or ms.gltype == 5 or ms.gltype == 8 \
+                            or ms.gltype == 6 or ms.gltype == 7:  # Origin and Links
+                        draw_arrow(screen_point_ap1, screen_point_bp1, a_size, a_type, b_type)
+
+                    if ms.gltype == 9:  # Angle
+                        dist, distloc = distance(an_p1, an_p2)
+                        mp1 = interpolate3d(an_p1, an_p2, math.fabs(dist / 1.1))
+
+                        dist, distloc = distance(an_p3, an_p2)
+                        mp2 = interpolate3d(an_p3, an_p2, math.fabs(dist / 1.1))
+
+                        screen_point_an_p1 = get_2d_point(region, rv3d, mp1)
+                        screen_point_an_p2 = get_2d_point(region, rv3d, an_p2)
+                        screen_point_an_p3 = get_2d_point(region, rv3d, mp2)
+
+                        draw_line(screen_point_an_p1, screen_point_an_p2)
+                        draw_line(screen_point_an_p2, screen_point_an_p3)
+                        draw_line(screen_point_an_p1, screen_point_an_p3)
+
+                    if ms.gltype == 11:  # arc
+                        # draw line from center of arc second point
+                        c = mathutils.Vector(a_p1)
+                        if ms.glarc_rad is True:
+                            if ms.glarc_extrad is False:
+                                draw_arrow(screen_point_ap1, screen_point_bp1, a_size, a_type, b_type)
+                            else:
+                                vne = mathutils.Vector((b_p1[0] - a_p1[0],
+                                                        b_p1[1] - a_p1[1],
+                                                        b_p1[2] - a_p1[2]))
+                                vne.normalize()
+                                vie = vne * ms.glspace
+                                pe = (b_p1[0] + vie[0], b_p1[1] + vie[1], b_p1[2] + vie[2])
+                                screen_point_pe = get_2d_point(region, rv3d, pe)
+                                draw_arrow(screen_point_ap1, screen_point_pe, a_size, a_type, b_type)
+
+                        # create arc around the centerpoint
+                        # rotation matrix around normal vector at center point
+                        mat_trans1 = mathutils.Matrix.Translation(-c)
+                        # get step
+                        n_step = 36.0
+                        if ms.glarc_full is False:
+                            step = arc_angle / n_step
+                        else:
+                            step = math.radians(360.0) / n_step
+                        #
+                        mat_rot1 = mathutils.Matrix.Rotation(step, 4, vn)
+                        mat_trans2 = mathutils.Matrix.Translation(c)
+                        p1 = mathutils.Vector(an_p1)  # first point of arc
+                        # Normal vector
+                        vn = mathutils.Vector((p1[0] - a_p1[0],
+                                               p1[1] - a_p1[1],
+                                               p1[2] - a_p1[2]))
+                        vn.normalize()
+                        vi = vn * ms.glspace
+
+                        p_01a = None
+                        p_01b = None
+                        p_02a = None
+                        p_02b = None
+                        # draw the arc
+                        for i in range(0, int(n_step)):
+                            p2 = mat_trans2 * mat_rot1 * mat_trans1 * p1
+                            p1_ = (p1[0] + vi[0], p1[1] + vi[1], p1[2] + vi[2])
+                            # First Point
+                            if i == 0:
+                                p_01a = (p1_[0], p1_[1], p1_[2])
+                                p_01b = (p1[0], p1[1], p1[2])
+
+                            # Normal vector
+                            vn = mathutils.Vector((p2[0] - a_p1[0],
+                                                   p2[1] - a_p1[1],
+                                                   p2[2] - a_p1[2]))
+                            vn.normalize()
+                            vi = vn * ms.glspace
+
+                            p2_ = (p2[0] + vi[0], p2[1] + vi[1], p2[2] + vi[2])
+                            # convert to screen coordinates
+                            screen_point_p1 = get_2d_point(region, rv3d, p1_)
+                            screen_point_p2 = get_2d_point(region, rv3d, p2_)
+                            if i == 0:
+                                draw_arrow(screen_point_p1, screen_point_p2, ms.glarc_s, ms.glarc_a, "99")
+                            elif i == int(n_step) - 1:
+                                draw_arrow(screen_point_p1, screen_point_p2, ms.glarc_s, "99", ms.glarc_b)
+                            else:
+                                draw_line(screen_point_p1, screen_point_p2)
+
+                            p1 = p2.copy()
+
+                            # Last Point
+                            if i == int(n_step) - 1:
+                                p_02a = (p2_[0], p2_[1], p2_[2])
+                                p_02b = (p2[0], p2[1], p2[2])
+
+                        # Draw close lines
+                        if ms.glarc_full is False:
+                            screen_point_p1a = get_2d_point(region, rv3d, p_01a)
+                            screen_point_p1b = get_2d_point(region, rv3d, p_01b)
+                            screen_point_p2a = get_2d_point(region, rv3d, p_02a)
+                            screen_point_p2b = get_2d_point(region, rv3d, p_02b)
+
+                            draw_line(screen_point_p1a, screen_point_p1b)
+                            draw_line(screen_point_p2a, screen_point_p2b)
+
+                    if ms.gltype == 20:  # Area
+                        obverts = get_mesh_vertices(myobj)
+                        tot = 0
+                        for face in ms.measureit_faces:
+                            myvertices = []
+                            for v in face.measureit_index:
+                                myvertices.extend([v.glidx])
+
+                            area = get_area_and_paint(myvertices, myobj, obverts, region, rv3d)
+                            tot += area
+                        # Draw Area number over first face
+                        if len(ms.measureit_faces) > 0:
+                            face = ms.measureit_faces[0]
+                            a = face.measureit_index[0].glidx
+                            b = face.measureit_index[2].glidx
+
+                            p1 = get_point(obverts[a].co, myobj)
+                            p2 = get_point(obverts[b].co, myobj)
+
+                            d1, dn = distance(p1, p2)
+                            midpoint3d = interpolate3d(p1, p2, math.fabs(d1 / 2))
+                            txtpoint2d = get_2d_point(region, rv3d, midpoint3d)
+                            # Scale
+                            if scene.measureit_scale is True:
+                                tot = tot * scene.measureit_scale_factor
+
+                            # mult by world scale
+                            tot *= scale
+                            tx_dist = str(format_distance(fmt, units, tot, 2))
+                            # -----------------------------------
+                            # Draw text
+                            # -----------------------------------
+                            if scene.measureit_gl_show_d is True and ms.gldist is True:
+                                msg = tx_dist + " "
+                            else:
+                                msg = " "
+                            if scene.measureit_gl_show_n is True and ms.glnames is True:
+                                msg += ms.gltxt
+                            if scene.measureit_gl_show_d is True or scene.measureit_gl_show_n is True:
+                                draw_text(myobj, txtpoint2d[0] + ms.glfontx, txtpoint2d[1] + ms.glfonty,
+                                          msg, ms.glcolorarea,
+                                          fsize)
+
+                except IndexError:
+                    ms.glfree = True
+                except:
+                    # print("Unexpected error:" + str(sys.exc_info()))
+                    # if error, disable segment
+                    pass
+
+    return
+
+
+# ------------------------------------------
+# Get polygon area and paint area
+#
+# ------------------------------------------
+def get_area_and_paint(myvertices, myobj, obverts, region, rv3d):
+    mymesh = myobj.data
+    totarea = 0
+    if len(myvertices) > 3:
+        # Tessellate the polygon
+        if myobj.mode != 'EDIT':
+            tris = mesh_utils.ngon_tessellate(mymesh, myvertices)
+        else:
+            bm = bmesh.from_edit_mesh(myobj.data)
+            myv = []
+            for v in bm.verts:
+                myv.extend([v.co])
+            tris = mesh_utils.ngon_tessellate(myv, myvertices)
+
+        for t in tris:
+            v1, v2, v3 = t
+            p1 = get_point(obverts[myvertices[v1]].co, myobj)
+            p2 = get_point(obverts[myvertices[v2]].co, myobj)
+            p3 = get_point(obverts[myvertices[v3]].co, myobj)
+
+            screen_point_p1 = get_2d_point(region, rv3d, p1)
+            screen_point_p2 = get_2d_point(region, rv3d, p2)
+            screen_point_p3 = get_2d_point(region, rv3d, p3)
+            draw_triangle(screen_point_p1, screen_point_p2, screen_point_p3)
+
+            # Area
+            area = get_triangle_area(p1, p2, p3)
+
+            totarea += area
+    elif len(myvertices) == 3:
+        v1, v2, v3 = myvertices
+        p1 = get_point(obverts[v1].co, myobj)
+        p2 = get_point(obverts[v2].co, myobj)
+        p3 = get_point(obverts[v3].co, myobj)
+
+        screen_point_p1 = get_2d_point(region, rv3d, p1)
+        screen_point_p2 = get_2d_point(region, rv3d, p2)
+        screen_point_p3 = get_2d_point(region, rv3d, p3)
+        draw_triangle(screen_point_p1, screen_point_p2, screen_point_p3)
+
+        # Area
+        area = get_triangle_area(p1, p2, p3)
+        totarea += area
+    else:
+        return 0.0
+
+    return totarea
+
+
+# ------------------------------------------
+# Get area using Heron formula
+#
+# ------------------------------------------
+def get_triangle_area(p1, p2, p3):
+    d1, dn = distance(p1, p2)
+    d2, dn = distance(p2, p3)
+    d3, dn = distance(p1, p3)
+    per = (d1 + d2 + d3) / 2.0
+    area = math.sqrt(per * (per - d1) * (per - d2) * (per - d3))
+    return area
+
+
+# ------------------------------------------
+# Get point in 2d space
+#
+# ------------------------------------------
+def get_2d_point(region, rv3d, point3d):
+    if rv3d is not None and region is not None:
+        return view3d_utils.location_3d_to_region_2d(region, rv3d, point3d)
+    else:
+        return get_render_location(point3d)
+
+
+# -------------------------------------------------------------
+# Get sum of a group
+#
+# myobj: Current object
+# Tag: group
+# -------------------------------------------------------------
+def get_group_sum(myobj, tag):
+    # noinspection PyBroadException
+    try:
+        tx = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
+              "T", "U", "V", "W", "X", "Y", "Z"]
+        g = tag[2:3]
+        mp = myobj.MeasureGenerator[0]
+        flag = False
+        # -----------------
+        # Sum loop segments
+        # -----------------
+        scale = bpy.context.scene.unit_settings.scale_length
+        tot = 0.0
+        obverts = get_mesh_vertices(myobj)
+        for idx in range(0, mp.measureit_num):
+            ms = mp.measureit_segments[idx]
+            if (ms.gltype == 1 or ms.gltype == 12 or
+                ms.gltype == 13 or ms.gltype == 14) and ms.gltot != '99' \
+                    and ms.glfree is False and g == tx[int(ms.gltot)]:  # only segments
+                if ms.glpointa <= len(obverts) and ms.glpointb <= len(obverts):
+                    p1 = get_point(obverts[ms.glpointa].co, myobj)
+                    if ms.gltype == 1:
+                        p2 = get_point(obverts[ms.glpointb].co, myobj)
+                    elif ms.gltype == 12:
+                        p2 = get_point((0.0,
+                                        obverts[ms.glpointa].co[1],
+                                        obverts[ms.glpointa].co[2]), myobj)
+                    elif ms.gltype == 13:
+                        p2 = get_point((obverts[ms.glpointa].co[0],
+                                        0.0,
+                                        obverts[ms.glpointa].co[2]), myobj)
+                    else:
+                        p2 = get_point((obverts[ms.glpointa].co[0],
+                                        obverts[ms.glpointa].co[1],
+                                        0.0), myobj)
+
+                    dist, distloc = distance(p1, p2, ms.glocx, ms.glocy, ms.glocz)
+                    if dist == distloc:
+                        usedist = dist
+                    else:
+                        usedist = distloc
+                    usedist *= scale
+                    tot += usedist
+                    flag = True
+
+        if flag is True:
+            # Return value
+            pr = bpy.context.scene.measureit_gl_precision
+            fmt = "%1." + str(pr) + "f"
+            units = bpy.context.scene.measureit_units
+
+            return format_distance(fmt, units, tot)
+        else:
+            return " "
+    except:
+        return " "
+
+
+# -------------------------------------------------------------
+# Create OpenGL text
+#
+# right: Align to right
+# -------------------------------------------------------------
+def draw_text(myobj, x_pos, y_pos, display_text, rgb, fsize, right=False):
+    gap = 12
+    font_id = 0
+    blf.size(font_id, fsize, 72)
+    # height of one line
+    mwidth, mheight = blf.dimensions(font_id, "Tp")  # uses high/low letters
+
+    # Calculate sum groups
+    m = 0
+    while "<#" in display_text:
+        m += 1
+        if m > 10:   # limit loop
+            break
+        i = display_text.index("<#")
+        tag = display_text[i:i + 4]
+        display_text = display_text.replace(tag, get_group_sum(myobj, tag.upper()))
+
+    # split lines
+    mylines = display_text.split("|")
+    idx = len(mylines) - 1
+    maxwidth = 0
+    maxheight = len(mylines) * mheight
+    # -------------------
+    # Draw all lines
+    # -------------------
+    for line in mylines:
+        text_width, text_height = blf.dimensions(font_id, line)
+        if right is True:
+            newx = x_pos - text_width - gap
+        else:
+            newx = x_pos
+        # calculate new Y position
+        new_y = y_pos + (mheight * idx)
+        # Draw
+        blf.position(font_id, newx, new_y, 0)
+        bgl.glColor4f(rgb[0], rgb[1], rgb[2], rgb[3])
+        blf.draw(font_id, " " + line)
+        # sub line
+        idx -= 1
+        # saves max width
+        if maxwidth < text_width:
+            maxwidth = text_width
+
+    return maxwidth, maxheight
+
+
+# -------------------------------------------------------------
+# Draw an OpenGL line
+#
+# -------------------------------------------------------------
+def draw_line(v1, v2):
+    # noinspection PyBroadException
+    try:
+        if v1 is not None and v2 is not None:
+            bgl.glBegin(bgl.GL_LINES)
+            bgl.glVertex2f(*v1)
+            bgl.glVertex2f(*v2)
+            bgl.glEnd()
+    except:
+        pass
+
+
+# -------------------------------------------------------------
+# Draw an OpenGL triangle
+#
+# -------------------------------------------------------------
+def draw_triangle(v1, v2, v3):
+    # noinspection PyBroadException
+    try:
+        if v1 is not None and v2 is not None and v3 is not None:
+            bgl.glBegin(bgl.GL_TRIANGLES)
+            bgl.glVertex2f(*v1)
+            bgl.glVertex2f(*v2)
+            bgl.glVertex2f(*v3)
+            bgl.glEnd()
+    except:
+        pass
+
+
+# -------------------------------------------------------------
+# Draw an Arrow
+#
+# -------------------------------------------------------------
+def draw_arrow(v1, v2, size=20, a_typ="1", b_typ="1"):
+
+    rad45 = math.radians(45)
+    rad315 = math.radians(315)
+    rad90 = math.radians(90)
+    rad270 = math.radians(270)
+
+    v = interpolate3d((v1[0], v1[1], 0.0), (v2[0], v2[1], 0.0), size)
+
+    v1i = (v[0] - v1[0], v[1] - v1[1])
+
+    v = interpolate3d((v2[0], v2[1], 0.0), (v1[0], v1[1], 0.0), size)
+    v2i = (v[0] - v2[0], v[1] - v2[1])
+
+    # Point A
+    if a_typ == "3":
+        rad_a = rad90
+        rad_b = rad270
+    else:
+        rad_a = rad45
+        rad_b = rad315
+
+    v1a = (int(v1i[0] * math.cos(rad_a) - v1i[1] * math.sin(rad_a) + v1[0]),
+           int(v1i[1] * math.cos(rad_a) + v1i[0] * math.sin(rad_a)) + v1[1])
+    v1b = (int(v1i[0] * math.cos(rad_b) - v1i[1] * math.sin(rad_b) + v1[0]),
+           int(v1i[1] * math.cos(rad_b) + v1i[0] * math.sin(rad_b) + v1[1]))
+
+    # Point B
+    if b_typ == "3":
+        rad_a = rad90
+        rad_b = rad270
+    else:
+        rad_a = rad45
+        rad_b = rad315
+
+    v2a = (int(v2i[0] * math.cos(rad_a) - v2i[1] * math.sin(rad_a) + v2[0]),
+           int(v2i[1] * math.cos(rad_a) + v2i[0] * math.sin(rad_a)) + v2[1])
+    v2b = (int(v2i[0] * math.cos(rad_b) - v2i[1] * math.sin(rad_b) + v2[0]),
+           int(v2i[1] * math.cos(rad_b) + v2i[0] * math.sin(rad_b) + v2[1]))
+
+    # Triangle o Lines
+    if a_typ == "1" or a_typ == "3":
+        draw_line(v1, v1a)
+        draw_line(v1, v1b)
+
+    if b_typ == "1" or b_typ == "3":
+        draw_line(v2, v2a)
+        draw_line(v2, v2b)
+
+    if a_typ == "2":
+        draw_triangle(v1, v1a, v1b)
+    if b_typ == "2":
+        draw_triangle(v2, v2a, v2b)
+
+    draw_line(v1, v2)
+
+
+# -------------------------------------------------------------
+# Draw an OpenGL Rectangle
+#
+# v1, v2 are corners (bottom left / top right)
+# -------------------------------------------------------------
+def draw_rectangle(v1, v2):
+    # noinspection PyBroadException
+    try:
+        if v1 is not None and v2 is not None:
+            v1b = (v2[0], v1[1])
+            v2b = (v1[0], v2[1])
+            draw_line(v1, v1b)
+            draw_line(v1b, v2)
+            draw_line(v2, v2b)
+            draw_line(v2b, v1)
+    except:
+        pass
+
+
+# -------------------------------------------------------------
+# format a point as (x, y, z) for display
+#
+# -------------------------------------------------------------
+def format_point(mypoint, pr):
+    pf = "%1." + str(pr) + "f"
+    fmt = " ("
+    fmt += pf % mypoint[0]
+    fmt += ", "
+    fmt += pf % mypoint[1]
+    fmt += ", "
+    fmt += pf % mypoint[2]
+    fmt += ")"
+
+    return fmt
+
+
+# -------------------------------------------------------------
+# Draw vertex num for debug
+#
+# -------------------------------------------------------------
+# noinspection PyUnresolvedReferences,PyUnboundLocalVariable,PyUnusedLocal
+def draw_vertices(context, myobj, region, rv3d):
+    # Only meshes
+    if myobj.type != "MESH":
+        return
+
+    scene = bpy.context.scene
+    rgb = scene.measureit_debug_color
+    fsize = scene.measureit_debug_font
+    precision = scene.measureit_debug_precision
+    # --------------------
+    # vertex Loop
+    # --------------------
+    if myobj.mode == 'EDIT':
+        bm = bmesh.from_edit_mesh(myobj.data)
+        obverts = bm.verts
+    else:
+        obverts = myobj.data.vertices
+
+    for v in obverts:
+        # Display only selected
+        if scene.measureit_debug_select is True:
+            if v.select is False:
+                continue
+        # noinspection PyBroadException
+        try:
+            a_p1 = get_point(v.co, myobj)
+            # colour
+            bgl.glColor4f(rgb[0], rgb[1], rgb[2], rgb[3])
+            # converting to screen coordinates
+            txtpoint2d = get_2d_point(region, rv3d, a_p1)
+            # Text
+            txt = str(v.index)
+            if scene.measureit_debug_location is True:
+                txt += format_point(v.co, precision)
+            draw_text(myobj, txtpoint2d[0], txtpoint2d[1], txt, rgb, fsize)
+        except:
+            print("Unexpected error:" + str(sys.exc_info()))
+            pass
+
+    return
+
+
+# -------------------------------------------------------------
+# Draw face num for debug
+#
+# -------------------------------------------------------------
+# noinspection PyUnresolvedReferences,PyUnboundLocalVariable,PyUnusedLocal
+def draw_faces(context, myobj, region, rv3d):
+    # Only meshes
+    if myobj.type != "MESH":
+        return
+
+    scene = bpy.context.scene
+    rgb = scene.measureit_debug_color2
+    rgb2 = scene.measureit_debug_color3
+    fsize = scene.measureit_debug_font
+    ln = scene.measureit_debug_normal_size
+    th = scene.measureit_debug_width
+    precision = scene.measureit_debug_precision
+
+    # --------------------
+    # face Loop
+    # --------------------
+    if myobj.mode == 'EDIT':
+        bm = bmesh.from_edit_mesh(myobj.data)
+        obverts = bm.verts
+        myfaces = bm.faces
+    else:
+        obverts = myobj.data.vertices
+        myfaces = myobj.data.polygons
+
+    for f in myfaces:
+        normal = f.normal
+        # Display only selected
+        if scene.measureit_debug_select is True:
+            if f.select is False:
+                continue
+        # noinspection PyBroadException
+        try:
+            if myobj.mode == 'EDIT':
+                a_p1 = get_point(f.calc_center_median(), myobj)
+            else:
+                a_p1 = get_point(f.center, myobj)
+
+            a_p2 = (a_p1[0] + normal[0] * ln, a_p1[1] + normal[1] * ln, a_p1[2] + normal[2] * ln)
+            # colour + line setup
+            bgl.glEnable(bgl.GL_BLEND)
+            bgl.glLineWidth(th)
+            bgl.glColor4f(rgb[0], rgb[1], rgb[2], rgb[3])
+            # converting to screen coordinates
+            txtpoint2d = get_2d_point(region, rv3d, a_p1)
+            point2 = get_2d_point(region, rv3d, a_p2)
+            # Text
+            if scene.measureit_debug_faces is True:
+                draw_text(myobj, txtpoint2d[0], txtpoint2d[1], str(f.index), rgb, fsize)
+            # Draw Normal
+            if scene.measureit_debug_normals is True:
+                bgl.glEnable(bgl.GL_BLEND)
+                bgl.glColor4f(rgb2[0], rgb2[1], rgb2[2], rgb2[3])
+                draw_arrow(txtpoint2d, point2, 10, "99", "1")
+
+                if len(obverts) > 2 and scene.measureit_debug_normal_details is True:
+                    if myobj.mode == 'EDIT':
+                        i1 = f.verts[0].index
+                        i2 = f.verts[1].index
+                        i3 = f.verts[2].index
+                    else:
+                        i1 = f.vertices[0]
+                        i2 = f.vertices[1]
+                        i3 = f.vertices[2]
+
+                    a_p1 = get_point(obverts[i1].co, myobj)
+                    a_p2 = get_point(obverts[i2].co, myobj)
+                    a_p3 = get_point(obverts[i3].co, myobj)
+                    # converting to screen coordinates
+                    a2d = get_2d_point(region, rv3d, a_p1)
+                    b2d = get_2d_point(region, rv3d, a_p2)
+                    c2d = get_2d_point(region, rv3d, a_p3)
+                    # draw vectors
+                    draw_arrow(a2d, b2d, 10, "99", "1")
+                    draw_arrow(b2d, c2d, 10, "99", "1")
+                    # Normal vector data
+                    txt = format_point(normal, precision)
+                    draw_text(myobj, point2[0], point2[1], txt, rgb2, fsize)
+
+        except:
+            print("Unexpected error:" + str(sys.exc_info()))
+            pass
+
+    return
+
+
+# --------------------------------------------------------------------
+# Distance between 2 points in 3D space
+# v1: first point
+# v2: second point
+# locx/y/z: Use this axis
+# return: distance
+# --------------------------------------------------------------------
+def distance(v1, v2, locx=True, locy=True, locz=True):
+    x = math.sqrt((v2[0] - v1[0]) ** 2 + (v2[1] - v1[1]) ** 2 + (v2[2] - v1[2]) ** 2)
+
+    # If axis is not used, make equal both (no distance)
+    v1b = [v1[0], v1[1], v1[2]]
+    v2b = [v2[0], v2[1], v2[2]]
+    if locx is False:
+        v2b[0] = v1b[0]
+    if locy is False:
+        v2b[1] = v1b[1]
+    if locz is False:
+        v2b[2] = v1b[2]
+
+    xloc = math.sqrt((v2b[0] - v1b[0]) ** 2 + (v2b[1] - v1b[1]) ** 2 + (v2b[2] - v1b[2]) ** 2)
+
+    return x, xloc
+
+
+# --------------------------------------------------------------------
+# Interpolate 2 points in 3D space
+# v1: first point
+# v2: second point
+# d1: distance
+# return: interpolate point
+# --------------------------------------------------------------------
+def interpolate3d(v1, v2, d1):
+    # calculate vector
+    v = (v2[0] - v1[0], v2[1] - v1[1], v2[2] - v1[2])
+    # calculate distance between points
+    d0, dloc = distance(v1, v2)
+
+    # calculate interpolate factor (distance from origin / distance total)
+    # if d1 > d0, the point is projected in 3D space
+    if d0 > 0:
+        x = d1 / d0
+    else:
+        x = d1
+
+    final = (v1[0] + (v[0] * x), v1[1] + (v[1] * x), v1[2] + (v[2] * x))
+    return final
+
+
+# --------------------------------------------------------------------
+# Get point rotated and relative to parent
+# v1: point
+# mainobject
+# --------------------------------------------------------------------
+def get_point(v1, mainobject):
+    # Using World Matrix
+    vt = mathutils.Vector((v1[0], v1[1], v1[2], 1))
+    m4 = mainobject.matrix_world
+    vt2 = m4 * vt
+    v2 = [vt2[0], vt2[1], vt2[2]]
+
+    return v2
+
+
+# --------------------------------------------------------------------
+# Get location in world space
+# v1: point
+# mainobject
+# --------------------------------------------------------------------
+def get_location(mainobject):
+    # Using World Matrix
+    m4 = mainobject.matrix_world
+
+    return [m4[0][3], m4[1][3], m4[2][3]]
+
+
+# --------------------------------------------------------------------
+# Get vertex data
+# mainobject
+# --------------------------------------------------------------------
+def get_mesh_vertices(myobj):
+    try:
+        if myobj.mode == 'EDIT':
+            bm = bmesh.from_edit_mesh(myobj.data)
+            obverts = bm.verts
+        else:
+            obverts = myobj.data.vertices
+
+        return obverts
+    except AttributeError:
+        return None
+
+
+# --------------------------------------------------------------------
+# Get position for scale text
+#
+# --------------------------------------------------------------------
+def get_scale_txt_location(context):
+    scene = context.scene
+    pos_x = int(context.region.width * scene.measureit_scale_pos_x / 100)
+    pos_y = int(context.region.height * scene.measureit_scale_pos_y / 100)
+
+    return pos_x, pos_y
+
+
+# --------------------------------------------------------------------
+# Get position in final render image
+# (Z < 0 out of camera)
+# return 2d position
+# --------------------------------------------------------------------
+def get_render_location(mypoint):
+
+    v1 = mathutils.Vector(mypoint)
+    scene = bpy.context.scene
+    co_2d = object_utils.world_to_camera_view(scene, scene.camera, v1)
+    # Get pixel coords
+    render_scale = scene.render.resolution_percentage / 100
+    render_size = (int(scene.render.resolution_x * render_scale),
+                   int(scene.render.resolution_y * render_scale))
+
+    return [round(co_2d.x * render_size[0]), round(co_2d.y * render_size[1])]
+
+
+# ---------------------------------------------------------
+# Get center of circle base on 3 points
+#
+# Point a: (x,y,z) arc start
+# Point b: (x,y,z) center
+# Point c: (x,y,z) midle point in the arc
+# Point d: (x,y,z) arc end
+# Return:
+# ang: angle (radians)
+# len: len of arc
+#
+# ---------------------------------------------------------
+def get_arc_data(pointa, pointb, pointc, pointd):
+    v1 = mathutils.Vector((pointa[0] - pointb[0], pointa[1] - pointb[1], pointa[2] - pointb[2]))
+    v2 = mathutils.Vector((pointc[0] - pointb[0], pointc[1] - pointb[1], pointc[2] - pointb[2]))
+    v3 = mathutils.Vector((pointd[0] - pointb[0], pointd[1] - pointb[1], pointd[2] - pointb[2]))
+
+    angle = v1.angle(v2) + v2.angle(v3)
+
+    rclength = math.pi * 2 * v2.length * (angle / (math.pi * 2))
+
+    return angle, rclength
+
+
+# -------------------------------------------------------------
+# Format a number to the right unit
+#
+# -------------------------------------------------------------
+def format_distance(fmt, units, value, factor=1):
+    s_code = "\u00b2"  # Superscript two
+    # ------------------------
+    # Units automatic
+    # ------------------------
+    if units == "1":
+        # Units
+        if bpy.context.scene.unit_settings.system == "IMPERIAL":
+            feet = value * (3.2808399 ** factor)
+            if round(feet, 2) >= 1.0:
+                fmt += " ft"
+                if factor == 2:
+                    fmt += s_code
+                tx_dist = fmt % feet
+            else:
+                inches = value * (39.3700787 ** factor)
+                fmt += " in"
+                if factor == 2:
+                    fmt += s_code
+                tx_dist = fmt % inches
+        elif bpy.context.scene.unit_settings.system == "METRIC":
+            if round(value, 2) >= 1.0:
+                fmt += " m"
+                if factor == 2:
+                    fmt += s_code
+                tx_dist = fmt % value
+            else:
+                if round(value, 2) >= 0.01:
+                    fmt += " cm"
+                    if factor == 2:
+                        fmt += s_code
+                    d_cm = value * (100 ** factor)
+                    tx_dist = fmt % d_cm
+                else:
+                    fmt += " mm"
+                    if factor == 2:
+                        fmt += s_code
+                    d_mm = value * (1000 ** factor)
+                    tx_dist = fmt % d_mm
+        else:
+            tx_dist = fmt % value
+    # ------------------------
+    # Units meters
+    # ------------------------
+    elif units == "2":
+        fmt += " m"
+        if factor == 2:
+            fmt += s_code
+        tx_dist = fmt % value
+    # ------------------------
+    # Units centimeters
+    # ------------------------
+    elif units == "3":
+        fmt += " cm"
+        if factor == 2:
+            fmt += s_code
+        d_cm = value * (100 ** factor)
+        tx_dist = fmt % d_cm
+    # ------------------------
+    # Units milimiters
+    # ------------------------
+    elif units == "4":
+        fmt += " mm"
+        if factor == 2:
+            fmt += s_code
+        d_mm = value * (1000 ** factor)
+        tx_dist = fmt % d_mm
+    # ------------------------
+    # Units feet
+    # ------------------------
+    elif units == "5":
+        fmt += " ft"
+        if factor == 2:
+            fmt += s_code
+        feet = value * (3.2808399 ** factor)
+        tx_dist = fmt % feet
+    # ------------------------
+    # Units inches
+    # ------------------------
+    elif units == "6":
+        fmt += " in"
+        if factor == 2:
+            fmt += s_code
+        inches = value * (39.3700787 ** factor)
+        tx_dist = fmt % inches
+    # ------------------------
+    # Default
+    # ------------------------
+    else:
+        tx_dist = fmt % value
+
+    return tx_dist
diff --git a/measureit/measureit_main.py b/measureit/measureit_main.py
new file mode 100644
index 0000000000000000000000000000000000000000..798bb5b79f7006cb817401b157906a785a6e1679
--- /dev/null
+++ b/measureit/measureit_main.py
@@ -0,0 +1,2061 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# ----------------------------------------------------------
+# File: measureit_main.py
+# Main panel for different Measureit general actions
+# Author: Antonio Vazquez (antonioya)
+#
+# ----------------------------------------------------------
+# noinspection PyUnresolvedReferences
+import bpy
+# noinspection PyUnresolvedReferences
+import bmesh
+# noinspection PyUnresolvedReferences
+import bgl
+# noinspection PyUnresolvedReferences
+from bpy.app.handlers import persistent
+# noinspection PyUnresolvedReferences
+from measureit_geometry import *
+from measureit_render import *
+
+
+# ------------------------------------------------------
+# Handler to detect new Blend load
+#
+# ------------------------------------------------------
+# noinspection PyUnusedLocal
+@persistent
+def load_handler(dummy):
+    RunHintDisplayButton.handle_remove(None, bpy.context)
+
+
+# ------------------------------------------------------
+# Handler to detect save Blend
+# Clear not used measured
+#
+# ------------------------------------------------------
+# noinspection PyUnusedLocal
+@persistent
+def save_handler(dummy):
+    # noinspection PyBroadException
+    try:
+        print("MeasureIt: Cleaning data")
+        objlist = bpy.context.scene.objects
+        for myobj in objlist:
+            if 'MeasureGenerator' in myobj:
+                mp = myobj.MeasureGenerator[0]
+                x = 0
+                for ms in mp.measureit_segments:
+                    ms.name = "segment_" + str(x)
+                    x += 1
+                    if ms.glfree is True:
+                        idx = mp.measureit_segments.find(ms.name)
+                        if idx > -1:
+                            print("MeasureIt: Removed segment not used")
+                            mp.measureit_segments.remove(idx)
+
+                # reset size
+                mp.measureit_num = len(mp.measureit_segments)
+    except:
+        pass
+
+bpy.app.handlers.load_post.append(load_handler)
+bpy.app.handlers.save_pre.append(save_handler)
+
+
+# ------------------------------------------------------------------
+# Define property group class for measureit faces index
+# ------------------------------------------------------------------
+class MeasureitIndex(bpy.types.PropertyGroup):
+    glidx = bpy.props.IntProperty(name="index",
+                                  description="vertex index")
+
+# Register
+bpy.utils.register_class(MeasureitIndex)
+
+
+# ------------------------------------------------------------------
+# Define property group class for measureit faces
+# ------------------------------------------------------------------
+class MeasureitFaces(bpy.types.PropertyGroup):
+    glface = bpy.props.IntProperty(name="glface",
+                                   description="Face number")
+    # Array of index
+    measureit_index = bpy.props.CollectionProperty(type=MeasureitIndex)
+
+# Register
+bpy.utils.register_class(MeasureitFaces)
+
+
+# ------------------------------------------------------------------
+# Define property group class for measureit data
+# ------------------------------------------------------------------
+class MeasureitProperties(bpy.types.PropertyGroup):
+    gltype = bpy.props.IntProperty(name="gltype",
+                                   description="Measure type (1-Segment, 2-Label, etc..)", default=1)
+    glpointa = bpy.props.IntProperty(name="glpointa",
+                                     description="Hidden property for opengl")
+    glpointb = bpy.props.IntProperty(name="glpointb",
+                                     description="Hidden property for opengl")
+    glpointc = bpy.props.IntProperty(name="glpointc",
+                                     description="Hidden property for opengl")
+    glcolor = bpy.props.FloatVectorProperty(name="glcolor",
+                                            description="Color for the measure",
+                                            default=(0.173, 0.545, 1.0, 1.0),
+                                            min=0.1,
+                                            max=1,
+                                            subtype='COLOR',
+                                            size=4)
+    glview = bpy.props.BoolProperty(name="glview",
+                                    description="Measure visible/hide",
+                                    default=True)
+    glspace = bpy.props.FloatProperty(name='glspace', min=-100, max=100, default=0.1,
+                                      precision=3,
+                                      description='Distance to display measure')
+    glwidth = bpy.props.IntProperty(name='glwidth', min=1, max=10, default=1,
+                                    description='line width')
+    glfree = bpy.props.BoolProperty(name="glfree",
+                                    description="This measure is free and can be deleted",
+                                    default=False)
+    gltxt = bpy.props.StringProperty(name="gltxt", maxlen=256,
+                                     description="Short description (use | for line break)")
+    gladvance = bpy.props.BoolProperty(name="gladvance",
+                                       description="Advanced options as line width or position",
+                                       default=False)
+    gldefault = bpy.props.BoolProperty(name="gldefault",
+                                       description="Display measure in position calculated by default",
+                                       default=True)
+    glnormalx = bpy.props.FloatProperty(name="glnormalx",
+                                        description="Change orientation in X axis",
+                                        default=1, min=-1, max=1, precision=2)
+    glnormaly = bpy.props.FloatProperty(name="glnormaly",
+                                        description="Change orientation in Y axis",
+                                        default=0, min=-1, max=1, precision=2)
+    glnormalz = bpy.props.FloatProperty(name="glnormalz",
+                                        description="Change orientation in Z axis",
+                                        default=0, min=-1, max=1, precision=2)
+    glfont_size = bpy.props.IntProperty(name="Text Size",
+                                        description="Text size",
+                                        default=14, min=6, max=150)
+    gllink = bpy.props.StringProperty(name="gllink",
+                                      description="linked object for linked measures")
+    glocwarning = bpy.props.BoolProperty(name="glocwarning",
+                                         description="Display a warning if some axis is not used in distance",
+                                         default=True)
+    glocx = bpy.props.BoolProperty(name="glocx",
+                                   description="Include changes in X axis for calculating the distance",
+                                   default=True)
+    glocy = bpy.props.BoolProperty(name="glocy",
+                                   description="Include changes in Y axis for calculating the distance",
+                                   default=True)
+    glocz = bpy.props.BoolProperty(name="glocz",
+                                   description="Include changes in Z axis for calculating the distance",
+                                   default=True)
+    glfontx = bpy.props.IntProperty(name="glfontx",
+                                    description="Change font position in X axis",
+                                    default=0, min=-3000, max=3000)
+    glfonty = bpy.props.IntProperty(name="glfonty",
+                                    description="Change font position in Y axis",
+                                    default=0, min=-3000, max=3000)
+    gldist = bpy.props.BoolProperty(name="gldist",
+                                    description="Display distance for this measure",
+                                    default=True)
+    glnames = bpy.props.BoolProperty(name="glnames",
+                                     description="Display text for this measure",
+                                     default=True)
+    gltot = bpy.props.EnumProperty(items=(('99', "-", "Select a group for sum"),
+                                          ('0', "A", ""),
+                                          ('1', "B", ""),
+                                          ('2', "C", ""),
+                                          ('3', "D", ""),
+                                          ('4', "E", ""),
+                                          ('5', "F", ""),
+                                          ('6', "G", ""),
+                                          ('7', "H", ""),
+                                          ('8', "I", ""),
+                                          ('9', "J", ""),
+                                          ('10', "K", ""),
+                                          ('11', "L", ""),
+                                          ('12', "M", ""),
+                                          ('13', "N", ""),
+                                          ('14', "O", ""),
+                                          ('15', "P", ""),
+                                          ('16', "Q", ""),
+                                          ('17', "R", ""),
+                                          ('18', "S", ""),
+                                          ('19', "T", ""),
+                                          ('20', "U", ""),
+                                          ('21', "V", ""),
+                                          ('22', "W", ""),
+                                          ('23', "X", ""),
+                                          ('24', "Y", ""),
+                                          ('25', "Z", "")),
+                                   name="Sum in Group",
+                                   description="Add segment length in selected group")
+    glorto = bpy.props.EnumProperty(items=(('99', "None", ""),
+                                           ('0', "A", "Point A must use selected point B location"),
+                                           ('1', "B", "Point B must use selected point A location")),
+                                    name="Orthogonal",
+                                    description="Display point selected as orthogonal (select axis to copy)")
+    glorto_x = bpy.props.BoolProperty(name="ox",
+                                      description="Copy X location",
+                                      default=False)
+    glorto_y = bpy.props.BoolProperty(name="oy",
+                                      description="Copy Y location",
+                                      default=False)
+    glorto_z = bpy.props.BoolProperty(name="oz",
+                                      description="Copy Z location",
+                                      default=False)
+    glarrow_a = bpy.props.EnumProperty(items=(('99', "--", "No arrow"),
+                                              ('1', "Line", "The point of the arrow are lines"),
+                                              ('2', "Triangle", "The point of the arrow is triangle"),
+                                              ('3', "TShape", "The point of the arrow is a T")),
+                                       name="A end",
+                                       description="Add arrows to point A")
+    glarrow_b = bpy.props.EnumProperty(items=(('99', "--", "No arrow"),
+                                              ('1', "Line", "The point of the arrow are lines"),
+                                              ('2', "Triangle", "The point of the arrow is triangle"),
+                                              ('3', "TShape", "The point of the arrow is a T")),
+                                       name="B end",
+                                       description="Add arrows to point B")
+    glarrow_s = bpy.props.IntProperty(name="Size",
+                                      description="Arrow size",
+                                      default=15, min=6, max=500)
+
+    glarc_full = bpy.props.BoolProperty(name="arcfull",
+                                        description="Create full circunference",
+                                        default=False)
+    glarc_extrad = bpy.props.BoolProperty(name="arcextrad",
+                                          description="Adapt radio lengh to arc line",
+                                          default=True)
+    glarc_rad = bpy.props.BoolProperty(name="arc rad",
+                                       description="Show arc radius",
+                                       default=True)
+    glarc_len = bpy.props.BoolProperty(name="arc len",
+                                       description="Show arc length",
+                                       default=True)
+    glarc_ang = bpy.props.BoolProperty(name="arc ang",
+                                       description="Show arc angle",
+                                       default=True)
+
+    glarc_a = bpy.props.EnumProperty(items=(('99', "--", "No arrow"),
+                                            ('1', "Line", "The point of the arrow are lines"),
+                                            ('2', "Triangle", "The point of the arrow is triangle"),
+                                            ('3', "TShape", "The point of the arrow is a T")),
+                                     name="Ar end",
+                                     description="Add arrows to point A")
+    glarc_b = bpy.props.EnumProperty(items=(('99', "--", "No arrow"),
+                                            ('1', "Line", "The point of the arrow are lines"),
+                                            ('2', "Triangle", "The point of the arrow is triangle"),
+                                            ('3', "TShape", "The point of the arrow is a T")),
+                                     name="Br end",
+                                     description="Add arrows to point B")
+    glarc_s = bpy.props.IntProperty(name="Size",
+                                    description="Arrow size",
+                                    default=15, min=6, max=500)
+    glarc_txradio = bpy.props.StringProperty(name="txradio",
+                                             description="Text for radius", default="r=")
+    glarc_txlen = bpy.props.StringProperty(name="txlen",
+                                           description="Text for length", default="L=")
+    glarc_txang = bpy.props.StringProperty(name="txang",
+                                           description="Text for angle", default="A=")
+    glcolorarea = bpy.props.FloatVectorProperty(name="glcolorarea",
+                                                description="Color for the measure of area",
+                                                default=(0.1, 0.1, 0.1, 1.0),
+                                                min=0.1,
+                                                max=1,
+                                                subtype='COLOR',
+                                                size=4)
+
+    # Array of faces
+    measureit_faces = bpy.props.CollectionProperty(type=MeasureitFaces)
+
+# Register
+bpy.utils.register_class(MeasureitProperties)
+
+
+# ------------------------------------------------------------------
+# Define object class (container of segments)
+# Measureit
+# ------------------------------------------------------------------
+class MeasureContainer(bpy.types.PropertyGroup):
+    measureit_num = bpy.props.IntProperty(name='Number of measures', min=0, max=1000, default=0,
+                                          description='Number total of measureit elements')
+    # Array of segments
+    measureit_segments = bpy.props.CollectionProperty(type=MeasureitProperties)
+
+
+bpy.utils.register_class(MeasureContainer)
+bpy.types.Object.MeasureGenerator = bpy.props.CollectionProperty(type=MeasureContainer)
+
+
+# ------------------------------------------------------------------
+# Define UI class
+# Measureit
+# ------------------------------------------------------------------
+class MeasureitEditPanel(bpy.types.Panel):
+    bl_idname = "measureit.editpanel"
+    bl_label = "Measureit"
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'UI'
+    bl_category = 'MesureIt'
+
+    # -----------------------------------------------------
+    # Verify if visible
+    # -----------------------------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        if 'MeasureGenerator' not in o:
+            return False
+        else:
+            mp = context.object.MeasureGenerator[0]
+            if mp.measureit_num > 0:
+                return True
+            else:
+                return False
+
+    # -----------------------------------------------------
+    # Draw (create UI interface)
+    # -----------------------------------------------------
+    # noinspection PyUnusedLocal
+    def draw(self, context):
+        layout = self.layout
+        scene = context.scene
+        if context.object is not None:
+            if 'MeasureGenerator' in context.object:
+                box = layout.box()
+                row = box.row()
+                row.label(context.object.name)
+                row = box.row()
+                row.prop(scene, 'measureit_gl_precision', text="Precision")
+                row.prop(scene, 'measureit_units')
+                row = box.row()
+                row.prop(scene, 'measureit_gl_show_d', text="Distances", toggle=True, icon="ALIGN")
+                row.prop(scene, 'measureit_gl_show_n', text="Texts", toggle=True, icon="FONT_DATA")
+
+                # Scale factor
+                row = box.row()
+                row.prop(scene, 'measureit_scale', text="Scale")
+                if scene.measureit_scale is True:
+                    row.prop(scene, 'measureit_scale_factor', text="1")
+                    row.prop(scene, 'measureit_scale_precision', text="")
+                    row.prop(scene, 'measureit_gl_scaletxt', text="")
+                    row = box.row()
+                    row.prop(scene, 'measureit_scale_color')
+                    row.prop(scene, 'measureit_scale_font')
+                    row = box.row()
+                    row.prop(scene, 'measureit_scale_pos_x')
+                    row.prop(scene, 'measureit_scale_pos_y')
+
+                # Override
+                row = box.row()
+                row.prop(scene, 'measureit_ovr', text="Override")
+                if scene.measureit_ovr is True:
+                    row.prop(scene, 'measureit_ovr_color', text="")
+                    row.prop(scene, 'measureit_ovr_font', text="Font")
+                    row.prop(scene, 'measureit_ovr_width', text="Width")
+
+                mp = context.object.MeasureGenerator[0]
+                # -----------------
+                # loop
+                # -----------------
+                if mp.measureit_num > 0:
+                    box = layout.box()
+                    for idx in range(0, mp.measureit_num):
+                        if mp.measureit_segments[idx].glfree is False:
+                            add_item(box, idx, mp.measureit_segments[idx])
+
+                row = box.row()
+                row.operator("measureit.deleteallsegmentbutton", text="Delete all", icon="X")
+                # -----------------
+                # Sum loop segments
+                # -----------------
+                if mp.measureit_num > 0:
+                    scale = bpy.context.scene.unit_settings.scale_length
+                    tx = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
+                          "T", "U", "V", "W", "X", "Y", "Z"]
+                    tot = [0.0] * len(tx)
+                    ac = [False] * len(tx)
+                    myobj = context.object
+                    obverts = get_mesh_vertices(myobj)
+                    viewtot = False
+                    for idx in range(0, mp.measureit_num):
+                        ms = mp.measureit_segments[idx]
+                        if (ms.gltype == 1 or ms.gltype == 12
+                            or ms.gltype == 13 or ms.gltype == 14) and ms.gltot != '99' \
+                                and ms.glfree is False:  # only segments
+                            if ms.glpointa <= len(obverts) and ms.glpointb <= len(obverts):
+                                p1 = get_point(obverts[ms.glpointa].co, myobj)
+                                if ms.gltype == 1:
+                                    p2 = get_point(obverts[ms.glpointb].co, myobj)
+                                elif ms.gltype == 12:
+                                    p2 = get_point((0.0,
+                                                    obverts[ms.glpointa].co[1],
+                                                    obverts[ms.glpointa].co[2]), myobj)
+                                elif ms.gltype == 13:
+                                    p2 = get_point((obverts[ms.glpointa].co[0],
+                                                    0.0,
+                                                    obverts[ms.glpointa].co[2]), myobj)
+                                else:
+                                    p2 = get_point((obverts[ms.glpointa].co[0],
+                                                    obverts[ms.glpointa].co[1],
+                                                    0.0), myobj)
+
+                                dist, distloc = distance(p1, p2, ms.glocx, ms.glocy, ms.glocz)
+                                if dist == distloc:
+                                    usedist = dist
+                                else:
+                                    usedist = distloc
+                                usedist *= scale
+                                tot[int(ms.gltot)] += usedist
+                                ac[int(ms.gltot)] = True
+                                viewtot = True
+                    # -----------------
+                    # Print values
+                    # -----------------
+                    if viewtot is True:
+                        pr = scene.measureit_gl_precision
+                        fmt = "%1." + str(pr) + "f"
+                        units = scene.measureit_units
+
+                        box = layout.box()
+                        box.label("Totals", icon='SOLO_ON')
+                        final = 0
+                        for idx in range(0, len(tot)):
+                            if ac[idx] is True:
+                                final += tot[idx]
+                                tx_dist = format_distance(fmt, units, tot[idx])
+                                row = box.row(True)
+                                row.label("Group " + tx[idx] + ":")
+                                row.label(" ")
+                                row.label(tx_dist)
+
+                        # Grand total
+                        row = box.row(True)
+                        row.label("")
+                        row.label(" ")
+                        row.label("-" * 20)
+                        tx_dist = format_distance(fmt, units, final)
+
+                        row = box.row(True)
+                        row.label("")
+                        row.label(" ")
+                        row.label(tx_dist)
+                        # delete all
+                        row = box.row()
+                        row.operator("measureit.deleteallsumbutton", text="Delete all", icon="X")
+
+
+# -----------------------------------------------------
+# Add segment to the panel.
+# -----------------------------------------------------
+def add_item(box, idx, segment):
+    row = box.row(True)
+    if segment.glview is True:
+        icon = "VISIBLE_IPO_ON"
+    else:
+        icon = "VISIBLE_IPO_OFF"
+
+    row.prop(segment, 'glview', text="", toggle=True, icon=icon)
+    row.prop(segment, 'gladvance', text="", toggle=True, icon="MANIPUL")
+    row.prop(segment, 'gltxt', text="")
+    row.prop(segment, 'glcolor', text="")
+    op = row.operator("measureit.deletesegmentbutton", text="", icon="X")
+    op.tag = idx  # saves internal data
+    if segment.gladvance is True:
+        row = box.row(True)
+        if segment.gltype != 10 and segment.gltype != 20:
+            row.prop(segment, 'glspace', text="Distance")
+
+        row.prop(segment, 'glfont_size', text="Font")
+        row.prop(segment, 'glfontx', text="X")
+        row.prop(segment, 'glfonty', text="Y")
+
+        # Arrows
+        if segment.gltype != 9 and segment.gltype != 10 and segment.gltype != 20:
+            row = box.row(True)
+            row.prop(segment, 'glarrow_a', text="")
+            row.prop(segment, 'glarrow_b', text="")
+            row.prop(segment, 'glarrow_s', text="Size")
+
+        if segment.gltype != 2 and segment.gltype != 10:
+            row = box.row(True)
+            row.prop(segment, 'gldist', text="Distance", toggle=True, icon="ALIGN")
+            row.prop(segment, 'glnames', text="Text", toggle=True, icon="FONT_DATA")
+            # sum distances
+            if segment.gltype == 1 or segment.gltype == 12 or segment.gltype == 13 or segment.gltype == 14:
+                row.prop(segment, 'gltot', text="Sum")
+
+        if segment.gltype != 10 and segment.gltype != 20:
+            row = box.row(True)
+            row.prop(segment, 'glwidth', text="Line")
+            row.prop(segment, 'gldefault', text="Automatic position")
+            if segment.gldefault is False:
+                row = box.row(True)
+                row.prop(segment, 'glnormalx', text="X")
+                row.prop(segment, 'glnormaly', text="Y")
+                row.prop(segment, 'glnormalz', text="Z")
+
+        # Loc axis
+        if segment.gltype != 2 and segment.gltype != 10 \
+                and segment.gltype != 12 and segment.gltype != 13 and segment.gltype != 14 and segment.gltype != 20:
+            row = box.row(True)
+            row.prop(segment, 'glocx', text="X", toggle=True)
+            row.prop(segment, 'glocy', text="Y", toggle=True)
+            row.prop(segment, 'glocz', text="Z", toggle=True)
+            if segment.glocx is False or segment.glocy is False or segment.glocz is False:
+                row = box.row()
+                if segment.gltype == 1:
+                    row.prop(segment, 'glorto', text="Orthogonal")
+                row.prop(segment, 'glocwarning', text="Warning")
+                # ortogonal (only segments)
+                if segment.gltype == 1:
+                    if segment.glorto != "99":
+                        row = box.row(True)
+                        row.prop(segment, 'glorto_x', text="X", toggle=True)
+                        row.prop(segment, 'glorto_y', text="Y", toggle=True)
+                        row.prop(segment, 'glorto_z', text="Z", toggle=True)
+
+        # Arc special
+        if segment.gltype == 11:
+            row = box.row(True)
+            row.prop(segment, 'glarc_rad', text="Radius")
+            row.prop(segment, 'glarc_len', text="Length")
+            row.prop(segment, 'glarc_ang', text="Angle")
+
+            row = box.row(True)
+            row.prop(segment, 'glarc_txradio', text="")
+            row.prop(segment, 'glarc_txlen', text="")
+            row.prop(segment, 'glarc_txang', text="")
+            row = box.row(True)
+            row.prop(segment, 'glarc_full', text="Full Circle")
+            if segment.glarc_rad is True:
+                row.prop(segment, 'glarc_extrad', text="Adapt radio")
+
+            row = box.row(True)
+            row.prop(segment, 'glarc_a', text="")
+            row.prop(segment, 'glarc_b', text="")
+            row.prop(segment, 'glarc_s', text="Size")
+
+        # Area special
+        if segment.gltype == 20:
+            row = box.row(True)
+            row.prop(segment, 'glcolorarea', text="")
+
+
+# ------------------------------------------------------------------
+# Define panel class for main functions.
+# ------------------------------------------------------------------
+class MeasureitMainPanel(bpy.types.Panel):
+    bl_idname = "measureit_main_panel"
+    bl_label = "Tools"
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = "TOOLS"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Draw UI
+    # ------------------------------
+    def draw(self, context):
+        layout = self.layout
+        scene = context.scene
+
+        # ------------------------------
+        # Tool Buttons
+        # ------------------------------
+        box = layout.box()
+        # ------------------------------
+        # Display Buttons
+        # ------------------------------
+        row = box.row()
+        if context.window_manager.measureit_run_opengl is False:
+            icon = 'PLAY'
+            txt = 'Show'
+        else:
+            icon = "PAUSE"
+            txt = 'Hide'
+
+        row.operator("measureit.runopenglbutton", text=txt, icon=icon)
+        row.prop(scene, "measureit_gl_ghost", text="", icon='GHOST_ENABLED')
+
+        # Tools
+        box = layout.box()
+        row = box.row()
+        row.operator("measureit.addsegmentbutton", text="Segment", icon="ALIGN")
+        row.prop(scene, "measureit_sum", text="Sum")
+
+        # To origin
+        row = box.row()
+        op = row.operator("measureit.addsegmentortobutton", text="X", icon="ALIGN")
+        op.tag = 0  # saves internal data
+        op = row.operator("measureit.addsegmentortobutton", text="Y", icon="ALIGN")
+        op.tag = 1  # saves internal data
+        op = row.operator("measureit.addsegmentortobutton", text="Z", icon="ALIGN")
+        op.tag = 2  # saves internal data
+
+        row = box.row()
+        row.operator("measureit.addanglebutton", text="Angle", icon="LINCURVE")
+        row.operator("measureit.addarcbutton", text="Arc", icon="MAN_ROT")
+
+        row = box.row()
+        row.operator("measureit.addlabelbutton", text="Label", icon="FONT_DATA")
+        row.operator("measureit.addnotebutton", text="Annotation", icon="NEW")
+
+        row = box.row()
+        row.operator("measureit.addlinkbutton", text="Link", icon="ROTATECENTER")
+        row.operator("measureit.addoriginbutton", text="Origin", icon="CURSOR")
+
+        row = box.row()
+        row.operator("measureit.addareabutton", text="Area", icon="MESH_GRID")
+
+        # ------------------------------
+        # Debug data
+        # ------------------------------
+        box = layout.box()
+        row = box.row(False)
+        if scene.measureit_debug is False:
+            row.prop(scene, "measureit_debug", icon="TRIA_RIGHT",
+                     text="Mesh Debug", emboss=False)
+        else:
+            row.prop(scene, "measureit_debug", icon="TRIA_DOWN",
+                     text="Mesh Debug", emboss=False)
+
+            row = box.row()
+            row.prop(scene, "measureit_debug_vertices", icon="LOOPSEL")
+            row.prop(scene, "measureit_debug_location", icon="EMPTY_DATA")
+            row.prop(scene, "measureit_debug_faces", icon="FACESEL")
+            row = box.row()
+            row.prop(scene, "measureit_debug_select", icon="GHOST_ENABLED")
+            row.prop(scene, "measureit_debug_normals", icon="MAN_TRANS")
+            if scene.measureit_debug_normals is True:
+                row.prop(scene, "measureit_debug_normal_size")
+                row.prop(scene, "measureit_debug_normal_details")
+            row = box.row()
+            row.prop(scene, 'measureit_debug_color', text="")
+            row.prop(scene, 'measureit_debug_color2', text="")
+            row.prop(scene, 'measureit_debug_color3', text="")
+            row = box.row()
+            row.prop(scene, 'measureit_debug_font', text="Font")
+            row.prop(scene, 'measureit_debug_width', text="Thickness")
+            row.prop(scene, 'measureit_debug_precision', text="Precision")
+
+
+# ------------------------------------------------------------------
+# Define panel class for conf functions.
+# ------------------------------------------------------------------
+class MeasureitConfPanel(bpy.types.Panel):
+    bl_idname = "measureit_conf_panel"
+    bl_label = "Configuration"
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = "TOOLS"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Draw UI
+    # ------------------------------
+    def draw(self, context):
+        layout = self.layout
+        scene = context.scene
+
+        # Configuration data
+        box = layout.box()
+        row = box.row()
+        row.prop(scene, "measureit_gl_txt", text="Text")
+        row = box.row()
+        row.prop(scene, "measureit_default_color", text="")
+        row.prop(scene, "measureit_hint_space")
+        # Arrow
+        row = box.row(True)
+        row.prop(scene, "measureit_glarrow_a", text="")
+        row.prop(scene, "measureit_glarrow_b", text="")
+        row.prop(scene, "measureit_glarrow_s", text="Size")
+
+        row = box.row()
+        row.prop(scene, "measureit_font_size")
+
+
+# ------------------------------------------------------------------
+# Define panel class for render functions.
+# ------------------------------------------------------------------
+class MeasureitRenderPanel(bpy.types.Panel):
+    bl_idname = "measureit_render_panel"
+    bl_label = "Render"
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = "TOOLS"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Draw UI
+    # ------------------------------
+    def draw(self, context):
+        layout = self.layout
+        scene = context.scene
+
+        # Render settings
+        box = layout.box()
+        row = box.row()
+        row.prop(scene, "measureit_render_type")
+        row = box.row()
+        row.operator("measureit.rendersegmentbutton", icon='SCRIPT')
+        row = box.row()
+        row.prop(scene, "measureit_render", text="Save render image")
+        row = box.row()
+        row.prop(scene, "measureit_rf", text="Frame")
+        if scene.measureit_rf is True:
+            row.prop(scene, "measureit_rf_color", text="Color")
+            row = box.row()
+            row.prop(scene, "measureit_rf_border", text="Space")
+            row.prop(scene, "measureit_rf_line", text="Width")
+
+
+# -------------------------------------------------------------
+# Defines button for add a measure segment
+#
+# -------------------------------------------------------------
+class AddSegmentButton(bpy.types.Operator):
+    bl_idname = "measureit.addsegmentbutton"
+    bl_label = "Add"
+    bl_description = "(EDITMODE only) Add a new measure segment between 2 vertices (select 2 vertices or more)"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        else:
+            if o.type == "MESH":
+                if bpy.context.mode == 'EDIT_MESH':
+                    return True
+                else:
+                    return False
+            else:
+                return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            scene = context.scene
+            mainobject = context.object
+            mylist = get_smart_selected(mainobject)
+            if len(mylist) < 2:  # if not selected linked vertex
+                mylist = get_selected_vertex(mainobject)
+
+            if len(mylist) >= 2:
+                if 'MeasureGenerator' not in mainobject:
+                    mainobject.MeasureGenerator.add()
+
+                mp = mainobject.MeasureGenerator[0]
+                for x in range(0, len(mylist) - 1, 2):
+                    # -----------------------
+                    # Only if not exist
+                    # -----------------------
+                    if exist_segment(mp, mylist[x], mylist[x + 1]) is False:
+                        # Create all array elements
+                        for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
+                            mp.measureit_segments.add()
+
+                        # Set values
+                        ms = mp.measureit_segments[mp.measureit_num]
+                        ms.gltype = 1
+                        ms.glpointa = mylist[x]
+                        ms.glpointb = mylist[x + 1]
+                        ms.glarrow_a = scene.measureit_glarrow_a
+                        ms.glarrow_b = scene.measureit_glarrow_b
+                        ms.glarrow_s = scene.measureit_glarrow_s
+                        # color
+                        ms.glcolor = scene.measureit_default_color
+                        # dist
+                        ms.glspace = scene.measureit_hint_space
+                        # text
+                        ms.gltxt = scene.measureit_gl_txt
+                        ms.glfont_size = scene.measureit_font_size
+                        # Sum group
+                        ms.gltot = scene.measureit_sum
+                        # Add index
+                        mp.measureit_num += 1
+
+                # redraw
+                context.area.tag_redraw()
+                return {'FINISHED'}
+            else:
+                self.report({'ERROR'},
+                            "MeasureIt: Select at least two vertices for creating measure segment.")
+                return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for add area measure
+#
+# -------------------------------------------------------------
+class AddAreaButton(bpy.types.Operator):
+    bl_idname = "measureit.addareabutton"
+    bl_label = "Area"
+    bl_description = "(EDITMODE only) Add a new measure for area (select 1 o more faces)"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        else:
+            if o.type == "MESH":
+                if bpy.context.mode == 'EDIT_MESH':
+                    return True
+                else:
+                    return False
+            else:
+                return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            scene = context.scene
+            mainobject = context.object
+            mylist = get_selected_faces(mainobject)
+            if len(mylist) >= 1:
+                if 'MeasureGenerator' not in mainobject:
+                    mainobject.MeasureGenerator.add()
+
+                mp = mainobject.MeasureGenerator[0]
+                mp.measureit_segments.add()
+                ms = mp.measureit_segments[mp.measureit_num]
+                ms.gltype = 20
+
+                f = -1
+                for face in mylist:
+                    # Create array elements
+                    ms.measureit_faces.add()
+                    f += 1
+                    # Set values
+                    mf = ms.measureit_faces[f]
+                    mf.glface = f
+                    i = 0
+                    for v in face:
+                        mf.measureit_index.add()
+                        mi = mf.measureit_index[i]
+                        mi.glidx = v
+                        i += 1
+
+                # color
+                rgb = scene.measureit_default_color
+                ms.glcolor = (rgb[0], rgb[1], rgb[2], 0.4)
+                # dist
+                ms.glspace = scene.measureit_hint_space
+                # text
+                ms.gltxt = scene.measureit_gl_txt
+                ms.glfont_size = scene.measureit_font_size
+                # Sum group
+                ms.gltot = scene.measureit_sum
+                # Add index
+                mp.measureit_num += 1
+                # redraw
+                context.area.tag_redraw()
+                return {'FINISHED'}
+            else:
+                self.report({'ERROR'},
+                            "MeasureIt: Select at least one face for creating area measure. ")
+                return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for add a measure segment to x/y/z origin
+#
+# -------------------------------------------------------------
+class AddSegmentOrtoButton(bpy.types.Operator):
+    bl_idname = "measureit.addsegmentortobutton"
+    bl_label = "Add"
+    bl_description = "(EDITMODE only) Add a new measure segment from vertex to object origin for one " \
+                     "axis (select 1 vertex)"
+    bl_category = 'Measureit'
+    tag = bpy.props.IntProperty()
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        else:
+            if o.type == "MESH":
+                if bpy.context.mode == 'EDIT_MESH':
+                    return True
+                else:
+                    return False
+            else:
+                return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            scene = context.scene
+            mainobject = context.object
+            mylist = get_smart_selected(mainobject)
+            if len(mylist) < 1:  # if not selected linked vertex
+                mylist = get_selected_vertex(mainobject)
+
+            if len(mylist) >= 1:
+                if 'MeasureGenerator' not in mainobject:
+                    mainobject.MeasureGenerator.add()
+
+                mp = mainobject.MeasureGenerator[0]
+                for x in range(0, len(mylist)):
+                    # -----------------------
+                    # Only if not exist
+                    # -----------------------
+                    if exist_segment(mp, mylist[x], mylist[x], 12 + int(self.tag)) is False:
+                        # Create all array elements
+                        for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
+                            mp.measureit_segments.add()
+
+                        # Set values
+                        ms = mp.measureit_segments[mp.measureit_num]
+                        ms.gltype = 12 + int(self.tag)
+                        ms.glpointa = mylist[x]
+                        ms.glpointb = mylist[x]
+                        ms.glarrow_a = scene.measureit_glarrow_a
+                        ms.glarrow_b = scene.measureit_glarrow_b
+                        ms.glarrow_s = scene.measureit_glarrow_s
+                        # color
+                        ms.glcolor = scene.measureit_default_color
+                        # dist
+                        ms.glspace = scene.measureit_hint_space
+                        # text
+                        ms.gltxt = scene.measureit_gl_txt
+                        ms.glfont_size = scene.measureit_font_size
+                        # Sum group
+                        ms.gltot = scene.measureit_sum
+                        # Add index
+                        mp.measureit_num += 1
+
+                # redraw
+                context.area.tag_redraw()
+                return {'FINISHED'}
+            else:
+                self.report({'ERROR'},
+                            "MeasureIt: Select at least one vertex for creating measure segment.")
+                return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for add a angle
+#
+# -------------------------------------------------------------
+class AddAngleButton(bpy.types.Operator):
+    bl_idname = "measureit.addanglebutton"
+    bl_label = "Angle"
+    bl_description = "(EDITMODE only) Add a new angle measure (select 3 vertices, 2nd is angle vertex)"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        else:
+            if o.type == "MESH":
+                if bpy.context.mode == 'EDIT_MESH':
+                    return True
+                else:
+                    return False
+            else:
+                return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            scene = context.scene
+            mainobject = context.object
+            mylist = get_selected_vertex_history(mainobject)
+            if len(mylist) == 3:
+                if 'MeasureGenerator' not in mainobject:
+                    mainobject.MeasureGenerator.add()
+
+                mp = mainobject.MeasureGenerator[0]
+                # -----------------------
+                # Only if not exist
+                # -----------------------
+                if exist_segment(mp, mylist[0], mylist[1], 9, mylist[2]) is False:
+                    # Create all array elements
+                    for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
+                        mp.measureit_segments.add()
+
+                    # Set values
+                    ms = mp.measureit_segments[mp.measureit_num]
+                    ms.gltype = 9
+                    ms.glpointa = mylist[0]
+                    ms.glpointb = mylist[1]
+                    ms.glpointc = mylist[2]
+                    # color
+                    ms.glcolor = scene.measureit_default_color
+                    # dist
+                    ms.glspace = scene.measureit_hint_space
+                    # text
+                    ms.gltxt = scene.measureit_gl_txt
+                    ms.glfont_size = scene.measureit_font_size
+                    # Add index
+                    mp.measureit_num += 1
+
+                # redraw
+                context.area.tag_redraw()
+                return {'FINISHED'}
+            else:
+                self.report({'ERROR'},
+                            "MeasureIt: Select three vertices for creating angle measure")
+                return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for add a arc
+#
+# -------------------------------------------------------------
+class AddArcButton(bpy.types.Operator):
+    bl_idname = "measureit.addarcbutton"
+    bl_label = "Angle"
+    bl_description = "(EDITMODE only) Add a new arc measure (select 3 vertices of the arc," \
+                     " vertices 1st and 3rd are arc extremes)"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        else:
+            if o.type == "MESH":
+                if bpy.context.mode == 'EDIT_MESH':
+                    return True
+                else:
+                    return False
+            else:
+                return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            scene = context.scene
+            mainobject = context.object
+            mylist = get_selected_vertex_history(mainobject)
+            if len(mylist) == 3:
+                if 'MeasureGenerator' not in mainobject:
+                    mainobject.MeasureGenerator.add()
+
+                mp = mainobject.MeasureGenerator[0]
+                # -----------------------
+                # Only if not exist
+                # -----------------------
+                if exist_segment(mp, mylist[0], mylist[1], 11, mylist[2]) is False:
+                    # Create all array elements
+                    for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
+                        mp.measureit_segments.add()
+
+                    # Set values
+                    ms = mp.measureit_segments[mp.measureit_num]
+                    ms.gltype = 11
+                    ms.glpointa = mylist[0]
+                    ms.glpointb = mylist[1]
+                    ms.glpointc = mylist[2]
+                    ms.glarrow_a = scene.measureit_glarrow_a
+                    ms.glarrow_b = scene.measureit_glarrow_b
+                    ms.glarrow_s = scene.measureit_glarrow_s
+                    # color
+                    ms.glcolor = scene.measureit_default_color
+                    # dist
+                    ms.glspace = scene.measureit_hint_space
+                    # text
+                    ms.gltxt = scene.measureit_gl_txt
+                    ms.glfont_size = scene.measureit_font_size
+                    # Add index
+                    mp.measureit_num += 1
+
+                # redraw
+                context.area.tag_redraw()
+                return {'FINISHED'}
+            else:
+                self.report({'ERROR'},
+                            "MeasureIt: Select three vertices for creating arc measure")
+                return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for add a label segment
+#
+# -------------------------------------------------------------
+class AddLabelButton(bpy.types.Operator):
+    bl_idname = "measureit.addlabelbutton"
+    bl_label = "Add"
+    bl_description = "(EDITMODE only) Add a new measure label (select 1 vertex)"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        else:
+            if o.type == "MESH":
+                if bpy.context.mode == 'EDIT_MESH':
+                    return True
+                else:
+                    return False
+            else:
+                return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            scene = context.scene
+            mainobject = context.object
+            mylist = get_selected_vertex(mainobject)
+            if len(mylist) == 1:
+                if 'MeasureGenerator' not in mainobject:
+                    mainobject.MeasureGenerator.add()
+
+                mp = mainobject.MeasureGenerator[0]
+                # -----------------------
+                # Only if not exist
+                # -----------------------
+                if exist_segment(mp, mylist[0], mylist[0], 2) is False:  # Both equal
+                    # Create all array elements
+                    for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
+                        mp.measureit_segments.add()
+
+                    # Set values
+                    ms = mp.measureit_segments[mp.measureit_num]
+                    ms.gltype = 2
+                    ms.glpointa = mylist[0]
+                    ms.glpointb = mylist[0]  # Equal
+                    ms.glarrow_a = scene.measureit_glarrow_a
+                    ms.glarrow_b = scene.measureit_glarrow_b
+                    ms.glarrow_s = scene.measureit_glarrow_s
+                    # color
+                    ms.glcolor = scene.measureit_default_color
+                    # dist
+                    ms.glspace = scene.measureit_hint_space
+                    # text
+                    ms.gltxt = scene.measureit_gl_txt
+                    ms.glfont_size = scene.measureit_font_size
+                    # Add index
+                    mp.measureit_num += 1
+
+                # redraw
+                context.area.tag_redraw()
+                return {'FINISHED'}
+            else:
+                self.report({'ERROR'},
+                            "MeasureIt: Select one vertex for creating measure label")
+                return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for add a link
+#
+# -------------------------------------------------------------
+class AddLinkButton(bpy.types.Operator):
+    bl_idname = "measureit.addlinkbutton"
+    bl_label = "Add"
+    bl_description = "(OBJECT mode only) Add a new measure between objects (select 2 " \
+                     "objects and optionally 1 or 2 vertices)"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        else:
+            if o.type == "MESH" or o.type == "EMPTY" or o.type == "CAMERA" or o.type == "LAMP":
+                if bpy.context.mode == 'OBJECT':
+                    return True
+                else:
+                    return False
+            else:
+                return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            scene = context.scene
+            mainobject = context.object
+            # -------------------------------
+            # Verify number of objects
+            # -------------------------------
+            if len(context.selected_objects) != 2:
+                self.report({'ERROR'},
+                            "MeasureIt: Select two objects only, and optionally 1 vertex or 2 vertices "
+                            "(one of each object)")
+                return {'FINISHED'}
+            # Locate other object
+            linkobject = None
+            for o in context.selected_objects:
+                if o.name != mainobject.name:
+                    linkobject = o.name
+            # Verify destination vertex
+            lkobj = bpy.data.objects[linkobject]
+            mylinkvertex = get_selected_vertex(lkobj)
+            if len(mylinkvertex) > 1:
+                self.report({'ERROR'},
+                            "MeasureIt: The destination object has more than one vertex selected. "
+                            "Select only 1 or none")
+                return {'FINISHED'}
+            # Verify origin vertex
+            myobjvertex = get_selected_vertex(mainobject)
+            if len(mylinkvertex) > 1:
+                self.report({'ERROR'},
+                            "MeasureIt: The active object has more than one vertex selected. Select only 1 or none")
+                return {'FINISHED'}
+
+            # -------------------------------
+            # Add properties
+            # -------------------------------
+            flag = False
+            if 'MeasureGenerator' not in mainobject:
+                mainobject.MeasureGenerator.add()
+
+            mp = mainobject.MeasureGenerator[0]
+
+            # if exist_segment(mp, mylist[0], mylist[0], 3) is False:
+            #     flag = True
+            # Create all array elements
+            for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
+                mp.measureit_segments.add()
+
+            # Set values
+            ms = mp.measureit_segments[mp.measureit_num]
+            # -----------------------
+            # Vertex to Vertex
+            # -----------------------
+            if len(myobjvertex) == 1 and len(mylinkvertex) == 1:
+                ms.gltype = 3
+                ms.glpointa = myobjvertex[0]
+                ms.glpointb = mylinkvertex[0]
+                flag = True
+            # -----------------------
+            # Vertex to Object
+            # -----------------------
+            if len(myobjvertex) == 1 and len(mylinkvertex) == 0:
+                ms.gltype = 4
+                ms.glpointa = myobjvertex[0]
+                ms.glpointb = 0
+                flag = True
+            # -----------------------
+            # Object to Vertex
+            # -----------------------
+            if len(myobjvertex) == 0 and len(mylinkvertex) == 1:
+                ms.gltype = 5
+                ms.glpointa = 0
+                ms.glpointb = mylinkvertex[0]
+                flag = True
+            # -----------------------
+            # Object to Object
+            # -----------------------
+            if len(myobjvertex) == 0 and len(mylinkvertex) == 0:
+                ms.gltype = 8
+                ms.glpointa = 0
+                ms.glpointb = 0  # Equal
+                flag = True
+
+            # ------------------
+            # only if created
+            # ------------------
+            if flag is True:
+                ms.glarrow_a = scene.measureit_glarrow_a
+                ms.glarrow_b = scene.measureit_glarrow_b
+                ms.glarrow_s = scene.measureit_glarrow_s
+                # color
+                ms.glcolor = scene.measureit_default_color
+                # dist
+                ms.glspace = scene.measureit_hint_space
+                # text
+                ms.gltxt = scene.measureit_gl_txt
+                ms.glfont_size = scene.measureit_font_size
+                # link
+                ms.gllink = linkobject
+                # Add index
+                mp.measureit_num += 1
+
+                # -----------------------
+                # Only if not exist
+                # -----------------------
+                # redraw
+                context.area.tag_redraw()
+                return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for add a origin segment
+#
+# -------------------------------------------------------------
+class AddOriginButton(bpy.types.Operator):
+    bl_idname = "measureit.addoriginbutton"
+    bl_label = "Add"
+    bl_description = "(OBJECT mode only) Add a new measure to origin (select object and optionally 1 vertex)"
+    bl_category = 'Measureit'
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    @classmethod
+    def poll(cls, context):
+        o = context.object
+        if o is None:
+            return False
+        else:
+            if o.type == "MESH" or o.type == "EMPTY" or o.type == "CAMERA" or o.type == "LAMP":
+                if bpy.context.mode == 'OBJECT':
+                    return True
+                else:
+                    return False
+            else:
+                return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            scene = context.scene
+            mainobject = context.object
+            mylist = get_selected_vertex(mainobject)
+            if 'MeasureGenerator' not in mainobject:
+                mainobject.MeasureGenerator.add()
+
+            mp = mainobject.MeasureGenerator[0]
+            # Create all array elements
+            for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
+                mp.measureit_segments.add()
+
+            # -----------------------
+            # Set values
+            # -----------------------
+            ms = mp.measureit_segments[mp.measureit_num]
+            flag = False
+            if len(mylist) > 0:
+                if len(mylist) == 1:
+                    if exist_segment(mp, mylist[0], mylist[0], 6) is False:  # Both equal
+                        flag = True
+                        # Vertex to origin
+                        ms.gltype = 6
+                        ms.glpointa = mylist[0]
+                        ms.glpointb = mylist[0]
+                else:
+                    self.report({'ERROR'},
+                                "MeasureIt: Enter in EDITMODE and select one vertex only for creating "
+                                "measure from vertex to origin")
+                    return {'FINISHED'}
+            else:
+                # Object to origin
+                if exist_segment(mp, 0, 0, 7) is False:  # Both equal
+                    flag = True
+                    ms.gltype = 7
+                    ms.glpointa = 0
+                    ms.glpointb = 0
+            # ------------------
+            # only if created
+            # ------------------
+            if flag is True:
+                ms.glarrow_a = scene.measureit_glarrow_a
+                ms.glarrow_b = scene.measureit_glarrow_b
+                ms.glarrow_s = scene.measureit_glarrow_s
+                # color
+                ms.glcolor = scene.measureit_default_color
+                # dist
+                ms.glspace = scene.measureit_hint_space
+                # text
+                ms.gltxt = scene.measureit_gl_txt
+                ms.glfont_size = scene.measureit_font_size
+                # Add index
+                mp.measureit_num += 1
+
+            # redraw
+            context.area.tag_redraw()
+
+            return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for delete a measure segment
+#
+# -------------------------------------------------------------
+class DeleteSegmentButton(bpy.types.Operator):
+    bl_idname = "measureit.deletesegmentbutton"
+    bl_label = "Delete"
+    bl_description = "Delete a measure"
+    bl_category = 'Measureit'
+    tag = bpy.props.IntProperty()
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            mainobject = context.object
+            mp = mainobject.MeasureGenerator[0]
+            ms = mp.measureit_segments[self.tag]
+            ms.glfree = True
+            # Delete element
+            mp.measureit_segments.remove(self.tag)
+            mp.measureit_num -= 1
+            # redraw
+            context.area.tag_redraw()
+            return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for delete all measure segment
+#
+# -------------------------------------------------------------
+class DeleteAllSegmentButton(bpy.types.Operator):
+    bl_idname = "measureit.deleteallsegmentbutton"
+    bl_label = "Delete"
+    bl_description = "Delete all measures (it cannot be undone)"
+    bl_category = 'Measureit'
+    tag = bpy.props.IntProperty()
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            # Add properties
+            mainobject = context.object
+            mp = mainobject.MeasureGenerator[0]
+
+            while len(mp.measureit_segments) > 0:
+                mp.measureit_segments.remove(0)
+
+            # reset size
+            mp.measureit_num = len(mp.measureit_segments)
+            # redraw
+            context.area.tag_redraw()
+            return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for delete all measure segment
+#
+# -------------------------------------------------------------
+class DeleteAllSumButton(bpy.types.Operator):
+    bl_idname = "measureit.deleteallsumbutton"
+    bl_label = "Delete"
+    bl_description = "Delete all sum groups"
+    bl_category = 'Measureit'
+    tag = bpy.props.IntProperty()
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    # noinspection PyMethodMayBeStatic
+    def execute(self, context):
+        if context.object is not None:
+            if 'MeasureGenerator' in context.object:
+                mp = context.object.MeasureGenerator[0]
+                for idx in range(0, mp.measureit_num):
+                    ms = mp.measureit_segments[idx]
+                    ms.gltot = '99'
+
+            return {'FINISHED'}
+
+
+# -------------------------------------------------------------
+# Defines button for render
+#
+# -------------------------------------------------------------
+class RenderSegmentButton(bpy.types.Operator):
+    bl_idname = "measureit.rendersegmentbutton"
+    bl_label = "Render"
+    bl_description = "Create a render image with measures. Use UV/Image editor to view image generated"
+    bl_category = 'Measureit'
+    tag = bpy.props.IntProperty()
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    # noinspection PyMethodMayBeStatic,PyUnusedLocal
+    def execute(self, context):
+        scene = context.scene
+        msg = "New image created with measures. Open it in UV/image editor"
+        camera_msg = "Unable to render. No camera found"
+        # -----------------------------
+        # Check camera
+        # -----------------------------
+        if scene.camera is None:
+            self.report({'ERROR'}, camera_msg)
+            return {'FINISHED'}
+        # -----------------------------
+        # Use default render
+        # -----------------------------
+        if scene.measureit_render_type == "1":
+            # noinspection PyBroadException
+            try:
+                result = bpy.data.images['Render Result']
+                if result.has_data is False:
+                    bpy.ops.render.render()
+            except:
+                bpy.ops.render.render()
+            print("MeasureIt: Using current render image on buffer")
+            if render_main(self, context) is True:
+                self.report({'INFO'}, msg)
+
+        # -----------------------------
+        # OpenGL image
+        # -----------------------------
+        if scene.measureit_render_type == "2":
+            self.set_camera_view()
+            self.set_only_render(True)
+
+            print("MeasureIt: Rendering opengl image")
+            bpy.ops.render.opengl()
+            if render_main(self, context) is True:
+                self.report({'INFO'}, msg)
+
+            self.set_only_render(False)
+
+        # -----------------------------
+        # OpenGL Animation
+        # -----------------------------
+        if scene.measureit_render_type == "3":
+            oldframe = scene.frame_current
+            self.set_camera_view()
+            self.set_only_render(True)
+            flag = False
+            # loop frames
+            for frm in range(scene.frame_start, scene.frame_end + 1):
+                scene.frame_set(frm)
+                print("MeasureIt: Rendering opengl frame %04d" % frm)
+                bpy.ops.render.opengl()
+                flag = render_main(self, context, True)
+                if flag is False:
+                    break
+
+            self.set_only_render(False)
+            scene.frame_current = oldframe
+            if flag is True:
+                self.report({'INFO'}, msg)
+
+        # -----------------------------
+        # Image
+        # -----------------------------
+        if scene.measureit_render_type == "4":
+            print("MeasureIt: Rendering image")
+            bpy.ops.render.render()
+            if render_main(self, context) is True:
+                self.report({'INFO'}, msg)
+
+        # -----------------------------
+        # Animation
+        # -----------------------------
+        if scene.measureit_render_type == "5":
+            oldframe = scene.frame_current
+            flag = False
+            # loop frames
+            for frm in range(scene.frame_start, scene.frame_end + 1):
+                scene.frame_set(frm)
+                print("MeasureIt: Rendering frame %04d" % frm)
+                bpy.ops.render.render()
+                flag = render_main(self, context, True)
+                if flag is False:
+                    break
+
+            scene.frame_current = oldframe
+            if flag is True:
+                self.report({'INFO'}, msg)
+
+        return {'FINISHED'}
+
+    # ---------------------
+    # Set cameraView
+    # ---------------------
+    # noinspection PyMethodMayBeStatic
+    def set_camera_view(self):
+        for area in bpy.context.screen.areas:
+            if area.type == 'VIEW_3D':
+                area.spaces[0].region_3d.view_perspective = 'CAMERA'
+
+    # -------------------------------------
+    # Set only render status
+    # -------------------------------------
+    # noinspection PyMethodMayBeStatic
+    def set_only_render(self, status):
+        screen = bpy.context.screen
+
+        v3d = False
+        s = None
+        # get spaceview_3d in current screen
+        for a in screen.areas:
+            if a.type == 'VIEW_3D':
+                for s in a.spaces:
+                    if s.type == 'VIEW_3D':
+                        v3d = s
+                        break
+
+        if v3d is not False:
+            s.show_only_render = status
+
+
+# -------------------------------------------------------------
+# Defines a new note
+#
+# -------------------------------------------------------------
+class AddNoteButton(bpy.types.Operator):
+    bl_idname = "measureit.addnotebutton"
+    bl_label = "Note"
+    bl_description = "(OBJECT mode only) Add a new annotation"
+    bl_category = 'Measureit'
+    tag = bpy.props.IntProperty()
+
+    # ------------------------------
+    # Poll
+    # ------------------------------
+    # noinspection PyUnusedLocal
+    @classmethod
+    def poll(cls, context):
+        if bpy.context.mode == 'OBJECT':
+            return True
+        else:
+            return False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            bpy.ops.object.empty_add(type='PLAIN_AXES')
+            myempty = bpy.data.objects[bpy.context.active_object.name]
+            myempty.location = bpy.context.scene.cursor_location
+            myempty.empty_draw_size = 0.01
+            myempty.name = "Annotation"
+            # Add properties
+            scene = context.scene
+            mainobject = myempty
+            if 'MeasureGenerator' not in mainobject:
+                mainobject.MeasureGenerator.add()
+
+            mp = mainobject.MeasureGenerator[0]
+            # Create all array elements
+            for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
+                mp.measureit_segments.add()
+
+            # Set values
+            ms = mp.measureit_segments[mp.measureit_num]
+            ms.gltype = 10
+            ms.glpointa = 0
+            ms.glpointb = 0  # Equal
+            # color
+            ms.glcolor = scene.measureit_default_color
+            # dist
+            ms.glspace = scene.measureit_hint_space
+            # text
+            ms.gltxt = scene.measureit_gl_txt
+            ms.glfont_size = scene.measureit_font_size
+            # Add index
+            mp.measureit_num += 1
+
+            # redraw
+            context.area.tag_redraw()
+            return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Defines button for enable/disable the tip display
+#
+# -------------------------------------------------------------
+class RunHintDisplayButton(bpy.types.Operator):
+    bl_idname = "measureit.runopenglbutton"
+    bl_label = "Display hint data manager"
+    bl_description = "Main control for enabling or disabling the display of measurements in the viewport"
+    bl_category = 'Measureit'
+
+    _handle = None  # keep function handler
+
+    # ----------------------------------
+    # Enable gl drawing adding handler
+    # ----------------------------------
+    @staticmethod
+    def handle_add(self, context):
+        if RunHintDisplayButton._handle is None:
+            RunHintDisplayButton._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (self, context),
+                                                                                  'WINDOW',
+                                                                                  'POST_PIXEL')
+            context.window_manager.measureit_run_opengl = True
+
+    # ------------------------------------
+    # Disable gl drawing removing handler
+    # ------------------------------------
+    # noinspection PyUnusedLocal
+    @staticmethod
+    def handle_remove(self, context):
+        if RunHintDisplayButton._handle is not None:
+            bpy.types.SpaceView3D.draw_handler_remove(RunHintDisplayButton._handle, 'WINDOW')
+        RunHintDisplayButton._handle = None
+        context.window_manager.measureit_run_opengl = False
+
+    # ------------------------------
+    # Execute button action
+    # ------------------------------
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            if context.window_manager.measureit_run_opengl is False:
+                self.handle_add(self, context)
+                context.area.tag_redraw()
+            else:
+                self.handle_remove(self, context)
+                context.area.tag_redraw()
+
+            return {'FINISHED'}
+        else:
+            self.report({'WARNING'},
+                        "View3D not found, cannot run operator")
+
+        return {'CANCELLED'}
+
+
+# -------------------------------------------------------------
+# Handle all draw routines (OpenGL main entry point)
+#
+# -------------------------------------------------------------
+def draw_main(context):
+    region = bpy.context.region
+    # Detect if Quadview to get drawing area
+    if not context.space_data.region_quadviews:
+        rv3d = bpy.context.space_data.region_3d
+    else:
+        # verify area
+        if context.area.type != 'VIEW_3D' or context.space_data.type != 'VIEW_3D':
+            return
+        i = -1
+        for region in context.area.regions:
+            if region.type == 'WINDOW':
+                i += 1
+                if context.region.id == region.id:
+                    break
+        else:
+            return
+
+        rv3d = context.space_data.region_quadviews[i]
+
+    scene = bpy.context.scene
+    # Get visible layers
+    layers = []
+    for x in range(0, 20):
+        if bpy.context.scene.layers[x] is True:
+            layers.extend([x])
+
+    # Display selected or all
+    if scene.measureit_gl_ghost is False:
+        objlist = context.selected_objects
+    else:
+        objlist = context.scene.objects
+
+    # Enable GL drawing
+    bgl.glEnable(bgl.GL_BLEND)
+    # ---------------------------------------
+    # Generate all OpenGL calls for measures
+    # ---------------------------------------
+    for myobj in objlist:
+        if myobj.hide is False:
+            if 'MeasureGenerator' in myobj:
+                # verify visible layer
+                for x in range(0, 20):
+                    if myobj.layers[x] is True:
+                        if x in layers:
+                            op = myobj.MeasureGenerator[0]
+                            draw_segments(context, myobj, op, region, rv3d)
+                        break
+    # ---------------------------------------
+    # Generate all OpenGL calls for debug
+    # ---------------------------------------
+    if scene.measureit_debug is True:
+        selobj = bpy.context.selected_objects
+        for myobj in selobj:
+            if scene.measureit_debug_vertices is True:
+                draw_vertices(context, myobj, region, rv3d)
+            if scene.measureit_debug_faces is True or scene.measureit_debug_normals is True:
+                draw_faces(context, myobj, region, rv3d)
+
+    # -----------------------
+    # restore opengl defaults
+    # -----------------------
+    bgl.glLineWidth(1)
+    bgl.glDisable(bgl.GL_BLEND)
+    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+
+
+# -------------------------------------------------------------
+# Handler for drawing OpenGl
+# -------------------------------------------------------------
+# noinspection PyUnusedLocal
+def draw_callback_px(self, context):
+    draw_main(context)
+
+
+# -------------------------------------------------------------
+# Check if the segment already exist
+#
+# -------------------------------------------------------------
+def exist_segment(mp, pointa, pointb, typ=1, pointc=None):
+    #  for ms in mp.measureit_segments[mp.measureit_num]
+    for ms in mp.measureit_segments:
+        if ms.gltype == typ and ms.glfree is False:
+            if typ != 9:
+                if ms.glpointa == pointa and ms.glpointb == pointb:
+                    return True
+                if ms.glpointa == pointb and ms.glpointb == pointa:
+                    return True
+            else:
+                if ms.glpointa == pointa and ms.glpointb == pointb and ms.glpointc == pointc:
+                    return True
+
+    return False
+
+
+# -------------------------------------------------------------
+# Get vertex selected
+# -------------------------------------------------------------
+def get_selected_vertex(myobject):
+    mylist = []
+    # if not mesh, no vertex
+    if myobject.type != "MESH":
+        return mylist
+    # --------------------
+    # meshes
+    # --------------------
+    oldobj = bpy.context.object
+    bpy.context.scene.objects.active = myobject
+    flag = False
+    if myobject.mode != 'EDIT':
+        bpy.ops.object.mode_set(mode='EDIT')
+        flag = True
+
+    bm = bmesh.from_edit_mesh(myobject.data)
+    tv = len(bm.verts)
+    for v in bm.verts:
+        if v.select:
+            mylist.extend([v.index])
+
+    if flag is True:
+        bpy.ops.object.editmode_toggle()
+    # Back context object
+    bpy.context.scene.objects.active = oldobj
+
+    # if select all vertices, then use origin
+    if tv == len(mylist):
+        return []
+
+    return mylist
+
+
+# -------------------------------------------------------------
+# Get vertex selected
+# -------------------------------------------------------------
+def get_selected_vertex_history(myobject):
+    mylist = []
+    # if not mesh, no vertex
+    if myobject.type != "MESH":
+        return mylist
+    # --------------------
+    # meshes
+    # --------------------
+    oldobj = bpy.context.object
+    bpy.context.scene.objects.active = myobject
+    flag = False
+    if myobject.mode != 'EDIT':
+        bpy.ops.object.mode_set(mode='EDIT')
+        flag = True
+
+    bm = bmesh.from_edit_mesh(myobject.data)
+    for v in bm.select_history:
+        mylist.extend([v.index])
+
+    if flag is True:
+        bpy.ops.object.editmode_toggle()
+    # Back context object
+    bpy.context.scene.objects.active = oldobj
+
+    return mylist
+
+
+# -------------------------------------------------------------
+# Get vertex selected segments
+# -------------------------------------------------------------
+def get_smart_selected(myobject):
+    mylist = []
+    # if not mesh, no vertex
+    if myobject.type != "MESH":
+        return mylist
+    # --------------------
+    # meshes
+    # --------------------
+    oldobj = bpy.context.object
+    bpy.context.scene.objects.active = myobject
+    flag = False
+    if myobject.mode != 'EDIT':
+        bpy.ops.object.mode_set(mode='EDIT')
+        flag = True
+
+    bm = bmesh.from_edit_mesh(myobject.data)
+    for e in bm.edges:
+        if e.select is True:
+            mylist.extend([e.verts[0].index])
+            mylist.extend([e.verts[1].index])
+
+    if flag is True:
+        bpy.ops.object.editmode_toggle()
+    # Back context object
+    bpy.context.scene.objects.active = oldobj
+
+    return mylist
+
+
+# -------------------------------------------------------------
+# Get vertex selected faces
+# -------------------------------------------------------------
+def get_selected_faces(myobject):
+    mylist = []
+    # if not mesh, no vertex
+    if myobject.type != "MESH":
+        return mylist
+    # --------------------
+    # meshes
+    # --------------------
+    oldobj = bpy.context.object
+    bpy.context.scene.objects.active = myobject
+    flag = False
+    if myobject.mode != 'EDIT':
+        bpy.ops.object.mode_set(mode='EDIT')
+        flag = True
+
+    bm = bmesh.from_edit_mesh(myobject.data)
+    for e in bm.faces:
+        myface = []
+        if e.select is True:
+            for i in range(0, len(e.verts)):
+                myface.extend([e.verts[i].index])
+
+            mylist.extend([myface])
+
+    if flag is True:
+        bpy.ops.object.editmode_toggle()
+    # Back context object
+    bpy.context.scene.objects.active = oldobj
+
+    return mylist
diff --git a/measureit/measureit_render.py b/measureit/measureit_render.py
new file mode 100644
index 0000000000000000000000000000000000000000..6c9733df3d9cc20a44029d086f88e7dd41f021cc
--- /dev/null
+++ b/measureit/measureit_render.py
@@ -0,0 +1,343 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# ----------------------------------------------------------
+# support routines for render measures in final image
+# Author: Antonio Vazquez (antonioya)
+#
+# ----------------------------------------------------------
+# noinspection PyUnresolvedReferences
+import bpy
+# noinspection PyUnresolvedReferences
+import bgl
+# noinspection PyUnresolvedReferences
+import blf
+# noinspection PyUnresolvedReferences
+import mathutils
+# noinspection PyUnresolvedReferences
+import bmesh
+import os
+import sys
+# noinspection PyUnresolvedReferences
+import bpy_extras.image_utils as img_utils
+# noinspection PyUnresolvedReferences
+import bpy_extras.object_utils as object_utils
+# noinspection PyUnresolvedReferences
+from bpy_extras import view3d_utils
+from math import ceil
+from measureit_geometry import *
+
+
+# -------------------------------------------------------------
+# Render image main entry point
+#
+# -------------------------------------------------------------
+def render_main(self, context, animation=False):
+    # noinspection PyBroadException,PyBroadException
+    # Save old info
+    settings = bpy.context.scene.render.image_settings
+    depth = settings.color_depth
+    settings.color_depth = '8'
+    # noinspection PyBroadException
+    try:
+        # Get visible layers
+        layers = []
+        scene = context.scene
+        for x in range(0, 20):
+            if scene.layers[x] is True:
+                layers.extend([x])
+
+        # Get object list
+        objlist = context.scene.objects
+        # --------------------
+        # Get resolution
+        # --------------------
+        scene = bpy.context.scene
+        render_scale = scene.render.resolution_percentage / 100
+
+        width = int(scene.render.resolution_x * render_scale)
+        height = int(scene.render.resolution_y * render_scale)
+        # ---------------------------------------
+        # Get output path
+        # ---------------------------------------
+        ren_path = bpy.context.scene.render.filepath
+        if len(ren_path) > 0:
+            if ren_path.endswith(os.path.sep):
+                initpath = os.path.realpath(ren_path) + os.path.sep
+            else:
+                (initpath, filename) = os.path.split(ren_path)
+            outpath = os.path.join(initpath, "measureit_tmp_render.png")
+        else:
+            self.report({'ERROR'},
+                        "MeasureIt: Unable to save temporary render image. Define a valid render path")
+            settings.color_depth = depth
+            return False
+
+        # Get Render Image
+        img = get_render_image(outpath)
+        if img is None:
+            self.report({'ERROR'},
+                        "MeasureIt: Unable to save temporary render image. Define a valid render path")
+            settings.color_depth = depth
+            return False
+
+        # -----------------------------
+        # Calculate rows and columns
+        # -----------------------------
+        tile_x = 240
+        tile_y = 216
+        row_num = ceil(height / tile_y)
+        col_num = ceil(width / tile_x)
+        print("MeasureIt: Image divided in " + str(row_num) + "x" + str(col_num) + " tiles")
+
+        # pixels out of visible area
+        cut4 = (col_num * tile_x * 4) - width * 4  # pixels aout of drawing area
+        totpixel4 = width * height * 4  # total pixels RGBA
+
+        viewport_info = bgl.Buffer(bgl.GL_INT, 4)
+        bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info)
+
+        # Load image on memory
+        img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)
+
+        # 2.77 API change
+        if bpy.app.version >= (2, 77, 0):
+            tex = img.bindcode[0]
+        else:
+            tex = img.bindcode
+
+        # --------------------------------------------
+        # Create output image (to apply texture)
+        # --------------------------------------------
+        if "measureit_output" in bpy.data.images:
+            out_img = bpy.data.images["measureit_output"]
+            if out_img is not None:
+                out_img.user_clear()
+                bpy.data.images.remove(out_img)
+
+        out = bpy.data.images.new("measureit_output", width, height)
+        tmp_pixels = [1] * totpixel4
+
+        # --------------------------------
+        # Loop for all tiles
+        # --------------------------------
+        for row in range(0, row_num):
+            for col in range(0, col_num):
+                buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
+                bgl.glDisable(bgl.GL_SCISSOR_TEST)  # if remove this line, get blender screenshot not image
+                bgl.glViewport(0, 0, tile_x, tile_y)
+
+                bgl.glMatrixMode(bgl.GL_PROJECTION)
+                bgl.glLoadIdentity()
+
+                # defines ortographic view for single tile
+                x1 = tile_x * col
+                y1 = tile_y * row
+                bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y)
+
+                # Clear
+                bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
+                bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)
+
+                bgl.glEnable(bgl.GL_TEXTURE_2D)
+                bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)
+
+                # defines drawing area
+                bgl.glBegin(bgl.GL_QUADS)
+
+                bgl.glColor3f(1.0, 1.0, 1.0)
+                bgl.glTexCoord2f(0.0, 0.0)
+                bgl.glVertex2f(0.0, 0.0)
+
+                bgl.glTexCoord2f(1.0, 0.0)
+                bgl.glVertex2f(width, 0.0)
+
+                bgl.glTexCoord2f(1.0, 1.0)
+                bgl.glVertex2f(width, height)
+
+                bgl.glTexCoord2f(0.0, 1.0)
+                bgl.glVertex2f(0.0, height)
+
+                bgl.glEnd()
+
+                # -----------------------------
+                # Loop to draw all lines
+                # -----------------------------
+                for myobj in objlist:
+                    if myobj.hide is False:
+                        if 'MeasureGenerator' in myobj:
+                            # verify visible layer
+                            for x in range(0, 20):
+                                if myobj.layers[x] is True:
+                                    if x in layers:
+                                        op = myobj.MeasureGenerator[0]
+                                        draw_segments(context, myobj, op, None, None)
+                                    break
+
+                # -----------------------------
+                # Loop to draw all debug
+                # -----------------------------
+                if scene.measureit_debug is True:
+                    selobj = bpy.context.selected_objects
+                    for myobj in selobj:
+                        if scene.measureit_debug_vertices is True:
+                            draw_vertices(context, myobj, None, None)
+                        if scene.measureit_debug_faces is True or scene.measureit_debug_normals is True:
+                            draw_faces(context, myobj, None, None)
+
+                if scene.measureit_rf is True:
+                    bgl.glColor3f(1.0, 1.0, 1.0)
+                    rfcolor = scene.measureit_rf_color
+                    rfborder = scene.measureit_rf_border
+                    rfline = scene.measureit_rf_line
+
+                    bgl.glLineWidth(rfline)
+                    bgl.glColor4f(rfcolor[0], rfcolor[1], rfcolor[2], rfcolor[3])
+
+                    x1 = rfborder
+                    x2 = width - rfborder
+                    y1 = int(math.ceil(rfborder / (width / height)))
+                    y2 = height - y1
+                    draw_rectangle((x1, y1), (x2, y2))
+
+                # --------------------------------
+                # copy pixels to temporary area
+                # --------------------------------
+                bgl.glFinish()
+                bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer)  # read image data
+                for y in range(0, tile_y):
+                    # final image pixels position
+                    p1 = (y * width * 4) + (row * tile_y * width * 4) + (col * tile_x * 4)
+                    p2 = p1 + (tile_x * 4)
+                    # buffer pixels position
+                    b1 = y * width * 4
+                    b2 = b1 + (tile_x * 4)
+
+                    if p1 < totpixel4:  # avoid pixel row out of area
+                        if col == col_num - 1:  # avoid pixel columns out of area
+                            p2 -= cut4
+                            b2 -= cut4
+
+                        tmp_pixels[p1:p2] = buffer[b1:b2]
+
+        # -----------------------
+        # Copy temporary to final
+        # -----------------------
+        out.pixels = tmp_pixels[:]  # Assign image data
+        img.gl_free()  # free opengl image memory
+
+        # delete image
+        img.user_clear()
+        bpy.data.images.remove(img)
+        # remove temp file
+        os.remove(outpath)
+        # reset
+        bgl.glEnable(bgl.GL_SCISSOR_TEST)
+        # -----------------------
+        # restore opengl defaults
+        # -----------------------
+        bgl.glLineWidth(1)
+        bgl.glDisable(bgl.GL_BLEND)
+        bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+        # Saves image
+        if out is not None and (scene.measureit_render is True or animation is True):
+            ren_path = bpy.context.scene.render.filepath
+            filename = "mit_frame"
+            if len(ren_path) > 0:
+                if ren_path.endswith(os.path.sep):
+                    initpath = os.path.realpath(ren_path) + os.path.sep
+                else:
+                    (initpath, filename) = os.path.split(ren_path)
+
+            ftxt = "%04d" % scene.frame_current
+            outpath = os.path.join(initpath, filename + ftxt + ".png")
+
+            save_image(self, outpath, out)
+
+        settings.color_depth = depth
+        return True
+
+    except:
+        settings.color_depth = depth
+        print("Unexpected error:" + str(sys.exc_info()))
+        self.report({'ERROR'}, "MeasureIt: Unable to create render image")
+        return False
+
+
+# --------------------------------------------------------------------
+# Get the final render image and return as image object
+#
+# return None if no render available
+# --------------------------------------------------------------------
+def get_render_image(outpath):
+    saved = False
+    # noinspection PyBroadException
+    try:
+        # noinspection PyBroadException
+        try:
+            result = bpy.data.images['Render Result']
+            if result.has_data is False:
+                # this save produce to fill data image
+                result.save_render(outpath)
+                saved = True
+        except:
+            print("No render image found")
+            return None
+
+        # Save and reload
+        if saved is False:
+            result.save_render(outpath)
+
+        img = img_utils.load_image(outpath)
+
+        return img
+    except:
+        print("Unexpected render image error")
+        return None
+
+
+# -------------------------------------
+# Save image to file
+# -------------------------------------
+def save_image(self, filepath, myimage):
+    # noinspection PyBroadException
+    try:
+
+        # Save old info
+        settings = bpy.context.scene.render.image_settings
+        myformat = settings.file_format
+        mode = settings.color_mode
+        depth = settings.color_depth
+
+        # Apply new info and save
+        settings.file_format = 'PNG'
+        settings.color_mode = "RGBA"
+        settings.color_depth = '8'
+        myimage.save_render(filepath)
+        print("MeasureIt: Image " + filepath + " saved")
+
+        # Restore old info
+        settings.file_format = myformat
+        settings.color_mode = mode
+        settings.color_depth = depth
+    except:
+        print("Unexpected error:" + str(sys.exc_info()))
+        self.report({'ERROR'}, "MeasureIt: Unable to save render image")
+        return