module help

hey guys
im hoping someone could help me here, i’m working on a script at the moment which i have as two files, one which is the main script and a library module.

in the library module i have all the functions and a class, however when i create an instance of the class none of the methods run, including init any help would be appreciated.

and i know this may not be how others would do it but i want to do it this way for a reason.

the main code is as follows

import Blender
import math
import bakingLib
from Blender import *
from Blender.Scene import Render
from bakingLib import *

selObj = Object.GetSelected()[0];
selObjName = selObj.getName();

camTrackObj = Object.Get("Track");
camTrackRef = camTrackObj.getName();

camObj = getSceneCam();

meshRaw = getSelMesh();
faces = meshRaw.faces;

renderHandle = renderer();
renderHandle.initRender;

norms = []
camPos = []
normLength = []

for face in faces:
	norms.append(face.normal);
	camPos.append([i*4 for i in face.normal]);
	normLength.append(vectorLength(face.normal));

for index in range(len(camPos)):
	camTrackObj.setLocation(norms[index][0],norms[index][1],norms[index][2]);
	camObj.setLocation(camPos[index][0],camPos[index][1],camPos[index][2]);
	#context.render();
	renderHandle.doRender;
	Redraw();

the library code is as follows :

def vectorLength(vec = []):
	"""Return the length of a given vector tuple"""
	if len(vec) <> 3:
		return 0;
	else:
		temp = (vec[0]**2) + (vec[1]**2) + (vec[2]**2);
		return math.sqrt(temp);

def getSceneCam ():
	"""Returns the object that the currently active camera is linked to."""
	curScene = Scene.getCurrent();
	sceneCam = curScene.getCurrentCamera();
	camName = sceneCam.getName();
	camObj = Object.Get(camName);
	return camObj

def getSelMesh ():
	"""Returns the raw mesh linked to the currently selected object."""
	meshObj = Object.GetSelected()[0];
	meshName = meshObj.getName();
	meshRaw = NMesh.GetRaw(meshName);
	return meshRaw

class renderer:
	"""Creates an object to deal with all rendering in a predetermined way."""
	curScene = Scene.getCurrent();
	context = curScene.getRenderingContext();

	def __init__ (self):
		print "Render initialised"

	def initRender ():
		"""Set up render parameters."""
		Render.EnableDispWin();
		context.enableExtensions(1);
		context.setRenderPath("C:/myRenderdir/");
		context.sizePreset(Render.PC);
		context.startFrame(1);
		context.endFrame(1);

	def doRender (completion=0):
		"""Render current scene."""
		print "Rendering ", (completion * 100),%	
		context.render();
		Render.CloseRenderWindow

You forgot the ‘self’, argument. All class functions and methods must have ‘self’ as the first argument.
So your class could look something like this:


class renderer: 
	"""Creates an object to deal with all rendering in a predetermined way.""" 

	def __init__(self):
		self.curScene = Scene.getCurrent()
		self.context = self.curScene.getRenderingContext()
		print "Render initialised"

	def initRender(self):
		"""Set up render parameters."""
		Render.EnableDispWin()
		self.context.enableExtensions(1)
		self.context.setRenderPath("C:/myRenderdir/")
		self.context.sizePreset(Render.PC)
		self.context.startFrame(1)
		self.context.endFrame(1)

	def doRender(self, completion=0): 
		"""Render current scene."""
		print "Rendering ", (completion * 100)
		self.context.render()
		Render.CloseRenderWindow()

I made some changes, personally I like to initialize variables in init, but the way you did it works too. Don’t forget that you have to call the initrender method as ‘renderHandle.initrender()’, not ‘renderHandle.initrender’ which just gives you a reference to the function without doing anything. But I suspect that you changed it because you got an error saying that the function takes no arguments, which was because of the missing ‘self’ var.
You don’t have to end every line with a semicolon btw, but it won’t cause problems if you prefer it that way.

thanks eeshlo, i figured out the ‘self’ argument was missing and i made the changes to my class as you suggested, however now i have another problem.

when i try to run the script i get an error ‘global name ‘math’ is not defined’ at the line below the #######################

for face in faces:
	norms.append(face.normal);
	camPos.append([i*4 for i in face.normal]);
	###############################
   normLength.append(vectorLength(face.normal));
	#temp = vectorLength(face.normal)

for index in range(len(camPos)):
	camTrackObj.setLocation(norms[index][0],norms[index][1],norms[index][2]);
	camObj.setLocation(camPos[index][0],camPos[index][1],camPos[index][2]);
	#context.render();				
class
	renderHandle.doRender();
	Redraw();

i presume this is referring to the math.sqrt call in the library module but i cant figure why this is so. i even added an “import math” at the start of the library module to no avail.

if i comment out the line thats causing the errors i get another of the same type in the line “renderHandle.doRender()” above “global name ‘context’ is not defined” which i think goes back to the class but i really cant figure it out.

thanks for the help
timmo

Well, there could be several things wrong. First, if the text is from your actual code, it looks like the offending line uses spaces instead of tabs, like the others. An often made mistake and a source of lots of confusion, but don’t mix spaces with tabs, python doesn’t like that, use either one or the other.

Then, if your module is in another textfile in Blender, which it probably is, when Blender imports a module from a textfile, it stores it. It never is actually reloaded, if there happen to be errors in it, then editing that file won’t work, since the module in memory is loaded, not the textfile. Normally it would be possible to use the reload(modulename) command, but in this case that won’t work either, and I’m actually not sure why that is.

On another note, you are trying to determine the length of a normal vector, which by definiition always has length one. So unless you did that as a test, and actually need it for other things, you could remove it.
If you need it for other things, then you could also omit the sqrt using the math module, and use x**0.5 instead.

However, an even better option, is to use the builtin Blender Mathutils module, then you can do calculations with vectors/matrices & quaternions, without defining your own, and your code probably will end up shorter and be more readable as well.
Printing the length of a vector would then be something like:


from Blender.Mathutils import *

v = Vector([1.0, 2.0, 3.0])
print v.length

as simple as that. See the Blender module documentation for more info:
http://www.blender.org/modules/documentation/234PythonDoc/Mathutils-module.html

Doing it in init makes sure all instance of the object have an independant copy of the variables. Particularly important if you’re initialising mutable variables.

Martin

thanks theeth, i know about putting variables in init however it wasnt really going to be an issue in this case.

timmo