From 26a2d2d3a99c1dda6237f078c40a4c9d9820b1c7 Mon Sep 17 00:00:00 2001
From: Campbell Barton <ideasman42@gmail.com>
Date: Mon, 22 Nov 2010 05:43:45 +0000
Subject: [PATCH] tool to visualize console mathutils vars

---
 space_view3d_math_vis/__init__.py | 100 +++++++++++++
 space_view3d_math_vis/draw.py     | 231 ++++++++++++++++++++++++++++++
 space_view3d_math_vis/utils.py    |  64 +++++++++
 3 files changed, 395 insertions(+)
 create mode 100644 space_view3d_math_vis/__init__.py
 create mode 100644 space_view3d_math_vis/draw.py
 create mode 100644 space_view3d_math_vis/utils.py

diff --git a/space_view3d_math_vis/__init__.py b/space_view3d_math_vis/__init__.py
new file mode 100644
index 000000000..a73ec1cc6
--- /dev/null
+++ b/space_view3d_math_vis/__init__.py
@@ -0,0 +1,100 @@
+#====================== BEGIN GPL LICENSE BLOCK ======================
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#======================= END GPL LICENSE BLOCK ========================
+
+bl_addon_info = {
+    "name": "Math Vis (Console)",
+    "author": "Campbell Barton",
+    "version": (0, 1),
+    "blender": (2, 5, 5),
+    "api": 33110,
+    "location": "3D View Toolbar, Python Console",
+    "description": "Display console defined mathutils variables in the 3D view",
+    "wiki_url": "",
+    "tracker_url": "",
+    "category": "3D View"}
+
+if "bpy" in locals():
+    from imp import reload
+    reload(utils)
+    reload(draw)
+else:
+    from . import utils, draw
+
+
+import bpy
+
+
+class VIEW3D_PT_math_vis(bpy.types.Panel):
+    bl_space_type = "VIEW_3D"
+    bl_region_type = "TOOLS"
+    bl_label = "Math View"
+
+    def draw(self, context):
+        layout = self.layout
+        view = context.space_data
+
+        col = layout.column(align=True) 
+
+        callbacks = draw.callbacks
+        ok = False
+        for region in context.area.regions:
+            if callbacks.get(hash(region)):
+                ok = True
+                break
+
+        col.operator("view3d.math_vis_toggle", emboss=False, icon='CHECKBOX_HLT' if ok else 'CHECKBOX_DEHLT')
+
+
+
+class SetupMathView(bpy.types.Operator):
+    '''Draw a line with the mouse'''
+    bl_idname = "view3d.math_vis_toggle"
+    bl_label = "Use Math Vis"
+
+    def execute(self, context):
+        callbacks = draw.callbacks
+        region = context.region
+        region_id = hash(region)
+        cb_data = callbacks.get(region_id)
+        if cb_data is None:
+            handle_pixel = region.callback_add(draw.draw_callback_px, (self, context), 'POST_PIXEL')
+            handle_view = region.callback_add(draw.draw_callback_view, (self, context), 'POST_VIEW')
+            callbacks[region_id] = region, handle_pixel, handle_view
+        else:
+            region.callback_remove(cb_data[1])
+            region.callback_remove(cb_data[2])
+            del callbacks[region_id]
+
+        context.area.tag_redraw()
+        return {'FINISHED'}
+
+
+def console_hook():
+    for region, handle_pixel, handle_view in draw.callbacks.values():
+        region.tag_redraw()
+
+
+def register():
+    import console_python
+    console_python.execute.hooks.append((console_hook, ()))
+
+def unregister():
+    import console_python
+    console_python.execute.hooks.remove((console_hook, ()))
+
+    draw.callbacks_clear()
diff --git a/space_view3d_math_vis/draw.py b/space_view3d_math_vis/draw.py
new file mode 100644
index 000000000..c8c23bbfe
--- /dev/null
+++ b/space_view3d_math_vis/draw.py
@@ -0,0 +1,231 @@
+#====================== 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
+import blf
+
+from . import utils
+from mathutils import Vector, Matrix
+
+callbacks = {}
+
+def callbacks_clear():
+    for region, handle_pixel, handle_view in callbacks.values():
+        region.callback_remove(handle_pixel)
+        region.callback_remove(handle_view)
+    callbacks.clear()
+
+
+def draw_callback_px(self, context):
+    from bgl import glColor3f
+    font_id = 0 # XXX, need to find out how best to get this.
+    blf.size(font_id, 12, 72)
+
+    data_matrix, data_quat, data_euler, data_vector, data_vector_array = utils.console_math_data()
+
+    if not data_matrix and not data_quat and not data_euler and not data_vector and not data_vector_array:
+
+        # draw some text
+        glColor3f(1.0, 0.0, 0.0)
+        blf.position(font_id, 180, 10, 0)
+        blf.draw(font_id, "Python Console has no mathutils definitions")
+        return
+
+    glColor3f(1.0, 1.0, 1.0)
+
+    region = context.region
+    region3d = context.space_data.region_3d
+    
+    region_mid_width = region.width / 2.0
+    region_mid_height = region.height / 2.0
+
+    # vars for projection
+    perspective_matrix = region3d.perspective_matrix.copy()
+
+    def draw_text(text, vec):
+        vec_4d = Vector((vec.x, vec.y, vec.z, 1.0))
+        vec_4d *= perspective_matrix
+        if vec_4d.w > 0.0:
+            x = region_mid_width + region_mid_width * (vec_4d.x / vec_4d.w)
+            y = region_mid_height + region_mid_height * (vec_4d.y / vec_4d.w)
+
+            blf.position(font_id, x + 3.0, y - 4.0, 0.0)
+            blf.draw(font_id, text)
+
+    # points
+    if data_vector:
+        for key, vec in data_vector.items():
+            draw_text(key, vec)
+
+    # lines
+    if data_vector_array:
+        for key, vec in data_vector_array.items():
+            draw_text(key, vec[0])
+
+    # matrix
+    if data_matrix:
+        for key, mat in data_matrix.items():
+            draw_text(key, mat[3])
+    
+    if data_quat:
+        loc = context.scene.cursor_location.copy()
+        for key, mat in data_quat.items():
+            draw_text(key, loc)
+
+    if data_euler:
+        loc = context.scene.cursor_location.copy()
+        for key, mat in data_euler.items():
+            draw_text(key, loc)
+
+
+def draw_callback_view(self, context):
+    from bgl import glEnable, glDisable, glColor3f, glVertex3f, glPointSize, glLineWidth, glBegin, glEnd, glLineStipple, GL_POINTS, GL_LINE_STRIP, GL_LINES, GL_LINE_STIPPLE
+
+    data_matrix, data_quat, data_euler, data_vector, data_vector_array = utils.console_math_data()
+
+
+    # draw_matrix vars
+    zero = Vector((0.0, 0.0, 0.0))
+    x_p = Vector((1.0, 0.0, 0.0))
+    x_n = Vector((-1.0, 0.0, 0.0))
+    y_p = Vector((0.0, 1.0, 0.0))
+    y_n = Vector((0.0, -1.0, 0.0))
+    z_p = Vector((0.0, 0.0, 1.0))
+    z_n = Vector((0.0, 0.0, -1.0))        
+    bb = [Vector() for i in range(8)]
+
+    def draw_matrix(mat):
+        zero_tx = zero * mat
+        
+        glLineWidth(2.0)
+        
+        # x
+        glColor3f(1.0, 0.2, 0.2)
+        glBegin(GL_LINES)
+        glVertex3f(*(zero_tx))
+        glVertex3f(*(x_p * mat))
+        glEnd()
+
+        glColor3f(0.6, 0.0, 0.0)
+        glBegin(GL_LINES)
+        glVertex3f(*(zero_tx))
+        glVertex3f(*(x_n * mat))
+        glEnd()
+
+        # y
+        glColor3f(0.2, 1.0, 0.2)
+        glBegin(GL_LINES)
+        glVertex3f(*(zero_tx))
+        glVertex3f(*(y_p * mat))
+        glEnd()
+
+        glColor3f(0.0, 0.6, 0.0)
+        glBegin(GL_LINES)
+        glVertex3f(*(zero_tx))
+        glVertex3f(*(y_n * mat))
+        glEnd()
+        
+        # z
+        glColor3f(0.2, 0.2, 1.0)
+        glBegin(GL_LINES)
+        glVertex3f(*(zero_tx))
+        glVertex3f(*(z_p * mat))
+        glEnd()
+
+        glColor3f(0.0, 0.0, 0.6)
+        glBegin(GL_LINES)
+        glVertex3f(*(zero_tx))
+        glVertex3f(*(z_n * mat))
+        glEnd()
+        
+        # bounding box
+        i = 0
+        glColor3f(1.0, 1.0, 1.0)
+        for x in (-1.0, 1.0):
+            for y in (-1.0, 1.0):
+                for z in (-1.0, 1.0):
+                    bb[i][:] = x, y, z
+                    bb[i] *= mat
+                    i += 1
+
+        # strip
+        glLineWidth(1.0)
+        glLineStipple(1, 0xAAAA)
+        glEnable(GL_LINE_STIPPLE)
+
+        glBegin(GL_LINE_STRIP)
+        for i in 0, 1, 3, 2, 0, 4, 5, 7, 6, 4:
+            glVertex3f(*bb[i])
+        glEnd()
+
+        # not done by the strip
+        glBegin(GL_LINES)
+        glVertex3f(*bb[1])
+        glVertex3f(*bb[5])
+        
+        glVertex3f(*bb[2])
+        glVertex3f(*bb[6])
+        
+        glVertex3f(*bb[3])
+        glVertex3f(*bb[7])
+        glEnd()
+        glDisable(GL_LINE_STIPPLE)
+
+
+    # points
+    if data_vector:
+        glPointSize(3.0);
+        glBegin(GL_POINTS)
+        glColor3f(0.5, 0.5, 1)
+        for key, vec in data_vector.items():
+            glVertex3f(*vec)
+        glEnd();
+        glPointSize(1.0)
+
+    # lines
+    if data_vector_array:
+        glColor3f(0.5, 0.5, 1)
+        glLineWidth(2.0)
+
+        for line in data_vector_array.values():
+            glBegin(GL_LINE_STRIP)
+            for vec in line:
+                glVertex3f(*vec)
+            glEnd();
+            glPointSize(1.0)
+
+        glLineWidth(1.0)
+
+    # matrix
+    if data_matrix:
+        for mat in data_matrix.values():
+            draw_matrix(mat)
+
+    if data_quat:
+        loc = context.scene.cursor_location.copy()
+        for quat in data_quat.values():
+            mat = quat.to_matrix().resize4x4()
+            mat[3][0:3] = loc
+            draw_matrix(mat)
+
+    if data_euler:
+        loc = context.scene.cursor_location.copy()
+        for eul in data_euler.values():
+            mat = eul.to_matrix().resize4x4()
+            mat[3][0:3] = loc
+            draw_matrix(mat)
\ No newline at end of file
diff --git a/space_view3d_math_vis/utils.py b/space_view3d_math_vis/utils.py
new file mode 100644
index 000000000..a9c26ae40
--- /dev/null
+++ b/space_view3d_math_vis/utils.py
@@ -0,0 +1,64 @@
+#====================== 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 sys
+
+def console_namespace():
+    import console_python
+    get_consoles = console_python.get_console
+    consoles = getattr(get_consoles, "consoles", None)
+    if consoles:
+        for console, stdout, stderr in get_consoles.consoles.values():
+            return console.locals
+    return {}
+
+def console_math_data():
+    from mathutils import Matrix, Vector, Quaternion, Euler
+
+    data_matrix = {}
+    data_quat = {}
+    data_euler = {}
+    data_vector = {}
+    data_vector_array = {}
+
+    for key, var in console_namespace().items():
+        if key[0] == "_":
+            continue
+
+        var_type = type(var)
+
+        if var_type is Matrix:
+            data_matrix[key] = var
+        elif var_type is Vector:
+            data_vector[key] = var
+        elif var_type is Quaternion:
+            data_quat[key] = var
+        elif var_type is Euler:
+            data_euler[key] = var
+        elif var_type in (list, tuple):
+            if var:
+                ok = True
+                for item in var:
+                    if type(item) is not Vector:
+                        ok = False
+                        break
+                if ok:
+                    data_vector_array[key] = var
+
+    return data_matrix, data_quat, data_euler, data_vector, data_vector_array
+
-- 
GitLab