[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [577] trunk/py/scripts/addons/ space_view3d_panel_measure.py: * Version 0.7 (0.7 final)

Martin Buerbaum martin.buerbaum at gmx.at
Wed Apr 14 15:44:02 CEST 2010


Revision: 577
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-extensions&revision=577
Author:   pontiac
Date:     2010-04-14 15:44:02 +0200 (Wed, 14 Apr 2010)

Log Message:
-----------
* Version 0.7 (0.7 final)
* Summary of changes:
* 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 necessarily active) object now gets the obj via the sel-object array.
* API change Mathutils -> mathutils (r557)
* Reduced PRECISION to 4
* 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.

Modified Paths:
--------------
    trunk/py/scripts/addons/space_view3d_panel_measure.py

Modified: trunk/py/scripts/addons/space_view3d_panel_measure.py
===================================================================
--- trunk/py/scripts/addons/space_view3d_panel_measure.py	2010-04-14 11:24:51 UTC (rev 576)
+++ trunk/py/scripts/addons/space_view3d_panel_measure.py	2010-04-14 13:44:02 UTC (rev 577)
@@ -19,14 +19,13 @@
 import bpy
 from bpy.props import *
 from mathutils import Vector, Matrix
+import bgl
+import blf
 
-# Precicion for display of float values.
-PRECISION = 5
-
 bl_addon_info = {
     'name': '3D View: Measure panel',
     'author': 'Buerbaum Martin (Pontiac)',
-    'version': '0.6.4',
+    'version': '0.7',
     'blender': (2, 5, 3),
     'location': 'View3D > Properties > Measure',
     'description': 'Measure distances between objects',
@@ -34,6 +33,10 @@
         'Scripts/3D_interaction/Panel_Measure',
     'category': '3D View'}
 
+# More links:
+# http://gitorious.org/blender-scripts/blender-measure-panel-script
+# http://blenderartists.org/forum/showthread.php?t=177800
+
 __bpydoc__ = """
 Measure panel
 
@@ -61,6 +64,23 @@
 "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.
@@ -124,7 +144,145 @@
 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 (context.selected_objects
+        and 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 = Vector(tuple(obj.location))
+
+                # 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)
+                    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 = Vector(tuple(verts_selected[0].co))
+                obj_loc = Vector(tuple(obj.location))
+
+                # 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 = Vector(tuple(obj.location))
+                vert1_loc = Vector(tuple(verts_selected[0].co))
+                vert2_loc = Vector(tuple(verts_selected[1].co))
+
+                # 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 (context.selected_objects
+            and len(context.selected_objects) > 2):
+            return None
+        elif (context.selected_objects
+              and len(context.selected_objects) == 2):
+            # 2 objects selected.
+            # We measure the distance between the 2 selected objects.
+            obj1 = context.selected_objects[0]
+            obj2 = context.selected_objects[1]
+            obj1_loc = Vector(tuple(obj1.location))
+            obj2_loc = Vector(tuple(obj2.location))
+            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 = Vector(tuple(obj.location))
+            return (obj_loc, cur_loc, COLOR_GLOBAL)
+
+        elif (not context.selected_objects
+              or len(context.selected_objects) == 0):
+            # Nothing selected.
+            # We measure the distance from the origin to the 3D cursor.
+            p1 = Vector(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):
@@ -222,20 +380,181 @@
 
 
 # User friendly access to the "space" setting.
-def measureGlobal(scene):
-    return (scene.measure_panel_transform == "measure_global")
+def measureGlobal(sce):
+    return (sce.measure_panel_transform == "measure_global")
 
 
 # User friendly access to the "space" setting.
-def measureLocal(scene):
-    return (scene.measure_panel_transform == "measure_local")
+def measureLocal(sce):
+    return (sce.measure_panel_transform == "measure_local")
 
 
-class OBJECT_OT_reenter_editmode(bpy.types.Operator):
+# 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])

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list