Below are a few funtions I had setup in an old script that can provide some insight to reading, writing and working with data from a text datablock.
Sample writing to a data block:
Pass a mesh object to the function to create a new (or overwrite an existing) text datablock in the current blender session based on the name of the object.
def mesh_to_txt(obj):
txtname = obj.name
verts = [v.co for v in obj.data.vertices]
edges = [e for e in obj.data.edges]
faces = [f for f in obj.data.polygons]
if txtname not in bpy.data.texts:
ntxt = bpy.data.texts.new(txtname)
else:
ntxt = bpy.data.texts[txtname]
ntxt.clear()
# verts
ntxt.write(f"verts = [\n")
for v in verts:
ntxt.write(f"\t{v.to_tuple()},\n")
ntxt.write(f"\t]\n")
# edges
ntxt.write(f"edges = [\n")
for e in edges:
ntxt.write(f"\t[")
for v in e.vertices:
ntxt.write(f"{v},")
ntxt.write(f"],\n")
ntxt.write(f"\t]\n")
# faces
ntxt.write(f"faces = [\n")
for f in faces:
ntxt.write(f"\t[")
for v in f.vertices:
ntxt.write(f"{v},")
ntxt.write(f"],\n")
ntxt.write(f"\t]\n")
A new text block will be created based on the name of the selected object and data formated like so:
verts = [
(1.0, 1.0, 1.0),
(1.0, 1.0, -1.0),
(1.0, -1.0, 1.0),
(1.0, -1.0, -1.0),
(-1.0, 1.0, 1.0),
(-1.0, 1.0, -1.0),
(-1.0, -1.0, 1.0),
(-1.0, -1.0, -1.0),
]
edges = [
[5,7,],
[1,5,],
[0,1,],
[7,6,],
[2,3,],
[4,5,],
[2,6,],
[0,2,],
[7,3,],
[6,4,],
[4,0,],
[3,1,],
]
faces = [
[0,4,6,2,],
[3,2,6,7,],
[7,6,4,5,],
[5,1,3,7,],
[1,0,2,3,],
[5,4,0,1,],
]
Reading data from a text datablock
Function that when given a string name corresponding to a text datablock reads the above format creating lists to use elsewhere. If the name provided txtname
is not found in the currect blend session the return values are empty lists.
def txt_to_mesh(txtname):
verts = []
edges = []
faces = []
line = 0
if txtname in bpy.data.texts:
ntxt = bpy.data.texts[txtname]
else:
return verts, edges, faces
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
if rd_line.startswith('verts'):
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
while rd_line.startswith('\t('):
verts.append(mathutils.Vector(eval(rd_line[1:-1])))
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
# skip to edges or faces
while rd_line.startswith('\t'):
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
if rd_line.startswith('edges'):
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
while rd_line.startswith('\t['):
edges.append(eval(rd_line[1:-1]))
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
# skip to edges or faces
while rd_line.startswith('\t'):
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
if rd_line.startswith('faces'):
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
while rd_line.startswith('\t['):
faces.append(eval(rd_line[1:-1]))
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
# skip to edges or faces
while rd_line.startswith('\t'):
line += 1
ntxt.cursor_set(line, character=0, select=False)
rd_line = ntxt.current_line.body
return verts, edges, faces
Using information read from datablock:
Function to create a mesh object from verts, edges, faces.
def add_mesh(name, verts, faces, edges=None, col_name=""):
if edges is None:
edges = []
mesh = bpy.data.meshes.new(name)
obj = bpy.data.objects.new(mesh.name, mesh)
if bpy.data.collections.get(col_name):
col = bpy.data.collections.get(col_name)
else:
col = bpy.context.scene.collection
col.objects.link(obj)
bpy.context.view_layer.objects.active = obj
mesh.from_pydata(verts, edges, faces)
for line in text.lines: print(line.body)
ortext.as_string()
$\endgroup$