private IList <VertexSLT> Intersection(LoopSLT Loop) { IList <VertexSLT> Res = new List <VertexSLT>(); VertexSLT TempVertex = new VertexSLT(); bool IntInterna = false; for (int i = 1; i < Loop.Vertices.Count; i++) { TempVertex = new VertexSLT(); IntInterna = false; if (Intersection(Loop.Vertices[i - 1], Loop.Vertices[i], out TempVertex, out IntInterna)) { if (IntInterna) { Res.Add(TempVertex); } } } TempVertex = new VertexSLT(); IntInterna = false; if (Intersection(Loop.Vertices[0], Loop.Vertices[Loop.Vertices.Count - 1], out TempVertex, out IntInterna)) { if (IntInterna) { Res.Add(TempVertex); } } 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); }
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 static bool IntLoopPlane(LoopSLT L1, double ZPlano, out LineSLT Corte) { bool Res = false; Corte = new LineSLT(); IList <LineSLT> TempLstCorte = new List <LineSLT>(); //omito los loop contenidos en el plano Z bool Omite = true;; for (int i = 1; i < L1.Vertices.Count; i++) { if (L1.Vertices[i].Z != ZPlano) { Omite = false; break; } } if (!Omite) { for (int i = 1; i < L1.Vertices.Count; i++) { LineSLT TempCorte = new LineSLT(); if (IntLinePlane(new LineSLT(L1.Vertices[i - 1], L1.Vertices[i]), ZPlano, out TempCorte)) { TempLstCorte.Add(TempCorte); } } LineSLT TempCorteCierre = new LineSLT(); if (IntLinePlane(new LineSLT(L1.Vertices[L1.Vertices.Count - 1], L1.Vertices[0]), ZPlano, out TempCorteCierre)) { TempLstCorte.Add(TempCorteCierre); } } if (TempLstCorte.Count == 0) { Res = false; } else { Res = true; //busco los puntos didtintos IList <LineSLT> TempList = new List <LineSLT>(); foreach (LineSLT V in TempLstCorte) { bool TR = false; foreach (LineSLT R in TempList) { if (R.EsIgual(V)) { TR = true; break; } } if (!TR) { TempList.Add(V); } } switch (TempList.Count) { case 1: Corte = TempList[0]; break; case 2: Corte = new LineSLT(TempList[0].V1, TempList[1].V1); break; case 3: if (!TempList[0].V1.EsIgual(TempList[0].V2)) { Corte = new LineSLT(TempList[0].V1, TempList[0].V2); } else if (!TempList[1].V1.EsIgual(TempList[1].V2)) { Corte = new LineSLT(TempList[1].V1, TempList[1].V2); } else if (!TempList[2].V1.EsIgual(TempList[2].V2)) { Corte = new LineSLT(TempList[2].V1, TempList[2].V2); } else { System.Windows.Forms.MessageBox.Show("No se han encontrado vértices distintos en ninguna recta."); } break; case 0: default: System.Windows.Forms.MessageBox.Show("Se han encontrado " + TempList.Count.ToString() + "cortes con el plano Z en un loop."); break; } } return(Res); }