1#pragma warning disable 0219
5using System.Collections;
6using System.Collections.Generic;
14 public static class pb_Stl_Importer
16 const int MAX_FACETS_PER_MESH = 65535 / 3;
23 public override string ToString()
25 return string.Format(
"{0:F2}: {1:F2}, {2:F2}, {3:F2}", normal, a, b, c);
32 public static Mesh[] Import(
string path)
38 return ImportBinary(path);
40 catch(System.Exception e)
42 UnityEngine.Debug.LogWarning(
string.Format(
"Failed importing mesh at path {0}.\n{1}", path, e.ToString()));
48 return ImportAscii(path);
52 private static Mesh[] ImportBinary(
string path)
56 using (FileStream fs =
new FileStream(path,
FileMode.Open, FileAccess.Read))
58 using (BinaryReader br =
new BinaryReader(fs,
new ASCIIEncoding()))
61 byte[] header = br.ReadBytes(80);
62 uint facetCount = br.ReadUInt32();
63 facets =
new Facet[facetCount];
65 for(uint i = 0; i < facetCount; i++)
67 facets[i] =
new Facet();
69 facets[i].normal.x = br.ReadSingle();
70 facets[i].normal.y = br.ReadSingle();
71 facets[i].normal.z = br.ReadSingle();
73 facets[i].a.x = br.ReadSingle();
74 facets[i].a.y = br.ReadSingle();
75 facets[i].a.z = br.ReadSingle();
77 facets[i].b.x = br.ReadSingle();
78 facets[i].b.y = br.ReadSingle();
79 facets[i].b.z = br.ReadSingle();
81 facets[i].c.x = br.ReadSingle();
82 facets[i].c.y = br.ReadSingle();
83 facets[i].c.z = br.ReadSingle();
91 return CreateMeshWithFacets(facets);
98 const int ENDLOOP = 5;
99 const int ENDFACET = 6;
100 const int ENDSOLID = 7;
103 private static int ReadState(
string line)
105 if(line.StartsWith(
"solid"))
107 else if(line.StartsWith(
"facet"))
109 else if(line.StartsWith(
"outer"))
111 else if(line.StartsWith(
"vertex"))
113 else if(line.StartsWith(
"endloop"))
115 else if(line.StartsWith(
"endfacet"))
117 else if(line.StartsWith(
"endsolid"))
123 private static Mesh[] ImportAscii(
string path)
125 List<Facet> facets =
new List<Facet>();
127 using(StreamReader sr =
new StreamReader(path))
130 int state = EMPTY, vertex = 0;
134 while(sr.Peek() > 0 && !exit)
136 line = sr.ReadLine().Trim();
137 int previousState = state;
138 state = ReadState(line);
147 f.normal = StringToVec3(line.Replace(
"facet normal ",
""));
155 if(vertex == 0) f.a = StringToVec3(line.Replace(
"vertex ",
""));
156 else if(vertex == 1) f.b = StringToVec3(line.Replace(
"vertex ",
""));
157 else if(vertex == 2) f.c = StringToVec3(line.Replace(
"vertex ",
""));
180 return CreateMeshWithFacets(facets);
183 private static Vector3 StringToVec3(
string str)
185 string[] split = str.Trim().Split(
null);
188 float.TryParse(split[0], out v.x);
189 float.TryParse(split[1], out v.y);
190 float.TryParse(split[2], out v.z);
199 private static bool IsBinary(
string path)
202 FileInfo file =
new FileInfo(path);
204 if(file.Length < 130)
207 var isBinary =
false;
209 using(FileStream f0 = file.OpenRead())
211 using(BufferedStream bs0 =
new BufferedStream(f0))
213 for(
long i = 0; i < 80; i++)
215 var readByte = bs0.ReadByte();
227 using (FileStream f0 = file.OpenRead())
229 using (BufferedStream bs0 =
new BufferedStream(f0))
231 var byteArray =
new byte[6];
233 for (var i = 0; i < 6; i++)
235 byteArray[i] = (byte)bs0.ReadByte();
238 var text = Encoding.UTF8.GetString(byteArray);
239 isBinary = text !=
"solid ";
250 private static Mesh[] CreateMeshWithFacets(IList<Facet> facets)
252 int fl = facets.Count, f = 0, mvc = MAX_FACETS_PER_MESH * 3;
253 Mesh[] meshes =
new Mesh[fl / MAX_FACETS_PER_MESH + 1];
255 for(
int i = 0; i < meshes.Length; i++)
257 int len = System.Math.Min(mvc, (fl - f) * 3);
260 int[] t =
new int[len];
262 for(
int it = 0; it < len; it += 3)
264 v[it ] = facets[f].a;
265 v[it+1] = facets[f].b;
266 v[it+2] = facets[f].c;
268 n[it ] = facets[f].normal;
269 n[it+1] = facets[f].normal;
270 n[it+2] = facets[f].normal;
279 meshes[i] =
new Mesh();
280 meshes[i].vertices = v;
281 meshes[i].normals = n;
282 meshes[i].triangles = t;
System.IO.FileMode FileMode