Display lamp information in 3D View

I’d like to know if this script that was written for 2.49 is currently possible to do in 2.6. It was written by Mariano Hidalgo “Useless Dreamer” and is described on his website, Unfortunately the link to the script, Lamp_Widgets.py is no longer working, but I have a saved copy.

It displays lamp information in a visual way in the 3D view …

http://airheaded.com/b/lamp_widgets_01.jpg

Dot color is Lamp’s color.
Dot size is Lamp’s energy.
Square on the floor shows Lamp’s distance.
Black triangle on top shows up if the lamp cast shadows.

Is this still possible – or even possible at all – with python in 2.6?

Without seeing the original script I’m going to say yes.

Well here’s the original script, but I haven’t had much luck with it. GLcommands confuse the heck out of me. :slight_smile:

""" Registration info for Blender menus:
Name: 'Lamp Widgets'
Blender: 241
Group: 'Object'
Tooltip: 'Displays extra info on each lamp on scene'
"""

# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2006 Mariano Hidalgo
#
# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------

__author__ = "Mariano Hidalgo a.k.a. uselessdreamer"
__url__ = ("http://uselessdreamer.byethost32.com")
__version__ = "1.0"

__bpydoc__ = """\
Displays extra information for lamps in the 3d View.

Dot Color is Lamp color. 
Dot Size is Lamp energy.
Square Size on floor is Lamp distance (scale 10:1).
Black triangle on top if Cast Shadows is enabled.
"""

import Blender
from Blender import Text, Scene
#SPACEHANDLER.VIEW3D.DRAW
script_text = """

##########################################
#
# Lamp Widgets 1.0
# by Mariano Hidalgo a.k.a uselessdreamer
#
# Dot Color is Lamp color. 
# Dot Size is Lamp energy.
# Square Size on floor is Lamp distance (scale 10:1).
# Black triangle on top if Cast Shadows is enabled.
#
##########################################

import Blender
from Blender import *
from Blender.BGL import *

# Get the Window matrix and create a gl Buffer with it¥s data.
viewMatrix = Window.GetPerspMatrix()
viewBuff= [viewMatrix[i][j] for i in xrange(4) for j in xrange(4)]
viewBuff=BGL.Buffer(GL_FLOAT, 16, viewBuff)
	
# Load the Window matrix for gl Drawing.
glLoadIdentity()
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadMatrixf(viewBuff)

# Enable Point antializing to get round points.
glEnable(GL_POINT_SMOOTH);

# Enable glBlend for alpha blending.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

# Get all objects in current Scene.
scn = Scene.GetCurrent()
obs = scn.getChildren()

for ob in obs:	
	if ob.getType() == "Lamp":
		show = 0
		for oL in ob.layers:
			for wL in Window.ViewLayers():
				if oL == wL: show = 1
		if show:
			lamp = ob.getData()
			
			glColor4f(0,0,0,1)
			glPointSize(8)
			glBegin(GL_POINTS) 
			glVertex3f(ob.LocX,ob.LocY,ob.LocZ) 
			glEnd()	
			
			# Set size and color.
			glColor4f(lamp.R,lamp.G,lamp.B,1)
			glPointSize(int(lamp.energy * 10))
			
			# Lamp colored dot.
			glBegin(GL_POINTS)
			glVertex3f(ob.LocX,ob.LocY,ob.LocZ)
			glEnd()			
	
			# Lamp distance square
			offset = lamp.dist /10
			z = 0						
			glColor4f(1,1,1,0.3)
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);		
			glBegin(GL_POLYGON)
			glVertex3f(ob.LocX-offset,ob.LocY-offset,z)
			glVertex3f(ob.LocX-offset,ob.LocY+offset,z)
			glVertex3f(ob.LocX+offset,ob.LocY+offset,z)
			glVertex3f(ob.LocX+offset,ob.LocY-offset,z)
			glEnd()
	
			# Lamp shadow triangle
			if lamp.mode == Lamp.Modes["Shadows"] or lamp.mode == Lamp.Modes["RayShadow"]:  
				glColor4f(0,0,0,0.8)
				glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)		
				glBegin(GL_POLYGON)
				glVertex3f(ob.LocX,ob.LocY,ob.LocZ+1)
				glVertex3f(ob.LocX-0.25,ob.LocY,ob.LocZ+0.6)
				glVertex3f(ob.LocX+0.25,ob.LocY,ob.LocZ+0.6)
				glEnd()
				
# Disable alpha blending and point smoothing.	
glDisable(GL_BLEND)
glDisable(GL_POINT_SMOOTH)
"""

try:
	txt = Text.Get("Lamp Widgets")
	Text.unlink(txt)	
	txt = Text.New("Lamp Widgets")
	txt.write(script_text)
except:
	txt = Text.New("Lamp Widgets")
	txt.write(script_text)

#Blender.Draw.PupMenu("Lamp WIdgets Setup%t|Enable in [View] --> [SpaceHandler Scripts] menu.")
scn = Scene.GetCurrent()
scn.clearScriptLinks(['Lamp Widgets'])
scn.addScriptLink('Lamp Widgets', 'Redraw')	

Looks pretty simple to convert to 2.6, I’ll have a go at it tomorrow morning over coffee.

Thanks Unc’, that would be great.

Besides ending up with a cool (and in my mind, very valuable) script, it’ll be nice to pour over your code to see what I was missing in my attempts

Sort of works, trying to figure out the gl matrix is making my head hurt so…


# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2006 Mariano Hidalgo
#
# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------

bl_info = {
    "name": "Lamp Widgets",
    "author": "Mariano Hidalgo a.k.a. uselessdreamer",
    "version": (1, 1, 0),
    "blender": (2, 6, 2),
    "location": "View3D",
    "description": "Displays extra info on each lamp on scene",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "3D View"
}

import bpy
import bgl as gl

class VIEW3D_MT_Lamp_Widgets(bpy.types.Operator):
    """Displays extra information for lamps in the 3d View.

    Dot Color is Lamp color. 
    Dot Size is Lamp energy.
    Square Size on floor is Lamp distance (scale 10:1).
    Black triangle on top if Cast Shadows is enabled.
    """
    bl_idname = "view3d.lamp_widgets"
    bl_label = "Lamp Widgets"

    def modal(self, context, event):
        context.area.tag_redraw()

        if event.type in ('RIGHTMOUSE', 'ESC'):
            context.region.callback_remove(self._handle)
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        if context.area.type != 'VIEW_3D':
            self.report({'WARNING'}, "View3D not found, cannot run operator")
            return {'CANCELLED'}

        context.window_manager.modal_handler_add(self)
        self._handle = context.region.callback_add(self.draw_lamp_widgets,
                                                   (context,),
                                                   'POST_PIXEL')
        return {'RUNNING_MODAL'}

    def draw_lamp_widgets(self, context):
        # Get the Window matrix and create a gl Buffer with its data.
        viewMatrix = context.space_data.region_3d.perspective_matrix
        viewBuff = [viewMatrix[j][i] for i in range(4) for j in range(4)]
        viewBuff = gl.Buffer(gl.GL_FLOAT, 16, viewBuff)

        # Load the Window matrix for gl Drawing.
        gl.glLoadIdentity()
        gl.glMatrixMode(gl.GL_PROJECTION)
        gl.glPushMatrix()
        gl.glLoadMatrixf(viewBuff)

        # Enable Point antializing to get round points.
        gl.glEnable(gl.GL_POINT_SMOOTH);

        # Enable glBlend for alpha blending.
        gl.glEnable(gl.GL_BLEND);
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);

        lamps = [obj for obj in context.visible_objects if obj.type == 'LAMP']

        for lamp in lamps:    
            gl.glColor4f(0.0, 0.0, 0.0, 1.0)
            gl.glPointSize(8)
            gl.glBegin(gl.GL_POINTS) 
            gl.glVertex3f(lamp.location[0],
                          lamp.location[1],
                          lamp.location[2]) 
            gl.glEnd()    
            
            # Set size and color.
            gl.glColor4f(lamp.data.color[0],
                         lamp.data.color[1],
                         lamp.data.color[2],
                         1.0)
            gl.glPointSize(int(lamp.data.energy * 10))
            
            # Lamp colored dot.
            gl.glBegin(gl.GL_POINTS)
            gl.glVertex3f(lamp.location[0],
                          lamp.location[1],
                          lamp.location[2])
            gl.glEnd()            
    
            # Lamp distance square
            offset = lamp.data.distance * 0.1
            z = 0.0

            gl.glColor4f(1.0, 1.0, 1.0, 0.3)
            #gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE);        
            gl.glBegin(gl.GL_LINE_LOOP)
            gl.glVertex3f(lamp.location[0] - offset,
                          lamp.location[1] - offset,
                          z)
            gl.glVertex3f(lamp.location[0] - offset,
                          lamp.location[1] + offset,
                          z)
            gl.glVertex3f(lamp.location[0] + offset,
                          lamp.location[1] + offset,
                          z)
            gl.glVertex3f(lamp.location[0] + offset,
                          lamp.location[1] - offset,
                          z)
            gl.glEnd()
    
            # Lamp shadow triangle
            if lamp.data.shadow_method != 'NOSHADOW':  
                gl.glColor4f(0.0, 0.0, 0.0, 0.8)
                #gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)        
                gl.glBegin(gl.GL_POLYGON)
                gl.glVertex3f(lamp.location[0],
                              lamp.location[1],
                              lamp.location[2] + 1)
                gl.glVertex3f(lamp.location[0] - 0.25,
                              lamp.location[1],
                              lamp.location[2] + 0.6)
                gl.glVertex3f(lamp.location[0] + 0.25,
                              lamp.location[1],
                              lamp.location[2] + 0.6)
                gl.glEnd()
                
        # Disable alpha blending and point smoothing.    
        gl.glDisable(gl.GL_BLEND)
        gl.glDisable(gl.GL_POINT_SMOOTH)


def register():
    bpy.utils.register_class(VIEW3D_MT_Lamp_Widgets)

def unregister():
    bpy.utils.unregister_class(VIEW3D_MT_Lamp_Widgets)

if __name__ == "__main__":
    register()


–edit–

Now that I think about it they changed the may matricies are stored to be column (or row) major now so that’s probably the problem.

–edit 2–

Yep, that was it so it’s fixed now with this edit.

Uncle, I can’t seem to get this to work. I’ve tried on both Mac and Windows, installing as an addon or running from the script editor. I’ve searched through every possible permutation of viewing - MultiTexture, GLSL, solid, textured, wire, etc. - with every type of lamp, shadow, color or energy… but no go.

Am I doing something wrong, or is there a OpenGL version, or Python version I should be using?

Oh, I only got it to half-ass work.

Open the script in the text editor and hit the ‘run script’ button then in the 3d view hit space bar and type ‘Lamp Widgets’ – hit escape or RMB to get it to stop displaying.

Getting it to work all the time would involve a lot more work to do right to make it properly disable itself when unregistered and I’m lazy so…

Hey! Terriffic! It works… albeit not as fluidly as I had hoped. But still, it works as advertised! Thanks a bunch Uncle.

I’ve got a very complex and dense scene with all sorts of different lights of different colors, and its nearly impossible to find the right one to adjust for specular results and stuff. And add to that various energy levels and shadow settings and… well, this is a great help! It’s much easier to tell which lamp is doing what without having to first find it, then select it, then look over to properties to see what’s happening.

But especially I can take a look at your code to see what you did, and how far off I was :slight_smile:

Seriously, thank you for your time and effort. That was a very unselfish thing to do, and I really do appreciate it. You’ve made a friend for life!