Package PyFoam :: Package Basics :: Module STLFile
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Basics.STLFile

  1  #  ICE Revision: $Id$ 
  2  """Read a STL file and do simple manipulations""" 
  3   
  4  from os import path 
  5  from PyFoam.Error import error 
  6   
  7  from PyFoam.ThirdParty.six import next as iterNext 
  8   
9 -class STLFile(object):
10 """Store a complete STL-file and do simple manipulations with it""" 11 12 noName="<no name given>" 13
14 - def __init__(self,fName=None):
15 """ 16 @param fName: filename of the STL-file. If None then an empty file is created 17 """ 18 self._filename=fName 19 20 if fName!=None: 21 self._contents=[l.strip() for l in open(fName).readlines()] 22 else: 23 self._contents=[] 24 25 self.resetInfo()
26
27 - def resetInfo(self):
28 """Set cached info to nothing""" 29 self._patchInfo=None
30
31 - def filename(self):
32 """The filename (without the full patch)""" 33 if self._filename==None: 34 return "<no filename given>" 35 else: 36 return path.basename(self._filename)
37
38 - def expectedToken(self,l,token,i):
39 if l.strip().find(token)!=0: 40 error("'%s' expected in line %d of %s" % (token,i+1,self.filename()))
41
42 - def patchInfo(self):
43 """Get info about the patches. A list of dictionaries with the relevant information""" 44 if self._patchInfo: 45 return self._patchInfo 46 47 self._patchInfo=[] 48 49 newPatch=True 50 51 e=enumerate(self._contents) 52 53 goOn=True 54 while goOn: 55 try: 56 i,l=iterNext(e) 57 if newPatch: 58 self.expectedToken(l,"solid",i) 59 info={} 60 if len(l.split())<2: 61 info["name"]=self.noName 62 else: 63 info["name"]=l.split()[1] 64 info["start"]=i+1 65 info["facets"]=0 66 info["min"]=[1e100]*3 67 info["max"]=[-1e100]*3 68 newPatch=False 69 elif l.strip().find("endsolid")==0: 70 info["end"]=i+1 71 self._patchInfo.append(info) 72 newPatch=True 73 else: 74 self.expectedToken(l,"facet normal",i) 75 i,l=iterNext(e) 76 self.expectedToken(l,"outer loop",i) 77 for v in range(3): 78 i,l=iterNext(e) 79 self.expectedToken(l,"vertex",i) 80 info["min"]=[min(m) for m in zip(info["min"], 81 [float(v) for v in l.strip().split()[1:4]])] 82 info["max"]=[max(m) for m in zip(info["max"], 83 [float(v) for v in l.strip().split()[1:4]])] 84 i,l=iterNext(e) 85 self.expectedToken(l,"endloop",i) 86 i,l=iterNext(e) 87 self.expectedToken(l,"endfacet",i) 88 info["facets"]+=1 89 except StopIteration: 90 goOn=False 91 92 93 if not newPatch: 94 error("File",self.filename(),"seems to be incomplete") 95 96 return self._patchInfo
97
98 - def writeTo(self,fName):
99 """Write to a file""" 100 f=open(fName,"w") 101 f.write("\n".join(self._contents))
102
103 - def __iter__(self):
104 for l in self._contents: 105 yield l
106
107 - def __iadd__(self,other):
108 self.resetInfo() 109 110 fName=path.splitext(other.filename())[0] 111 moreThanOne=len(other.patchInfo())>1 112 113 nr=1 114 115 for l in other: 116 if l.strip().find("solid")==0: 117 parts=l.split() 118 if len(parts)==1: 119 l=parts[0]+" "+fName 120 if moreThanOne: 121 l+="_%04d" % nr 122 else: 123 l=parts[0]+" %s:%s" %(fName," ".join(parts[1:])) 124 nr+=1 125 126 self._contents.append(l) 127 128 return self
129 130 # Should work with Python3 and Python2 131