#!/usr/bin/env python
solid_name = 'ASCII_STL_of_a_sphericon_by_CMG_Lee'
n_face_side = 60
r = 1000
import re, io, math
def fmt(string): ## string.format(**vars()) using tags {expression!format} by CMG Lee
def f(tag): i_sep = tag.rfind('!'); return (re.sub('\.0+$', '', str(eval(tag[1:-1])))
if (i_sep < 0) else ('{:%s}' % tag[i_sep + 1:-1]).format(eval(tag[1:i_sep])))
return (re.sub(r'(?<!{){[^{}]+}', lambda m:f(m.group()), string)
.replace('{{', '{').replace('}}', '}'))
def append(obj, string): return obj.append(fmt(string))
def tabbify(cellss, separator='|'):
cellpadss = [list(rows) + [''] * (len(max(cellss, key=len)) - len(rows)) for rows in cellss]
fmts = ['%%%ds' % (max([len(str(cell)) for cell in cols])) for cols in zip(*cellpadss)]
return '\n'.join([separator.join(fmts) % tuple(rows) for rows in cellpadss])
def roundm(x, multiple=1):
if (isinstance(x, tuple)): return tuple(roundm(list(x), multiple))
elif (isinstance(x, list )): return [roundm(x_i, multiple) for x_i in x]
else: return int(math.floor(float(x) / multiple + 0.5)) * multiple
facetss = []
## Find facets
for i_face_side in range(n_face_side + 1):
rad = math.pi * i_face_side / n_face_side
(r_sin,r_cos) = roundm([r * function(rad) for function in [math.sin,math.cos]])
if (i_face_side > 0):
facetss.append([1000 + i_face_side, r, 0,0, 0,-r_cos_old,-r_sin_old, 0,-r_cos,-r_sin])
facetss.append([2000 + i_face_side, -r, 0,0, 0, r_cos_old,-r_sin_old, 0, r_cos,-r_sin])
facetss.append([3000 + i_face_side, 0, r,0, -r_cos_old,0, r_sin_old, -r_cos,0, r_sin])
facetss.append([4000 + i_face_side, 0,-r,0, r_cos_old,0, r_sin_old, r_cos,0, r_sin])
(r_sin_old,r_cos_old) = (r_sin,r_cos)
## Calculate normals
for facets in facetss:
us = [facets[i_xyz + 3] - facets[i_xyz] for i_xyz in range(3)]
vs = [facets[i_xyz] - facets[i_xyz + 6] for i_xyz in range(3)]
normals = [us[1]*vs[2] - us[2]*vs[1], us[2]*vs[0] - us[0]*vs[2], us[0]*vs[1] - us[1]*vs[0]]
normal_length = sum([component * component for component in normals]) ** 0.5
facets += ['%.5f' % (component / normal_length) for component in normals]
facetss = sorted(facetss)
print(tabbify([['s.f'] + ['%s%d' % (xyz, n) for n in range(3) for xyz in list('XYZ')] +
['N%s' % (xyz) for xyz in list('xyz')]] + facetss))
## Compile STL
outs = [fmt('''\
facet normal {facets[10]} {facets[11]} {facets[12]}
outer loop
vertex {facets[1]} {facets[2]} {facets[3]}
vertex {facets[4]} {facets[5]} {facets[6]}
vertex {facets[7]} {facets[8]} {facets[9]}
endloop
endfacet''') for facets in facetss]
with io.open(__file__[:__file__.rfind('.')] + '.stl', 'w', newline='\n') as f_out:
f_out.write('solid %s\n%s\nendsolid %s\n\n## Please keep Python script below\n%s' %
(solid_name, '\n'.join(outs), solid_name, io.open(__file__).read()))