panorama tutorial made

Look just above here where it says “reaper.” Just below that you see the words “Forum Groupie.” Now look at S68’s name and then just below there. :smiley: Yes blender is still using 2.3. There are good reasons.

I’m afraid marty is right… the current version of blender works with python 2.3 which you can still download freely. I’m sure blender will be upgraded to comply with 2.4 but since it’s open source… exactly when no one knows.

Look in the python thread for explanations on how exactly to install python for blender. Most people get it wrong the first time.

BTW: S68 have you found any software for the turntable thing yet??? I had a look around and all I’ve been able to find are a couple dodgy javascripts and non free software.

Great, thanks for the help guys. I installed the older version of python and it works great. Awesome script!

Would anyone be open to a script enhancement request? I’ve noticed that it seems to make an assumption about what is front, left, right, back, etc. The assumption is that positioning the camera at:

rotx: 90
roty: 0
rotz: 0

is a front image.

But, in blender that could really be anything. For instance, in my drawing, the front it actually at

rotx: 90
roty: 0
rotz: 90

Would it be possible to have the script read in the current orientation of the camera? Then it could make the assumption that the user set the camera up to be pointing at the front. Basedon on that assumption, it could rotate it 90 degrees and get side images and 180 to get a back image. Does that make sense? Anyone think that’s a good idea?

reaper

Hey! does this mean that I cannot joke :stuck_out_tongue: ?

macouno No, … no soft, have you seen my last email & post in Python? I imèplemented turntable in the script. i’m playing with VR ObjectWorx demo, and demo means ‘cannot save’ hence … nothing to show :frowning:

Personally I hate java

reaper It could be done, but the same effect can be achieved by selecting all objects in the scene and rotating them around the center :slight_smile: it is soooo relative… if indeed in blender front is in any direction why can’t you assume that it is y positive direction when you start modeling?

Indeed since default FrontView (NUM1) is that view this is extremely intuitive.

Stefano

[edit]this bit deleted[edit]It’s your web site. :smiley:

Hey, did you see Alltaken’s post about the script at Blender3D? http://www.blender3d.it/index.php?filename=lab/3dviewer.html It’s an old article, at least a year. That ability, post to a page sans 3rd party plug, would be an awesome addition to the script you have going here. Their technique would solve the turntable question too. I’d like to see that technique implemented myself as well but programming though, blah, it’s so difficult.

I won’t argue with that logic. I completely understand that I could make it the front. And if the script ends up not being updated, I will likely rotate and move my entire model to acommodate.

However, as an example, I spent a week drawing this:

And I know that when I want to move something from side to side, I can select it, hit g and lock it on the y axis. It’s burned into my mind from tweaking it to death. The point is that the script is requiring that the user either:

  1. Model a certain way to get it to work properly.
  2. Modify his drawing against his wishes to get it to work properly.
  3. Or Modify the produced images to get the final pano to look right.

The pano it produces for me starts with a view of the side wall rather than the front stage. I spent quite a bit of time hacking away at the image… rotating, renaming, etc… to get it to start at the front stage.

In the end, I first have to say that I still very much appreciate the script. Unfortunately, the script makes a poor assumption that limits its own usability because it forces the user to make decisions he probably does not want to. If I knew python, I’d have modified it myself already. I’m more perl oriented unfortunately. Learning tcl as well. [I’m a little surprised they did not choose tcl for the API for blender. It is becoming industry starndard API… at least in my business which is not rendering]. So, it’s obviously not a good thing when software makes an assumption that limits its usability. Sometimes it’s necessary due to time tradeoff in implementing it properly. I am not sure in this case. But I still believe that the proper way to implement this is to give the user control somehow.

Another way to do it would be to just allow the user to enter the rotx, roty, rotz information into a box in the gui if detecting it is difficult. That entered information could be labelled, “Front view: rotx __ roty__ rotz__”.

Anyways, I know that is a long post, but I think you deserved a complete answer.

reaper

hey Stephano, I’ve updated my previous post. All in good fun. :wink:
I’d like to add that I think reaper makes a good point. Current view would be a good starting point for the script. And it seems like it would be easy enough, seems because I really don’t know. Just take the current position and add 90 degres? Anyway, from a user’s point of view it makes a lot of sense.

Marty that actually does make sense… though I don’t know if I agree it’s nessecary. Oh and yeah I’ve seen that “3d viewer” a while ago but it’s not great… the quicktime turntable version is quite a lot better. If we can find the software that is.

Reaper… you can always just rename the 4 side images so the one you want is in front and rotate the top and bottom ones in an image editor. It’s easy enough… and we’re not going to adapt the script right now I think… I certainly do not have the time…

I understand. I was able to get the results I wanted after renaming all the images and rotating several. It ended up being some work for me. I originally tried it with png images. Did you know that windows brightens the image if you rotate it through the image previewer? I had to re-render everything in jpg format.

In the end, this script is intended to save time for the user trying to make a pano. But it may create some work at the same time.

I understand work is required to enhance the script and will leave it to you guys to decide whether or not you find it worthwhile or have the time. I feel the point has been made. I would certainly appreciate it and offer my thanks if you did the enhancements. Thanks for responding and explaining your points.

reaper

Ehm well that’s close to the truth but not quite it.

Blender saves .PNG images somehow with slightly different colors than other apps… I have no idea why but it does. Normally you don’t notice but when you put images next to each other the difference is striking.

The trick is… if you edit and save a .png image in an editor… you have to open and save all images. Just opening and saving the other images as well solves the brightness issue.

I think there’s a slight error in the .png encoding that blender does… it’s not related to this script specificly.

Of course the script is meant to be a time saver… I used to do my panos by hand and well… it saves me a lot of time. If you want to do something very different from what the script does you can still do it by hand…

The only thing the script does that isn’t easy to do by hand is the lens setting calculation for cylindrical images… which stefano worked out brilliantly.

Perhaps you should try doing one yourself… you might prefer it that way… if you want to change something in the script and share it with us you’re of course very welcome.

What do you gentlemen think of this? I think it is working properly. If you like it, I prefer it become the official new version to help others down the line. As I said, I do not know python. So, I had to hack quite a bit. It may need some cleaning despite being functional.

reaper



... removed and re-added below with improvements...


I’ll try to clean it up soon. I think I added some params to a subroutine that probably don’t need to be there. I could also set the initial values of rotx, roty and rotz so that it would work as it did before I touched it.

reaper

I only had a quick look at the script, so I don’t know if there is any cleaning-up needed in the coding. But here goes: in my opinion the addition of being able to set the starting rotation is a good one. It might be a good idea to integrate it with v0.0.6 though, instead of 0.0.5.
One other thing I think is lacking is that the script doesn’t detect the current rotation automatically, so I added that.

Just replace line 97-101:

## Initialize the rot values

rotx = 0
roty = 0
rotz = 0

by:

## Initialize the rot values

cam = Object.Get(Scene.getCurrent().getCurrentCamera().getName())

rotx = cam.RotX*90*2/math.pi
roty = cam.RotY*90*2/math.pi
rotz = cam.RotZ*90*2/math.pi

I’ll have a better look at the script tomorrow, good night.

Nice addition. I’ve included it. For those who can’t read python, his change took the current rotation of the camera as the default entry. So, you can set the camera to the direction you want to be front or you can type it in in the entry boxes I’ve provided. The only problem is that it no longer makes an assumption based on no knowledge of the model. But I think that was useless anyway. So, here’s the most up to date code. I cleaned up the unnecessary parameters in the sub routine calls…

#!BPY

"""
Name: 'BGC'
Blender: 236
Group: 'Wizards'
Tooltip: 'Make Camera spin and render 6 cubic images!'
"""

#############################################################
#                                                           #
# Blender Go Cubic                !                         #
#                                                           #
# (C) February 2005 Stefano <S68> Selleri                   #
# Released under the Blender Artistic Licence (BAL)         #
# See www.blender.org                                       #
#                                                           #
# Adapted by macouno for full functionality                 #
#                                                           #
#############################################################
# History                                                   #
# V: 0.0.0 - 13-11-04 - Macouno published his clever tut    #
#                       on Panoramas, but I'm too lazy to   #
#                       set cameras by hand!                #
#    0.0.2 - 13-11-04 - A GUI!                              #
#    0.0.3 - 27-02-05 - Made the renderer reset all changes #
#                       it renames the files after render   #
#    0.0.4 - 04-03-05 - Included cylindrical render         #
#                       And made it get correct path data   #
#    0.0.5 - 05-03-05 - New UI functionalities, partial     #
#                       cubic renderings, Multiple pano     #
#                       settings.                           #
#                                                           #
#############################################################




import Blender
from Blender import *
import os
import re
import math


#############################################################
# GLOBALS                                                   #
#############################################################
VERSION         ='0.0.5'

EVENTHASH = {
    'NOEVENT': 1,
    'REDRAW': 2,
    'EXIT': 3,
    'DO_CUB': 4,
    'DO_CYL': 5,

    'CYL_STRONG': 101,
    'CYL_WEAK' : 102,

    'CUB_ALL': 201,
    'CUB_NONE': 202,
    }

#############################################################
# Populate the menu                                         #
#############################################################

## Get scene data
cur = Scene.getCurrent()

## Get the current image render context
cntx = cur.getRenderingContext()

## Get the current frame
fra = cntx.currentFrame()

## Get the current file directory
base = Blender.Get('filename')
filename = base
dirx = Blender.sys.dirname(filename)

## Get the render path
pth1 = cntx.getRenderPath()

try:
    rel = re.search(r'\/\/',pth1).start()
except:
    rel = -1

if rel != -1:
    pthx = pth1[2:]    
    pthx = Blender.sys.join(dirx,pthx)
else:
    pthx = pth1

## Initialize the rot values to the rotation of the selected camera

cam = Object.Get(Scene.getCurrent().getCurrentCamera().getName())

rotx = cam.RotX*90*2/math.pi
roty = cam.RotY*90*2/math.pi
rotz = cam.RotZ*90*2/math.pi

DATAHASH = {
    'SIZE': Draw.Create(500),
    'ROTX': Draw.Create(rotx),
    'ROTY': Draw.Create(roty),
    'ROTZ': Draw.Create(rotz),
    'SIZEXC': Draw.Create(25),
    'SIZEXT': Draw.Create(1000),
    'SIZEYC': Draw.Create(500),
    'FRAME': Draw.Create(fra),
    'NAME': Draw.Create(pthx),
    'TYPE': Draw.Create(2),
    'PARTS': Draw.Create(40),

    'CF1': Draw.Create(1),
    'CF2': Draw.Create(1),
    'CF3': Draw.Create(1),
    'CF4': Draw.Create(1),
    'CF5': Draw.Create(1),
    'CF6': Draw.Create(1)
}

#############################################################
# Store Settings For later re-use                           #
#############################################################
def GetSettings(cntx):

    State = {}
    cntx = cur.getRenderingContext()
    
    State['Rpath'] = cntx.getRenderPath()

    State['SizeX'] = cntx.imageSizeX()
    State['SizeY'] = cntx.imageSizeY()
    State['aspectRatioX'] = cntx.aspectRatioX()
    State['aspectRatioY'] = cntx.aspectRatioY()
    State['partsX'] = cntx.partsX()
    State['partsY'] = cntx.partsY()

    State['Frame'] = cntx.currentFrame()
    State['startFrame'] = cntx.startFrame()
    State['endFrame'] = cntx.endFrame()

    State['CameraObj'] = cur.getCurrentCamera()
    State['CameraIpo'] = State['CameraObj'].getIpo()
    State['CameraDat'] = State['CameraObj'].getData()
    State['CameraLen'] = State['CameraDat'].getLens()
    State['CameraEul'] = State['CameraObj'].getEuler()

    return (State)

#############################################################
# Restore Settings                                          #
#############################################################
def SetSettings(cntx,State):

    cntx.setRenderPath(State['Rpath'])

    cntx.imageSizeX(State['SizeX'])
    cntx.imageSizeY(State['SizeY'])
    cntx.aspectRatioX(State['aspectRatioX'])
    cntx.aspectRatioY(State['aspectRatioY'])
    cntx.partsX(State['partsX'])
    cntx.partsY(State['partsY'])

    cntx.currentFrame(State['Frame'])
    cntx.startFrame(State['startFrame'])
    cntx.endFrame(State['endFrame'])

    cur.setCurrentCamera(State['CameraObj'])
    State['CameraObj'].setEuler(State['CameraEul'])
    try:
        State['CameraObj'].setIpo(State['CameraIpo'])
    except:
        State['CameraObj'].clearIpo()
    State['CameraDat'].setLens(State['CameraLen'])

    return ()

#############################################################
# set image stuff                                           #
#############################################################
def SetImage(cntx):
    global DATAHASH

    if DATAHASH['TYPE'].val == 1:
        cntx.setImageType(Scene.Render.JPEG)
        ext = '.jpg'
    elif DATAHASH['TYPE'].val == 3:
        cntx.setImageType(Scene.Render.TARGA)
        ext = '.tga'
    else:
        cntx.setImageType(Scene.Render.PNG)
        ext= '.png'

    ## enable extensions
    cntx.enableExtensions(1)

    return (ext)

#############################################################
# SET FOR RENDER   Cylindrical                              #
#############################################################
def RenderCyl():

    ## Get the current image render context
    cntx = cur.getRenderingContext()

    ############################## GET THE CURRENT DATA
    Current = GetSettings(cntx)

    ############################## SET THE DATA
    ## Enable pano rendering
    cntx.enablePanorama(1)

    ## Set the nr of parts
    cntx.partsY(1)
    cntx.partsX(DATAHASH['PARTS'].val)

    ## Set image extension
    ext = SetImage(cntx)

    ## Set the image render size
    cntx.imageSizeX(DATAHASH['SIZEXC'].val)
    cntx.imageSizeY(DATAHASH['SIZEYC'].val)

    ## Set the aspect ratio
    cntx.aspectRatioX(1)
    cntx.aspectRatioY(1)

    ## Set the start and end frames
    cntx.startFrame(DATAHASH['FRAME'].val)
    cntx.endFrame(DATAHASH['FRAME'].val)

    ## Calculate lense setting
    setx = float(DATAHASH['SIZEXC'].val)
    sety = float(DATAHASH['SIZEYC'].val)
    setp = DATAHASH['PARTS'].val
    if setx < sety:
        lenz = (setx/sety) * (16/math.tan(math.pi/setp))
    else:
        lenz = (16/math.tan(math.pi/setp))

    Current['CameraDat'].setLens(lenz)

    ## Set the Render path
    cntx.setRenderPath(DATAHASH['NAME'].val)

    ########################## RENDER
    print "Starting Rendering Process *CYLINDER*"
    cntx.renderAnim()
    print "Rendered Cylindrical panorama"

    #############################################################
    # RESET AFTER RENDER                                        #
    #############################################################
    SetSettings(cntx,Current)
    cntx.enablePanorama(0)

#############################################################
# Perform single Render                                     #
#############################################################
def DoCubeFace (i,Ex,Ey,Ez,pthx,ext,frchk,Current):

    ## Set the render path
    pth2 = (pthx + str(i))
    cntx.setRenderPath(pth2)

    ## Set the camera angle
    Current['CameraObj'].setEuler(Ex,Ey,Ez)
    cntx.renderAnim()

    ## Rename the rendered file
    newname = (pth2 + ext);
    oldname = (pth2 + frchk);
    if os.path.isfile(newname):
        os.remove(newname)
    os.rename(oldname, newname)
    print "Renamed "+oldname+" to "+newname

#############################################################
# SET FOR RENDER   CUBE                                     #
#############################################################

def RenderCub():

    ## Get the current image render context
    cntx = cur.getRenderingContext()

    ############################## GET THE CURRENT DATA
    Current = GetSettings(cntx)

    ########################## SET THE DATA
    ## Clear the Ipo
    Current['CameraObj'].clearIpo()

    ## Set render path
    pthx = DATAHASH['NAME'].val

    ## Set image extension
    ext = SetImage(cntx)

    ## Set frame numbers for file correction
    frchk = `DATAHASH['FRAME'].val`
    frnmbr = DATAHASH['FRAME'].val

    if frnmbr < 10:
        frchk = ('000' + frchk)
    elif frnmbr < 100:
        frchk = ('00' + frchk)
    elif frnmbr < 1000:
        frchk = ('0' + frchk)

    ## disable extensions
    cntx.enableExtensions(0)

    ## Set the aspect ratio
    cntx.aspectRatioX(1)
    cntx.aspectRatioY(1)

    ## Set the image render size
    cntx.imageSizeX(DATAHASH['SIZE'].val)
    cntx.imageSizeY(DATAHASH['SIZE'].val)

    ## Set the lens to 16.0
    Current['CameraDat'].setLens(16.0)

    ## Set the start and end frames
    cntx.startFrame(DATAHASH['FRAME'].val)
    cntx.endFrame(DATAHASH['FRAME'].val)

    ########################## first anim
    print "Starting Rendering Process *CUBIC*"

    rotx = DATAHASH['ROTX'].val;
    rotx = rotx*math.pi/2/90;

    roty = DATAHASH['ROTY'].val;
    roty = roty*math.pi/2/90;

    rotz = DATAHASH['ROTZ'].val;
    rotz = rotz*math.pi/2/90;

    print "RotX ", rotx
    print "RotY ", roty
    print "RotZ ", rotz

    if (DATAHASH['CF1'].val==1):
        DoCubeFace (1,rotx,roty,rotz,pthx,ext,frchk,Current)

    if (DATAHASH['CF2'].val==1):
        DoCubeFace (2,rotx,roty,rotz-math.pi/2,pthx,ext,frchk,Current)

    if (DATAHASH['CF3'].val==1):
        DoCubeFace (3,rotx,roty,rotz-math.pi,pthx,ext,frchk,Current)

    if (DATAHASH['CF4'].val==1):
        DoCubeFace (4,rotx,roty,rotz-3*math.pi/2,pthx,ext,frchk,Current)

    if (DATAHASH['CF5'].val==1):
        DoCubeFace (5,rotx+math.pi/2,roty,rotz,pthx,ext,frchk,Current)

    if (DATAHASH['CF6'].val==1):
        DoCubeFace (6,rotx-math.pi/2,roty,rotz,pthx,ext,frchk,Current)

    print "Rendered Cubic Panorama"

    #############################################################
    # RESET AFTER RENDER                                        #
    #############################################################
    SetSettings(cntx,Current)
    cntx.enableExtensions(1)

#############################################################
# MAIN WINDOW                                               #
#############################################################
def MainWindow():
    global EVENTHASH,VERSION
    global DATA


    #############################################################
    # Backgrounds                                               #
    #############################################################

    BGL.glClearColor(0.5, 0.5, 0.5, 0.0)
    BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)

    BGL.glColor3f(0, 0, 0) 			# Black
    BGL.glRectf(2, 2, 340, 480)

    BGL.glColor3f(1, 0.9, 0.7) 			# Light blue
    BGL.glRectf(3, 3, 339, 479)

    BGL.glColor3f(0.3, 0.27, 0.35) 		# Dark purple 1
    BGL.glRectf(4, 4, 338, 78)

    BGL.glColor3f(0, 0, 0) 			# Black 1
    BGL.glRectf(4, 79, 338, 113)

    BGL.glColor3f(0.3, 0.27, 0.35) 		# Dark purple 2
    BGL.glRectf(4, 114, 338, 213)

    BGL.glColor3f(0, 0, 0) 			# Black 2
    BGL.glRectf(4, 214, 338, 248)

    BGL.glColor3f(0.3, 0.27, 0.35) 		# Dark purple 3
    BGL.glRectf(4, 249, 338, 348)

    BGL.glColor3f(0, 0, 0) 			# Black 3
    BGL.glRectf(4, 349, 338, 383)

    BGL.glColor3f(0.3, 0.27, 0.35) 		# Dark purple 3
    BGL.glRectf(4, 384, 338, 443)

    BGL.glColor3f(0, 0, 0) 			# Black 4
    BGL.glRectf(4, 444, 338, 478)

    #############################################################
    # Common Header                                             #
    #############################################################

    BGL.glColor3f(1, 0.9, 0.7)
    BGL.glRasterPos2d(15, 457)
    Draw.Text("BGC - Blender Go Cube v. "+VERSION)
    BGL.glRasterPos2d(15, 425)
    Draw.Text("(C) Feb 2005")
    BGL.glRasterPos2d(15, 409)
    Draw.Text("Stefano Selleri <a.k.a. S68>")
    BGL.glRasterPos2d(15, 393)
    Draw.Text("macouno and reaper")
    Draw.Button("EXIT", EVENTHASH['EXIT'], 279, 449, 50, 24, "Exit BGC")
    Draw.Button("GO", EVENTHASH['DO_CYL'], 279, 219, 50, 25, "Render cylindrical panorama")
    Draw.Button("GO", EVENTHASH['DO_CUB'], 279, 84, 50, 25, "Render cubic panorama")


    #############################################################
    # General Screen                                            #
    #############################################################
    BGL.glColor3f(1, 0.9, 0.7)
    BGL.glRasterPos2d(15, 362)
    Draw.Text("General settings:")

    DATAHASH['FRAME'] =  Draw.Slider(
                        "Frame: ", EVENTHASH['NOEVENT'], 15, 319, 250, 18,
                        DATAHASH['FRAME'].val, 1, 18000, 0,
                        "The frame to render. Current frame is default")

    DATAHASH['NAME'] =  Draw.String(
                        "Path: ", EVENTHASH['NOEVENT'], 15, 289, 250, 18,
                        DATAHASH['NAME'].val, 128,
                        "Complete path and an image name without extension")

    types = "Image type %t|JPG %x1|PNG %x2|Targa %x3"

    DATAHASH['TYPE'] = Draw.Menu(types, EVENTHASH['NOEVENT'],
                                 15, 259, 250, 18, 2,
                                 "The image type. Type will remain set after the script is closed.")



    #############################################################
    # Cylindrical Screen                                        #
    #############################################################
    BGL.glColor3f(1, 0.9, 0.7)
    BGL.glRasterPos2d(15, 227)
    Draw.Text("Cylindrical panorama settings:")


    DATAHASH['PARTS'] = Draw.Slider(
                        "X Parts: ", EVENTHASH['CYL_STRONG'], 15, 184, 250, 18,
                        DATAHASH['PARTS'].val, 4, 64, 0,
                        "The nr of slices the cylinder will render in. The more slices the less distortion.")

    DATAHASH['SIZEXC'] =Draw.Slider(
                        "Part. Size X: ", EVENTHASH['CYL_STRONG'], 15, 164, 250, 18,
                        DATAHASH['SIZEXC'].val, 4, 10000, 0,
                        "The width of each X part. Will be multiplied by the nr of parts.")

    DATAHASH['SIZEXT'] =Draw.Slider(
                        "Tot. Size X: ", EVENTHASH['CYL_WEAK'], 15, 144, 250, 18,
                        DATAHASH['SIZEXT'].val, 4, 100000, 0,
                        "The width of the whole panorama.")

    DATAHASH['SIZEYC'] =Draw.Slider(
                        "Size Y: ", EVENTHASH['NOEVENT'], 15, 124, 250, 18,
                        DATAHASH['SIZEYC'].val, 4, 10000, 0,
                        "The total height of the cylindrical image")



    #############################################################
    # Cubic Screen                                              #
    #############################################################
    BGL.glColor3f(1, 0.9, 0.7)
    BGL.glRasterPos2d(15, 92)
    Draw.Text("Cubic panorama settings:")
    BGL.glColor3f(1, 1, 1)

    BGL.glRasterPos2d(15, 60)
    Draw.Text("FRONT:")

    DATAHASH['ROTX'] =  Draw.Number(
		        "RotX: ", EVENTHASH['NOEVENT'], 65, 55, 65, 18,
                        DATAHASH['ROTX'].val, 0, 360, 
                        "X Rotation of camera for front view")

    DATAHASH['ROTY'] =  Draw.Number(
                        "RotY: ", EVENTHASH['NOEVENT'], 130, 55, 65, 18,
                        DATAHASH['ROTY'].val, 0, 360, 
                        "Y Rotation of camera for front view")
    DATAHASH['ROTZ'] =  Draw.Number(
                        "RotZ: ", EVENTHASH['NOEVENT'], 190, 55, 65, 18,
                        DATAHASH['ROTZ'].val, 0, 360,
                        "Z Rotation of camera for front view")
    
    DATAHASH['SIZE'] =  Draw.Slider(
                        "Size: ", EVENTHASH['NOEVENT'], 15, 33, 240, 18,
                        DATAHASH['SIZE'].val, 4, 10000, 0,
                        "The image will be a square")
 
    ##### Toggles to switch on/off determined faces
    DATAHASH['CF1'] =   Draw.Toggle(
                        "1", EVENTHASH['NOEVENT'], 257, 33, 18, 18,
                        DATAHASH['CF1'].val,
                        "Render Face 1 (Front) Image ?")
    DATAHASH['CF2'] =   Draw.Toggle(
                        "2", EVENTHASH['NOEVENT'], 275, 33, 18, 18,
                        DATAHASH['CF2'].val,
                        "Render Face 2 (Right) Image ?")
    DATAHASH['CF3'] =   Draw.Toggle(
                        "3", EVENTHASH['NOEVENT'], 293, 33, 18, 18,
                        DATAHASH['CF3'].val,
                        "Render Face 3 (Back) Image ?")
    DATAHASH['CF4'] =   Draw.Toggle(
                        "4", EVENTHASH['NOEVENT'], 311, 33, 18, 18,
                        DATAHASH['CF4'].val,
                        "Render Face 4 (Left) Image ?")
    DATAHASH['CF5'] =   Draw.Toggle(
                        "5", EVENTHASH['NOEVENT'], 293, 51, 18, 18,
                        DATAHASH['CF5'].val,
                        "Render Face 5 (Top) Image ?")
    DATAHASH['CF6'] =   Draw.Toggle(
                        "6", EVENTHASH['NOEVENT'], 293, 15, 18, 18,
                        DATAHASH['CF6'].val,
                        "Render Face 6 (Bottom) Image ?")

    Draw.Button("All", EVENTHASH['CUB_ALL'], 257, 51, 36, 18,
                "Set all six renders to ON (Default)")

    Draw.Button("None", EVENTHASH['CUB_NONE'], 257, 15, 36, 18,
                "Set all six renders to OFF")

#############################################################
# Graphics                                                  #
#############################################################

def draw():
    MainWindow()

#############################################################
# Event Handler                                             #
#############################################################

def event(evt, val):
	if (evt== Draw.QKEY and not val):
		Draw.Exit()

def bevent(evt):
    global EVENTHASH,DATAHASH

    if   (evt == EVENTHASH['EXIT']):
        print 'EXIT'
        Draw.Exit()
    elif (evt == EVENTHASH['DO_CUB']):
        RenderCub()
        Draw.Redraw()
    elif (evt == EVENTHASH['DO_CYL']):
        RenderCyl()
        Draw.Redraw()
    #### Cylindrical UI Updates
    elif (evt == EVENTHASH['CYL_STRONG']):
        ## PartsX or SizeX changed, we only need to update TotalSize X
        DATAHASH['SIZEXT'].val = DATAHASH['PARTS'].val*DATAHASH['SIZEXC'].val
        Draw.Redraw()
    elif (evt == EVENTHASH['CYL_WEAK']):
        ## TotalSizeX changed, we need to update BOTH SizeX and TotalSize X
        DATAHASH['SIZEXC'].val = int(DATAHASH['SIZEXT'].val/DATAHASH['PARTS'].val)
        DATAHASH['SIZEXT'].val = DATAHASH['PARTS'].val*DATAHASH['SIZEXC'].val
        Draw.Redraw()
    #### Cubic UI Updates
    elif (evt == EVENTHASH['CUB_ALL']):
        DATAHASH['CF1'].val = 1
        DATAHASH['CF2'].val = 1
        DATAHASH['CF3'].val = 1
        DATAHASH['CF4'].val = 1
        DATAHASH['CF5'].val = 1
        DATAHASH['CF6'].val = 1
        Draw.Redraw()
    elif (evt == EVENTHASH['CUB_NONE']):
        DATAHASH['CF1'].val = 0
        DATAHASH['CF2'].val = 0
        DATAHASH['CF3'].val = 0
        DATAHASH['CF4'].val = 0
        DATAHASH['CF5'].val = 0
        DATAHASH['CF6'].val = 0
        Draw.Redraw()

#############################################################
# Registering all functions                                 #
#############################################################

Draw.Register(draw, event, bevent)

Well, I just gave the latest version a full fledged spin. It is now everything I had hoped for… just great. A user can simply place a camera in a scene, point it forward, start this script and program the size. Hit a button and you get all 6 renders. Or the user can just toss the camera in the scene and then enter the rot values in the script that correspond to the front view. Very nice! Quite useful.

reaper

OMG, whi not posting a diff… now I have to search for what you’ve done :slight_smile:

OK, I’ll add a ‘front’ direction on the ‘official’ release, asap. THis means probably saturday :slight_smile:

Stefano

P.S.
/me takes off Python coder hat and wear Admin Hat

“There is a full thread in the Python forum for these discussions :)”

First we find out that these admin guys have no sense of humor. Now we find out they not only need the code enhancements delivered on a silver platter, they need a diff as well. Hahahaha wink I tried to do a nice side by side diff but couldn’t get the post to look right. If you want a text file e-mail somewhere with a better diff, pm me your e-mail address…

reaper

97,104d97
< ## Initialize the rot values to the rotation of the selected camera
<
< cam = Object.Get(Scene.getCurrent().getCurrentCamera().getName())
<
< rotx = cam.RotX902/math.pi
< roty = cam.RotY902/math.pi
< rotz = cam.RotZ902/math.pi
<
107,109d99
< ‘ROTX’: Draw.Create(rotx),
< ‘ROTY’: Draw.Create(roty),
< ‘ROTZ’: Draw.Create(rotz),
338,350d327
< rotx = DATAHASH[‘ROTX’].val;
< rotx = rotxmath.pi/2/90;
<
< roty = DATAHASH[‘ROTY’].val;
< roty = roty
math.pi/2/90;
<
< rotz = DATAHASH[‘ROTZ’].val;
< rotz = rotz*math.pi/2/90;
<
< print "RotX ", rotx
< print "RotY ", roty
< print "RotZ ", rotz
<
352c329
< DoCubeFace (1,rotx,roty,rotz,pthx,ext,frchk,Current)

> DoCubeFace (1,math.pi/2.0,0.0,0.0,pthx,ext,frchk,Current)
355c332
< DoCubeFace (2,rotx,roty,rotz-math.pi/2,pthx,ext,frchk,Current)

> DoCubeFace (2,math.pi/2.0,0.0,-math.pi/2.0,pthx,ext,frchk,Current)
358c335
< DoCubeFace (3,rotx,roty,rotz-math.pi,pthx,ext,frchk,Current)

> DoCubeFace (3,math.pi/2.0,0.0,-math.pi,pthx,ext,frchk,Current)
361c338
< DoCubeFace (4,rotx,roty,rotz-3*math.pi/2,pthx,ext,frchk,Current)

> DoCubeFace (4,math.pi/2.0,0.0,-3.0*math.pi/2.0,pthx,ext,frchk,Current)
364c341
< DoCubeFace (5,rotx+math.pi/2,roty,rotz,pthx,ext,frchk,Current)

> DoCubeFace (5,math.pi,0.0,0.0,pthx,ext,frchk,Current)
367c344
< DoCubeFace (6,rotx-math.pi/2,roty,rotz,pthx,ext,frchk,Current)

> DoCubeFace (6,0.0,0.0,0.0,pthx,ext,frchk,Current)
434c411
< Draw.Text(“macouno and reaper”)

> Draw.Text(“and macouno”)
503,519d479
< BGL.glRasterPos2d(15, 60)
< Draw.Text(“FRONT:”)
<
< DATAHASH[‘ROTX’] = Draw.Number(
< "RotX: ", EVENTHASH[‘NOEVENT’], 65, 55, 65, 18,
< DATAHASH[‘ROTX’].val, 0, 360,
< “X Rotation of camera for front view”)
<
< DATAHASH[‘ROTY’] = Draw.Number(
< "RotY: ", EVENTHASH[‘NOEVENT’], 130, 55, 65, 18,
< DATAHASH[‘ROTY’].val, 0, 360,
< “Y Rotation of camera for front view”)
< DATAHASH[‘ROTZ’] = Draw.Number(
< "RotZ: ", EVENTHASH[‘NOEVENT’], 190, 55, 65, 18,
< DATAHASH[‘ROTZ’].val, 0, 360,
< “Z Rotation of camera for front view”)