/// <summary> /// バイナリ形式でのSTLファイル読み込み /// </summary> /// <param name="filePath">ファイルパス</param> /// <returns>正常終了した場合は true、その他の場合は false</returns> /// <remarks>前提としてリトルエンディアンとする</remarks> public bool ReadBinary(string filePath) { // filePath が null か、ファイルが存在しない場合はエラーとする if (filePath == null || File.Exists(filePath) == false) { return(false); } try { // バイナリファイルの読み込み using var reader = new BinaryReader(new FileStream(filePath, FileMode.Open, FileAccess.Read)); // ヘッダ読み込み Header = reader.ReadBytes(HeaderLength); // ファセットの枚数読み込み uint size = reader.ReadUInt32(); // ファイルの残りのバイト数 long rest = reader.BaseStream.Length - reader.BaseStream.Position; // ファセット1枚分のバイト数 const int FacetLength = 50; // ファイルの残りのバイト数が、求められるファセットの枚数分のバイト数より少なければエラー if (rest < FacetLength * size) { return(false); } // 全ファセット読み込み Facets = new StlFacet[size]; for (int i = 0; i < size; ++i) { // ファセット1個分のバイト配列読み込み byte[] bytes = reader.ReadBytes(FacetLength); // ファセットデータ生成と配列への格納 int index = 0; const int offset = sizeof(float); Facets[i] = new StlFacet( new StlVertex( BitConverter.ToSingle(bytes, index), BitConverter.ToSingle(bytes, index += offset), BitConverter.ToSingle(bytes, index += offset)), new StlVertex( BitConverter.ToSingle(bytes, index += offset), BitConverter.ToSingle(bytes, index += offset), BitConverter.ToSingle(bytes, index += offset)), new StlVertex( BitConverter.ToSingle(bytes, index += offset), BitConverter.ToSingle(bytes, index += offset), BitConverter.ToSingle(bytes, index += offset)), new StlVertex( BitConverter.ToSingle(bytes, index += offset), BitConverter.ToSingle(bytes, index += offset), BitConverter.ToSingle(bytes, index += offset)) ); } } catch (Exception) { return(false); } return(true); }
/// <summary> /// テキスト(ASCII)形式でのSTLファイル読み込み /// </summary> /// <param name="filePath">ファイルパス</param> /// <returns>正常終了した場合は true、その他の場合は false</returns> public bool ReadAscii(string filePath) { // filePath が null か、ファイルが存在しない場合はエラーとする if (filePath == null || File.Exists(filePath) == false) { return(false); } try { // テキストファイルの読み込み using (StreamReader reader = new StreamReader(filePath, Encoding.ASCII)) { // ファセットデータの一時格納用リスト var facets = new List <StlFacet>(); // ファセット1個分のデータ生成 var facet = new StlFacet(); // 頂点読み込み時、何個目の頂点か int vertexNumber = 0; // ファイル末尾まで繰り返す while (!reader.EndOfStream) { // ファイルの一行を読み込む string line = reader.ReadLine(); // 一行が空ならスルー if (line == null || line.Length <= 0) { continue; } // 一行の先頭の空白文字を削除 line = line.TrimStart(); if (line.StartsWith("vertex ")) { var text = line.Remove(0, 7); switch (vertexNumber) { case 0: TextToVertex(text, ref facet.Vertex1); break; case 1: TextToVertex(text, ref facet.Vertex2); break; case 2: TextToVertex(text, ref facet.Vertex3); break; } vertexNumber++; } else if (line.StartsWith("facet normal ")) { var text = line.Remove(0, 13); TextToVertex(text, ref facet.Normal); } else if (line.StartsWith("endfacet")) { facets.Add(facet); facet = new StlFacet(); vertexNumber = 0; } else if (line.StartsWith("solid ")) { var header = line.Remove(0, 6); Header = Encoding.ASCII.GetBytes(header); } else if (line.StartsWith("endsolid ")) { var footer = line.Remove(0, 9); Footer = Encoding.ASCII.GetBytes(footer); } // テキストを頂点データに変換する void TextToVertex(string text, ref StlVertex vec) { var values = text.Split(' '); vec.X = float.Parse(values[0], NumberStyles.Float); vec.Y = float.Parse(values[1], NumberStyles.Float); vec.Z = float.Parse(values[2], NumberStyles.Float); } } // ファセットデータの一時格納用リストを配列化してメンバーに設定 Facets = facets.ToArray(); } } catch (Exception) { return(false); } return(true); }