public static string[] GetStlFileLocations(string fileToSlice) { int extruderCount = ActiveSliceSettings.Instance.ExtruderCount; switch (Path.GetExtension(fileToSlice).ToUpper()) { case ".STL": case ".GCODE": return(new string[] { fileToSlice }); case ".AMF": List <MeshGroup> meshGroups = MeshFileIo.Load(fileToSlice); List <MeshGroup> extruderMeshGroups = new List <MeshGroup>(); for (int extruderIndex = 0; extruderIndex < extruderCount; extruderIndex++) { extruderMeshGroups.Add(new MeshGroup()); } int maxExtruderIndex = 0; foreach (MeshGroup meshGroup in meshGroups) { foreach (Mesh mesh in meshGroup.Meshes) { MeshMaterialData material = MeshMaterialData.Get(mesh); int extruderIndex = Math.Max(0, material.MaterialIndex - 1); maxExtruderIndex = Math.Max(maxExtruderIndex, extruderIndex); if (extruderIndex >= extruderCount) { extruderMeshGroups[0].Meshes.Add(mesh); } else { extruderMeshGroups[extruderIndex].Meshes.Add(mesh); } } } List <string> extruderFilesToSlice = new List <string>(); for (int i = 0; i < extruderMeshGroups.Count; i++) { MeshGroup meshGroup = extruderMeshGroups[i]; List <int> materialsToInclude = new List <int>(); materialsToInclude.Add(i + 1); if (i == 0) { for (int j = extruderCount + 1; j < maxExtruderIndex + 2; j++) { materialsToInclude.Add(j); } } extruderFilesToSlice.Add(SaveAndGetFilenameForMaterial(meshGroup, materialsToInclude)); } return(extruderFilesToSlice.ToArray()); default: throw new NotImplementedException(); } }
private void trackballTumbleWidget_DrawGlContent(object sender, EventArgs e) { for (int groupIndex = 0; groupIndex < MeshGroups.Count; groupIndex++) { MeshGroup meshGroupToRender = MeshGroups[groupIndex]; int part = 0; foreach (Mesh meshToRender in meshGroupToRender.Meshes) { MeshMaterialData meshData = MeshMaterialData.Get(meshToRender); RGBA_Bytes drawColor = GetMaterialColor(meshData.MaterialIndex); if (meshGroupToRender == SelectedMeshGroup) { drawColor = GetSelectedMaterialColor(meshData.MaterialIndex); } RenderMeshToGl.Render(meshToRender, drawColor, MeshGroupTransforms[groupIndex].TotalTransform, RenderType); part++; } } foreach (InteractionVolume interactionVolume in interactionVolumes) { interactionVolume.DrawGlContent(e); } // we don't want to render the bed or bulid volume before we load a model. if (MeshGroups.Count > 0 || AllowBedRenderingWhenEmpty) { if (RenderBed) { RenderMeshToGl.Render(printerBed, this.BedColor); } if (buildVolume != null && RenderBuildVolume) { RenderMeshToGl.Render(buildVolume, this.BuildVolumeColor); } if (false) // this is code to draw a small axis indicator { double big = 10; double small = 1; Mesh xAxis = PlatonicSolids.CreateCube(big, small, small); RenderMeshToGl.Render(xAxis, RGBA_Bytes.Red); Mesh yAxis = PlatonicSolids.CreateCube(small, big, small); RenderMeshToGl.Render(yAxis, RGBA_Bytes.Green); Mesh zAxis = PlatonicSolids.CreateCube(small, small, big); RenderMeshToGl.Render(zAxis, RGBA_Bytes.Blue); } } }
public static Mesh DoMerge(List <MeshGroup> meshGroupsToMerge, MeshOutputSettings outputInfo) { Mesh allPolygons = new Mesh(); if (outputInfo.CsgOptionState == MeshOutputSettings.CsgOption.DoCsgMerge) { foreach (MeshGroup meshGroup in meshGroupsToMerge) { foreach (Mesh mesh in meshGroup.Meshes) { allPolygons = CsgOperations.Union(allPolygons, mesh); } } } else { foreach (MeshGroup meshGroup in meshGroupsToMerge) { foreach (Mesh mesh in meshGroup.Meshes) { int currentMeshMaterialIntdex = MeshMaterialData.Get(mesh).MaterialIndex; if (outputInfo.MaterialIndexsToSave == null || outputInfo.MaterialIndexsToSave.Contains(currentMeshMaterialIntdex)) { foreach (Face face in mesh.Faces) { List <Vertex> faceVertices = new List <Vertex>(); foreach (FaceEdge faceEdgeToAdd in face.FaceEdges()) { // we allow duplicates (the true) to make sure we are not changing the loaded models acuracy. Vertex newVertex = allPolygons.CreateVertex(faceEdgeToAdd.firstVertex.Position, CreateOption.CreateNew, SortOption.WillSortLater); faceVertices.Add(newVertex); } // we allow duplicates (the true) to make sure we are not changing the loaded models acuracy. allPolygons.CreateFace(faceVertices.ToArray(), CreateOption.CreateNew); } } } } allPolygons.CleanAndMergMesh(); } return(allPolygons); }
private static void ReadMesh(XmlReader xmlTree, MeshGroup meshGroup, double scale, ProgressData progressData) { List <Vector3> vertices = new List <Vector3>(); while (xmlTree.Read()) { switch (xmlTree.Name) { case "vertices": using (XmlReader verticesTree = xmlTree.ReadSubtree()) { ReadVertices(verticesTree, vertices, scale, progressData); if (progressData.LoadCanceled) { return; } } break; case "volume": string materialId = xmlTree["materialid"]; Mesh loadedMesh = null; using (XmlReader volumeTree = xmlTree.ReadSubtree()) { loadedMesh = ReadVolume(volumeTree, vertices, progressData); if (progressData.LoadCanceled) { return; } meshGroup.Meshes.Add(loadedMesh); } if (loadedMesh != null && materialId != null) { MeshMaterialData material = MeshMaterialData.Get(loadedMesh); material.MaterialIndex = int.Parse(materialId); } break; } } }
void trackballTumbleWidget_DrawGlContent(object sender, EventArgs e) { for (int groupIndex = 0; groupIndex < MeshGroups.Count; groupIndex++) { MeshGroup meshGroupToRender = MeshGroups[groupIndex]; int part = 0; foreach (Mesh meshToRender in meshGroupToRender.Meshes) { MeshMaterialData meshData = MeshMaterialData.Get(meshToRender); RGBA_Bytes drawColor = GetMaterialColor(meshData.MaterialIndex); if (meshGroupToRender == SelectedMeshGroup) { drawColor = GetSelectedMaterialColor(meshData.MaterialIndex); } RenderMeshToGl.Render(meshToRender, drawColor, MeshGroupTransforms[groupIndex].TotalTransform, RenderType); part++; } } foreach (InteractionVolume interactionVolume in interactionVolumes) { interactionVolume.DrawGlContent(e); } // we don't want to render the bed or bulid volume before we load a model. if (MeshGroups.Count > 0 || AllowBedRenderingWhenEmpty) { if (RenderBed) { RenderMeshToGl.Render(printerBed, this.BedColor); } if (buildVolume != null && RenderBuildVolume) { RenderMeshToGl.Render(buildVolume, this.BuildVolumeColor); } } }
public static IPrimitive Convert(PolygonMesh.MeshGroup meshGroup, MaterialAbstract partMaterial = null) { List <IPrimitive> renderCollection = new List <IPrimitive>(); SolidMaterial otherMaterial = new SolidMaterial(new RGBA_Floats(.1, .2, .9), .01, 0.0, 2.0); if (partMaterial == null) { partMaterial = new SolidMaterial(new RGBA_Floats(.9, .2, .1), .01, 0.0, 2.0); } int index = 0; Vector3[] triangle = new Vector3[3]; foreach (PolygonMesh.Mesh mesh in meshGroup.Meshes) { int materialIntdex = MeshMaterialData.Get(mesh).MaterialIndex; foreach (PolygonMesh.Face face in mesh.Faces) { foreach (PolygonMesh.Vertex vertex in face.Vertices()) { triangle[index++] = vertex.Position; if (index == 3) { index = 0; if (materialIntdex == 1) { renderCollection.Add(new TriangleShape(triangle[0], triangle[1], triangle[2], partMaterial)); } else { renderCollection.Add(new TriangleShape(triangle[0], triangle[1], triangle[2], otherMaterial)); } } } } } return(BoundingVolumeHierarchy.CreateNewHierachy(renderCollection)); }
public static string[] GetStlFileLocations(string fileToSlice, bool doMergeInSlicer, ref string mergeRules) { extrudersUsed.Clear(); int extruderCount = ActiveSliceSettings.Instance.GetValue <int>(SettingsKey.extruder_count); for (int extruderIndex = 0; extruderIndex < extruderCount; extruderIndex++) { extrudersUsed.Add(false); } // If we have support enabled and are using an extruder other than 0 for it if (ActiveSliceSettings.Instance.GetValue <bool>("support_material")) { if (ActiveSliceSettings.Instance.GetValue <int>("support_material_extruder") != 0) { int supportExtruder = Math.Max(0, Math.Min(ActiveSliceSettings.Instance.GetValue <int>(SettingsKey.extruder_count) - 1, ActiveSliceSettings.Instance.GetValue <int>("support_material_extruder") - 1)); extrudersUsed[supportExtruder] = true; } } // If we have raft enabled and are using an extruder other than 0 for it if (ActiveSliceSettings.Instance.GetValue <bool>("create_raft")) { if (ActiveSliceSettings.Instance.GetValue <int>("raft_extruder") != 0) { int raftExtruder = Math.Max(0, Math.Min(ActiveSliceSettings.Instance.GetValue <int>(SettingsKey.extruder_count) - 1, ActiveSliceSettings.Instance.GetValue <int>("raft_extruder") - 1)); extrudersUsed[raftExtruder] = true; } } switch (Path.GetExtension(fileToSlice).ToUpper()) { case ".STL": case ".GCODE": extrudersUsed[0] = true; return(new string[] { fileToSlice }); case ".AMF": List <MeshGroup> meshGroups = MeshFileIo.Load(fileToSlice); if (meshGroups != null) { List <MeshGroup> extruderMeshGroups = new List <MeshGroup>(); for (int extruderIndex = 0; extruderIndex < extruderCount; extruderIndex++) { extruderMeshGroups.Add(new MeshGroup()); } int maxExtruderIndex = 0; foreach (MeshGroup meshGroup in meshGroups) { foreach (Mesh mesh in meshGroup.Meshes) { MeshMaterialData material = MeshMaterialData.Get(mesh); int extruderIndex = Math.Max(0, material.MaterialIndex - 1); maxExtruderIndex = Math.Max(maxExtruderIndex, extruderIndex); if (extruderIndex >= extruderCount) { extrudersUsed[0] = true; extruderMeshGroups[0].Meshes.Add(mesh); } else { extrudersUsed[extruderIndex] = true; extruderMeshGroups[extruderIndex].Meshes.Add(mesh); } } } int savedStlCount = 0; List <string> extruderFilesToSlice = new List <string>(); for (int extruderIndex = 0; extruderIndex < extruderMeshGroups.Count; extruderIndex++) { MeshGroup meshGroup = extruderMeshGroups[extruderIndex]; List <int> materialsToInclude = new List <int>(); materialsToInclude.Add(extruderIndex + 1); if (extruderIndex == 0) { for (int j = extruderCount + 1; j < maxExtruderIndex + 2; j++) { materialsToInclude.Add(j); } } if (doMergeInSlicer) { int meshCount = meshGroup.Meshes.Count; for (int meshIndex = 0; meshIndex < meshCount; meshIndex++) { Mesh mesh = meshGroup.Meshes[meshIndex]; if ((meshIndex % 2) == 0) { mergeRules += "({0}".FormatWith(savedStlCount); } else { if (meshIndex < meshCount - 1) { mergeRules += ",({0}".FormatWith(savedStlCount); } else { mergeRules += ",{0}".FormatWith(savedStlCount); } } int currentMeshMaterialIntdex = MeshMaterialData.Get(mesh).MaterialIndex; if (materialsToInclude.Contains(currentMeshMaterialIntdex)) { extruderFilesToSlice.Add(SaveAndGetFilenameForMesh(mesh)); } savedStlCount++; } for (int i = 0; i < meshCount - 1; i++) { mergeRules += ")"; } } else { extruderFilesToSlice.Add(SaveAndGetFilenameForMaterial(meshGroup, materialsToInclude)); } } return(extruderFilesToSlice.ToArray()); } return(new string[] { "" }); default: return(new string[] { "" }); } }
public static bool Save(List <MeshGroup> meshToSave, Stream stream, MeshOutputSettings outputInfo) { TextWriter amfFile = new StreamWriter(stream); amfFile.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); amfFile.WriteLine("<amf unit=\"millimeter\" version=\"1.1\">"); if (outputInfo != null) { foreach (KeyValuePair <string, string> metaData in outputInfo.MetaDataKeyValue) { amfFile.WriteLine(Indent(1) + "<metadata type=\"{0}\">{1}</metadata>".FormatWith(metaData.Key, metaData.Value)); } } { int objectId = 1; bool continueProcessing; int totalMeshes = 0; foreach (MeshGroup meshGroup in meshToSave) { foreach (Mesh mesh in meshGroup.Meshes) { totalMeshes++; } } double ratioPerMesh = 1d / totalMeshes; double currentRation = 0; for (int meshGroupIndex = 0; meshGroupIndex < meshToSave.Count; meshGroupIndex++) { MeshGroup meshGroup = meshToSave[meshGroupIndex]; amfFile.WriteLine(Indent(1) + "<object id=\"{0}\">".FormatWith(objectId++)); { int vertexCount = 0; List <int> meshVertexStart = new List <int>(); amfFile.WriteLine(Indent(2) + "<mesh>"); { amfFile.WriteLine(Indent(3) + "<vertices>"); { for (int meshIndex = 0; meshIndex < meshGroup.Meshes.Count; meshIndex++) { Mesh mesh = meshGroup.Meshes[meshIndex]; double vertCount = (double)mesh.Vertices.Count; meshVertexStart.Add(vertexCount); for (int vertexIndex = 0; vertexIndex < mesh.Vertices.Count; vertexIndex++) { Vertex vertex = mesh.Vertices[vertexIndex]; if (outputInfo.ReportProgress != null) { outputInfo.ReportProgress(currentRation + vertexIndex / vertCount * ratioPerMesh * .5, "", out continueProcessing); } Vector3 position = vertex.Position; amfFile.WriteLine(Indent(4) + "<vertex>"); { amfFile.WriteLine(Indent(5) + "<coordinates>"); amfFile.WriteLine(Indent(6) + "<x>{0}</x>".FormatWith(position.x)); amfFile.WriteLine(Indent(6) + "<y>{0}</y>".FormatWith(position.y)); amfFile.WriteLine(Indent(6) + "<z>{0}</z>".FormatWith(position.z)); amfFile.WriteLine(Indent(5) + "</coordinates>"); } amfFile.WriteLine(Indent(4) + "</vertex>"); vertexCount++; } currentRation += ratioPerMesh * .5; } } amfFile.WriteLine(Indent(3) + "</vertices>"); for (int meshIndex = 0; meshIndex < meshGroup.Meshes.Count; meshIndex++) { Mesh mesh = meshGroup.Meshes[meshIndex]; int firstVertexIndex = meshVertexStart[meshIndex]; MeshMaterialData material = MeshMaterialData.Get(mesh); if (material.MaterialIndex == -1) { amfFile.WriteLine(Indent(3) + "<volume>"); } else { amfFile.WriteLine(Indent(3) + "<volume materialid=\"{0}\">".FormatWith(material.MaterialIndex)); } double faceCount = (double)mesh.Faces.Count; for (int faceIndex = 0; faceIndex < mesh.Faces.Count; faceIndex++) { if (outputInfo.ReportProgress != null) { outputInfo.ReportProgress(currentRation + faceIndex / faceCount * ratioPerMesh * .5, "", out continueProcessing); } Face face = mesh.Faces[faceIndex]; List <Vertex> positionsCCW = new List <Vertex>(); foreach (FaceEdge faceEdge in face.FaceEdges()) { positionsCCW.Add(faceEdge.firstVertex); } int numPolys = positionsCCW.Count - 2; int secondIndex = 1; int thirdIndex = 2; for (int polyIndex = 0; polyIndex < numPolys; polyIndex++) { amfFile.WriteLine(Indent(4) + "<triangle>"); amfFile.WriteLine(Indent(5) + "<v1>{0}</v1>".FormatWith(firstVertexIndex + mesh.Vertices.IndexOf(positionsCCW[0]))); amfFile.WriteLine(Indent(5) + "<v2>{0}</v2>".FormatWith(firstVertexIndex + mesh.Vertices.IndexOf(positionsCCW[secondIndex]))); amfFile.WriteLine(Indent(5) + "<v3>{0}</v3>".FormatWith(firstVertexIndex + mesh.Vertices.IndexOf(positionsCCW[thirdIndex]))); amfFile.WriteLine(Indent(4) + "</triangle>"); secondIndex = thirdIndex; thirdIndex++; } } currentRation += ratioPerMesh * .5; amfFile.WriteLine(Indent(3) + "</volume>"); } } amfFile.WriteLine(Indent(2) + "</mesh>"); } amfFile.WriteLine(Indent(1) + "</object>"); } HashSet <int> materials = new HashSet <int>(); foreach (MeshGroup meshGroup in meshToSave) { foreach (Mesh mesh in meshGroup.Meshes) { MeshMaterialData material = MeshMaterialData.Get(mesh); if (material.MaterialIndex != -1) { materials.Add(material.MaterialIndex); } } } foreach (int material in materials) { amfFile.WriteLine(Indent(1) + "<material id=\"{0}\">".FormatWith(material)); amfFile.WriteLine(Indent(2) + "<metadata type=\"Name\">Material {0}</metadata>".FormatWith(material)); amfFile.WriteLine(Indent(1) + "</material>"); } } amfFile.WriteLine("</amf>"); amfFile.Flush(); return(true); }
public static List <Mesh> SplitVolumesIntoMeshes(Mesh meshToSplit, ReportProgressRatio reportProgress) { List <Mesh> discreetVolumes = new List <Mesh>(); HashSet <Face> facesThatHaveBeenAdded = new HashSet <Face>(); Mesh meshFromCurrentVolume = null; Stack <Face> attachedFaces = new Stack <Face>(); for (int faceIndex = 0; faceIndex < meshToSplit.Faces.Count; faceIndex++) { Face currentFace = meshToSplit.Faces[faceIndex]; // If this face as not been added to any volume, create a new volume and add all of the attached faces. if (!facesThatHaveBeenAdded.Contains(currentFace)) { attachedFaces.Push(currentFace); meshFromCurrentVolume = new Mesh(); MeshMaterialData materialDataToCopy = MeshMaterialData.Get(meshToSplit); MeshMaterialData newMaterialData = MeshMaterialData.Get(meshFromCurrentVolume); newMaterialData.MaterialIndex = materialDataToCopy.MaterialIndex; while (attachedFaces.Count > 0) { Face faceToAdd = attachedFaces.Pop(); foreach (Vertex attachedVertex in faceToAdd.Vertices()) { foreach (Face faceAttachedToVertex in attachedVertex.ConnectedFaces()) { if (!facesThatHaveBeenAdded.Contains(faceAttachedToVertex)) { // marke that this face has been taken care of facesThatHaveBeenAdded.Add(faceAttachedToVertex); // add it to the list of faces we need to walk attachedFaces.Push(faceAttachedToVertex); // Add a new face to the new mesh we are creating. List <Vertex> faceVertices = new List <Vertex>(); foreach (FaceEdge faceEdgeToAdd in faceAttachedToVertex.FaceEdges()) { Vertex newVertex = meshFromCurrentVolume.CreateVertex(faceEdgeToAdd.firstVertex.Position, CreateOption.CreateNew, SortOption.WillSortLater); faceVertices.Add(newVertex); } meshFromCurrentVolume.CreateFace(faceVertices.ToArray(), CreateOption.CreateNew); } } } } meshFromCurrentVolume.CleanAndMergMesh(); discreetVolumes.Add(meshFromCurrentVolume); meshFromCurrentVolume = null; } if (reportProgress != null) { double progress = faceIndex / (double)meshToSplit.Faces.Count; bool continueProcessing; reportProgress(progress, "Split Into Meshes", out continueProcessing); } } return(discreetVolumes); }
public static string[] GetStlFileLocations(string fileToSlice) { extrudersUsed.Clear(); int extruderCount = ActiveSliceSettings.Instance.ExtruderCount; for (int extruderIndex = 0; extruderIndex < extruderCount; extruderIndex++) { extrudersUsed.Add(false); } // If we have support enabled and and are using an extruder other than 0 for it if (ActiveSliceSettings.Instance.SupportEnabled) { if (ActiveSliceSettings.Instance.SupportExtruder != 0) { int supportExtruder = Math.Max(0, Math.Min(ActiveSliceSettings.Instance.ExtruderCount - 1, ActiveSliceSettings.Instance.SupportExtruder - 1)); extrudersUsed[supportExtruder] = true; } } // If we have raft enabled and are using an extruder other than 0 for it if (ActiveSliceSettings.Instance.RaftEnabled) { if (ActiveSliceSettings.Instance.RaftExtruder != 0) { int raftExtruder = Math.Max(0, Math.Min(ActiveSliceSettings.Instance.ExtruderCount - 1, ActiveSliceSettings.Instance.RaftExtruder - 1)); extrudersUsed[raftExtruder] = true; } } switch (Path.GetExtension(fileToSlice).ToUpper()) { case ".STL": case ".GCODE": extrudersUsed[0] = true; return(new string[] { fileToSlice }); case ".AMF": List <MeshGroup> meshGroups = MeshFileIo.Load(fileToSlice); List <MeshGroup> extruderMeshGroups = new List <MeshGroup>(); for (int extruderIndex = 0; extruderIndex < extruderCount; extruderIndex++) { extruderMeshGroups.Add(new MeshGroup()); } int maxExtruderIndex = 0; foreach (MeshGroup meshGroup in meshGroups) { foreach (Mesh mesh in meshGroup.Meshes) { MeshMaterialData material = MeshMaterialData.Get(mesh); int extruderIndex = Math.Max(0, material.MaterialIndex - 1); maxExtruderIndex = Math.Max(maxExtruderIndex, extruderIndex); if (extruderIndex >= extruderCount) { extrudersUsed[0] = true; extruderMeshGroups[0].Meshes.Add(mesh); } else { extrudersUsed[extruderIndex] = true; extruderMeshGroups[extruderIndex].Meshes.Add(mesh); } } } List <string> extruderFilesToSlice = new List <string>(); for (int i = 0; i < extruderMeshGroups.Count; i++) { MeshGroup meshGroup = extruderMeshGroups[i]; List <int> materialsToInclude = new List <int>(); materialsToInclude.Add(i + 1); if (i == 0) { for (int j = extruderCount + 1; j < maxExtruderIndex + 2; j++) { materialsToInclude.Add(j); } } extruderFilesToSlice.Add(SaveAndGetFilenameForMaterial(meshGroup, materialsToInclude)); } return(extruderFilesToSlice.ToArray()); default: throw new NotImplementedException(); } }