panorama tutorial made

I’ve been doing panoramas of my blender scenes for a while and every time I post them people ask me how.

So since I was updating my site today here’s a little tutorial:

http://www.alienhelpdesk.com/index.php?id=5

And there’s some example panoramas here:

http://www.alienhelpdesk.com/index.php?id=9

Enjoy :wink:

Cool!

Thanx :slight_smile:

Stefano

Boy, how lazy I am :slight_smile:

doing macouno procedure by hand is tiresome

So here is Version 0.0.0 of new script BGC (Blender Go Cubic)

Just load it and run.

I’ll add a GUI later on today

Stefano


#!BPY

"""
Name: 'BGC'
Blender: 236
Group: 'Animation'
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                                       #
#                                                           #
#############################################################
# 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!                #
#############################################################

import Blender
from Blender import *

pi = 3.1415926535897932384626433832795

cur = Scene.getCurrent()

cntx = cur.getRenderingContext()
cntx.imageSizeX(1000)
cntx.imageSizeY(1000)
#Image type...

CamO = cur.getCurrentCamera()
CamC = CamO.getData()

CamC.setLens(16.0)

## First shot
CamO.setEuler(pi/2,0.,0.)
cntx.startFrame(1)
cntx.endFrame(1)
cntx.renderAnim()

## Second shot
CamO.setEuler(pi/2,0.,-pi/2)
cntx.startFrame(2)
cntx.endFrame(2)
cntx.renderAnim()

## Third shot
CamO.setEuler(pi/2,0.,-pi)
cntx.startFrame(3)
cntx.endFrame(3)
cntx.renderAnim()

## Fourth shot
CamO.setEuler(pi/2,0.,-3*pi/2)
cntx.startFrame(4)
cntx.endFrame(4)
cntx.renderAnim()

## Fifth shot
CamO.setEuler(0.,0.,0.)
cntx.startFrame(5)
cntx.endFrame(5)
cntx.renderAnim()

## Sixth shot
CamO.setEuler(pi,0.,0.)
cntx.startFrame(6)
cntx.endFrame(6)
cntx.renderAnim()

Ok but. it’d be handiest if the script were to:

  1. automaticly set the camera to 16.00

  2. let you set an image size in the script.

  3. Would render the current frame 6 times but with consecutive numbers in the filenames.

  4. After render reset the camera lens and render size to it’s original setting.

That way you could just take any existing scene even an animated one and it’d just render that correct without having to make a sepparate panorama version.

I think it already does this:

CamC.setLens(16.0)

yes but does it reset it to it’s original value after it’s done?

Thing is… I think I’d end up using the script a lot myself… but only if it did everything.

Think… you have a scene… any scene and you like a certain frame in it.

You load the script… do some settings and voila… panorama… no matter what you’re doing… and you can just keep animating/building as you were.

I might have a look myself, but am kinda busy.

beautiful!

I’m working on the script now… should be doing something else, but can’t help myself.

Got the script to set the camera to 16.0 and then reset it to whatever it was before.

I’ll let you guys know about my progress later on… And S68 I’ll contact you… we may be able to cooperate… always nice :wink:

Ok some development.

Here’s what I came up with now.

ok editing this post since the code I put here was crappy.

I’m on my way now… almost there :wink:

Good :slight_smile:

Glad you liked

Actually it alrready does all that you asked for except setting back the settings to the values they had before, but it is a good idea!

I just uploaded an updated version with a GUI on blender CVS

http://projects.blender.org/viewcvs/viewcvs.cgi/bstar/BGC/?cvsroot=bstar

If you so wish you can work on this, adding all necessary comments and I’ll update the CVS!

Stefano

P.S. version 0.0.0 had UP and DOWN image swapped…

import Blender
from Blender import *
import os

pi = 3.1415926535897932384626433832795


#############################################################
# GLOBALS                                                   #
#############################################################
VERSION         ='0.0.2'

EVENTHASH = {
    'NOEVENT': 1,
    'REDRAW': 2,
    'EXIT': 3,
    'DO': 4
    }

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

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



## Get the current frame
fra = Blender.Get('curframe')

## Get the current start and end frames
fr1 = cntx.startFrame()
fr2 = cntx.endFrame()

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

## Get aspect ratio
asp1 = cntx.aspectRatioX()
asp2 = cntx.aspectRatioY()

## Get image size
cntx1 = cntx.imageSizeX()
cntx2 = cntx.imageSizeY()

## Get camera settings functions
CamO = cur.getCurrentCamera()
CamG = CamO.getData()

## Get the camera angles
ang1 = CamO.getEuler()

## Get the lens value as it is
Cam1 = CamG.getLens()

DATAHASH = {
    'SIZE': Draw.Create(100),
    'FRAME': Draw.Create(fra),
    'NAME': Draw.Create(pth1),
    'TYPE': Draw.Create(2)
    }

##
##
## Set everything
##
##

def RenderIt():

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


    ## 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
    CamG.setLens(16.0)

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



    #########################firts anim################################

    ## Set the render path
    pth2 = (pth1 + '1')

    cntx.setRenderPath(pth2)

    ## Set the camera angle
    CamO.setEuler(pi/2,0.,0.)

    cntx.renderAnim()

    oldname = (pth2 +'0011')

    newname = (pth2 + ext)

    print oldname
    print newname

    os.rename(oldname, newname)

    ##########################second anim##################################

    ## Set the render path
    pth2 = (pth1 + '2')

    cntx.setRenderPath(pth2)

    ## Set the camera angle
    CamO.setEuler(pi/2,0.,-pi/2)

    cntx.renderAnim()

    ##########################third anim##################################

    ## Set the render path
    pth2 = (pth1 + '3')

    cntx.setRenderPath(pth2)

    ## Set the camera angle
    CamO.setEuler(pi/2,0.,-pi)

    cntx.renderAnim()

    ##########################fourth anim##################################

    ## Set the render path
    pth2 = (pth1 + '4')

    cntx.setRenderPath(pth2)

    ## Set the camera angle
    CamO.setEuler(pi/2,0.,-3*pi/2)

    cntx.renderAnim()

    ##########################fifth anim##################################

    ## Set the render path
    pth2 = (pth1 + '5')

    cntx.setRenderPath(pth2)

    ## Set the camera angle
    CamO.setEuler(pi,0.,0.)

    cntx.renderAnim()

    ##########################fifth anim##################################

    ## Set the render path
    pth2 = (pth1 + '6')

    cntx.setRenderPath(pth2)

    ## Set the camera angle
    CamO.setEuler(0.,0.,0.)

    cntx.renderAnim() 


    ## Set the aspect ratio back to it's original setting
    cntx.aspectRatioX(asp1)
    cntx.aspectRatioY(asp2)

    ## Set the image render size back to it's original setting
    cntx.imageSizeX(cntx1)
    cntx.imageSizeY(cntx2)

    ## Set the lens back to it's original setting
    CamG.setLens(Cam1)

    ## set the start and end frames back to their original settings
    cntx.startFrame(fr1)
    cntx.endFrame(fr2)
    
    ## Set the render path back to its original setting
    cntx.setRenderPath(pth1)

    ## Set the camera angle back to it's original setting
    CamO.setEuler(ang1)

    ## enable extensions
    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, 482, 520)
    BGL.glColor3f(0.48, 0.4, 0.57) 		# Light Purple
    BGL.glRectf(4, 479, 480, 510)
    BGL.glRectf(4, 34, 480, 450)
    BGL.glColor3f(0.3, 0.27, 0.35) 		# Dark purple
    BGL.glRectf(4, 451,480, 478)
    BGL.glRectf(4, 4, 480, 33)

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

    BGL.glColor3f(0.9, 0.8, 1)
    BGL.glRasterPos2d(10, 500)
    Draw.Text("BGC - Blender Go Cube v. "+VERSION)
    BGL.glRasterPos2d(10, 484)
    Draw.Text("(C) Feb 2005 Stefano Selleri <a.k.a. S68>")
    Draw.Button("Exit", EVENTHASH['EXIT'], 407, 482, 70, 24)
         
    Draw.Button("GENERATE", EVENTHASH['DO'], 7, 7, 470, 24)
    BGL.glColor3f(0.9, 0.9, 0.9)

    #############################################################
    # Screen                                                    #
    #############################################################
    BGL.glRasterPos2d(10, 425)
    Draw.Text("Rendering Parameters:")

    DATAHASH['SIZE'] =  Draw.Slider(
                        "Image size: ", EVENTHASH['NOEVENT'], 20, 400, 250, 18,
                        DATAHASH['SIZE'].val, 4, 10000, 0,
                        "The image will be a square")

    DATAHASH['FRAME'] =  Draw.Slider(
                        "Frame: ", EVENTHASH['NOEVENT'], 20, 380, 250, 18,
                        DATAHASH['FRAME'].val, 4, 10000, 0,
                        "The frame you want to render")

    DATAHASH['NAME'] =  Draw.String(
                        "Path: ", EVENTHASH['NOEVENT'], 20, 360, 250, 18,
                        DATAHASH['NAME'].val, 128,
                        "You need a full path and an image name without extension")

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

    DATAHASH['TYPE'] = Draw.Menu(types, EVENTHASH['NOEVENT'],
                                 20, 340, 250, 18, 2, "Images will be this type")


#############################################################
# Graphics                                                  #
#############################################################
def draw():
    MainWindow()
    
#############################################################
# Event Handler                                             #
#############################################################
def event(evt, val): 
	if (evt== Draw.QKEY and not val):
		Draw.Exit()

def bevent(evt):
    global EVENTHASH

    if   (evt == EVENTHASH['EXIT']):
        print 'EXIT'
        Draw.Exit()
    elif (evt == EVENTHASH['DO']):
        RenderIt()
        Draw.Redraw()
	
#############################################################
# Registering all functions                                 #
#############################################################

Draw.Register(draw, event, bevent)

This is what I have so far, but the drop down menu for image types doesn’t work yet :frowning:

Oh and s68 I’m working on it all now… so I’ll try to be on #blenderchat if you want to work on it some more see me there, it’s such a waste if we do it independantly and do it double :wink:

cntx.setImageType(Scene.Render.JPG)

doesn’t work :frowning:

it should be JPEG

Fixed the menu by now as well. You forgot to type .val behind the DATAHASH[‘type’] in the if elif statements

Ok done

Go here for the script:

You need a full pyton install though!

http://www.alienhelpdesk.com/index.php?id=16

Cool script guys! good work. Macouno, you keep saying that the script requires a full python install, but I don’t have python installed and the script works just fine.

Really?

In your case what are the images created called then???

The full python install would be needed to get access to the .os module to rename the files after render. I wonder what your result is.

Well… ym first version actually did not use os. so maybe he is using old one :slight_smile:

furthermore the new python API provides some os. workaround… so…

Stefano

I had an idea.

How about we incorporate a cilindrical render in it as well? That shouldn’t be too hard.

Which are the specs?

Stefano

There’s an article on it in the documentation.

But there is a problem… as always.

First off… blender only wants to render with the pano function if the sizex is equal to or larger than sizey

You get all sorts of weirdness when this is not the case.

And then there’s the camera… really to get a true cylindrical panorama you should have a camera that doesn’t focus on a point in the middle but a line at it’s relative “horizon”.

Sadly the camera in blender won’t do that.

So you really want a camera with the highest possible lens value… which means you need lots of parts… for instance 8 parts with a 38.5 camera…

But that makes the “panorama strip” very narrow… it doesn’t have any height to it.

Right now… either you can see a long way above and below with lots of distortion or you get a very vertically narrow view with little distortion.

I haven’t come up with a solution to this yet. And I need those camera angles I posted about in the general thread to figure it out somehow.

Doing some work on this and I can’t figure this out.

What we want is as low a lens setting as possible with a high sizey value a low sizex value and as many parts as possible basicly.

But it’s as if this thing doesn’t work in a linear fashion.

For instance with 64 xparts a 16 lense and 50 as sizex and 1000 as size y I get 56 pixels too many in total width (as an overlap)… it would only be fixaeable if it were 50 pixels cause that’s just 1 part less.