diff --git a/space_view3d_panel_measure.py b/space_view3d_panel_measure.py
new file mode 100644
index 0000000000000000000000000000000000000000..782bbc44766ab183d1696c75d7c999ba9d446f60
--- /dev/null
+++ b/space_view3d_panel_measure.py
@@ -0,0 +1,985 @@
+# ##### 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 #####
+
+import bpy
+from bpy.props import *
+from mathutils import Vector, Matrix
+import bgl
+import blf
+
+bl_addon_info = {
+    'name': '3D View: Measure panel',
+    'author': 'Buerbaum Martin (Pontiac)',
+    'version': '0.7',
+    'blender': (2, 5, 3),
+    'location': 'View3D > Properties > Measure',
+    'description': 'Measure distances between objects',
+    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
+        'Scripts/3D_interaction/Panel_Measure',
+    'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
+        'func=detail&aid=21445&group_id=153&atid=469',
+    'category': 'Broken'}
+
+# More links:
+# http://gitorious.org/blender-scripts/blender-measure-panel-script
+# http://blenderartists.org/forum/showthread.php?t=177800
+
+__bpydoc__ = """
+Measure panel
+
+This script displays in OBJECT MODE:
+* The distance of the 3D cursor to the origin of the
+  3D space (if NOTHING is selected).
+* The distance of the 3D cursor to the center of an object
+  (if exactly ONE object is selected).
+* The distance between 2 object centers
+  (if exactly TWO objects are selected).
+* The surface area of any selected mesh object.
+
+Display in EDIT MODE (Local and Global space supported):
+* The distance of the 3D cursor to the origin
+  (in Local space it is the object center instead).
+* The distance of the 3D cursor to a selected vertex.
+* The distance between 2 selected vertices.
+
+Usage:
+
+This functionality can be accessed via the
+"Properties" panel in 3D View ([N] key).
+
+It's very helpful to use one or two "Empty" objects with
+"Snap during transform" enabled for fast measurement.
+
+Version history:
+v0.7 - Initial support for drawing lines.
+    (Thanks to Algorith for applying my perspective_matrix patch.)
+    The distance value (in BUs) is also drawn in the 3D view now.
+    Also fixed some wrong calculations of global/local distances.
+    Now it's really "what you see is what is calculated".
+    Use bl_addon_info for Add-On information.
+    Use "3D View" in category & name
+    Renamed reenter_editmode to view3d.reenter_editmode.
+    Renamed panel_measure.py into space_view3d_panel_measure.py
+    Active object is only used for edit-mode now. Measurement
+    with exactly one sel. (but not neccessarily active) object
+    now gets the obj via the sel-object array.
+    API change Mathutils -> mathutils (r557)
+    Deselecting 1 of 2 objects now works correctly (active object is ignored).
+    Force a redraw of the area so disabling the "measure_panel_draw"
+    checkbox will clear the line/text.
+    Only calculate area (CPU heavy) if a "area" checkbox is enabled.
+v0.6.4 - Fixed unneeded meshdata duplication (sometimes crashes Blender).
+    The script now correctly calculated the surface area (faceAreaGlobal)
+    of scaled meshes.
+    http://projects.blender.org/tracker/
+    ?func=detail&atid=453&aid=21913&group_id=153
+v0.6.3 - Added register & unregister functions.
+v0.6.2 - Fixed precision of second area property.
+    Reduced display precision to 5 (instead of 6).
+    Added (commented out code) for shortcut [F5] for
+    updating EditMode selection & calculation.
+    Changed the script so it can be managed from the "Add-Ons" tab
+    in the user preferences.
+    Corrected FSF address.
+v0.6.1 - Updated reenter_editmode operator description.
+    Fixed search for selected mesh objects.
+    Added "BU^2" after values that are not yet translated via "unit".
+v0.6
+    *) Fix:  Removed EditMode/ObjectMode toggle stuff. This causes all the
+       crashes and is generally not stable.
+       Instead I've added a manual "refresh" button.
+       I registered a new operator OBJECT_OT_reenter_editmode for this.
+    *) Use "unit" settings (i.e. none/metric/imperial)
+    *) Fix: Only display surface area (>=3 objects) if return value is >=0.
+    *) Minor: Renamed objectFaceArea to objectSurfaceArea
+    *) Updated Vector() and tuple() usage.
+    *) Fixed some comments.
+v0.5 - Global surface area (object mode) is now calculated as well.
+    Support area calculation for face selection.
+    Also made measurement panel closed by default. (Area calculation
+    may use up a lot of CPU/RAM in extreme cases)
+v0.4.1 - Various cleanups.
+    Using the shorter "scene" instead of "context.scene"
+    New functions measureGlobal() and measureLocal() for
+    user-friendly access to the "space" setting.
+v0.4 - Calculate & display the surface area of mesh
+    objects (local space only right now).
+    Expanded global/local switch.
+    Made "local" option for 3Dcursor-only in edit mode actually work.
+    Fixed local/global calculation for 3Dcursor<->vertex in edit mode.
+v0.3.2 - Fixed calculation & display of local/global coordinates.
+    The user can now select via dropdown which space is wanted/needed
+    Basically this is a bugfix and new feature at the same time :-)
+v0.3.1 - Fixed bug where "measure_panel_dist" wasn't defined
+    before it was used.
+    Also added the distance calculation "origin -> 3D cursor" for edit mode.
+v0.3 - Support for mesh edit mode (1 or 2 selected vertices)
+v0.2.1 - Small fix (selecting nothing didn't calculate the distance
+    of the cursor from the origin anymore)
+v0.2 - Distance value is now displayed via a FloatProperty widget (and
+    therefore saved to file too right now [according to ideasman42].
+    The value is save inside the scene right now.)
+    Thanks goes to ideasman42 (Campbell Barton) for helping me out on this.
+v0.1 - Initial revision. Seems to work fine for most purposes.
+
+TODO:
+
+There is a random segmentation fault when moving the 3D cursor in edit mode.
+Mainly this happens when clicking inside the white circle of the translation
+manipulator. There may be other cases though.
+
+See the other "todo" comments below.
+"""
+
+# Precicion for display of float values.
+PRECISION = 4
+
+# Name of the custom properties as stored in the scene.
+COLOR_LOCAL = (1.0, 0.0, 0.0, 0.8)
+COLOR_GLOBAL = (0.0, 0.0, 1.0, 0.8)
+
+
+# Returns a single selected object.
+# Returns None if more than one (or nothing) is selected.
+# Note: Ignores the active object.
+def getSingleObject(context):
+    if len(context.selected_objects) == 1:
+        return context.selected_objects[0]
+
+    return None
+
+
+# Returns a list with 2 3D points (Vector) and a color (RGBA)
+# depending on the current view mode and the selection.
+def getMeasurePoints(context):
+    sce = context.scene
+
+    # Get a single selected object (or nothing).
+    obj = getSingleObject(context)
+
+    if (context.mode == 'EDIT_MESH'):
+        obj = context.active_object
+
+        if (obj and obj.type == 'MESH' and obj.data):
+            # Get mesh data from Object.
+            mesh = obj.data
+
+            # Get transformation matrix from object.
+            ob_mat = obj.matrix
+            # Also make an inversed copy! of the matrix.
+            ob_mat_inv = ob_mat.copy()
+            Matrix.invert(ob_mat_inv)
+
+            # Get the selected vertices.
+            # @todo: Better (more efficient) way to do this?
+            verts_selected = [v for v in mesh.verts if v.selected == 1]
+
+            if len(verts_selected) == 0:
+                # Nothing selected.
+                # We measure the distance from...
+                # local  ... the object center to the 3D cursor.
+                # global ... the origin to the 3D cursor.
+                cur_loc = sce.cursor_location
+                obj_loc = obj.location.copy()
+
+                # Convert to local space, if needed.
+                if measureLocal(sce):
+                    p1 = cur_loc
+                    p2 = obj_loc
+                    return (p1, p2, COLOR_GLOBAL)
+
+                else:
+                    p1 = Vector((0.0, 0.0, 0.0))
+                    p2 = cur_loc
+                    return (p1, p2, COLOR_GLOBAL)
+
+            elif len(verts_selected) == 1:
+                # One vertex selected.
+                # We measure the distance from the
+                # selected vertex object to the 3D cursor.
+                cur_loc = sce.cursor_location
+                vert_loc = verts_selected[0].co.copy()
+                obj_loc = obj.location.copy()
+
+                # Convert to local or global space.
+                if measureLocal(sce):
+                    p1 = obj_loc + vert_loc
+                    p2 = cur_loc
+                    return (p1, p2, COLOR_LOCAL)
+
+                else:
+                    p1 = vert_loc * ob_mat + obj_loc
+                    p2 = cur_loc
+                    return (p1, p2, COLOR_GLOBAL)
+
+            elif len(verts_selected) == 2:
+                # Two vertices selected.
+                # We measure the distance between the
+                # two selected vertices.
+                obj_loc = obj.location.copy()
+                vert1_loc = verts_selected[0].co.copy()
+                vert2_loc = verts_selected[1].co.copy()
+
+                # Convert to local or global space.
+                if measureLocal(sce):
+                    p1 = obj_loc + vert1_loc
+                    p2 = obj_loc + vert2_loc
+                    return (p1, p2, COLOR_LOCAL)
+
+                else:
+                    p1 = obj_loc + vert1_loc * ob_mat
+                    p2 = obj_loc + vert2_loc * ob_mat
+                    return (p1, p2, COLOR_GLOBAL)
+
+            else:
+                return None
+
+    elif (context.mode == 'OBJECT'):
+        # We are working on object mode.
+
+        if len(context.selected_objects) > 2:
+            return None
+        elif len(context.selected_objects) == 2:
+            # 2 objects selected.
+            # We measure the distance between the 2 selected objects.
+            obj1, obj2 = context.selected_objects
+            obj1_loc = obj1.location.copy()
+            obj2_loc = obj2.location.copy()
+            return (obj1_loc, obj2_loc, COLOR_GLOBAL)
+
+        elif (obj):
+            # One object selected.
+            # We measure the distance from the object to the 3D cursor.
+            cur_loc = sce.cursor_location
+            obj_loc = obj.location.copy()
+            return (obj_loc, cur_loc, COLOR_GLOBAL)
+
+        elif not context.selected_objects:
+            # Nothing selected.
+            # We measure the distance from the origin to the 3D cursor.
+            p1 = Vector((0.0, 0.0, 0.0))
+            p2 = sce.cursor_location
+            return (p1, p2, COLOR_GLOBAL)
+
+        else:
+            return None
+
+
+# Return the area of a face (in global space).
+# @note Copies the functionality of the following functions,
+# but also respects the scaling (via the "obj.matrix" parameter):
+# @sa: rna_mesh.c:rna_MeshFace_area_get
+# @sa: math_geom.c:area_quad_v3
+# @sa: math_geom.c:area_tri_v3
+def faceAreaGlobal(face, obj):
+    area = 0.0
+
+    mat = obj.matrix
+
+    if len(face.verts) == 4:
+        # Quad
+
+        # Get vertex indices
+        v1, v2, v3, v4 = face.verts
+
+        # Get vertex data
+        v1 = obj.data.verts[v1]
+        v2 = obj.data.verts[v2]
+        v3 = obj.data.verts[v3]
+        v4 = obj.data.verts[v4]
+
+        # Apply transform matrix to vertex coordinates.
+        v1 = v1.co * mat
+        v2 = v2.co * mat
+        v3 = v3.co * mat
+        v4 = v4.co * mat
+
+        vec1 = v2 - v1
+        vec2 = v4 - v1
+
+        n = vec1.cross(vec2)
+
+        area = n.length / 2.0
+
+        vec1 = v4 - v3
+        vec2 = v2 - v3
+
+        n = vec1.cross(vec2)
+
+        area += n.length / 2.0
+
+    elif len(face.verts) == 3:
+        # Triangle
+
+        # Get vertex indices
+        v1, v2, v3 = face.verts
+
+        # Get vertex data
+        v1 = obj.data.verts[v1]
+        v2 = obj.data.verts[v2]
+        v3 = obj.data.verts[v3]
+
+        # Apply transform matrix to vertex coordinates.
+        v1 = v1.co * mat
+        v2 = v2.co * mat
+        v3 = v3.co * mat
+
+        vec1 = v3 - v2
+        vec2 = v1 - v2
+
+        n = vec1.cross(vec2)
+
+        area = n.length / 2.0
+
+    return area
+
+
+# Calculate the surface area of a mesh object.
+# *) Set selectedOnly=1 if you only want to count selected faces.
+# *) Set globalSpace=1 if you want to calculate
+#    the global surface area (object mode).
+# Note: Be sure you have updated the mesh data before
+#       running this with selectedOnly=1!
+# @todo Support other object types (surfaces, etc...)?
+def objectSurfaceArea(obj, selectedOnly, globalSpace):
+    if (obj and obj.type == 'MESH' and obj.data):
+        areaTotal = 0
+
+        mesh = obj.data
+
+        # Count the area of all the faces.
+        for face in mesh.faces:
+            if not selectedOnly or face.selected:
+                if globalSpace:
+                    areaTotal += faceAreaGlobal(face, obj)
+                else:
+                    areaTotal += face.area
+
+        return areaTotal
+
+    # We can not calculate an area for this object.
+    return -1
+
+
+# User friendly access to the "space" setting.
+def measureGlobal(sce):
+    return (sce.measure_panel_transform == "measure_global")
+
+
+# User friendly access to the "space" setting.
+def measureLocal(sce):
+    return (sce.measure_panel_transform == "measure_local")
+
+
+# Converts 3D coordinates in a 3DRegion
+# into 2D screen coordinates for that region.
+def region3d_get_2d_coordinates(context, loc_3d):
+    # Get screen information
+    mid_x = context.region.width / 2.0
+    mid_y = context.region.height / 2.0
+    width = context.region.width
+    height = context.region.height
+
+    # Get matrices
+    view_mat = context.space_data.region_3d.perspective_matrix
+    total_mat = view_mat
+
+    # order is important
+    vec = total_mat * Vector((loc_3d[0], loc_3d[1], loc_3d[2], 1.0))
+
+    # dehomogenise
+    vec = Vector((
+        vec[0] / vec[3],
+        vec[1] / vec[3],
+        vec[2] / vec[3]))
+
+    x = int(mid_x + vec[0] * width / 2.0)
+    y = int(mid_y + vec[1] * height / 2.0)
+
+    return Vector((x, y, 0))
+
+
+def draw_measurements_callback(self, context):
+    sce = context.scene
+
+    draw = 0
+    if hasattr(sce, "measure_panel_draw"):
+        draw = sce.measure_panel_draw
+
+    # 2D drawing code example
+    #bgl.glBegin(bgl.GL_LINE_STRIP)
+    #bgl.glVertex2i(0, 0)
+    #bgl.glVertex2i(80, 100)
+    #bgl.glEnd()
+
+    # Get measured 3D points and colors.
+    line = getMeasurePoints(context)
+    if (line and draw):
+        p1, p2, color = line
+
+        # Get and convert the Perspective Matrix of the current view/region.
+        view3d = bpy.context.space_data
+        region = view3d.region_3d
+        perspMatrix = region.perspective_matrix
+        tempMat = [perspMatrix[i][j] for i in range(4) for j in range(4)]
+        perspBuff = bgl.Buffer(bgl.GL_FLOAT, 16, tempMat)
+
+        # ---
+        # Store previous OpenGL settings.
+        # Store MatrixMode
+        MatrixMode_prev = bgl.Buffer(bgl.GL_INT, [1])
+        bgl.glGetIntegerv(bgl.GL_MATRIX_MODE, MatrixMode_prev)
+        MatrixMode_prev = MatrixMode_prev[0]
+
+        # Store projection matrix
+        ProjMatrix_prev = bgl.Buffer(bgl.GL_DOUBLE, [16])
+        bgl.glGetFloatv(bgl.GL_PROJECTION_MATRIX, ProjMatrix_prev)
+
+        # Store Line width
+        lineWidth_prev = bgl.Buffer(bgl.GL_FLOAT, [1])
+        bgl.glGetFloatv(bgl.GL_LINE_WIDTH, lineWidth_prev)
+        lineWidth_prev = lineWidth_prev[0]
+
+        # Store GL_BLEND
+        blend_prev = bgl.Buffer(bgl.GL_BYTE, [1])
+        bgl.glGetFloatv(bgl.GL_BLEND, blend_prev)
+        blend_prev = blend_prev[0]
+
+        # Store glColor4f
+        color_prev = bgl.Buffer(bgl.GL_FLOAT, [4])
+        bgl.glGetFloatv(bgl.GL_COLOR, color_prev)
+
+        # ---
+        # Prepare for 3D drawing
+        bgl.glLoadIdentity()
+        bgl.glMatrixMode(bgl.GL_PROJECTION)
+        bgl.glLoadMatrixf(perspBuff)
+
+        bgl.glColor4f(color[0], color[1], color[2], color[3])
+        bgl.glEnable(bgl.GL_BLEND)
+
+        # ---
+        # Draw 3D stuff.
+        width = 2
+        bgl.glLineWidth(width)
+        bgl.glBegin(bgl.GL_LINE_STRIP)
+        bgl.glVertex3f(p1[0], p1[1], p1[2])
+        bgl.glVertex3f(p2[0], p2[1], p2[2])
+        bgl.glEnd()
+
+        # ---
+        # Restore previous OpenGL settings
+        bgl.glLoadIdentity()
+        bgl.glMatrixMode(MatrixMode_prev)
+        bgl.glLoadMatrixf(ProjMatrix_prev)
+        bgl.glLineWidth(lineWidth_prev)
+        if not blend_prev:
+            bgl.glDisable(bgl.GL_BLEND)
+        bgl.glColor4f(color_prev[0],
+            color_prev[1],
+            color_prev[2],
+            color_prev[3])
+
+        # ---
+        # Draw (2D) text
+        # We do this after drawing the lines so
+        # we can draw it OVER the line.
+        coord_2d = region3d_get_2d_coordinates(context, p2 + (p1 - p2) * 0.5)
+        offset = 10  # Offset the text a bit to the right.
+        blf.position(coord_2d[0] + offset, coord_2d[1], 0)
+
+        dist = (p1 - p2).length
+        text = "Distance: " + str(round(dist, PRECISION)) + " BU"
+        # @todo Get user pref for text color in 3D View
+        bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
+        blf.size(12, 72)  # Prevent font size to randomly change.
+        blf.draw(text)
+
+
+class VIEW3D_OT_display_measurements(bpy.types.Operator):
+    '''Display the measurements made in the 'Measure' panel'''
+    bl_idname = "view3d.display_measurements"
+    bl_label = "Display the measurements made in the" \
+        " 'Measure' panel in the 3D View."
+    bl_options = {'REGISTER'}
+
+    def modal(self, context, event):
+        context.area.tag_redraw()
+
+        return {'FINISHED'}
+
+    def execute(self, context):
+        if context.area.type == 'VIEW_3D':
+            if not self.bl_label in context.manager.operators.keys():
+                # Add the region OpenGL drawing callback
+                for WINregion in context.area.regions:
+                    if WINregion.type == 'WINDOW':
+                        break
+
+                context.manager.add_modal_handler(self)
+                self._handle = WINregion.callback_add(
+                    draw_measurements_callback,
+                    (self, context),
+                    'POST_PIXEL')
+
+                print("Measure panel display callback added")
+
+            return {'RUNNING_MODAL'}
+
+        else:
+            self.report({'WARNING'}, "View3D not found, cannot run operator")
+            return {'CANCELLED'}
+
+
+class VIEW3D_OT_reenter_editmode(bpy.types.Operator):
+    bl_label = "Re-enter EditMode"
+    bl_idname = "view3d.reenter_editmode"
+    bl_description = "Update mesh data of an active mesh object." \
+        " This is done by exiting and re-entering mesh edit mode."
+    bl_options = {'REGISTER'}
+
+    def invoke(self, context, event):
+
+        # Get the active object.
+        obj = context.active_object
+
+        if (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH'):
+            # Exit and re-enter mesh EditMode.
+            bpy.ops.object.mode_set(mode='OBJECT')
+            bpy.ops.object.mode_set(mode='EDIT')
+            return {'FINISHED'}
+
+        return {'CANCELLED'}
+
+
+class VIEW3D_PT_measure(bpy.types.Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'UI'
+    bl_label = "Measure"
+    bl_default_closed = True
+
+    def poll(self, context):
+        # Only display this panel in the object and edit mode 3D view.
+        if (context.area.type == 'VIEW_3D' and
+            (context.mode == 'EDIT_MESH'
+            or context.mode == 'OBJECT')):
+            return 1
+
+        return 0
+
+    def draw_header(self, context):
+        layout = self.layout
+        sce = context.scene
+
+        # Execute operator (this adds the callback)
+        # if it wasn't done yet.
+        bpy.ops.view3d.display_measurements()
+
+        # Define property for the draw setting.
+        sce.BoolProperty(
+            attr="measure_panel_draw",
+            description="Draw distances in 3D View",
+            default=1)
+
+        # Define property for the calc-area setting.
+        # @todo prevent double calculations for each refresh automatically?
+        sce.BoolProperty(
+            attr="measure_panel_calc_area",
+            description="Calculate mesh surface area (heavy CPU" \
+                " usage on bigger meshes)",
+            default=0)
+
+        layout.prop(sce, "measure_panel_draw")
+
+    def draw(self, context):
+        layout = self.layout
+        sce = context.scene
+
+        # Force a redraw.
+        # This prevents the lines still be drawn after
+        # disabling the "measure_panel_draw" checkbox.
+        # @todo Better solution?
+        context.area.tag_redraw()
+
+        # Get a single selected object (or nothing).
+        obj = getSingleObject(context)
+
+        # Define a temporary attribute for the distance value
+        sce.FloatProperty(
+            name="Distance",
+            attr="measure_panel_dist",
+            precision=PRECISION,
+            unit="LENGTH")
+        sce.FloatProperty(
+            attr="measure_panel_area1",
+            precision=PRECISION,
+            unit="AREA")
+        sce.FloatProperty(
+            attr="measure_panel_area2",
+            precision=PRECISION,
+            unit="AREA")
+
+        TRANSFORM = [
+            ("measure_global", "Global",
+                "Calculate values in global space."),
+            ("measure_local", "Local",
+                "Calculate values inside the local object space.")]
+
+        # Define dropdown for the global/local setting
+        bpy.types.Scene.EnumProperty(
+            attr="measure_panel_transform",
+            name="Space",
+            description="Choose in which space you want to measure.",
+            items=TRANSFORM,
+            default='measure_global')
+
+        if (context.mode == 'EDIT_MESH'):
+            obj = context.active_object
+
+            if (obj and obj.type == 'MESH' and obj.data):
+                # "Note: a Mesh will return the selection state of the mesh
+                # when EditMode was last exited. A Python script operating
+                # in EditMode must exit EditMode before getting the current
+                # selection state of the mesh."
+                # http://www.blender.org/documentation/249PythonDoc/
+                # /Mesh.MVert-class.html#sel
+                # We can only provide this by existing & re-entering EditMode.
+                # @todo: Better way to do this?
+
+                # Get mesh data from Object.
+                mesh = obj.data
+
+                # Get transformation matrix from object.
+                ob_mat = obj.matrix
+                # Also make an inversed copy! of the matrix.
+                ob_mat_inv = ob_mat.copy()
+                Matrix.invert(ob_mat_inv)
+
+                # Get the selected vertices.
+                # @todo: Better (more efficient) way to do this?
+                verts_selected = [v for v in mesh.verts if v.selected == 1]
+
+                if len(verts_selected) == 0:
+                    # Nothing selected.
+                    # We measure the distance from...
+                    # local  ... the object center to the 3D cursor.
+                    # global ... the origin to the 3D cursor.
+
+                    # Get the 2 measure points
+                    line = getMeasurePoints(context)
+                    if line != 0:
+                        dist_vec = line[0] - line[1]
+
+                    sce.measure_panel_dist = dist_vec.length
+
+                    row = layout.row()
+                    row.prop(sce, "measure_panel_dist")
+
+                    row = layout.row()
+                    row.label(text="", icon='CURSOR')
+                    row.label(text="", icon='ARROW_LEFTRIGHT')
+                    if measureLocal(sce):
+                        row.label(text="Obj. Center")
+                    else:
+                        row.label(text="Origin [0,0,0]")
+
+                    row = layout.row()
+                    row.operator("view3d.reenter_editmode",
+                        text="Update selection & distance")
+#                       @todo
+#                        description="The surface area value can" \
+#                            " not be updated in mesh edit mode" \
+#                            " automatically. Press this button" \
+#                            " to do this manually, after you changed" \
+#                            " the selection.")
+
+                    row = layout.row()
+                    row.prop(sce,
+                        "measure_panel_transform",
+                        expand=True)
+
+                elif len(verts_selected) == 1:
+                    # One vertex selected.
+                    # We measure the distance from the
+                    # selected vertex object to the 3D cursor.
+
+                    # Get the 2 measure points
+                    line = getMeasurePoints(context)
+                    if line != 0:
+                        dist_vec = line[0] - line[1]
+
+                    sce.measure_panel_dist = dist_vec.length
+
+                    row = layout.row()
+                    row.prop(sce, "measure_panel_dist")
+
+                    row = layout.row()
+                    row.label(text="", icon='CURSOR')
+                    row.label(text="", icon='ARROW_LEFTRIGHT')
+                    row.label(text="", icon='VERTEXSEL')
+
+                    row = layout.row()
+                    row.operator("view3d.reenter_editmode",
+                        text="Update selection & distance")
+
+                    row = layout.row()
+                    row.prop(sce,
+                        "measure_panel_transform",
+                        expand=True)
+
+                elif len(verts_selected) == 2:
+                    # Two vertices selected.
+                    # We measure the distance between the
+                    # two selected vertices.
+
+                    # Get the 2 measure points
+                    line = getMeasurePoints(context)
+                    if line != 0:
+                        dist_vec = line[0] - line[1]
+
+                    sce.measure_panel_dist = dist_vec.length
+
+                    row = layout.row()
+                    row.prop(sce, "measure_panel_dist")
+
+                    row = layout.row()
+                    row.label(text="", icon='VERTEXSEL')
+                    row.label(text="", icon='ARROW_LEFTRIGHT')
+                    row.label(text="", icon='VERTEXSEL')
+
+                    row = layout.row()
+                    row.operator("view3d.reenter_editmode",
+                        text="Update selection & distance")
+
+                    row = layout.row()
+                    row.prop(sce,
+                        "measure_panel_transform",
+                        expand=True)
+
+                else:
+                    row = layout.row()
+                    row.prop(sce, "measure_panel_calc_area",
+                        text="Surface area (selected faces):")
+
+                    if (sce.measure_panel_calc_area):
+                        # Get selected faces
+                        # @todo: Better (more efficient) way to do this?
+                        faces_selected = [f for f in mesh.faces
+                            if f.selected == 1]
+
+                        if len(faces_selected) > 0:
+                            area = objectSurfaceArea(obj, True,
+                                measureGlobal(sce))
+                            if (area >= 0):
+                                row = layout.row()
+                                row.label(
+                                    text=str(len(faces_selected)),
+                                    icon='FACESEL')
+                                sce.measure_panel_area1 = area
+                                row.prop(sce, "measure_panel_area1")
+
+                                row = layout.row()
+                                row.operator("view3d.reenter_editmode",
+                                    text="Update selection & area")
+
+                                row = layout.row()
+                                row.prop(sce,
+                                    "measure_panel_transform",
+                                    expand=True)
+
+                        else:
+                            row = layout.row()
+                            row.label(text="Selection not supported.",
+                                icon='INFO')
+
+                            row = layout.row()
+                            row.operator("view3d.reenter_editmode",
+                                text="Update selection")
+
+                    else:
+                        row = layout.row()
+                        row.operator("view3d.reenter_editmode",
+                            text="Update selection")
+
+        elif (context.mode == 'OBJECT'):
+            # We are working on object mode.
+
+            if len(context.selected_objects) > 2:
+                # We have more that 2 objects selected...
+
+                row = layout.row()
+                row.prop(sce, "measure_panel_calc_area",
+                        text="Surface area (selected faces):")
+
+                if (sce.measure_panel_calc_area):
+
+                    mesh_objects = [o for o in context.selected_objects
+                        if (o.type == 'MESH')]
+
+                    if (len(mesh_objects) > 0):
+                        # ... and at least one of them is a mesh.
+
+                        # Calculate and display surface area of the objects.
+                        # @todo: Convert to scene units! We do not have a
+                        # FloatProperty field here for automatic conversion.
+
+                        row = layout.row()
+                        for o in mesh_objects:
+                            area = objectSurfaceArea(o, False,
+                                measureGlobal(sce))
+                            if (area >= 0):
+                                row = layout.row()
+                                row.label(text=o.name, icon='OBJECT_DATA')
+                                row.label(text=str(round(area, PRECISION))
+                                    + " BU^2")
+
+                        row = layout.row()
+                        row.prop(sce,
+                            "measure_panel_transform",
+                            expand=True)
+
+            elif len(context.selected_objects) == 2:
+                # 2 objects selected.
+                # We measure the distance between the 2 selected objects.
+
+                obj1, obj2 = context.selected_objects
+
+                # Get the 2 measure points
+                line = getMeasurePoints(context)
+                if line != 0:
+                    dist_vec = line[0] - line[1]
+
+                sce.measure_panel_dist = dist_vec.length
+
+                row = layout.row()
+                row.prop(sce, "measure_panel_dist")
+
+                row = layout.row()
+                row.label(text="", icon='OBJECT_DATA')
+                row.prop(obj1, "name", text="")
+
+                row.label(text="", icon='ARROW_LEFTRIGHT')
+
+                row.label(text="", icon='OBJECT_DATA')
+                row.prop(obj2, "name", text="")
+
+                row = layout.row()
+                row.prop(sce, "measure_panel_calc_area",
+                    text="Surface area:")
+
+                if (sce.measure_panel_calc_area):
+                    # Calculate and display surface area of the objects.
+                    area1 = objectSurfaceArea(obj1, False, measureGlobal(sce))
+                    area2 = objectSurfaceArea(obj2, False, measureGlobal(sce))
+                    if (area1 >= 0 or area2 >= 0):
+                        if (area1 >= 0):
+                            row = layout.row()
+                            row.label(text=obj1.name, icon='OBJECT_DATA')
+                            sce.measure_panel_area1 = area1
+                            row.prop(sce, "measure_panel_area1")
+
+                        if (area2 >= 0):
+                            row = layout.row()
+                            row.label(text=obj2.name, icon='OBJECT_DATA')
+                            sce.measure_panel_area2 = area2
+                            row.prop(sce, "measure_panel_area2")
+
+                        row = layout.row()
+                        row.prop(sce,
+                            "measure_panel_transform",
+                            expand=True)
+
+            elif (obj):
+                # One object selected.
+                # We measure the distance from the object to the 3D cursor.
+
+                # Get the 2 measure points
+                line = getMeasurePoints(context)
+                if line != 0:
+                    dist_vec = line[0] - line[1]
+
+                sce.measure_panel_dist = dist_vec.length
+
+                row = layout.row()
+                #row.label(text=str(dist_vec.length))
+                row.prop(sce, "measure_panel_dist")
+
+                row = layout.row()
+                row.label(text="", icon='CURSOR')
+
+                row.label(text="", icon='ARROW_LEFTRIGHT')
+
+                row.label(text="", icon='OBJECT_DATA')
+                row.prop(obj, "name", text="")
+
+                row = layout.row()
+                row.prop(sce, "measure_panel_calc_area",
+                    text="Surface area:")
+
+                if (sce.measure_panel_calc_area):
+                    # Calculate and display surface area of the object.
+                    area = objectSurfaceArea(obj, False, measureGlobal(sce))
+                    if (area >= 0):
+                        row = layout.row()
+                        row.label(text=obj.name, icon='OBJECT_DATA')
+                        sce.measure_panel_area1 = area
+                        row.prop(sce, "measure_panel_area1")
+
+                        row = layout.row()
+                        row.prop(sce,
+                            "measure_panel_transform",
+                            expand=True)
+
+            elif not context.selected_objects:
+                # Nothing selected.
+                # We measure the distance from the origin to the 3D cursor.
+
+                # Get the 2 measure points
+                line = getMeasurePoints(context)
+                if line != 0:
+                    dist_vec = line[0] - line[1]
+
+                sce.measure_panel_dist = dist_vec.length
+
+                row = layout.row()
+                row.prop(sce, "measure_panel_dist")
+
+                row = layout.row()
+                row.label(text="", icon='CURSOR')
+                row.label(text="", icon='ARROW_LEFTRIGHT')
+                row.label(text="Origin [0,0,0]")
+
+            else:
+                row = layout.row()
+                row.label(text="Selection not supported.",
+                    icon='INFO')
+
+
+def register():
+    bpy.types.register(VIEW3D_PT_measure)
+    bpy.types.register(VIEW3D_OT_reenter_editmode)
+    bpy.types.register(VIEW3D_OT_display_measurements)
+
+
+def unregister():
+    bpy.types.unregister(VIEW3D_PT_measure)
+    bpy.types.unregister(VIEW3D_OT_reenter_editmode)
+    bpy.types.unregister(VIEW3D_OT_display_measurements)
+
+if __name__ == "__main__":
+    register()