7

So I'm trying to import some actual ascii art into the scripting window's txt editor, aiming to convert it into an extruded 3d mesh to create the basis for some quick mazes.

But upon conversion despite the looking fine in the text editor, the formatting is completely thrown off when it turns into a 3d Object, and messing with the alignment didn't help much.

I feel there is a logical answer to this problem, but have found no way to resolve my issue, any feedback on this would be nice

I feel there is a logical answer to this problem, but have found no way to resolve my issue, any feedback on this would be nice

Chris
  • 59,454
  • 6
  • 30
  • 84
user124502
  • 73
  • 2
  • 1
    I don't really know what you're doing there, that thing on the left is a text object or what? To me it looks like the decades old problem of trying to do something with a proportional font what needs an anti-proportional font. I mean, go into word, put this line art there and format it with Courier New font. I guess it would look okay. Then format it with Arial or Times New Roman and all is broken. Maybe you should choose a different font for the text object? – Gordon Brinkmann May 21 '21 at 08:53

2 Answers2

10

You need to set the font to a monospaced font. BFont is proportional and so the characters are different sizes.

enter image description here

I used Consolas which is a monospaced font, and the text is exactly as it looks in the editor. I believe Consolas ships with Windows.

enter image description here

This is with the default BFont:

enter image description here

Dale Cieslak
  • 2,758
  • 15
  • 16
5

Here is a script which turns ASCII art into fully connected geometry:

enter image description here

It supports the characters "|_/\", and variable font size. By default, it replace the geometry of the active mesh object.

Run it with bpy.MazeGen.ASCIIGrid(D.texts["Maze"], run=True) in the console panel.

import bpy, bmesh

class ASCIIGrid(): def init(self, text, chardims=(0.6, 1.0), run=False, ctx=None): self.text = "\n".join(l.body for l in text.lines) if isinstance(text, bpy.types.Text) else text self.chardims = tuple(chardims) self.ctx = ctx or bpy.context if run: self.Run() def MakeBMesh(self): self.bm = bmesh.new() self.lines = self.text.split("\n") self.height, self.width = len(self.lines)+1, (max(len(l) for l in self.lines)+1)2 self.grid = [[self.bm.verts.new((c/2self.chardims[0], -rself.chardims[1], 0)) for c in range(self.width)] for r in range(self.height)] return self def ConnectBMesh(self): for r, li in enumerate(self.lines): for c, ch in enumerate(li): if ch == "|": self.bm.edges.new((self.grid[r][c2+1], self.grid[r+1][c*2+1])) elif ch == "_": self.bm.edges.new((self.grid[r+1][c*2], self.grid[r+1][c*2+1])) self.bm.edges.new((self.grid[r+1][c*2+1], self.grid[r+1][c*2+2])) elif ch == "/": self.bm.edges.new((self.grid[r+1][c*2], self.grid[r][c*2+2])) elif ch == "\": self.bm.edges.new((self.grid[r][c*2], self.grid[r+1][c*2+2])) return self def FillBMesh(self): for r, ro in enumerate(self.grid): for c, ve in enumerate(ro): if {self.grid[r+1][c] if r < self.height-1 else ..., self.grid[r-1][c] if r else ...}.intersection({v for e in ve.link_edges for v in e.verts}): left, right = self.grid[r][c-1] if c else ..., self.grid[r][c+1] if c < self.width-1 else ... for side in (left, right): if side is ...: continue if side.link_edges: self.bm.edges.new((ve, side)) return self def CleanBMesh(self): used = {v for e in self.bm.edges for v in e.verts} for v in self.bm.verts: if v not in used: self.bm.verts.remove(v) def InjectToMesh(self, mesh=None): if mesh is None: mesh = self.ctx.object.data self.bm.to_mesh(mesh) return self def Run(self, mesh=None): self.MakeBMesh() self.ConnectBMesh() self.FillBMesh() self.CleanBMesh() self.InjectToMesh(mesh=mesh) return self

class O: def init(self, d): self.dict = d

bpy.MazeGen = O(globals())

Will Chen
  • 1,607
  • 8
  • 21