1
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
10 """Store a complete STL-file and do simple manipulations with it"""
11
12 noName="<no name given>"
13
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
28 """Set cached info to nothing"""
29 self._patchInfo=None
30
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
41
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
102
104 for l in self._contents:
105 yield l
106
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
131