public static bool loadModelSTL_ascii(SimpleModel simpleModel, string filename, FMatrix3x3 matrix) { SimpleVolume vol = new SimpleVolume(); using (StreamReader f = new StreamReader(filename)) { // check for "SOLID" FPoint3 vertex = new FPoint3(); int n = 0; Point3 v0 = new Point3(0, 0, 0); Point3 v1 = new Point3(0, 0, 0); Point3 v2 = new Point3(0, 0, 0); string line = f.ReadLine(); Regex onlySingleSpaces = new Regex("\\s+", RegexOptions.Compiled); while (line != null) { line = onlySingleSpaces.Replace(line, " "); var parts = line.Trim().Split(' '); if (parts[0].Trim() == "vertex") { vertex.x = Convert.ToDouble(parts[1]); vertex.y = Convert.ToDouble(parts[2]); vertex.z = Convert.ToDouble(parts[3]); // change the scale from mm to micrometers vertex *= 1000.0; n++; switch (n) { case 1: v0 = matrix.apply(vertex); break; case 2: v1 = matrix.apply(vertex); break; case 3: v2 = matrix.apply(vertex); vol.addFaceTriangle(v0, v1, v2); n = 0; break; } } line = f.ReadLine(); } } if (vol.faceTriangles.Count > 3) { simpleModel.volumes.Add(vol); return(true); } return(false); }
public static bool loadModelSTL_ascii(SimpleModel simpleModel, string filename, FMatrix3x3 matrix) { SimpleVolume vol = new SimpleVolume(); using (StreamReader f = new StreamReader(filename)) { // check for "SOLID" FPoint3 vertex = new FPoint3(); int n = 0; Point3 v0 = new Point3(0, 0, 0); Point3 v1 = new Point3(0, 0, 0); Point3 v2 = new Point3(0, 0, 0); string line = f.ReadLine(); Regex onlySingleSpaces = new Regex("\\s+", RegexOptions.Compiled); while (line != null) { line = onlySingleSpaces.Replace(line, " "); var parts = line.Trim().Split(' '); if (parts[0].Trim() == "vertex") { vertex.x = Convert.ToDouble(parts[1]); vertex.y = Convert.ToDouble(parts[2]); vertex.z = Convert.ToDouble(parts[3]); // change the scale from mm to micrometers vertex *= 1000.0; n++; switch (n) { case 1: v0 = matrix.apply(vertex); break; case 2: v1 = matrix.apply(vertex); break; case 3: v2 = matrix.apply(vertex); vol.addFaceTriangle(v0, v1, v2); n = 0; break; } } line = f.ReadLine(); } } if (vol.faceTriangles.Count > 3) { simpleModel.volumes.Add(vol); return true; } return false; }
private static bool loadModelSTL_binary(SimpleModel simpleModel, string filename, FMatrix3x3 matrix) { SimpleVolume vol = new SimpleVolume(); using (FileStream stlStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { // load it as a binary stl // skip the first 80 bytes // read in the number of triangles stlStream.Position = 0; BinaryReader br = new BinaryReader(stlStream); byte[] fileContents = br.ReadBytes((int)stlStream.Length); int currentPosition = 80; uint numTriangles = System.BitConverter.ToUInt32(fileContents, currentPosition); long bytesForNormals = numTriangles * 3 * 4; long bytesForVertices = numTriangles * 3 * 4; long bytesForAttributs = numTriangles * 2; currentPosition += 4; long numBytesRequiredForVertexData = currentPosition + bytesForNormals + bytesForVertices + bytesForAttributs; if (fileContents.Length < numBytesRequiredForVertexData || numTriangles < 4) { stlStream.Close(); return(false); } Point3[] vector = new Point3[3]; for (int i = 0; i < numTriangles; i++) { // skip the normal currentPosition += 3 * 4; for (int j = 0; j < 3; j++) { vector[j] = new Point3( System.BitConverter.ToSingle(fileContents, currentPosition + 0 * 4) * 1000, System.BitConverter.ToSingle(fileContents, currentPosition + 1 * 4) * 1000, System.BitConverter.ToSingle(fileContents, currentPosition + 2 * 4) * 1000); currentPosition += 3 * 4; } currentPosition += 2; // skip the attribute vol.addFaceTriangle(vector[2], vector[1], vector[0]); } } if (vol.faceTriangles.Count > 3) { simpleModel.volumes.Add(vol); return(true); } return(false); }
public OptimizedVolume(SimpleVolume volume, OptimizedModel model) { this.model = model; vertices.Capacity = volume.faceTriangles.Count * 3; facesTriangle.Capacity = volume.faceTriangles.Count; Dictionary <int, List <int> > indexMap = new Dictionary <int, List <int> >(); Stopwatch t = new Stopwatch(); t.Start(); for (int i = 0; i < volume.faceTriangles.Count; i++) { OptimizedFace f = new OptimizedFace(); if ((i % 1000 == 0) && t.Elapsed.Seconds > 2) { LogOutput.logProgress("optimized", i + 1, volume.faceTriangles.Count); } for (int j = 0; j < 3; j++) { Point3 p = volume.faceTriangles[i].v[j]; int hash = (int)(((p.x + MELD_DIST / 2) / MELD_DIST) ^ (((p.y + MELD_DIST / 2) / MELD_DIST) << 10) ^ (((p.z + MELD_DIST / 2) / MELD_DIST) << 20)); int idx = 0; bool add = true; if (indexMap.ContainsKey(hash)) { for (int n = 0; n < indexMap[hash].Count; n++) { if ((vertices[indexMap[hash][n]].position - p).testLength(MELD_DIST)) { idx = indexMap[hash][n]; add = false; break; } } } if (add) { if (!indexMap.ContainsKey(hash)) { indexMap.Add(hash, new List <int>()); } indexMap[hash].Add(vertices.Count); idx = vertices.Count; vertices.Add(new OptimizedPoint3(p)); } f.vertexIndex[j] = idx; } if (f.vertexIndex[0] != f.vertexIndex[1] && f.vertexIndex[0] != f.vertexIndex[2] && f.vertexIndex[1] != f.vertexIndex[2]) { //Check if there is a face with the same points bool duplicate = false; for (int _idx0 = 0; _idx0 < vertices[f.vertexIndex[0]].usedByFacesList.Count; _idx0++) { for (int _idx1 = 0; _idx1 < vertices[f.vertexIndex[1]].usedByFacesList.Count; _idx1++) { for (int _idx2 = 0; _idx2 < vertices[f.vertexIndex[2]].usedByFacesList.Count; _idx2++) { if (vertices[f.vertexIndex[0]].usedByFacesList[_idx0] == vertices[f.vertexIndex[1]].usedByFacesList[_idx1] && vertices[f.vertexIndex[0]].usedByFacesList[_idx0] == vertices[f.vertexIndex[2]].usedByFacesList[_idx2]) { duplicate = true; } } } } if (!duplicate) { vertices[f.vertexIndex[0]].usedByFacesList.Add(facesTriangle.Count); vertices[f.vertexIndex[1]].usedByFacesList.Add(facesTriangle.Count); vertices[f.vertexIndex[2]].usedByFacesList.Add(facesTriangle.Count); facesTriangle.Add(f); } } } //fprintf(stdout, "\rAll faces are optimized in %5.1fs.\n",timeElapsed(t)); int openFacesCount = 0; for (int i = 0; i < facesTriangle.Count; i++) { OptimizedFace f = facesTriangle[i]; f.touchingFaces[0] = getFaceIdxWithPoints(f.vertexIndex[0], f.vertexIndex[1], i); f.touchingFaces[1] = getFaceIdxWithPoints(f.vertexIndex[1], f.vertexIndex[2], i); f.touchingFaces[2] = getFaceIdxWithPoints(f.vertexIndex[2], f.vertexIndex[0], i); if (f.touchingFaces[0] == -1) { openFacesCount++; } if (f.touchingFaces[1] == -1) { openFacesCount++; } if (f.touchingFaces[2] == -1) { openFacesCount++; } } //fprintf(stdout, " Number of open faces: %i\n", openFacesCount); }
private static bool loadModelSTL_binary(SimpleModel simpleModel, string filename, FMatrix3x3 matrix) { SimpleVolume vol = new SimpleVolume(); using (FileStream stlStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { // load it as a binary stl // skip the first 80 bytes // read in the number of triangles stlStream.Position = 0; BinaryReader br = new BinaryReader(stlStream); byte[] fileContents = br.ReadBytes((int)stlStream.Length); int currentPosition = 80; uint numTriangles = System.BitConverter.ToUInt32(fileContents, currentPosition); long bytesForNormals = numTriangles * 3 * 4; long bytesForVertices = numTriangles * 3 * 4; long bytesForAttributs = numTriangles * 2; currentPosition += 4; long numBytesRequiredForVertexData = currentPosition + bytesForNormals + bytesForVertices + bytesForAttributs; if (fileContents.Length < numBytesRequiredForVertexData || numTriangles < 4) { stlStream.Close(); return false; } Point3[] vector = new Point3[3]; for (int i = 0; i < numTriangles; i++) { // skip the normal currentPosition += 3 * 4; for (int j = 0; j < 3; j++) { vector[j] = new Point3( System.BitConverter.ToSingle(fileContents, currentPosition + 0 * 4) * 1000, System.BitConverter.ToSingle(fileContents, currentPosition + 1 * 4) * 1000, System.BitConverter.ToSingle(fileContents, currentPosition + 2 * 4) * 1000); currentPosition += 3 * 4; } currentPosition += 2; // skip the attribute vol.addFaceTriangle(vector[2], vector[1], vector[0]); } } if (vol.faceTriangles.Count > 3) { simpleModel.volumes.Add(vol); return true; } return false; }
public OptimizedVolume(SimpleVolume volume, OptimizedModel model) { this.parentModel = model; vertices.Capacity = volume.faceTriangles.Count * 3; facesTriangle.Capacity = volume.faceTriangles.Count; Dictionary <int, List <int> > indexMap = new Dictionary <int, List <int> >(); Stopwatch t = new Stopwatch(); t.Start(); for (int faceIndex = 0; faceIndex < volume.faceTriangles.Count; faceIndex++) { if (MatterSlice.Canceled) { return; } OptimizedFace optimizedFace = new OptimizedFace(); if ((faceIndex % 1000 == 0) && t.Elapsed.Seconds > 2) { LogOutput.logProgress("optimized", faceIndex + 1, volume.faceTriangles.Count); } for (int vertexIndex = 0; vertexIndex < 3; vertexIndex++) { Point3 p = volume.faceTriangles[faceIndex].vertices[vertexIndex]; int hash = (int)(((p.x + MELD_DIST / 2) / MELD_DIST) ^ (((p.y + MELD_DIST / 2) / MELD_DIST) << 10) ^ (((p.z + MELD_DIST / 2) / MELD_DIST) << 20)); int idx = 0; bool add = true; if (indexMap.ContainsKey(hash)) { for (int n = 0; n < indexMap[hash].Count; n++) { if ((vertices[indexMap[hash][n]].position - p).AbsLengthLEQ(MELD_DIST)) { idx = indexMap[hash][n]; add = false; break; } } } if (add) { if (!indexMap.ContainsKey(hash)) { indexMap.Add(hash, new List <int>()); } indexMap[hash].Add(vertices.Count); idx = vertices.Count; vertices.Add(new OptimizedPoint3(p)); } optimizedFace.vertexIndex[vertexIndex] = idx; } if (optimizedFace.vertexIndex[0] != optimizedFace.vertexIndex[1] && optimizedFace.vertexIndex[0] != optimizedFace.vertexIndex[2] && optimizedFace.vertexIndex[1] != optimizedFace.vertexIndex[2]) { //Check if there is a face with the same points bool duplicate = false; for (int _idx0 = 0; _idx0 < vertices[optimizedFace.vertexIndex[0]].usedByFacesList.Count; _idx0++) { for (int _idx1 = 0; _idx1 < vertices[optimizedFace.vertexIndex[1]].usedByFacesList.Count; _idx1++) { for (int _idx2 = 0; _idx2 < vertices[optimizedFace.vertexIndex[2]].usedByFacesList.Count; _idx2++) { if (vertices[optimizedFace.vertexIndex[0]].usedByFacesList[_idx0] == vertices[optimizedFace.vertexIndex[1]].usedByFacesList[_idx1] && vertices[optimizedFace.vertexIndex[0]].usedByFacesList[_idx0] == vertices[optimizedFace.vertexIndex[2]].usedByFacesList[_idx2]) { duplicate = true; } } } } if (!duplicate) { vertices[optimizedFace.vertexIndex[0]].usedByFacesList.Add(facesTriangle.Count); vertices[optimizedFace.vertexIndex[1]].usedByFacesList.Add(facesTriangle.Count); vertices[optimizedFace.vertexIndex[2]].usedByFacesList.Add(facesTriangle.Count); facesTriangle.Add(optimizedFace); } } } //fprintf(stdout, "\rAll faces are optimized in %5.1fs.\n",timeElapsed(t)); int openFacesCount = 0; for (int faceIndex = 0; faceIndex < facesTriangle.Count; faceIndex++) { OptimizedFace optimizedFace = facesTriangle[faceIndex]; optimizedFace.touchingFaces[0] = getOtherFaceIndexContainingVertices(optimizedFace.vertexIndex[0], optimizedFace.vertexIndex[1], faceIndex); optimizedFace.touchingFaces[1] = getOtherFaceIndexContainingVertices(optimizedFace.vertexIndex[1], optimizedFace.vertexIndex[2], faceIndex); optimizedFace.touchingFaces[2] = getOtherFaceIndexContainingVertices(optimizedFace.vertexIndex[2], optimizedFace.vertexIndex[0], faceIndex); if (optimizedFace.touchingFaces[0] == -1) { openFacesCount++; } if (optimizedFace.touchingFaces[1] == -1) { openFacesCount++; } if (optimizedFace.touchingFaces[2] == -1) { openFacesCount++; } } //fprintf(stdout, " Number of open faces: %i\n", openFacesCount); }