Example #1
0
        public void InitializeLayerData(ExtruderData slicer, ConfigSettings config, int extruderIndex, int extruderCount, Polygons extraPathingConsideration)
        {
            for (int layerIndex = 0; layerIndex < slicer.layers.Count; layerIndex++)
            {
                int start = slicer.layers.Count * extruderIndex;
                LogOutput.Log("Generating Layer Outlines {0}/{1}\n".FormatWith(start + layerIndex + 1, extruderCount * slicer.layers.Count));
                if (config.outputOnlyFirstLayer && layerIndex > 0)
                {
                    break;
                }

                Layers.Add(new SliceLayer());
                Layers[layerIndex].LayerZ = slicer.layers[layerIndex].Z;

                Layers[layerIndex].AllOutlines = slicer.layers[layerIndex].PolygonList;

                Layers[layerIndex].AllOutlines = Layers[layerIndex].AllOutlines.GetCorrectedWinding();

                long avoidInset    = config.ExtrusionWidth_um * 3 / 2;
                var  boundary      = Layers[layerIndex].AllOutlines.GetBounds();
                var  extraBoundary = extraPathingConsideration.GetBounds();
                boundary.ExpandToInclude(extraBoundary);
                boundary.Inflate(config.ExtrusionWidth_um * 10);
                Layers[layerIndex].PathFinder = new Pathfinding.PathFinder(Layers[layerIndex].AllOutlines, avoidInset, boundary);
            }
        }
Example #2
0
        public static int ProcessArgs(string[] args)
        {
            if (args.Length == 0)
            {
                print_usage();
                return(0);
            }

            ConfigSettings config    = new ConfigSettings();
            fffProcessor   processor = new fffProcessor(config);

            LogOutput.Log("\nMatterSlice version {0}\n\n".FormatWith(ConfigConstants.VERSION));

            if (ProcessArgs(args, config, processor) == 0)
            {
                return(0);
            }

            if (!Canceled)
            {
                processor.DoProcessing();
            }
            if (!Canceled)
            {
                processor.finalize();
            }
            if (Canceled)
            {
                processor.Cancel();
            }

            Canceled = true;

            return(0);
        }
Example #3
0
        public static void InitializeLayerPathing(ConfigSettings config, Polygons extraPathingConsideration, List <ExtruderLayers> extruders)
        {
            for (int layerIndex = 0; layerIndex < extruders[0].Layers.Count; layerIndex++)
            {
                if (MatterSlice.Canceled)
                {
                    return;
                }

                LogOutput.Log("Generating Outlines {0}/{1}\n".FormatWith(layerIndex + 1, extruders[0].Layers.Count));

                long avoidInset = config.ExtrusionWidth_um * 3 / 2;

                var allOutlines = new Polygons();
                for (int extruderIndex = 0; extruderIndex < extruders.Count; extruderIndex++)
                {
                    allOutlines.AddRange(extruders[extruderIndex].Layers[layerIndex].AllOutlines);
                }

                var boundary      = allOutlines.GetBounds();
                var extraBoundary = extraPathingConsideration.GetBounds();

                boundary.ExpandToInclude(extraBoundary);
                boundary.Inflate(config.ExtrusionWidth_um * 10);

                var pathFinder = new Pathfinding.PathFinder(allOutlines, avoidInset, boundary, config.AvoidCrossingPerimeters);

                // assign the same pathing to all extruders for this layer
                for (int extruderIndex = 0; extruderIndex < extruders.Count; extruderIndex++)
                {
                    extruders[extruderIndex].Layers[layerIndex].PathFinder = pathFinder;
                }
            }
        }
Example #4
0
        public void Finalize(int maxObjectHeight, int moveSpeed, string endCode)
        {
            WriteFanCommand(0);
            WriteRetraction();
            setZ(maxObjectHeight + 5000);
            WriteMove(GetPositionXY(), moveSpeed, 0);
            WriteCode(endCode);
            WriteComment("filament used = {0:0.0}".FormatWith(GetTotalFilamentUsed(0) + GetTotalFilamentUsed(1)));
            WriteComment("filament used extruder 1 (mm) = {0:0.0}".FormatWith(GetTotalFilamentUsed(0)));
            WriteComment("filament used extruder 2 (mm) = {0:0.0}".FormatWith(GetTotalFilamentUsed(1)));
            WriteComment("total print time (s) = {0:0}".FormatWith(GetTotalPrintTime()));

            LogOutput.Log("Print time: {0}\n".FormatWith((int)(GetTotalPrintTime())));
            LogOutput.Log("Filament: {0}\n".FormatWith((int)(GetTotalFilamentUsed(0))));
            LogOutput.Log("Filament2: {0}\n".FormatWith((int)(GetTotalFilamentUsed(1))));

            if (GetOutputType() == ConfigConstants.OUTPUT_TYPE.ULTIGCODE)
            {
                string numberString;
                numberString = "{0}".FormatWith((int)(GetTotalPrintTime()));
                //replaceTagInStart("<__TIME__>", numberString);
                numberString = "{0}".FormatWith((int)(GetTotalFilamentUsed(0)));
                //replaceTagInStart("<FILAMENT>", numberString);
                numberString = "{0}".FormatWith((int)(GetTotalFilamentUsed(1)));
                //replaceTagInStart("<FILAMEN2>", numberString);
            }
        }
Example #5
0
 static void print_usage()
 {
     LogOutput.logError("usage: MatterSlice [-h] [-d] [-v] [-m 3x3matrix] [-c <config file>]\n       [-s <settingkey>=<value>] -o <output.gcode> <model.stl>\n\n");
     LogOutput.logError("    [] enclose optional settings, <> are required.\n\n");
     LogOutput.logError("    -h Show this message.\n");
     LogOutput.logError("    -d Save the currently loaded settings to settings.ini (usefull to see all settings).\n");
     LogOutput.logError("    -v Increment verbose level.\n");
     LogOutput.logError("    -m A 3x3 matrix for translating and rotating the layers.\n");
     LogOutput.logError("    -c A config file to apply to the current settings.\n       Can be applyed multiple times.\n       Formated like the default.ini (partial settings are fine).\n");
     LogOutput.logError("    -s Specify a setting on the command line.\n       Uses the same names and values as default.ini.\n");
     LogOutput.logError("    -o Specify the path and filename to save 'output.gcode'.\n");
     LogOutput.logError("    model.stl, the file that will be loaded and sliced.\n");
 }
Example #6
0
		public bool LoadStlFile(string input_filename)
		{
			preSetup(config.extrusionWidth_um);
			timeKeeper.Restart();
			LogOutput.Log("Loading {0} from disk...\n".FormatWith(input_filename));
			if (!SimpleModel.loadModelFromFile(simpleModel, input_filename, config.modelRotationMatrix))
			{
				LogOutput.LogError("Failed to load model: {0}\n".FormatWith(input_filename));
				return false;
			}
			LogOutput.Log("Loaded from disk in {0:0.0}s\n".FormatWith(timeKeeper.Elapsed.Seconds));
			return true;
		}
Example #7
0
        public void Finalize(long maxObjectHeight, int moveSpeed, string endCode)
        {
            WriteFanCommand(0);
            WriteCode(endCode);
            WriteComment("filament used = {0:0.0}".FormatWith(GetTotalFilamentUsed(0) + GetTotalFilamentUsed(1)));
            WriteComment("filament used extruder 1 (mm) = {0:0.0}".FormatWith(GetTotalFilamentUsed(0)));
            WriteComment("filament used extruder 2 (mm) = {0:0.0}".FormatWith(GetTotalFilamentUsed(1)));
            WriteComment("total print time (s) = {0:0}".FormatWith(GetTotalPrintTime()));

            LogOutput.Log("Print time: {0}\n".FormatWith((int)(GetTotalPrintTime())));
            LogOutput.Log("Filament: {0}\n".FormatWith((int)(GetTotalFilamentUsed(0))));
            LogOutput.Log("Filament2: {0}\n".FormatWith((int)(GetTotalFilamentUsed(1))));
        }
Example #8
0
		private void sliceModels(SliceDataStorage storage)
		{
			timeKeeper.Restart();
#if false
            optomizedModel.saveDebugSTL("debug_output.stl");
#endif

			LogOutput.Log("Slicing model...\n");
			List<Slicer> slicerList = new List<Slicer>();
			for (int volumeIndex = 0; volumeIndex < optomizedModel.volumes.Count; volumeIndex++)
			{
				Slicer slicer = new Slicer(optomizedModel.volumes[volumeIndex], config);
				slicerList.Add(slicer);
			}

#if false
            slicerList[0].DumpSegmentsToGcode("Volume 0 Segments.gcode");
            slicerList[0].DumpPolygonsToGcode("Volume 0 Polygons.gcode");
            //slicerList[0].DumpPolygonsToHTML("Volume 0 Polygons.html");
#endif

			LogOutput.Log("Sliced model in {0:0.0}s\n".FormatWith(timeKeeper.Elapsed.Seconds));
			timeKeeper.Restart();

			LogOutput.Log("Generating support map...\n");
			storage.support.GenerateSupportGrid(optomizedModel, config);

			storage.modelSize = optomizedModel.size_um;
			storage.modelMin = optomizedModel.minXYZ_um;
			storage.modelMax = optomizedModel.maxXYZ_um;

			LogOutput.Log("Generating layer parts...\n");
			for (int volumeIndex = 0; volumeIndex < slicerList.Count; volumeIndex++)
			{
				storage.volumes.Add(new SliceVolumeStorage());
				LayerPart.CreateLayerParts(storage.volumes[volumeIndex], slicerList[volumeIndex], config.repairOverlaps);

				if (config.enableRaft)
				{
					//Add the raft offset to each layer.
					for (int layerNr = 0; layerNr < storage.volumes[volumeIndex].layers.Count; layerNr++)
					{
						storage.volumes[volumeIndex].layers[layerNr].printZ += config.raftBaseThickness_um + config.raftInterfaceThicknes_um;
					}
				}
			}
			LogOutput.Log("Generated layer parts in {0:0.0}s\n".FormatWith(timeKeeper.Elapsed.Seconds));
			timeKeeper.Restart();
		}
Example #9
0
        public void TellFileSize()
        {
            double fsize = gcodeFileStream.BaseStream.Length;

            if (fsize > 1024 * 1024)
            {
                fsize /= 1024.0 * 1024.0;
                LogOutput.Log("Wrote {0:0.0} MB.\n".FormatWith(fsize));
            }
            if (fsize > 1024)
            {
                fsize /= 1024.0;
                LogOutput.Log("Wrote {0:0.0} kilobytes.\n".FormatWith(fsize));
            }
        }
Example #10
0
 private static void print_usage()
 {
     LogOutput.LogError("usage: MatterSlice [-h] [-d] [-v] [-t] [-m 3x3matrix]\n       [-b boolean math] [-c <config file>]\n       [-s <settingkey>=<value>] -o <output.gcode> <model.stl>\n\n");
     LogOutput.LogError("    [] enclose optional settings, <> are required.\n\n");
     LogOutput.LogError("    -h Show this message.\n");
     LogOutput.LogError("    -d Save the currently loaded settings to settings.ini (useful to see\n       all settings).\n");
     LogOutput.LogError("    -v Increment verbose level.\n");
     LogOutput.LogError("    -t Run unit tests.\n");
     LogOutput.LogError("    -m A 3x3 matrix for translating and rotating the layers.\n");
     LogOutput.LogError("    -b A string describing the boolean math to do on the loaded models.\n       (indexA,indexB) - parentheses = union\n       {indexA,indexBToRemove} - curly brackets = difference\n       [indexA,indexB] - square brackets = intersection\n       Example: b (0,[1,{2,3}]) intersect 2+3, remove from 1, union with 0\n");
     LogOutput.LogError("    -c A config file to apply to the current settings.\n       Can be applied multiple times.\n       Formated like the default.ini (partial settings are fine).\n");
     LogOutput.LogError("    -s Specify a setting on the command line.\n       Uses the same names and values as default.ini.\n");
     LogOutput.LogError("    -o Specify the path and filename to save 'output.gcode'.\n");
     LogOutput.LogError("    model.stl, the file that will be loaded and sliced.\n");
 }
Example #11
0
        public void DoProcessing()
        {
            if (!gcode.IsOpened())
            {
                return;
            }

            timeKeeper.Restart();
            LogOutput.Log("Analyzing and optimizing model...\n");
            optomizedModel = new OptimizedModel(simpleModel);
            if (MatterSlice.Canceled)
            {
                return;
            }
            optomizedModel.SetPositionAndSize(simpleModel, config.positionToPlaceObjectCenter_um.X, config.positionToPlaceObjectCenter_um.Y, -config.bottomClipAmount_um, config.centerObjectInXy);
            for (int volumeIndex = 0; volumeIndex < simpleModel.volumes.Count; volumeIndex++)
            {
                LogOutput.Log("  Face counts: {0} . {1} {2:0.0}%\n".FormatWith((int)simpleModel.volumes[volumeIndex].faceTriangles.Count, (int)optomizedModel.volumes[volumeIndex].facesTriangle.Count, (double)(optomizedModel.volumes[volumeIndex].facesTriangle.Count) / (double)(simpleModel.volumes[volumeIndex].faceTriangles.Count) * 100));
                LogOutput.Log("  Vertex counts: {0} . {1} {2:0.0}%\n".FormatWith((int)simpleModel.volumes[volumeIndex].faceTriangles.Count * 3, (int)optomizedModel.volumes[volumeIndex].vertices.Count, (double)(optomizedModel.volumes[volumeIndex].vertices.Count) / (double)(simpleModel.volumes[volumeIndex].faceTriangles.Count * 3) * 100));
            }

            LogOutput.Log("Optimize model {0:0.0}s \n".FormatWith(timeKeeper.Elapsed.Seconds));
            timeKeeper.Reset();

            Stopwatch timeKeeperTotal = new Stopwatch();

            timeKeeperTotal.Start();
            preSetup(config.extrusionWidth_um);
            sliceModels(storage);

            processSliceData(storage);
            if (MatterSlice.Canceled)
            {
                return;
            }
            writeGCode(storage);
            if (MatterSlice.Canceled)
            {
                return;
            }

            LogOutput.logProgress("process", 1, 1);             //Report to the GUI that a file has been fully processed.
            LogOutput.Log("Total time elapsed {0:0.00}s.\n".FormatWith(timeKeeperTotal.Elapsed.Seconds));
        }
Example #12
0
        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);
        }
Example #13
0
		private void writeGCode(SliceDataStorage storage)
		{
			gcode.WriteComment("filamentDiameter = {0}".FormatWith(config.filamentDiameter));
			gcode.WriteComment("extrusionWidth = {0}".FormatWith(config.extrusionWidth));
			gcode.WriteComment("firstLayerExtrusionWidth = {0}".FormatWith(config.firstLayerExtrusionWidth));
			gcode.WriteComment("layerThickness = {0}".FormatWith(config.layerThickness));
			gcode.WriteComment("firstLayerThickness = {0}".FormatWith(config.firstLayerThickness));

			if (fileNumber == 1)
			{
				if (gcode.GetOutputType() == ConfigConstants.OUTPUT_TYPE.ULTIGCODE)
				{
					gcode.WriteComment("TYPE:UltiGCode");
					gcode.WriteComment("TIME:<__TIME__>");
					gcode.WriteComment("MATERIAL:<FILAMENT>");
					gcode.WriteComment("MATERIAL2:<FILAMEN2>");
				}
				gcode.WriteCode(config.startCode);
				if (gcode.GetOutputType() == ConfigConstants.OUTPUT_TYPE.BFB)
				{
					gcode.WriteComment("enable auto-retraction");
					gcode.WriteLine("M227 S{0} P{1}".FormatWith(config.retractionOnTravel * 2560, config.retractionOnTravel * 2560));
				}
			}
			else
			{
				gcode.WriteFanCommand(0);
				gcode.ResetExtrusionValue();
				gcode.WriteRetraction();
				gcode.setZ(maxObjectHeight + 5000);
				gcode.WriteMove(gcode.GetPositionXY(), config.travelSpeed, 0);
				gcode.WriteMove(new IntPoint(storage.modelMin.x, storage.modelMin.y), config.travelSpeed, 0);
			}
			fileNumber++;

			int totalLayers = storage.volumes[0].layers.Count;
			// let's remove any of the layers on top that are empty
			{
				for (int layerIndex = totalLayers - 1; layerIndex >= 0; layerIndex--)
				{
					bool layerHasData = false;
					foreach (SliceVolumeStorage currentVolume in storage.volumes)
					{
						SliceLayer currentLayer = currentVolume.layers[layerIndex];
						for (int partIndex = 0; partIndex < currentVolume.layers[layerIndex].parts.Count; partIndex++)
						{
							SliceLayerPart currentPart = currentLayer.parts[partIndex];
							if (currentPart.TotalOutline.Count > 0)
							{
								layerHasData = true;
								break;
							}
						}
					}

					if (layerHasData)
					{
						break;
					}
					totalLayers--;
				}
			}
			gcode.WriteComment("Layer count: {0}".FormatWith(totalLayers));

			// keep the raft generation code inside of raft
			Raft.GenerateRaftGCodeIfRequired(storage, config, gcode);

			int volumeIndex = 0;
			for (int layerIndex = 0; layerIndex < totalLayers; layerIndex++)
			{
				if (MatterSlice.Canceled)
				{
					return;
				}
				LogOutput.Log("Writing Layers {0}/{1}\n".FormatWith(layerIndex + 1, totalLayers));

				LogOutput.logProgress("export", layerIndex + 1, totalLayers);

				int extrusionWidth_um = config.extrusionWidth_um;
				if (layerIndex == 0)
				{
					extrusionWidth_um = config.firstLayerExtrusionWidth_um;
				}

				if (layerIndex == 0)
				{
					skirtConfig.setData(config.firstLayerSpeed, extrusionWidth_um, "SKIRT");
					inset0Config.setData(config.firstLayerSpeed, extrusionWidth_um, "WALL-OUTER");
					insetXConfig.setData(config.firstLayerSpeed, extrusionWidth_um, "WALL-INNER");
					fillConfig.setData(config.firstLayerSpeed, extrusionWidth_um, "FILL", false);
					bridgConfig.setData(config.firstLayerSpeed, extrusionWidth_um, "BRIDGE");

					supportNormalConfig.setData(config.firstLayerSpeed, config.supportExtrusionWidth_um, "SUPPORT");
					supportInterfaceConfig.setData(config.firstLayerSpeed, config.extrusionWidth_um, "SUPPORT-INTERFACE");
				}
				else
				{
					skirtConfig.setData(config.insidePerimetersSpeed, extrusionWidth_um, "SKIRT");
					inset0Config.setData(config.outsidePerimeterSpeed, extrusionWidth_um, "WALL-OUTER");
					insetXConfig.setData(config.insidePerimetersSpeed, extrusionWidth_um, "WALL-INNER");
					fillConfig.setData(config.infillSpeed, extrusionWidth_um, "FILL", false);
					bridgConfig.setData(config.bridgeSpeed, extrusionWidth_um, "BRIDGE");

					supportNormalConfig.setData(config.supportMaterialSpeed, config.supportExtrusionWidth_um, "SUPPORT");
					supportInterfaceConfig.setData(config.supportMaterialSpeed, config.extrusionWidth_um, "SUPPORT-INTERFACE");
				}

				gcode.WriteComment("LAYER:{0}".FormatWith(layerIndex));
				if (layerIndex == 0)
				{
					gcode.SetExtrusion(config.firstLayerThickness_um, config.filamentDiameter_um, config.extrusionMultiplier);
				}
				else
				{
					gcode.SetExtrusion(config.layerThickness_um, config.filamentDiameter_um, config.extrusionMultiplier);
				}

				GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);

				// get the correct height for this layer
				int z = config.firstLayerThickness_um + layerIndex * config.layerThickness_um;
				if (config.enableRaft)
				{
					z += config.raftBaseThickness_um + config.raftInterfaceThicknes_um + config.raftSurfaceLayers * config.raftSurfaceThickness_um;
					if (layerIndex == 0)
					{
						// We only raise the first layer of the print up by the air gap.
						// To give it:
						//   Less press into the raft
						//   More time to cool
						//   more surface area to air while extruding
						z += config.raftAirGap_um;
					}
				}

				gcode.setZ(z);

				// We only create the skirt if we are on layer 0 and the first volume and there is no raft.
				if (layerIndex == 0 && volumeIndex == 0 && !Raft.ShouldGenerateRaft(config))
				{
					AddSkirtToGCode(storage, gcodeLayer, volumeIndex, layerIndex);
				}

				bool printSupportFirst = (storage.support.generated && config.supportExtruder >= 0 && config.supportExtruder == gcodeLayer.getExtruder());
				if (printSupportFirst)
				{
					AddSupportToGCode(storage, gcodeLayer, layerIndex, config);
				}

				int fanSpeedPercent = GetFanSpeed(layerIndex, gcodeLayer);

				for (int volumeCnt = 0; volumeCnt < storage.volumes.Count; volumeCnt++)
				{
					if (volumeCnt > 0)
					{
						volumeIndex = (volumeIndex + 1) % storage.volumes.Count;
					}

					AddVolumeLayerToGCode(storage, gcodeLayer, volumeIndex, layerIndex, extrusionWidth_um, fanSpeedPercent);
				}

				if (!printSupportFirst)
				{
					AddSupportToGCode(storage, gcodeLayer, layerIndex, config);
				}

				//Finish the layer by applying speed corrections for minimum layer times.
				gcodeLayer.ForceMinimumLayerTime(config.minimumLayerTimeSeconds, config.minimumPrintingSpeed);

				gcode.WriteFanCommand(fanSpeedPercent);

				int currentLayerThickness_um = config.layerThickness_um;
				if (layerIndex <= 0)
				{
					currentLayerThickness_um = config.firstLayerThickness_um;
				}

				gcodeLayer.WriteGCode(config.doCoolHeadLift, currentLayerThickness_um);
			}

			LogOutput.Log("Wrote layers in {0:0.00}s.\n".FormatWith(timeKeeper.Elapsed.Seconds));
			timeKeeper.Restart();
			gcode.TellFileSize();
			gcode.WriteFanCommand(0);

			//Store the object height for when we are printing multiple objects, as we need to clear every one of them when moving to the next position.
			maxObjectHeight = Math.Max(maxObjectHeight, storage.modelSize.z);
		}
Example #14
0
		private void processSliceData(SliceDataStorage storage)
		{
			if (config.continuousSpiralOuterPerimeter)
			{
				config.numberOfTopLayers = 0;
				config.infillPercent = 0;
			}

			MultiVolumes.RemoveVolumesIntersections(storage.volumes);
			MultiVolumes.OverlapMultipleVolumesSlightly(storage.volumes, config.multiVolumeOverlapPercent);
#if False
            LayerPart.dumpLayerparts(storage, "output.html");
#endif

			int totalLayers = storage.volumes[0].layers.Count;
#if DEBUG
			for (int volumeIndex = 1; volumeIndex < storage.volumes.Count; volumeIndex++)
			{
				if (totalLayers != storage.volumes[volumeIndex].layers.Count)
				{
					throw new Exception("All the valumes must have the same number of layers (they just can have empty layers).");
				}
			}
#endif

			for (int layerIndex = 0; layerIndex < totalLayers; layerIndex++)
			{
				for (int volumeIndex = 0; volumeIndex < storage.volumes.Count; volumeIndex++)
				{
					if (MatterSlice.Canceled)
					{
						return;
					}
					int insetCount = config.numberOfPerimeters;
					if (config.continuousSpiralOuterPerimeter && (int)(layerIndex) < config.numberOfBottomLayers && layerIndex % 2 == 1)
					{
						//Add extra insets every 2 layers when spiralizing, this makes bottoms of cups watertight.
						insetCount += 5;
					}

					SliceLayer layer = storage.volumes[volumeIndex].layers[layerIndex];
					int extrusionWidth = config.extrusionWidth_um;
					if (layerIndex == 0)
					{
						extrusionWidth = config.firstLayerExtrusionWidth_um;
					}
					Inset.generateInsets(layer, extrusionWidth, insetCount);
				}
				LogOutput.Log("Creating Insets {0}/{1}\n".FormatWith(layerIndex + 1, totalLayers));
			}

			if (config.wipeShieldDistanceFromShapes_um > 0)
			{
				CreateWipeShields(storage, totalLayers);
			}

			LogOutput.Log("Generated inset in {0:0.0}s\n".FormatWith(timeKeeper.Elapsed.Seconds));
			timeKeeper.Restart();

			for (int layerIndex = 0; layerIndex < totalLayers; layerIndex++)
			{
				if (MatterSlice.Canceled)
				{
					return;
				}
				
				//Only generate bottom and top layers and infill for the first X layers when spiralize is choosen.
				if (!config.continuousSpiralOuterPerimeter || (int)(layerIndex) < config.numberOfBottomLayers)
				{
					for (int volumeIndex = 0; volumeIndex < storage.volumes.Count; volumeIndex++)
					{
						int extrusionWidth = config.extrusionWidth_um;
						if (layerIndex == 0)
						{
							extrusionWidth = config.firstLayerExtrusionWidth_um;
						}

						TopsAndBottoms.GenerateTopAndBottom(layerIndex, storage.volumes[volumeIndex], extrusionWidth, config.numberOfBottomLayers, config.numberOfTopLayers);
					}
				}
				LogOutput.Log("Creating Top & Bottom Layers {0}/{1}\n".FormatWith(layerIndex + 1, totalLayers));
			}
			LogOutput.Log("Generated top bottom layers in {0:0.0}s\n".FormatWith(timeKeeper.Elapsed.Seconds));
			timeKeeper.Restart();

			if (config.wipeTowerSize_um > 0)
			{
				Polygon p = new Polygon();
				storage.wipeTower.Add(p);
				p.Add(new IntPoint(storage.modelMin.x - 3000, storage.modelMax.y + 3000));
				p.Add(new IntPoint(storage.modelMin.x - 3000, storage.modelMax.y + 3000 + config.wipeTowerSize_um));
				p.Add(new IntPoint(storage.modelMin.x - 3000 - config.wipeTowerSize_um, storage.modelMax.y + 3000 + config.wipeTowerSize_um));
				p.Add(new IntPoint(storage.modelMin.x - 3000 - config.wipeTowerSize_um, storage.modelMax.y + 3000));

				storage.wipePoint = new IntPoint(storage.modelMin.x - 3000 - config.wipeTowerSize_um / 2, storage.modelMax.y + 3000 + config.wipeTowerSize_um / 2);
			}

			if (config.enableRaft)
			{
				Raft.GenerateRaftOutlines(storage, config.raftExtraDistanceAroundPart_um, config);

				Skirt.generateSkirt(storage,
					config.skirtDistance_um + config.raftBaseLineSpacing_um,
					config.raftBaseLineSpacing_um,
					config.numberOfSkirtLoops,
					config.skirtMinLength_um,
					config.raftBaseThickness_um, config);
			}
			else
			{
				Skirt.generateSkirt(storage,
					config.skirtDistance_um,
					config.firstLayerExtrusionWidth_um,
					config.numberOfSkirtLoops,
					config.skirtMinLength_um,
					config.firstLayerThickness_um, config);
			}
		}
Example #15
0
        public Slicer(OptimizedVolume ov, ConfigSettings config)
        {
            int initialLayerThickness_um = config.firstLayerThickness_um;
            int layerThickness_um        = config.layerThickness_um;

            ConfigConstants.REPAIR_OUTLINES outlineRepairTypes = config.repairOutlines;

            modelSize = ov.parentModel.size_um;
            modelMin  = ov.parentModel.minXYZ_um;

            int 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 SlicerLayer(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;
                int    minZ = p0.z;
                int    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;
                    }

                    SlicerSegment 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(outlineRepairTypes);
            }
        }
Example #16
0
        public ExtruderData(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 + 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;
            }

            LogOutput.Log(string.Format("Layer count: {0}\n", layerCount));
            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++)
            {
                LogOutput.Log($"Slicing model {layerIndex + 1}/{layers.Count}\n");

                layers[layerIndex].MakePolygons();
            }
        }
Example #17
0
        public static int ProcessArgs(string[] args)
        {
#if DEBUG
            Tests.BridgeTests.Run();
#endif
            ConfigSettings config    = new ConfigSettings();
            fffProcessor   processor = new fffProcessor(config);

            LogOutput.log("\nMatterSlice version {0}\n\n".FormatWith(ConfigConstants.VERSION));

            for (int argn = 0; argn < args.Length; argn++)
            {
                string str = args[argn];
                if (str[0] == '-')
                {
                    for (int stringIndex = 1; stringIndex < str.Length; stringIndex++)
                    {
                        switch (str[stringIndex])
                        {
                        case 'h':
                            print_usage();
                            return(0);

                        case 'v':
                            LogOutput.verbose_level++;
                            break;

                        case 'o':
                            argn++;
                            if (!processor.setTargetFile(args[argn]))
                            {
                                LogOutput.logError("Failed to open {0} for output.\n".FormatWith(args[argn]));
                                return(1);
                            }
                            break;

                        case 'c':
                        {
                            // Read a config file from the given path
                            argn++;
                            if (!config.ReadSettings(args[argn]))
                            {
                                LogOutput.logError("Failed to read config '{0}'\n".FormatWith(args[argn]));
                            }
                        }
                        break;

                        case 'd':
                            config.DumpSettings("settings.ini");
                            break;

                        case 's':
                        {
                            argn++;
                            int equalsPos = args[argn].IndexOf('=');
                            if (equalsPos != -1)
                            {
                                string key   = args[argn].Substring(0, equalsPos);
                                string value = args[argn].Substring(equalsPos + 1);
                                if (key.Length > 1)
                                {
                                    if (!config.SetSetting(key, value))
                                    {
                                        LogOutput.logError("Setting not found: {0} {1}\n".FormatWith(key, value));
                                    }
                                }
                            }
                        }
                        break;

                        case 'm':
                            argn++;
                            throw new NotImplementedException("m");
#if false
                            sscanf(argv[argn], "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf",
                                   &config.matrix.m[0][0], &config.matrix.m[0][1], &config.matrix.m[0][2],
                                   &config.matrix.m[1][0], &config.matrix.m[1][1], &config.matrix.m[1][2],
                                   &config.matrix.m[2][0], &config.matrix.m[2][1], &config.matrix.m[2][2]);
#endif
                            break;

                        default:
                            throw new NotImplementedException("Unknown option: {0}\n".FormatWith(str));
                            LogOutput.logError("Unknown option: {0}\n".FormatWith(str));
                            break;
                        }
                    }
                }
                else
                {
                    processor.processFile(args[argn]);
                }
            }

            processor.finalize();
            return(0);
        }
Example #18
0
        public Slicer(OptimizedVolume ov, int initialLayerThickness, int layerThickness, ConfigConstants.REPAIR_OUTLINES outlineRepairTypes)
        {
            modelSize = ov.model.size;
            modelMin  = ov.model.minXYZ;

            int heightWithoutFirstLayer      = modelSize.z - initialLayerThickness;
            int countOfNormalThicknessLayers = heightWithoutFirstLayer / layerThickness;

            int layerCount = countOfNormalThicknessLayers + 1; // we have to add in the first layer (that is a differnt size)

            LogOutput.log(string.Format("Layer count: {0}\n", layerCount));
            layers.Capacity = layerCount;
            for (int i = 0; i < layerCount; i++)
            {
                layers.Add(new SlicerLayer());
            }

            for (int layerIndex = 0; layerIndex < layerCount; layerIndex++)
            {
                if (layerIndex == 0)
                {
                    layers[layerIndex].z = initialLayerThickness / 2;
                }
                else
                {
                    layers[layerIndex].z = initialLayerThickness + layerThickness / 2 + layerThickness * (layerIndex - 1);
                }
            }

            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;
                int    minZ = p0.z;
                int    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 || layerIndex < 0)
                    {
                        continue;
                    }

                    SlicerSegment 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;
                    }
                    layers[layerIndex].faceTo2DSegmentIndex[faceIndex] = layers[layerIndex].segmentList.Count;
                    polyCrossingAtThisZ.faceIndex             = faceIndex;
                    polyCrossingAtThisZ.hasBeenAddedToPolygon = false;
                    layers[layerIndex].segmentList.Add(polyCrossingAtThisZ);
                }
            }

            for (int layerIndex = 0; layerIndex < layers.Count; layerIndex++)
            {
                layers[layerIndex].MakePolygons(ov, outlineRepairTypes);
            }
        }
        public OptimizedMesh(SimpleMesh simpleMesh, OptimizedMeshCollection containingCollection)
        {
            this.containingCollection = containingCollection;
            vertices.Capacity         = simpleMesh.faceTriangles.Count * 3;
            facesTriangle.Capacity    = simpleMesh.faceTriangles.Count;

            Dictionary <int, List <int> > indexMap = new Dictionary <int, List <int> >();

            Stopwatch t = new Stopwatch();

            t.Start();
            for (int faceIndex = 0; faceIndex < simpleMesh.faceTriangles.Count; faceIndex++)
            {
                if (MatterSlice.Canceled)
                {
                    return;
                }
                OptimizedFace optimizedFace = new OptimizedFace();
                if ((faceIndex % 1000 == 0) && t.Elapsed.TotalSeconds > 2)
                {
                    LogOutput.logProgress("optimized", faceIndex + 1, simpleMesh.faceTriangles.Count);
                }
                for (int vertexIndex = 0; vertexIndex < 3; vertexIndex++)
                {
                    IntPoint p    = simpleMesh.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).Length() < 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);
        }
Example #20
0
        public static int ProcessArgs(string[] args, ConfigSettings config, FffProcessor processor)
        {
            for (int argn = 0; argn < args.Length; argn++)
            {
                string str = args[argn];
                if (str[0] == '-')
                {
                    for (int stringIndex = 1; stringIndex < str.Length; stringIndex++)
                    {
                        switch (str[stringIndex])
                        {
                        case 'h':
                            print_usage();
                            return(0);

                        case 'v':
                            LogOutput.verbose_level++;
                            break;

                        case 'o':
                            argn++;
                            if (!processor.SetTargetFile(args[argn]))
                            {
                                LogOutput.LogError("Failed to open {0} for output.\n".FormatWith(args[argn]));
                                return(1);
                            }

                            break;

                        case 'c':
                        {
                            // Read a config file from the given path
                            argn++;
                            if (!config.ReadSettings(args[argn]))
                            {
                                LogOutput.LogError("Failed to read config '{0}'\n".FormatWith(args[argn]));
                            }

                            // process any matrix and mesh requested by config file
                            List <string> commands = new List <string>();
                            foreach (string command in SplitCommandLine.DoSplit(config.AdditionalArgsToProcess))
                            {
                                commands.Add(command);
                            }

                            string[] subArgs = commands.ToArray();
                            ProcessArgs(subArgs, config, processor);
                        }

                        break;

                        case 'd':
                            config.DumpSettings("settings.ini");
                            break;

                        case 's':
                        {
                            argn++;
                            int equalsPos = args[argn].IndexOf('=');
                            if (equalsPos != -1)
                            {
                                string key   = args[argn].Substring(0, equalsPos);
                                string value = args[argn].Substring(equalsPos + 1);
                                if (key.Length > 1)
                                {
                                    if (!config.SetSetting(key, value))
                                    {
                                        LogOutput.LogError("Setting not found: {0} {1}\n".FormatWith(key, value));
                                    }
                                }
                            }
                        }

                        break;

                        case 'm':
                            argn++;
                            string[] matrixValues = args[argn].Split(',');
                            var      loadedMatrix = Matrix4X4.Identity;
                            for (int i = 0; i < 4; i++)
                            {
                                for (int j = 0; j < 4; j++)
                                {
                                    string valueString = matrixValues[i * 4 + j];
                                    double value;
                                    if (double.TryParse(valueString, out value))
                                    {
                                        loadedMatrix[i, j] = value;
                                    }
                                }
                            }

                            config.ModelMatrix = loadedMatrix;
                            break;

                        default:
                            throw new NotImplementedException("Unknown option: {0}\n".FormatWith(str));
                            // LogOutput.logError("Unknown option: {0}\n".FormatWith(str));
                            // break;
                        }
                    }
                }
                else
                {
                    using (new QuickTimer2("LoadStlFile"))
                    {
                        processor.LoadStlFile(args[argn]);
                    }
                }
            }

            return(1);
        }