private bool _LeeSLTBinario(String FicheroSLT) { /*****Binary STL * * Because ASCII STL files can become very large, a binary version of STL exists. A binary STL file has an 80-character header (which is generally ignored, but should never begin with * "solid" because that will lead most software to assume that this is an ASCII STL file). Following the header is a 4-byte unsigned integer indicating the number of triangular facets * in the file. Following that is data describing each triangle in turn. The file simply ends after the last triangle. * * Each triangle is described by twelve 32-bit doubleing-point numbers: three for the normal and then three for the X/Y/Z coordinate of each vertex – just as with the ASCII version of STL. * After these follows a 2-byte ("short") unsigned integer that is the "attribute byte count" – in the standard format, this should be zero because most software does not understand anything else. * * doubleing-point numbers are represented as IEEE doubleing-point numbers and are assumed to be little-endian, although this is not stated in documentation. * * UINT8[80] – Header * UINT32 – Number of triangles * * foreach triangle * REAL32[3] – Normal vector * REAL32[3] – Vertex 1 * REAL32[3] – Vertex 2 * REAL32[3] – Vertex 3 * UINT16 – Attribute byte count * end */ bool Res = true; System.IO.StreamReader SR = new System.IO.StreamReader(FicheroSLT, Encoding.ASCII); //Evalua si es binario o ASCII string LineaSLT = SR.ReadLine(); LineaSLT = LineaSLT.TrimStart(new char[2] { ' ', '\t' }); SR.Close(); SR.Dispose(); if (!LineaSLT.StartsWith("solid ")) { System.IO.FileStream FS = new System.IO.FileStream(FicheroSLT, System.IO.FileMode.Open, System.IO.FileAccess.Read); System.IO.BinaryReader BR = new System.IO.BinaryReader(FS); //Cabecera UINT8[80] – Header for (int i = 0; i < 80; i++) { char TempChar = BR.ReadChar(); if (TempChar != '\0') { Nombre += TempChar; } } //Número de triángulos UINT32 – Number of triangles UInt32 NumTriangulos = BR.ReadUInt32(); if (NumTriangulos > 0) { LoopSLT TempLoop = new LoopSLT(); FacetSLT TempFacet = new FacetSLT(); for (UInt32 Ui = 0; Ui < NumTriangulos; Ui++) { //Vector Normal REAL32[3] – Normal vector TempFacet._Normal = new VertexSLT(Round(BR.ReadSingle()), Round(BR.ReadSingle()), Round(BR.ReadSingle())); //REAL32[3] – Vertex 1 TempLoop.Vertices.Add(new VertexSLT(Round(BR.ReadSingle()), Round(BR.ReadSingle()), Round(BR.ReadSingle()))); //REAL32[3] – Vertex 2 TempLoop.Vertices.Add(new VertexSLT(Round(BR.ReadSingle()), Round(BR.ReadSingle()), Round(BR.ReadSingle()))); //REAL32[3] – Vertex 3 TempLoop.Vertices.Add(new VertexSLT(Round(BR.ReadSingle()), Round(BR.ReadSingle()), Round(BR.ReadSingle()))); TempLoop.ActualizaBoundingZ(); TempFacet._Loops.Add(TempLoop); //Attribute byte count TempFacet._Attribute = BR.ReadUInt16(); if (TempFacet.EsValido()) { _Facets.Add(TempFacet); } else { Res = false; Fallos.Add("Lectura SLT Binario: Faceta no válida"); } TempLoop = new LoopSLT(); TempFacet = new FacetSLT(); } } else { Res = false; Fallos.Add("Lectura SLT Binario: Número de triángulos nulo o igual a 0"); } BR.Close(); FS.Close(); BR.Dispose(); FS.Dispose(); } else { Res = false; Fallos.Add("Lectura SLT Binario: El Fichero comienza por 'solid '"); } return(Res); }
public bool TestSLT() { bool Res = true; //http://www.ennex.com/~fabbers/StL.asp //Verifica la Orientación de cada faceta. foreach (FacetSLT F in _Facets) { foreach (LoopSLT L in F._Loops) { if (L.Vertices.Count() >= 3) { VertexSLT TempV = ProductoVectorialUnitario(L.Vertices[0], L.Vertices[1], L.Vertices[2], true); if (F._Normal.EsIgual(TempV)) { //OK } else { //Redefino el vector normal F._Normal = TempV; } } else { //Fallo, cara con menos de tres vértices Res = false; Fallos.Add("Test SLT: Loop con menos de 3 vértices"); } } } //Verifica la Regla vértice a vértice. //Cada vértice tiene que existir por lo menos 3 veces IList <KeyValuePair <VertexSLT, byte> > ConteoVertices = new List <KeyValuePair <VertexSLT, byte> >(); //Cargo el resumen de vértices verificando que no se dupliquen foreach (FacetSLT F in _Facets) { foreach (LoopSLT L in F._Loops) { foreach (VertexSLT V in L.Vertices) { bool Ex = false; VertexSLT TempV = new VertexSLT(); byte TempCount = 0; for (int iV = 0; iV < ConteoVertices.Count(); iV++) { if (ConteoVertices[iV].Key.EsIgual(V)) { Ex = true; TempV = ConteoVertices[iV].Key; TempCount = ConteoVertices[iV].Value; ConteoVertices.RemoveAt(iV); TempCount++; ConteoVertices.Add(new KeyValuePair <VertexSLT, byte>(TempV, TempCount)); break; } } if (!Ex) { ConteoVertices.Add(new KeyValuePair <VertexSLT, byte>(V, 1)); } } } } //Verifico el resumen de vértices for (int i = 0; i < ConteoVertices.Count(); i++) { if (ConteoVertices[i].Value < 3) { Res = false; Fallos.Add("Test SLT: Fallo en la Regla vértice a vértice"); } } PassTest = Res; return(Res); }
private bool _LeeSLTASCII(String FicheroSLT) { /*****ASCII STL * * An ASCII STL file begins with the line: * * solid name * * Where name is an optional string (though if name is omitted there must still be a space after solid). The file continues with any number of triangles, each represented as follows: * * facet normal ni nj nk * outer loop * vertex v1x v1y v1z * vertex v2x v2y v2z * vertex v3x v3y v3z * endloop * endfacet * * Where each n or v is a doubleing-point number in sign-mantissa-"e"-sign-exponent format, e.g., "2.648000e-002" (noting that each v must be non-negative). The file concludes with: * * endsolid name * * The structure of the format suggests that other possibilities exist (e.g., facets with more than one "loop", or loops with more than three vertices). In practice, however, all facets are simple triangles. * * White space (spaces, tabs, newlines) may be used anywhere in the file except within numbers or words. The spaces between "facet" and "normal" and between "outer" and "loop" are required.*/ bool Res = true; System.IO.StreamReader SR = new System.IO.StreamReader(FicheroSLT, Encoding.ASCII); //Evalua si es binario o ASCII string LineaSLT = SR.ReadLine(); LineaSLT = LineaSLT.TrimStart(new char[2] { ' ', '\t' }); if (LineaSLT.StartsWith("solid ")) { Nombre = LineaSLT.Substring(5); bool FinSolido = false; bool EnFacet = false; bool EnOuterLoop = false; VertexSLT TempVertex = new VertexSLT(); LoopSLT TempLoop = new LoopSLT(); FacetSLT TempFacet = new FacetSLT(); do { LineaSLT = SR.ReadLine(); LineaSLT = LineaSLT.TrimStart(new char[2] { ' ', '\t' }); if (LineaSLT.StartsWith("facet normal ")) { //facet normal ni nj nk if (EnOuterLoop) { Fallos.Add("Lectura SLT ASCII: Nueva Faceta sin cierre correcto de Vértices"); Res = false; } else { //Obtengo el Vertex Normal y lo almaceno LineaSLT = LineaSLT.Substring(12); string[] TempStr = LineaSLT.Split(' '); if (TempStr.Length == 3) { TempFacet._Normal = new VertexSLT(Convert.ToSingle(TempStr[0]), Convert.ToSingle(TempStr[1]), Convert.ToSingle(TempStr[2])); } else { Fallos.Add("Lectura SLT ASCII: El Vector Normal de la Faceta no tiene 3 domensiones"); Res = false; } } EnFacet = true; } else if (LineaSLT == "outer loop") { if (EnOuterLoop) { Fallos.Add("Lectura SLT ASCII: Inicio de Loop sin cierre del anterior"); Res = false; } else { EnOuterLoop = true; } } else if (LineaSLT.StartsWith("vertex ")) { if (EnOuterLoop && EnFacet) { //vertex v1x v1y v1z LineaSLT = LineaSLT.Substring(6); string[] TempStr = LineaSLT.Split(' '); if (TempStr.Length == 3) { TempLoop.Vertices.Add(new VertexSLT(Convert.ToSingle(TempStr[0]), Convert.ToSingle(TempStr[1]), Convert.ToSingle(TempStr[2]))); } else { Fallos.Add("Lectura SLT ASCII: Un Vértice de la Faceta no tiene 3 domensiones"); Res = false; } } else { Fallos.Add("Lectura SLT ASCII: Vértice fuera de un Loop o una Faceta"); Res = false; } } else if (LineaSLT == "endloop" || LineaSLT == "end loop") { if (EnOuterLoop) { TempLoop.ActualizaBoundingZ(); TempFacet._Loops.Add(TempLoop); } else { Fallos.Add("Lectura SLT ASCII: Cierre de Loop incorrecto"); Res = false; } TempLoop = new LoopSLT(); EnOuterLoop = false; } else if (LineaSLT == "endfacet" || LineaSLT == "end facet") { if (EnFacet) { if (TempFacet.EsValido()) { _Facets.Add(TempFacet); } else { Fallos.Add("Lectura SLT ASCII: Faceta no válida"); Res = false; } } else { Fallos.Add("Lectura SLT ASCII: Fin de Faceta no válida"); Res = false; } TempFacet = new FacetSLT(); EnFacet = false; } else if (LineaSLT == "endsolid " + Nombre) { //Fin de sólido if (!EnFacet && !EnOuterLoop) { FinSolido = true; } else { Fallos.Add("Lectura SLT ASCII: Fin de solido sin cierre correcto de Facetas o Vértices"); Res = false; } } else { //No contemplado } }while (!SR.EndOfStream || !FinSolido); } else { Res = false; Fallos.Add("Lectura SLT ASCII: El Fichero no comienza por 'solid '"); } SR.Close(); SR.Dispose(); return(Res); }