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.
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 #set first to active object (used in parenting) text.splitlines() # split up lines text.rsplit # split up words text # split up letters bpy.ops.object.text_add(view_align = True) # add text object selected = bpy.context.selected_objects # 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.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 #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 #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.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.