PDA

View Full Version : Convert Font Object To Mesh



Atom
09-Nov-07, 09:09
Hi All,

I have created a 3d text object using python code.
I have extruded it via python code.
Now I want to convert it to a mesh via python code.
I have looked in the API under Object and Mesh and Text and Font, but I can not find the function or method to convert a text object to a mesh.

Is there a way to simply invoke the menu command of the 3D viewport?

Or is there a better way to achieve this?

Thanks

pgr1973
09-Nov-07, 10:57
Maybe the 'getFromObject()' Method of the class Mesh?

http://www.blender.org/documentation/245PythonDoc/Mesh.Mesh-class.html#getFromObject

Don't know, if that's the way, but I would start trying from there ...

Regards Paddy

iliketosayblah
09-Nov-07, 12:27
there is a way to convert text to mesh but it isnt a script. alt+c when text selected (not edit mode)

Atom
09-Nov-07, 12:53
pgr1973,

So how do I use the method?
This is my problem with the API, there is no example code.
Here is what I have...


myTextValue = "Blender Text Moving Along A Path"
myTextName = "ap_Text"
localTextObject = Text3d.New(myTextName)
localTextObject.setText(myTextValue)
localTextObject.setExtrudeDepth(0.01)
localScene = Scene.GetCurrent()
localObj = localScene.objects.new(localTextObject)
localObj.makeDisplayList()
localObj.select(1)

So now I need something like this...


myNewMeshObject = getFromObject(localObj,0,0)

Does anyone know how to invoke this method?

pgr1973
09-Nov-07, 13:21
When I need something I don't quite know how to use, I always let my editor (jEdit in my case) search the whole .blender/scripts directory for the Method (in this case). Most of the times a Method is already been used by another script, and I can get clues on how to use it.

Looking at your code I would think, that you first have to create your new Mesh object
e.g.

myNewMeshObject = Mesh.New('myNewMesh')
and after that you can assign the Mesh data to it with


myNewMeshObject.getFromObject(localObj,0,0)

Probably you need to change the 'localObj' to something like localObj.name or localObj[0] or something like that (depending on whatever localObj actually is). If you don't know that, just let Blender print it on the console, e.g.


print "localObj is:",localObj

Taking a second look at your code-snippet, I think you don't need 'localObj' at all, but can use 'localTextObject' as data-source for your new Mesh. But I'm just guessing.

Blender also put's out errors on the console, so if assigning something to something results in an error, it probably tells you what went wrong there (including line numbers of the script).

When Blender created your new 'myNewMeshObject' you have to link it to the current scene.

Atom
11-Nov-07, 09:19
I appreciate you taking the time to comment.

Here is my latest version:


import Blender
from Blender import *

localScene = Scene.GetCurrent() #Get a reference to the scene.

myTextValue = "Blender Text Moving Along A Path"
myTextName = "ap_Text"
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.
localObj = localScene.objects.new(myNewMeshObject) #Add this new mesh object to the scene.

localObj.makeDisplayList()
localObj.select(1)

This does work, but it leaves a copy of the original font3d object in the scene.

How would I delete that via code?

Ideally, I would like to avoid adding the 3d font to the scene, but getFromObject only operates on objects in the scene, not objects created locally via code.

pgr1973
12-Nov-07, 08:28
http://www.blender.org/documentation/245PythonDoc/Scene.Scene-class.html#unlink

Atom
12-Nov-07, 13:32
I have gotten a little further.

Here is my latest script:


import Blender
import math
from Blender import Mathutils
from Blender.Mathutils import *
from Blender import *
from math import *
def bezFromVecs(vecs):
bt= BezTriple.New(vecs[0].x, vecs[0].y, vecs[0].z, vecs[1].x, vecs[1].y, vecs[1].z, vecs[2].x, vecs[2].y, vecs[2].z)
bt.handleTypes= (BezTriple.HandleTypes.FREE, BezTriple.HandleTypes.FREE)
return bt
def bezList2Curve(bezier_vecs):
# Create the curve data with one point
cu= Curve.New()
cu.appendNurb(bezFromVecs(bezier_vecs[0])) # We must add with a point to start with
cu_nurb= cu[0] # Get the first curve just added in the CurveData
i= 1 # skip first vec triple because it was used to init the curve
while i<len(bezier_vecs):
bt_vec_triple= bezier_vecs[i]
bt= bezFromVecs(bt_vec_triple)
cu_nurb.append(bt)
i+=1
# Add the Curve into the scene
scn= Scene.GetCurrent()
ob = scn.objects.new(cu)
return ob

def vecList2bezList(vecs, smoothness):
smoothness = smoothness * 0.5
if len(vecs) == 0:
return [[[0,0,0],[0,0,0],[0,0,0]]]
if len(vecs) == 1:
return [[vecs[0],vecs[0],vecs[0]]]
if len(vecs) == 2:
return [[vecs[0],vecs[0],vecs[1]],[vecs[0],vecs[1],vecs[1]]]
newbezlist = [[vecs[0],vecs[0],vecs[0]+smoothness*(2 * vecs[1] - vecs[0] - vecs[2])]]
for i in xrange(1,len(vecs) - 1):
newbezlist.append([vecs[i]-smoothness*(vecs[i+1] - vecs[i-1]),vecs[i],vecs[i]+smoothness*(vecs[i+1] - vecs[i-1])])
newbezlist.append([vecs[-1]+smoothness*(2*vecs[-2] - vecs[-1] - vecs[-3]),vecs[-1],vecs[-1]])
return newbezlist
print "Starting text generation."
localScene = Scene.GetCurrent() #Get a reference to the scene.

myTextValue = "Blender Text Moving Along A Path"
myTextName = "ap_Text"
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."
#Build a three point curve.
localCurvePoints = []
localCurvePoints.append(Vector(0,10,-10))
localCurvePoints.append(Vector(0,0,0))
localCurvePoints.append(Vector(0,10,10))
localCurveObj = bezList2Curve(vecList2bezList(localCurvePoints,0.5 ))
localCurveObj.setName("ap_Curve")
localModifiers = localObj.modifiers
tempMod = localModifiers.append(Modifier.Types.CURVE)
tempMod[Modifier.Settings.OBJECT] = localCurveObj
print "Finished curve generation."

print "Done."


This does work, but there is a strange anomaly where the text crosses over the zero-point of the curve. My font mesh gets stretched and inverted when it crosses the center of the curve.

Try this:
1.) Run the script posted.
2.) Delselct all and select the font mesh.
3.) Activate the grab tool and drag along the X axis (red arrow) and observe the error as it crosses the center of the curve.

My guess is that the problem is in the generation of the curve.

That's odd, I can't add an image attachment to a reply...:no: