Can't Get Beginner's Script to Run

Just started on my first-ever Blender scipt in Python, and to get me started I copied the beginner’s script off the Wiki (the one on generating a pentagon and creating a GUI). I made sure to put down everything exactly, but it won’t work in 2.41. How can I update it properly to get it to work? I want to start generating my own primitives with Python before moving onto the C/C++ portion to hardcode them, cuz I’m planning on joining Summer of Code 2006. :smiley:

I made sure to put down everything exactly, but it won’t work in 2.41.

What makes you think it is not working?

How can I update it properly to get it to work?

By fixing whatever problems exist. How to do that? Haven’t a clue. If you do not tell us what the symptoms are, all we have are random guesses. So let the guessing begin:

  1. Your computer is not plugged in
  2. You hosed up the indentation in the script.

How is it not working? Details…

does it say something about syntax errors, attribute errors, or name errors?

Aligorith

Some needed elaboration. It went like this: I put down the code exactly as it was from the tutorial. Nothing was changed at all, except for the notations. When I pressed Alt-P, no errors of any sort appeared, but the code just wouldn’t run. I’m sure I had everything properly spaced, since the debugger didn’t nag me for that either.

It would help if you post either the code or a link to the original source.

My guess … without seeing the code… if the code has functions defined in it, but you never actually call them then nothing will happen when you press alt-p

E.g. this code will do “nothing”

def test():
  print 'hello'

but this one will print ‘hello’ (on the console window)

def test():
  print 'hello'

test()

Lesson learned, will always always post code on from now on, rather than assume you will know which tutorial I am trying to point you to.
Presenting the code (it’s from the Python wiki):

Poly Generator Script

importing modules

import Blender
from Blender import NMesh
from Blender.BGL import *
from Blender.Draw import *

import math
from math import *

Polygon parameters

T_NumberOfSides = Create(3)
T_Radius = Create(1.0)

Events

EVENT_NOEVENT = 1
EVENT_DRAW = 2
EVENT_EXIT = 3

############################

GUI drawing

############################
def draw():
global T_NumberOfSides
global T_Radius
global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT

# Titles
glClear(GL_COLOR_BUFFER_BIT)
glRasterPos2d(8, 103)
Text("Demo Polygon Script")

# Parameters GUI Buttons
glRasterPos2d(8, 103)
Text("Parameters: ")
T_NumberOfSides = Number("Number of sides: ", EVENT_NOEVENT, 10, 55, 210, 18,
                T_NumberOfSides.val, 3, 20, "Number of sides out of Polygon");
T_Radius        = Slider("Radius: ", EVENT_NOEVENT, 10, 35, 210, 18,
                T_Radius.val, 0.001, 20.0, 1, "Radius of the Polygon");
                
# Draw and Exit buttons
Button("Draw" , EVENT_DRAW , 10, 10, 80, 18)
Button("Exit" , EVENT_EXIT , 140, 10, 80, 18)
Handling Events##################
def event(evt, val):
    if (evt == QKEY and not val):
            Exit()
            
def bevent(evt):
    global T_NumberOfSides
    global T_Radius
    global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT
    
    # Manages GUI events
    if (evt == EVENT_EXIT):
            Exit()
    elif (evt == EVENT_DRAW):
            Polygon(T_NumberOfSides.val, T_Radius.val)
            Blender.Redraw()
            
# Register the commands
Register(draw,event,bevent)

Script Header (main script)

def Polygon(NumberOfSides,Radius):

# Creates a new polygon
poly = NMesh.GetRaw()

# Populates its vertices
for i in range(0,NumberOfSides):
    phi = 3.141592653589 * 2 * i / NumberOfSides
    x = Radius * cos(phi)    # X coordinates
    y = Radius * sin(phi)    # Y coordinates
    z = 0                    # Z coordinates
    
    v = NMesh.Vert(x,y,z)
    poly.verts.append(v)    # append polygon from V
    
    # Adds a new vertex to the center
    v = NMesh.vert(0.,0.,0.)
    poly.verts.append(v)
    
    # Connects the verts to form a face
    for i in range(0,NumberOfSides):
            f = NMesh.Face()
            f.v.append(poly.verts[i])
            f.v.append(poly.verts[(i+1)%NumberOfSides])
            f.v.append(poly.verts[NumberOfSides])
            poly.faces.append(f)

    # Creats a new Object with the new Mesh
    polyObj = NMesh.PutRaw(poly)
    
    Blender.Redraw()

Yup, there’s the code. And the test mstram gave me does work correctly in the console window.

Ok, first, when you post code here, after you paste or type it into the message , highlight it all and then click on the # thingy which will preserve any indentation. At first I was going to say that all of the indentation was missing until I previewed a message using the '#" thing.

Two things prevented it from working

  1. Incorrect indentation - Python is one of the only programming languages (that I know of), where whitespace (tabs, spaces) is significant. When you enter a def or for or if, the following code has to be indented. And a ‘def’ has to start at the left margin … unless you actually want to define a function within a function … which confusingly enough is legal

  2. The code

# Adds a new vertex to the center
        v = NMesh.vert(0.,0.,0.)

‘vert’ acutally has to be capitlized (Vert). You would have found that out if the code was indented properly, you would have received an error message 'AttributeError:‘module’ object has no attribute ‘vert’. As I did after fixing the indentation :slight_smile:

To find out what the problem was I ran the ‘dir’ python command on NMesh like :

print dir(NMesh) 

or even better :

for i in dir(NMesh):
  print i

which prints :

----- <module 'Blender.NMesh' (built-in)> -----------
Col
...
....
.
Vert

And we see that the last entry printed is in fact Vert :slight_smile:

The dir() function is very handy.

If you create a function like this :

def dd(o):
   print '------------',o,'-----------'
   for i in dir(o):
      print i
   print '-----------------------'

Then you can put code like this:

dd(NMesh)

in your script for debugging / learning what methods and attributes are available.

E.g. You can start a script with


import Blender

def dd(o):
   print '------------',o,'-----------'
   for i in dir(o):
      print i
   print '-----------------------'

dd(Blender)

Which will print out :

Armature
BGL
BezTriple
..
...
...

And then you can do a

dd(Blender.Armature)

… And so on

You can download the entire Blender Python API docs from here:
here

One other point, the code :

Register(draw,event,bevent)

is what ‘activates’ the gui. That line especially if not at the left margin will
cause the script to ‘do nothing’. Moving it out to margin ‘activated’ it, (which
triggered a bunch of other errors caused by improper indentation)

It’s also a good idea to have it at the bottom of the script after all of the
other functions are defined. Python usually requires that, I’m not sure why
the Polygon function was still working even with it’s definition physically later
in the script than where it was called (in the bevent function)

Finally here is the working code :slight_smile:

Mike

# importing modules
import Blender
from Blender import NMesh
from Blender.BGL import *
from Blender.Draw import *

import math
from math import *

# Polygon parameters
T_NumberOfSides = Create(3)
T_Radius        = Create(1.0)

# Events
EVENT_NOEVENT = 1
EVENT_DRAW = 2
EVENT_EXIT = 3

############################
##    GUI drawing    ############
############################
def draw():
    global T_NumberOfSides
    global T_Radius
    global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT
    
    # Titles
    glClear(GL_COLOR_BUFFER_BIT)
    glRasterPos2d(8, 103)
    Text("Demo Polygon Script")
    
    # Parameters GUI Buttons
    glRasterPos2d(8, 103)
    Text("Parameters: ")
    T_NumberOfSides = Number("Number of sides: ", EVENT_NOEVENT, 10, 55, 210, 18,
                    T_NumberOfSides.val, 3, 20, "Number of sides out of Polygon");
    T_Radius        = Slider("Radius: ", EVENT_NOEVENT, 10, 35, 210, 18,
                    T_Radius.val, 0.001, 20.0, 1, "Radius of the Polygon");
                    
    # Draw and Exit buttons
    Button("Draw" , EVENT_DRAW , 10, 10, 80, 18)
    Button("Exit" , EVENT_EXIT , 140, 10, 80, 18)
    
##### Handling Events##################
def event(evt, val):
	if (evt == QKEY and not val):
		Exit()
                
def bevent(evt):
	global T_NumberOfSides
	global T_Radius
	global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT
  
	# Manages GUI events
	if (evt == EVENT_EXIT):
		Exit()
	elif (evt == EVENT_DRAW):
		Polygon(T_NumberOfSides.val, T_Radius.val)
		Blender.Redraw()
                
    
# Script Header (main script)
def Polygon(NumberOfSides,Radius):
	# Creates a new polygon
	poly = NMesh.GetRaw()
    
    # Populates its vertices
	for i in range(0,NumberOfSides):
		phi = 3.141592653589 * 2 * i / NumberOfSides
		x = Radius * cos(phi)    # X coordinates
		y = Radius * sin(phi)    # Y coordinates
		z = 0                    # Z coordinates
		v = NMesh.Vert(x,y,z)
		poly.verts.append(v)    # append polygon from V
		# Adds a new vertex to the center
		v = NMesh.Vert(0.,0.,0.)
		poly.verts.append(v)
    # Connects the verts to form a face
	
	for i in range(0,NumberOfSides):
		f = NMesh.Face()
		f.v.append(poly.verts[i])
		f.v.append(poly.verts[(i+1)%NumberOfSides])
		f.v.append(poly.verts[NumberOfSides])
		poly.faces.append(f)
		
		# Creats a new Object with the new Mesh
	polyObj = NMesh.PutRaw(poly)

# Register the commands

Register(draw,event,bevent)
Blender.Redraw()


   ##############################################
   ### debug  code to check valid 'NMesh' members
   ## and functions

def dd(o):
	print '-----------',o,'-----------'
	for i in dir(o):
		print i
	print '------------------------'

dd(NMesh)

Thank you for the explanation, mstram. Originally I thought I had copied the code the way it was from the tute and then that I would have to update it somehow to Python 2.4, but it was just human error on my part.:o
The code does run on my end. Thanks again; I’ll be working on generating my own primitives now. :slight_smile:

Hah! /me high-fives himself and congratulates his psychotic powers: