Blender 3D: Blending Into Python/OrphanScripts

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Orphan Scripts[edit | edit source]

Hi, post unmaintained scripts here.

Be wary of malicious code, especially the OS module, check in the history every so often for edits to see nobody's doing bad stuff.

Currently there are two scripts here in need of nice mothers or fathers.

This script is a simple L system that allows you to use pre-defined meshes. It DOES work in 2.43 and could possibly be a building generator (with some work).

#
# =====================
# README
# =====================
#
# this is a simple L-system that uses pre-made mesh elemental blocks
#
# source blocks are in a different layer - press tilde (`) in 3d view
# to see them all
#
# a new mesh is created every time; edge creases are carried over from
# source meshes to allow subsurf work
#
# this system uses the turtle concept with pushable/poppable state,
# just like most other L-systems
# however, the "drawing" operation here is to place a pre-made mesh
# instead the usual plant-oriented stuff
# as a result, this should be pretty well suitable for Discombobulator
# style work such as generating lots of small detail
#
# turtle instructions and any other tokens are XML-like tags
# instead of single characters; they can also contain an arbitrary
# argument string
# rewriting rules are actually defined as functions to allow
# procedural flexibility
#
# things left to do really depend on what the actual use is
# some ideas include using lists instead of strings for arbitrary
# argument data (may help with speed); supplying environment
# info to the rule function (for queries, like in some advanced
# L-systems out there) as well as the current model info
# for true Discombobulator-style detail generation there has
# to be a mode to populate the axiom (initial state) with
# existing model faces
#
# of course, more code cleanup is in order
#

import sys
import re

import Blender
from Blender import Mathutils
from Blender import NMesh

substrate = '<LimbArray>'#'<twist:90><turn:90><LimbArray>'

# custom characters and their translations
custom = [ \
	('<Stem>', '<add:Stem><offset:0.5,0,0>'), \
	('<Joint2>', '<add:Joint2Start><offset:0.2,0,0><pitch:-30_0><add:Joint2Middle><turn:-20_20><add:Joint2End><offset:0.2,0,0>') \
	]

print "growing..."

# force recompile of ruleset
if 'ruleset' in sys.modules: del sys.modules['ruleset']
import ruleset

rules = [ (re.compile('<' + name + '(?::([^>]+))?>'), getattr(ruleset, name)) for name in dir(ruleset) ]

# do the matching
for stage in range(20):

	curPos = 0

	while True:
		newPos, newEnd = None, None
		newStr = None
		for regex, func in rules:
			match = regex.search(substrate, curPos)
			if match != None:
				if newPos == None or newPos > match.start():
					newPos = match.start()
					newEnd = match.end()
					newStr = func(match.group(1))

		if newPos == None: break

		substrate = substrate[:newPos] + newStr + substrate[newEnd:]
		curPos += len(newStr)
		
# translate custom chars
for char, repl in custom:
	substrate = re.sub(char, repl, substrate)

print "interpreting..."

# interpret the result
class StackFrame:

	# prev is the parent frame
	def __init__(self, prev=None):
		self.prev = prev
		if prev != None:
			self.matrix = prev.matrix
		else:
			self.matrix = Mathutils.Matrix()
			self.matrix.identity()
			self.matrix.resize4x4()

	# modifications
	def rotate(self, axis, angle):
		rot = Mathutils.RotationMatrix(angle, 4, axis)
		self.matrix = rot * self.matrix
	
	def offset(self, xyz):
		tra = Mathutils.TranslationMatrix(Mathutils.Vector(xyz))
		self.matrix = tra * self.matrix

	def scale(self, ratio):
		sca = Mathutils.Matrix( \
			[ ratio, 0, 0, 0 ], \
			[ 0, ratio, 0, 0 ], \
			[ 0, 0, ratio, 0 ], \
			[ 0, 0, 0, 1 ])
		self.matrix = sca * self.matrix
		
	# raises exception if no parent
	def getPrev(self):
		if self.prev == None:
			raise Exception, "no parent frames"
		return self.prev

	# appends current mesh to given one
	# does NOT change position
	def addMesh(self, meshObj, dest):
		mesh = meshObj.getData()

		vertBase = len(dest.verts)
		for v in mesh.verts:
			vec = Mathutils.Vector(v.co[0], v.co[1], v.co[2], 1)
			vec = vec*self.matrix
			cv = NMesh.Vert(vec.x, vec.y, vec.z)
			dest.verts.append(cv)

		for f in mesh.faces:
			cf = NMesh.Face([ dest.verts[v.index + vertBase] for v in f.v ])
			dest.addFace(cf)
	
		if mesh.edges != None:
			for e in mesh.edges:
				v1, v2 = e.v1, e.v2
				nv1, nv2 = dest.verts[v1.index + vertBase], dest.verts[v2.index + vertBase]
				ne = dest.addEdge(nv1, nv2)
				ne.crease = e.crease
		#dest.update()



# create result mesh
mesh = NMesh.New()
#mesh.addEdgesData() # for things like creases

# do the dew
frame = StackFrame()

# parses and interprets a string of type
# X:Y_Z (randomly choose either X or something between Y and Z)
def number(str):
	import random
	choices = str.split(':')
	choice = random.choice(choices)
	limits = choice.split('_', 2)
	if len(limits) == 2:
		return random.uniform(float(limits[0]), float(limits[1]))
	return float(limits[0])

instrMatch = re.compile(r"""
	<
		(?P<instr1>
			\w+
		)
		(?:
			:
			(?P<arg>
				[^>]+
			)
		)?
	>
	|
	(?P<instr2>
		[\[\]]
	)
	""", re.VERBOSE)
curPos = 0
while True:
	match = instrMatch.search(substrate, curPos)
	if match == None: break

	curPos = match.end()
	
	# collect instruction
	instr = match.group('instr1')
	if instr == None: instr = match.group('instr2')

	arg = match.group('arg')

	# do the dew
	if instr == "[":
		frame = StackFrame(frame)
	elif instr == "]":
		frame = frame.getPrev()
	elif instr == "offset":
		frame.offset([ number(a) for a in arg.split(',', 3) ])
	elif instr == "turn":
		frame.rotate("z", number(arg))
	elif instr == "pitch":
		frame.rotate("y", number(arg))
	elif instr == "twist":
		frame.rotate("x", number(arg))
	elif instr == "scale":
		frame.scale(number(arg))
	elif instr == "add":
		frame.addMesh(Blender.Object.Get(arg), mesh)

NMesh.PutRaw(mesh, "Result", 1, 1)


This script apparently WONT work in blender 2.43, updates welcome.

# Jamesk's Walk-o-matic version 0.49.9 (MODIFIED)
# for Blender 2.25 and a fully installed Python 2.0 [required]
# CHANGES FOR BLENDER 2.36 GENERALLY MARKED '#MDR:' ...
# Badly coded changes for Blender 2.43 by TwinStripe :) ! Appears to perform more passes but produces the same results!?!

# SET/CHECK THE PARAMETERS BELOW BEFORE EXECUTING THE SCRIPT.
# Make sure to select your proxy object, then run the script with ALT+P.
# Please consult the documentation for a full description of the parameters.
# ...Aaaaand check the console window for any messages.

# GENERAL SETTINGS:
FF = FIRST_FRAME = 1        # begin evaluating at this frame
LF = LAST_FRAME = 850       # stop evaluating after this frame

HS = HEEL_SEPARATION = 3.0  # desired distance between heel targets (in Blender Units)
MT = MOVE_TIME = 8.0        # number of frames/cycle a foot is moving
MSD = MOVE_STOP_DELAY = 0   # any value above zero will prolong the time a foot stays in the air.
HEEL_TO_FLAT_DISTANCE = 1   # desired distance between a heel target and its associated foot look-at-target
FLAT_TO_TLAT_DISTANCE = 0.5 # desired distance between a foot look-at-target and its associated toe look-at-target

AL = ALWAYS_LIFT = 0             # set to zero to prevent feet moving up/down when proxy has speed 0
CTD = C_TARG_DISTANCE = 2.0      # how far above proxy to place center target
LA = LIFT_AXIS = 'local'         # lift feet along global Z or local proxy Z?
CTDLA = CTD_LIFT_AXIS = 'global' # raise center target along global Z or local proxy Z?

# NAMES FOR THE EMPTIES:
HEEL_LEFT, HEEL_RIGHT = 'heel.ikt.left', 'heel.ikt.right' 
FLAT_LEFT, FLAT_RIGHT = 'foot.lat.left', 'foot.lat.right' 
TLAT_LEFT, TLAT_RIGHT = 'toe.lat.left', 'toe.lat.right'  
TARGET_CENTRE = 'target.centre'                    

# LIFT ENVELOPE SETTINGS:
LP = LIFT_PEAK = 0.5        # how far to lift above proxy initially 
FLATLP = FLAT_LIFT_PEAK = 0.2 # how far to lift foot look-at-target above proxy initially
TLATLP = TLAT_LIFT_PEAK = 0.2 # how far to lift toe look-at-target above proxy initially
LPT = LIFT_PEAK_TIME = 0.2  # time to reach lift-peak. (relative to movetime)

MP = MID_PEAK = 0.4         # how far from proxy after lift-peak
FLATMP = FLAT_MID_PEAK = 0.4 # how far to lift foot look-at-target
TLATMP = TLAT_MID_PEAK = 0.4 # how far to lift toe look-at-target
MPT = MID_PEAK_TIME = 0.5   # time to reach mid-peak (relative to movetime)

FP = FINAL_PEAK = 0.5       # how far from proxy before setting down again
FLATFP = FLAT_FINAL_PEAK = 0.7 # how far to lift foot look-at-target
TLATFP = TLAT_FINAL_PEAK = 0.9 # how far to lift toe look-at-target
FPT = FINAL_PEAK_TIME = 0.8 # time to reach final_peak (relative to - you guessed it - movetime)


#
# Concept and coding by James Kaufeldt a.k.a. Jamesk 
# Made in Sweden, november 2002
# Contact: james.k@home.se
#
# Special thanx to
# - [d0pamine] and [theeth] for some hints regarding vector math.
# - Martin [Strubi] Strubel from whom I borrowed the "normalize" function,
#   len3(x), dist3(x,y) and sub3(x,y) funcs found in his "vect.py" utility module.
# - [eeshlo] for pointing out how simple it was to give names to the empties.
#
# ---------------------------------------------------------------------------------------
# EDITABLE SECTION ENDS HERE!
#
# NO USER DEFINABLE VALUES BEYOND THIS POINT!
# ---------------------------------------------------------------------------------------
#
#
#
#

LT = MT
CT = MT + LT  

from Blender import Object, Scene, Window, Ipo
from Blender.Scene import Render
from Blender.Window import Types
import sys, math

proxy = Object.GetSelected()

status = 'UNDEFINED ERROR'
Layer = 0
print
print '----------------------------------'
print 'W A L K - O - M A T I C   V 0.49.9'
print '----------------------------------'
print
# make sure that there's an actual walker proxy to use:
if proxy == []:
    print 'No proxy indicated, terminating...'
    status = 'NO PROXY OBJECT SELECTED'
if proxy != []:
    proxy = proxy[0]
    print 'Proxy in use: \t',proxy
    Layer = proxy.Layer
    print ' in Layer',Layer
    status = 'OK'
sys.stdout.flush()

scene = Scene.GetCurrent()

# make sure there's a scene to use (should always be one, but wth...)
if scene == []:
    print 'No scene available, terminating...'
    status = 'NO CURRENT SCENE AVAILABLE'
if scene != []:
    print 'Target scene: \t',scene
sys.stdout.flush()

# some generally useful functions below:
def normalize(v):
    r = math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
    return (v[0]/r, v[1]/r, v[2]/r)

def len3(x):
    return math.sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2])

def sub3(x, y):
    return ((x[0] - y[0]), (x[1] - y[1]), (x[2] - y[2]))

def dist3(x, y):
    return len3(sub3(x, y))

def moveAlong(origpos, distance, vector):
    newpos = [0,0,0]
    newpos[0] = origpos[0]+distance*vector[0]
    newpos[1] = origpos[1]+distance*vector[1]
    newpos[2] = origpos[2]+distance*vector[2]
    return newpos

def invertVector(v):
    return (-v[0], -v[1], -v[2])

#MDR:
def selectFrame(f):
    f = int(f)
    if scene.getRenderingContext().currentFrame() != f:
       scene.getRenderingContext().currentFrame(f)
       Window.Redraw(Window.Types.VIEW3D)

# MDR:
# Conversion routine:  try to get an object, return None if it's not there.
#   Just like Blender used to do.  The easiest way to accomplish this is to
#   allow the exception to occur, and catch it.

def TryGetObject(v):
  try:
    return Object.Get(v)
  except:
    return None


def getOffset(origin, frame, xdir, xdist, forward):
    # origin: the point to offset           frame: framenumber
    # xdir:  1 = positive offset along X, -1 = negative offset
    # xdist: how much to offset
    selectFrame(frame)
    loc = origin.getMatrix()[3]
    loc = moveAlong(loc, forward, normalize(origin.getMatrix()[1]))
    direction = normalize(origin.getMatrix()[0])
    if xdir == -1:
        direction = invertVector(direction)
    return moveAlong(loc, xdist, direction)

def getLiftAxisOffset(origin, frame, liftaxis, liftdist):
    # origin: the point to offset             frame: framenumber
    # liftaxis: 'global' or 'local' lifting   liftdist: the amount of lift    
    selectFrame(frame)
    loc = origin.getMatrix()[3]
    direction = normalize(origin.getMatrix()[2])
    if liftaxis=='global':
        direction = [0,0,1.0]
    return moveAlong(loc, liftdist, direction)

def getElevation(origin, frame, axis, zdist, xdir, xdist, forward):
    # origin: the point to offset     frame: framenumber
    # axis: 'local' or 'global'       zdist: how much to elevate
    # xdir: the X offset              xdist: the distance to offset along X
    loc = getOffset(origin, frame, xdir, xdist, forward)
    if axis=='local':
        direction = normalize(origin.getMatrix()[2])
        return moveAlong(loc, zdist, direction)
    if axis=='global':
        direction = [0, 0, 1.0]
        return moveAlong(loc, zdist, direction)
    
def writeCurvePoint(ipo, frame, point):
    # ipo: the IPOblock to use           frame: at what frame
    # point: the 3D coordinate to write
    xc = ipo.getCurve('LocX')
    yc = ipo.getCurve('LocY')
    zc = ipo.getCurve('LocZ')
    for idx, c in enumerate([xc,yc,zc]):
        c.addBezier((frame, point[idx]))
        c.update()
     
def makeIPO(name, ipol, expol):
    # name: desired name for this IPOblock    ipol: type of interpolation
    # expol: type of extrapolation
    ipo = Ipo.New('Object', name)
    xc = ipo.addCurve('LocX')
    yc = ipo.addCurve('LocY')
    zc = ipo.addCurve('LocZ')
    for curve in [xc, yc, zc]:
        curve.setInterpolation(ipol)
        curve.setExtrapolation(expol)
    return ipo

def move(ipo, origin, destination, startframe, framespan, proxob, xdir, xdist, forward):
    # ipo - what ipo to write points to                 origin - the location (3Dpoint) to start at
    # destination - the location to end up at           startframe - frame to set the first curvepoint at
    # framespan - total number of frames for the move   proxob - the proxy/reference object
    # xdir - pos or neg offset along proxy X-axis       xdist - how much to offset along proxy X-axis
    writeCurvePoint(ipo, startframe, origin)

    if AL==1 or origin!=destination:
        # Write curvepoints for LiftPeak and LiftPeakTime:
        # Pretty hackish formulae for proxyTime here... But they do work, so wtf...
        lpProxyTime = startframe + (LPT*framespan*2)-framespan*0.25
        lpRealTime = startframe+(framespan+MSD)*LPT
        lpLocation = getElevation(proxob, lpProxyTime, LA, LP, xdir, xdist, forward)
        writeCurvePoint(ipo, lpRealTime, lpLocation)
        # Write curvepoints for MidPeak and MidPeakTime:
        mpProxyTime = startframe + (MPT*framespan*2)-framespan*0.25
        mpRealTime = startframe+(framespan+MSD)*MPT
        mpLocation = getElevation(proxob, mpProxyTime, LA, MP, xdir, xdist, forward)
        writeCurvePoint(ipo, mpRealTime, mpLocation)
        # Write curvepoints for FinalPeak and FinalPeakTime:
        fpProxyTime = startframe + (FPT*framespan*2)-framespan*0.25
        fpRealTime = startframe+(framespan+MSD)*FPT
        fpLocation = getElevation(proxob, fpProxyTime, LA, FP, xdir, xdist, forward)
        writeCurvePoint(ipo, fpRealTime, fpLocation)
    
    writeCurvePoint(ipo, startframe+framespan+MSD, destination)
    return (startframe+framespan, destination)

def hold(ipo, location, startframe, framespan):
    # ipo - what ipo to write points to                 # location - the position (3Dpoint) to hold at
    # startframe - the first frame in the hold sequence # framespan - total number of frames to hold
    writeCurvePoint(ipo, startframe+MSD, location)
    writeCurvePoint(ipo, startframe+framespan, location)
    return (startframe+framespan, location)

def recalculator(assignedTargets, targ1, targ2, basetarg):
    # rewrites some globals based on the current arrangement of the empties:
    loc1 = targ1.getLocation()
    loc2 = targ2.getLocation()
    loc3 = basetarg.getLocation()
    # HEEL_SEPARATION:
    if assignedTargets=='heels':
        print 'Default heel empties found. Recalculating:'
        global HS
        HS = dist3(loc1, loc2)
        print 'HEEL_SEPARATION set to',HS
    if assignedTargets=='flats':
        print 'Default foot look-at targets found. Reusing.'
        global HEEL_TO_FLAT_DISTANCE
        HEEL_TO_FLAT_DISTANCE = dist3(loc2, loc3)
        print 'HEEL_TO_FLAT_DISTANCE set to', HEEL_TO_FLAT_DISTANCE
    if assignedTargets=='tlats':
        print 'Default toe look-at targets found. Reusing.'
        global FLAT_TO_TLAT_DISTANCE
        FLAT_TO_TLAT_DISTANCE = dist3(loc2, loc3)
        print 'FLAT_TO_TLAT_DISTANCE set to',FLAT_TO_TLAT_DISTANCE
    

def doIt(forwardOffset, addCenter, whatsUp, firstName, secondName):
    print
    print 'Currently processing:',whatsUp
    # Start building the IPO for the right foot:
    ffootipo = makeIPO('rfoot', 'Linear', 'Constant')
    cpf = currentProxyFrame = FF

    # make first step (only half as far as the others):
    ffootloc = getOffset(proxy, cpf, 1, HS/2, forwardOffset)
    ffootframe = cpf
    targetloc = getOffset(proxy, cpf+MT, 1, HS/2, forwardOffset)
    ffootframe, ffootloc = move(ffootipo, ffootloc, targetloc, ffootframe, MT/2,proxy, 1, HS/2, forwardOffset)
    ffootframe, ffootloc = hold(ffootipo, ffootloc, ffootframe, LT)

    # now make the rest of the steps (full length):
    while True:
        cpf += CT
        targetloc = getOffset(proxy, cpf+MT, 1, HS/2, forwardOffset)
        ffootframe, ffootloc = move(ffootipo, ffootloc, targetloc, ffootframe, MT,proxy, 1, HS/2, forwardOffset)
        ffootframe, ffootloc = hold(ffootipo, ffootloc, ffootframe, LT)
        if cpf>LF:
            break
   
    # Then we'll build the IPO for the left foot:
    sfootipo = makeIPO('lfoot', 'Linear', 'Constant')
    cpf = currentProxyFrame = FF

    # this one starts in hold-mode (waits for right foot to finish)
    sfootloc = getOffset(proxy, cpf, -1, HS/2, forwardOffset)
    sfootframe = cpf
    sfootframe, sfootloc = hold(sfootipo, sfootloc, cpf, MT/2)

    while True:
        cpf += CT
        targetloc = getOffset(proxy, cpf, -1, HS/2, forwardOffset)
        sfootframe, sfootloc = move(sfootipo, sfootloc, targetloc, sfootframe, MT,proxy, -1, HS/2, forwardOffset)
        sfootframe, sfootloc = hold(sfootipo, sfootloc, sfootframe, LT)
        if cpf>LF:
            break

    if addCenter:
        # And to finish it off, let's put something in the middle of this:
        # This will simply add a third target floating above the proxy.
        # It will respect the specified lift axis, hence useful as parent for an armature
        ctargetipo = makeIPO('center', 'Linear', 'Constant')
        for cframe in range(FF, LF):
            targetloc = getLiftAxisOffset(proxy, cframe, CTDLA, CTD)
            writeCurvePoint(ctargetipo, cframe, targetloc)

    # Finished. Add or reuse empties and link them to their respective IPOblocks.
    leftikt = TryGetObject(firstName)
    leftnew = False
    if leftikt==None:
        leftikt = Object.New('Empty')
        leftnew = True
        
    rightikt = TryGetObject(secondName)
    rightnew = False
    if rightikt==None:
        rightikt = Object.New('Empty')
        rightnew = True
    leftikt.name = firstName
    rightikt.name = secondName
    print 'Targets',leftikt,rightikt
    if addCenter:
        centertarget = TryGetObject(TARGET_CENTRE)
        centernew = False
        if centertarget==None:
            centertarget = Object.New('Empty')
            centernew = True
        centertarget.name = TARGET_CENTRE
        print 'Centertarget',centertarget
        centertarget.Layer = Layer
        if centernew: 
			scene.link(centertarget)
		
	    #MDR: 'SetIPO' was 'link'...
        centertarget.setIpo(ctargetipo)
    leftikt.Layer = Layer
    rightikt.Layer = Layer
    if leftnew: 
		scene.link(leftikt)
    if rightnew: 
		scene.link(rightikt)
		
	#MDR: Ditto... 'setIpo' was 'link'...
    leftikt.setIpo(sfootipo)
    rightikt.setIpo(ffootipo)
    print whatsUp,'IPO:s',sfootipo,ffootipo
    print '---------------------------------------------------------'
    sys.stdout.flush()
    


#########################################
# if everything's OK, let's get to work #
#########################################
if status=='OK':
    currentUserFrame = scene.getRenderingContext().currentFrame()

    # grab any walkomat empties left in the scene:
    oldleftheel =TryGetObject(HEEL_LEFT)
    oldrightheel =TryGetObject(HEEL_RIGHT)

    oldleftflat =TryGetObject(FLAT_LEFT)
    oldrightflat =TryGetObject(FLAT_RIGHT)

    oldlefttlat =TryGetObject(TLAT_LEFT)
    oldrighttlat=TryGetObject(TLAT_RIGHT)

    emptyipo = makeIPO('emptydummy', 'Linear', 'Constant')

    # recalculate if there were any such empties:
    if oldleftheel!=None and oldrightheel!=None:
        # assign an empty IPO first to clear any anim:
        # why isn't there some 'unlink' function somewhere???
        #
        # MDR: These 'setIpo' calls were 'link' ....
        #
        oldleftheel.setIpo(emptyipo)
        oldrightheel.setIpo(emptyipo)
        recalculator('heels', oldleftheel, oldrightheel, oldrightheel)

    if oldleftflat!=None and oldrightflat!=None:
        oldleftflat.setIpo(emptyipo)
        oldrightflat.setIpo(emptyipo)
        recalculator('flats', oldleftflat, oldrightflat, oldrightheel)

    if oldlefttlat!=None and oldrighttlat!=None:
        oldlefttlat.setIpo(emptyipo)
        oldrighttlat.setIpo(emptyipo)
        recalculator('tlats', oldlefttlat, oldrighttlat, oldrightflat)

    # first pass, heel targets:
    doIt(0, 1, 'Heel targets', HEEL_LEFT, HEEL_RIGHT)

    #second pass, foot look-at targets:
    LP = FLATLP
    MP = FLATMP
    FP = FLATFP
    doIt(HEEL_TO_FLAT_DISTANCE, 0, 'Foot look-at targets', FLAT_LEFT, FLAT_RIGHT)

    #third pass, toe look-at targets:
    LP = TLATLP
    MP = TLATMP
    FP = TLATFP
    doIt(HEEL_TO_FLAT_DISTANCE+FLAT_TO_TLAT_DISTANCE, 0, 'Toe look-at targets', TLAT_LEFT, TLAT_RIGHT)

    # At last, as a friendly gesture, restore the frame to whatever the user
    # was looking at before running the script, and refresh the screens:  
    scene.getRenderingContext().currentFrame(currentUserFrame)
    Window.RedrawAll()
    print 'Processing completed.'
    print 'Thank you for using Walk-O-Matic :D'
    sys.stdout.flush()

    
###################################################
# if things are not right, print some dying words:#
###################################################
if status!='OK':
    print ''
    print 'Walk-o-matic is sadly forced to report that'
    print 'it could not go to work properly.'
    print 'Cause of termination: ',status
    print 'Please consult the documentation regarding proper use.'
    sys.stdout.flush()