Automatic 3D Text Travels Along Curve

Hi All,
I have been working on a script to automatically make 3D text travel along a curve.
I replaced the faulty code taken from the API documentation with Patrick Grochowy curve generator from the meanderpaths script.

Here is the corrected code:


import Blender
import math
from Blender.Draw import *
from Blender import Mathutils
from Blender.Mathutils import *
from Blender import *
from math import *
#Adjust settings here.
bevelSize = Create(0.2)
stepDist = Create(0.2)
numbSteps = Create(2)       #Number of points -1 created in the curve.
bBoxSize = Create(20)       #Bounding box size.
myTextValue = "Blender Text Moving Along A Path"  #Text that will be created.
# Functions
def makeMeanderPointsCurvy(curveCount,startPoint):
 print " makeMeanderPoints code developed by:"
 print " © October 2007 Patrick Grochowy"
 print " PGR - Kommunikationsdesign - [www.grochowy.de](http://www.grochowy.de)"
 print "
"
 
 meanderPoints = [] # all the meanderPoints into this
 print "numbSteps:" + str(numbSteps.val) + "
"
 xStepDist = baX / numbSteps.val # gesamter X-Bereich durch Anzahl der Schritte
 xStep = 0
 xStartPos = startPoint[0]
 yStartPos = startPoint[1]
 zStartPos = startPoint[2]
 print "  making a curvy curve ..."
 print "  startPoint:",startPoint
 curr_pX = xStartPos
 curr_pY = yStartPos
 curr_pZ = zStartPos
 while ((xStep * xStepDist) < baX):
  pX = curr_pX
  pY = curr_pY
  pZ = curr_pZ
 
  # point calculation start
  rndDir = math.floor((Rand(1,6)))  
  if (rndDir == 1): # nach Rechts
   pX = pX + xStepDist
   pY = pY
   pZ = pZ
  elif (rndDir == 2): # nach Unten
   pX = pX + xStepDist
   pY = pY
   pZ = pZ - xStepDist
   if (pZ < (bbMinZ + bevelSize.val)):
    pZ = bbMinZ + bevelSize.val
  elif (rndDir == 3): # nach Oben
   pX = pX + xStepDist
   pY = pY
   pZ = pZ + xStepDist
   if (pZ > (bbMaxZ - bevelSize.val)):
    pZ = bbMaxZ - bevelSize.val
  elif (rndDir == 4): # nach Nah
   pX = pX + xStepDist
   pY = pY + xStepDist
   if (pY > (bbMaxY - bevelSize.val)):
    pY = bbMaxY - bevelSize.val
   pZ = pZ
  elif (rndDir == 5): # nach Fern
   pX = pX + xStepDist
   pY = pY - xStepDist
   if (pY < (bbMinY + bevelSize.val)):
    pY = bbMinY + bevelSize.val
   pZ = pZ
  # point calculation end
 
  # assign values to the new point
  currPoint = Vector(pX,pY,pZ)
  meanderPoints.append(currPoint)
  print "  currPoint:",currPoint
 
  curr_pX = pX
  curr_pY = pY
  curr_pZ = pZ
  xStep += 1
 return meanderPoints
 
def makeBB(boxSize):
 global selBbObject, bbMinX, bbMaxX, bbMinY, bbMaxY, bbMinZ, bbMaxZ, baX, baY, baZ, centerX, centerY, centerZ
 
 print "Generating bounding box."
 bbMinX = boxSize * -1
 bbMaxX = boxSize
 bbMinY =  boxSize * -1
 bbMaxY = boxSize
 bbMinZ =  boxSize * -1
 bbMaxZ = boxSize
 
 baX = bbMaxX - bbMinX # BoundingAreaX
 baY = bbMaxY - bbMinY # BoundingAreaY
 baZ = bbMaxZ - bbMinZ # BoundingAreaZ
 centerX = bbMinX+(baX/2)
 centerY = bbMinY+(baY/2)
 centerZ = bbMinZ+(baZ/2)
 return True
#Execution begins here.
makeBB(bBoxSize.val)       #Create a bounding box to contain our curve points.
print "Starting text generation."
localScene = Scene.GetCurrent()             #Get a reference to the scene.
myTextName = "ap_Text"      #Temporary name of text, it gets converted to mesh later on.      
localTextObject = Text3d.New(myTextName)       #Create a text object.
localTextObject.setText(myTextValue)         #Set the copy for the text.
localTextObject.setExtrudeDepth(0.01)          #Give it some depth.
 
localObj = localScene.objects.new(localTextObject)    #Add it to the scene.
 
myNewMeshObject = Mesh.New('myFontMesh')        #Create a new mesh container.
myNewMeshObject.getFromObject(localObj,0,0)        #Make this new mesh get it's data from the 3D text already in the scene.
localScene.unlink(localObj)           #We are done with this object, let's get rid of it.
localObj = localScene.objects.new(myNewMeshObject)  #Add this new mesh object to the scene.
 
localObj.makeDisplayList()
localObj.select(1)
print "Finished text generation."
 
print "Starting curve generation."
startingPoints = [] # define list of starting points
Y = Rand()
Z = Rand()
Y = bbMinY + (bevelSize.val / 2) + (fabs(Y) * (fabs(baY) - bevelSize.val))
Z = bbMinZ + (bevelSize.val / 2) + (fabs(Z) * (fabs(baZ) - bevelSize.val))
startingPoints.append(Vector(bbMinX,Y,Z))
print " Also taken from meandering by:"
print " PGR - Kommunikationsdesign - [www.grochowy.de](http://www.grochowy.de)"
curveCount = 1
for vector in startingPoints: # create the curves starting points
 bt = BezTriple.New(vector[0], vector[1], vector[2])
 bt.handleTypes = (BezTriple.HandleTypes.ALIGN, BezTriple.HandleTypes.ALIGN)
 cu = Curve.New("mp-Curve_01")
 cu.appendNurb(bt)
 cu.setFlag(7) # aktiviert 3D; keine Ahnung warum, bzw. wie man das Bitfield angibt
 cu_nurb = cu[0]
 
 for vector in makeMeanderPointsCurvy(curveCount,Vector(vector[0],vector[1],vector[2])):
  mPntBt = BezTriple.New(vector[0], vector[1], vector[2])
  cu_nurb.append(mPntBt)
  cu_nurb.recalc()
 
 for cuBt in cu_nurb:
  cuBt.handleTypes = [BezTriple.HandleTypes.AUTO, BezTriple.HandleTypes.AUTO]
 
 cu_nurb.setType(1)
 cu_nurb.recalc()
 scn = Scene.GetCurrent()
 ob = scn.objects.new(cu)
 ob.setName("ap_Curve")
 localModifiers = localObj.modifiers
 tempMod = localModifiers.append(Modifier.Types.CURVE)
 tempMod[Modifier.Settings.OBJECT] = ob
print "Finished curve generation."
#localCurveObj.makeParent(localTextObject)
#object.select(1) #Select this object.
Draw.Redraw(1)
print "Done."

Open a text window and execute the script. The screen redraw fails at the end, I don’t know why?

Select an object or manipulate the viewport and the generated text along curve object will appear.
If you drag the text along the X-axis, it will travel down the curve.
Now you can key frame locations and or edit the points of the randomly generated curve to fit your needs.

I hope this helps anyone who wanted to automaticall generated 3D text that travels along a curve.:cool: