#!/usr/bin/env python # coding: utf-8 # In[112]: import os,sys import numpy from stl import mesh import numpy as np prefix = sys.argv[1] print(prefix) # In[113]: def do_svg(self): svg_top = '' else: # Establish SVG canvas that will fit all the data + small space xmin, ymin, xmax, ymax = self.bounds if xmin == xmax and ymin == ymax: # This is a point; buffer using an arbitrary size xmin, ymin, xmax, ymax = self.buffer(1).bounds else: # Expand bounds by a fraction of the data ranges expand = 0.04 # or 4%, same as R plots widest_part = max([xmax - xmin, ymax - ymin]) expand_amount = widest_part * expand xmin -= expand_amount ymin -= expand_amount xmax += expand_amount ymax += expand_amount dx = xmax - xmin dy = ymax - ymin width = min([max([100., dx]), 300]) height = min([max([100., dy]), 300]) # try: # scale_factor = max([dx, dy]) / max([width, height]) # except ZeroDivisionError: scale_factor = 1. view_box = "{} {} {} {}".format(xmin, ymin, dx, dy) #transform = "matrix(1,0,0,-1,0,{})".format(ymax + ymin) return svg_top + ( '>' '{0}' ).format( self.svg(scale_factor)) def stl_to_svg(fname_in): print(fname_in) themeshes = mesh.Mesh.from_file(fname_in) from shapely.geometry import Point, Polygon aX = themeshes.points[:,0::3] aY = themeshes.points[:,1::3] aZ = themeshes.points[:,2::3] def minmax(ptsin): return np.asarray([np.min(ptsin), np.max(ptsin)]) dX = np.diff(minmax(aX)) dY = np.diff(minmax(aY)) dZ = np.diff(minmax(aZ)) arr_so = np.asarray([dX,dY,dZ]).T so_a = np.argsort(arr_so).flatten()[1:] dims_show = [['X','Y','Z'][y] for y in np.sort(so_a)] polys = list() for pts in themeshes.points: d = dict() d['X'] = pts[0::3] d['Y'] = pts[1::3] d['Z'] = pts[2::3] carr = np.asarray([d[dims_show[0]], d[dims_show[1]] ]).T polys.append(Polygon(carr).buffer(0.1)) from shapely.ops import unary_union un = unary_union(polys) with open(fname_in.replace('.stl','.svg'),'w') as f: f.write(do_svg(un)) [stl_to_svg(x) for x in os.listdir() if (x.endswith('.stl') and x.startswith(prefix))]