public void saveDebugSTL(string filename) { #if true OptimizedMesh vol = OptimizedMeshes[0]; using (StreamWriter stream = new StreamWriter(filename)) { BinaryWriter f = new BinaryWriter(stream.BaseStream); Byte[] header = new Byte[80]; f.Write(header); int n = vol.facesTriangle.Count; f.Write(n); for (int i = 0; i < vol.facesTriangle.Count; i++) { // stl expects a normal (we don't care about it's data) f.Write((float)1); f.Write((float)1); f.Write((float)1); for (int vert = 0; vert < 3; vert++) { f.Write((float)(vol.vertices[vol.facesTriangle[i].vertexIndex[vert]].position.X / 1000.0)); f.Write((float)(vol.vertices[vol.facesTriangle[i].vertexIndex[vert]].position.Y / 1000.0)); f.Write((float)(vol.vertices[vol.facesTriangle[i].vertexIndex[vert]].position.Z / 1000.0)); } f.Write((short)0); } } #else char buffer[80] = "MatterSlice_STL_export";
public OptimizedMeshCollection(SimpleMeshCollection simpleMeshCollection) { for (int simpleMeshIndex = 0; simpleMeshIndex < simpleMeshCollection.SimpleMeshes.Count; simpleMeshIndex++) { OptimizedMeshes.Add(null); } Agg.Parallel.For(0, simpleMeshCollection.SimpleMeshes.Count, (simpleMeshIndex) => // for (int simpleMeshIndex = 0; simpleMeshIndex < simpleMeshCollection.SimpleMeshes.Count; simpleMeshIndex++) { OptimizedMeshes[simpleMeshIndex] = new OptimizedMesh(simpleMeshCollection.SimpleMeshes[simpleMeshIndex], this); if (MatterSlice.Canceled) { return; } }); }
public ExtruderData(OptimizedMesh ov, ConfigSettings config) { long initialLayerThickness_um = config.FirstLayerThickness_um; long layerThickness_um = config.LayerThickness_um; modelSize = ov.containingCollection.size_um; modelMin = ov.containingCollection.minXYZ_um; long heightWithoutFirstLayer = modelSize.Z - initialLayerThickness_um + Math.Max(0, modelMin.Z); int countOfNormalThicknessLayers = Math.Max(0, (int)((heightWithoutFirstLayer / (double)layerThickness_um) + .5)); int layerCount = countOfNormalThicknessLayers; if (initialLayerThickness_um > 0) { // we have to add in the first layer (that is a different size) layerCount++; } if (config.outputOnlyFirstLayer) { layerCount = 1; } layers.Capacity = layerCount; for (int layerIndex = 0; layerIndex < layerCount; layerIndex++) { long z; if (layerIndex == 0) { z = initialLayerThickness_um / 2; } else { z = initialLayerThickness_um + layerThickness_um / 2 + layerThickness_um * (layerIndex - 1); } layers.Add(new MeshProcessingLayer(z)); } for (int faceIndex = 0; faceIndex < ov.facesTriangle.Count; faceIndex++) { if (MatterSlice.Canceled) { return; } IntPoint p0 = ov.vertices[ov.facesTriangle[faceIndex].vertexIndex[0]].position; IntPoint p1 = ov.vertices[ov.facesTriangle[faceIndex].vertexIndex[1]].position; IntPoint p2 = ov.vertices[ov.facesTriangle[faceIndex].vertexIndex[2]].position; long minZ = p0.Z; long maxZ = p0.Z; if (p1.Z < minZ) { minZ = p1.Z; } if (p2.Z < minZ) { minZ = p2.Z; } if (p1.Z > maxZ) { maxZ = p1.Z; } if (p2.Z > maxZ) { maxZ = p2.Z; } for (int layerIndex = 0; layerIndex < layers.Count; layerIndex++) { long z = layers[layerIndex].Z; if (z < minZ || z > maxZ) { continue; } SlicePerimeterSegment polyCrossingAtThisZ; if (p0.Z < z && p1.Z >= z && p2.Z >= z) { // p1 p2 // -------- // p0 polyCrossingAtThisZ = GetCrossingAtZ(p0, p2, p1, z); } else if (p0.Z >= z && p1.Z < z && p2.Z < z) { // p0 // -------- // p1 p2 polyCrossingAtThisZ = GetCrossingAtZ(p0, p1, p2, z); } else if (p1.Z < z && p0.Z >= z && p2.Z >= z) { // p0 p2 // -------- // p1 polyCrossingAtThisZ = GetCrossingAtZ(p1, p0, p2, z); } else if (p1.Z >= z && p0.Z < z && p2.Z < z) { // p1 // -------- // p0 p2 polyCrossingAtThisZ = GetCrossingAtZ(p1, p2, p0, z); } else if (p2.Z < z && p1.Z >= z && p0.Z >= z) { // p1 p0 // -------- // p2 polyCrossingAtThisZ = GetCrossingAtZ(p2, p1, p0, z); } else if (p2.Z >= z && p1.Z < z && p0.Z < z) { // p2 // -------- // p1 p0 polyCrossingAtThisZ = GetCrossingAtZ(p2, p0, p1, z); } else { // Not all cases create a segment, because a point of a face could create just a dot, and two touching faces // on the slice would create two segments continue; } polyCrossingAtThisZ.hasBeenAddedToPolygon = false; layers[layerIndex].SegmentList.Add(polyCrossingAtThisZ); } } for (int layerIndex = 0; layerIndex < layers.Count; layerIndex++) { layers[layerIndex].MakePolygons(); } }
public Slicer(OptimizedMesh ov, ConfigSettings config) { int initialLayerThickness_um = config.firstLayerThickness_um; int layerThickness_um = config.layerThickness_um; modelSize = ov.containingCollection.size_um; modelMin = ov.containingCollection.minXYZ_um; long heightWithoutFirstLayer = modelSize.z - initialLayerThickness_um - config.bottomClipAmount_um; int countOfNormalThicknessLayers = Math.Max(0, (int)((heightWithoutFirstLayer / (double)layerThickness_um) + .5)); int layerCount = countOfNormalThicknessLayers; if (initialLayerThickness_um > 0) { // we have to add in the first layer (that is a differnt size) layerCount++; } LogOutput.Log(string.Format("Layer count: {0}\n", layerCount)); layers.Capacity = layerCount; for (int layerIndex = 0; layerIndex < layerCount; layerIndex++) { int z; if (layerIndex == 0) { z = initialLayerThickness_um / 2; } else { z = initialLayerThickness_um + layerThickness_um / 2 + layerThickness_um * (layerIndex - 1); } layers.Add(new MeshProcessingLayer(z)); } for (int faceIndex = 0; faceIndex < ov.facesTriangle.Count; faceIndex++) { Point3 p0 = ov.vertices[ov.facesTriangle[faceIndex].vertexIndex[0]].position; Point3 p1 = ov.vertices[ov.facesTriangle[faceIndex].vertexIndex[1]].position; Point3 p2 = ov.vertices[ov.facesTriangle[faceIndex].vertexIndex[2]].position; long minZ = p0.z; long maxZ = p0.z; if (p1.z < minZ) minZ = p1.z; if (p2.z < minZ) minZ = p2.z; if (p1.z > maxZ) maxZ = p1.z; if (p2.z > maxZ) maxZ = p2.z; for (int layerIndex = 0; layerIndex < layers.Count; layerIndex++) { int z = layers[layerIndex].Z; if (z < minZ || z > maxZ) { continue; } SlicePerimeterSegment polyCrossingAtThisZ; if (p0.z < z && p1.z >= z && p2.z >= z) { // p1 p2 // -------- // p0 polyCrossingAtThisZ = GetCrossingAtZ(p0, p2, p1, z); } else if (p0.z >= z && p1.z < z && p2.z < z) { // p0 // -------- // p1 p2 polyCrossingAtThisZ = GetCrossingAtZ(p0, p1, p2, z); } else if (p1.z < z && p0.z >= z && p2.z >= z) { // p0 p2 // -------- // p1 polyCrossingAtThisZ = GetCrossingAtZ(p1, p0, p2, z); } else if (p1.z >= z && p0.z < z && p2.z < z) { // p1 // -------- // p0 p2 polyCrossingAtThisZ = GetCrossingAtZ(p1, p2, p0, z); } else if (p2.z < z && p1.z >= z && p0.z >= z) { // p1 p0 // -------- // p2 polyCrossingAtThisZ = GetCrossingAtZ(p2, p1, p0, z); } else if (p2.z >= z && p1.z < z && p0.z < z) { // p2 // -------- // p1 p0 polyCrossingAtThisZ = GetCrossingAtZ(p2, p0, p1, z); } else { //Not all cases create a segment, because a point of a face could create just a dot, and two touching faces // on the slice would create two segments continue; } polyCrossingAtThisZ.hasBeenAddedToPolygon = false; layers[layerIndex].SegmentList.Add(polyCrossingAtThisZ); } } for (int layerIndex = 0; layerIndex < layers.Count; layerIndex++) { layers[layerIndex].MakePolygons(); } }