hello there,
I’m toying around with using Blender as a text animation tool for a possible gig, and I’ve run into a few bumps.
selecting/ parenting more than one object is not always working - it sometimes works, sometimes doesn’t.
The same problem arises with spacing. I’m trying to space individual 3d text blocks automatically as they are added.
I have a rough sketch on what I want (in the blend file) , and I’m about halfway there .
Ideally, I would like to create an empty parent for each line, and a parent for each paragraph.
http://speedmodeling.org/smcfiles/amdbcg_text%20animation.blend
import bpyimport sys
runningTotal = 1
paragraph = "hello there, this is a testerama
\
This is line two, I'm doing my best
\
to learn how to type, to learn how to try
\
you may wonder why
\
This is paragraph two, it is brand new
\
okay now this is done
"
#"text
#split text into paragraphs and lines
#"
# this does nothing, but has useful commands
def helps(text):
bpy.context.scene.objects.active = bpy.data.objects[0] #set first to active object (used in parenting)
text.splitlines() # split up lines
text.rsplit # split up words
text[2] # split up letters
bpy.ops.object.text_add(view_align = True) # add text object
selected = bpy.context.selected_objects[0] # first active object
last = bpy.data.curves[-1] # select last text item
last.body = out # set last body text to "out"
# find an object. if it exists , return true
def Find(object):
if (bpy.context.scene.objects.find(object) >=1):
return True
else:
return False
# select an object (it sortof works ... any suggestions on alternatives helpful)
def Select(object):
bpy.context.scene.objects.active = bpy.data.objects[object]
# parents the child to the parent object (input 2 strings names)
# note : for some reason this only works if the last one is selected
# helper of out()
def Parent(word, line):
Select(str(line) +"_" + str(word)) # this should be text
Select("line"+str(line))
bpy.ops.object.parent_set(type='OBJECT', xmirror=False, keep_transform=False)
return
#note: this is not called since it's toasted (non functional).
# I was trying to get it to take the cursor location, and increment it based on the size of the word.
# ideally, this is used to place words right after eachother.
def Spacing(line = 1 ,Word = "Text"):
# find line parent
global runningTotal
#parentloc = Select('line'+str(line))
#parentloc = bpy.context.object['parent1'].location.x
w = str(line) + "_"+ str(Word)
word = Select(w)
word = bpy.data.scenes[0].objects[w]
word = word.dimensions.x
cursor = bpy.context.scene.cursor_location
cursor.x = cursor.x + word
return
# just some doodling stuff... it is called (and functional when commented as is)
#- I was working on another function for Spacing()
def cursor(Word,line = 1):
# word = Word
# cursor = bpy.context.scene.cursor_location
# Select(str(line)+"_"+str(word))
# word = bpy.data.objects[Word]
# runningTotal = cursor.x+word.dimensions.x
# cursor.x = runningTotal
# print("active:" + str(bpy.context.scene.objects.active))
return bpy.context.scene.cursor_location
#cursor = bpy.context.scene.cursor_location
#cursor.x = cursor.x + size.x
#loc = (cursor.x, 0, 0)
# return loc
# this is where the text becomes 3d text
# note: this works.
# create a text object and put the word in the 3d view
def out(word, Line = 1):
line = str(Line)
bpy.ops.object.text_add(view_align = True) # add text object
last = bpy.data.curves[-1] # select last text item
last.body =word
bpy.context.scene.objects.active.name =str(line) +"_"+ str(word)
# bpy.ops.transform.translate(value = ((Spacing(line,word)),0,0))
#parent the word to the line,
# print out where the cursor is for debugging purposes
Parent(word,line)
print(cursor(word))
return
# Structure() is used to create empties for controlling paragraphs & lines. input line name, outputs empties
#note: this works,
def Structure( Name = 1):
name = str(Name)
parent = str("parent"+str(name))
FirstParent = Find(parent)
print(FirstParent)
# if no parent is found, add one
if (FirstParent == False):
bpy.ops.object.empty_add(type='PLAIN_AXES')
print("added")
selected = bpy.context.selected_objects[0] #first active obj
selected.name = str("parent"+str(name))
# create a new circle empty and scale it down a bit
bpy.ops.object.empty_add(type='CIRCLE', rotation = (90,0,0))
selected = bpy.context.selected_objects[0] #first active obj
selected.scale.xyz = .3
circle = selected.name = str("line"+str(name))
#parent this empty to the FirstParent (named "parent1",etc)
bpy.context.scene.objects.active = bpy.data.objects[circle]
bpy.context.scene.objects.active = bpy.data.objects[parent]
bpy.ops.object.parent_set(type='OBJECT', xmirror=False, keep_transform=False)
bpy.ops.object.select_all(action = 'DESELECT')
return
#l= [1,2,3,4] #sample
#outList(l)
# helper for out - input a LIST and output using out()
# moves the cursor
def outList(wordList):
while(len(wordList) > 0):
try:
word = wordList.pop(0)
out(str(word))
except(IndexError):
print("caught index error in outList")
break
# reads in the paragraph and outputs single words to parent line empty
# also sets the lines to a parent paragraph empty
# note: this is the main call.
def read(text):
# this works - input is a line number /name
Structure(1)
#read in text and split into lines
#take the first line, and split into words
line = text.splitlines()
lyrics = line[0].rsplit()
outList(lyrics)
return
#call read()
read(paragraph)
#read(paragraph) (done)
# add text object (done)
# send to 3d area (done)
#parent words to a line empty (done)
#-------
#parent lines to a paragraph empty' (sortof done)
#scale it to fit a window (spacing/scaling not done)
#--------
#Spacing() or ideas on how to space individual words would be appreciated.
help or just a brief overview/suggestions would be great.