Пример #1
0
        public void CorrectRayOnCircle()
        {
            var testPartPath = TestContext.CurrentContext.ResolveProjectPath(new string[] { "..", "..", "..", "examples", "RayTracerTest" });

            var  testPart      = Path.Combine(testPartPath, "circle_100x100_centered.stl");
            Mesh simpleMesh    = StlProcessing.Load(testPart, CancellationToken.None);
            var  bvhCollection = MeshToBVH.Convert(simpleMesh);

            var scene = new Scene();

            scene.shapes.Add(bvhCollection);

            RayTracer raytracer = new RayTracer()
            {
                AntiAliasing  = AntiAliasing.None,
                MultiThreaded = false,
            };

            int samples = 40;
            var advance = MathHelper.Tau / samples;

            TestSingleAngle(scene, raytracer, advance, 15);

            for (int i = 0; i < samples; i++)
            {
                TestSingleAngle(scene, raytracer, advance, i);
            }
        }
Пример #2
0
        private void AddTestStl()
        {
            Stopwatch loadTime = new Stopwatch();

            loadTime.Start();

            PolygonMesh.Mesh simpleMesh = StlProcessing.Load("Simple.stl");
            //PolygonMesh.Mesh simpleMesh = StlProcessing.Load("Complex.stl");
            //PolygonMesh.Mesh simpleMesh = StlProcessing.Load("bunny.stl");
            //PolygonMesh.Mesh simpleMesh = StlProcessing.Load("bunny_binary.stl");

            loadTime.Stop();

            timingStrings.Add("Time to load STL {0:0.0}s".FormatWith(loadTime.Elapsed.TotalSeconds));

            Stopwatch bvhTime = new Stopwatch();

            bvhTime.Start();
            IPrimitive bvhCollection = MeshToBVH.Convert(simpleMesh);

            bvhTime.Stop();

            timingStrings.Add("Time to create BVH {0:0.0}s".FormatWith(bvhTime.Elapsed.TotalSeconds));

            renderCollection.Add(bvhCollection);
        }
Пример #3
0
        public async Task StoreMesh(IObject3D object3D, bool publishAfterSave, CancellationToken cancellationToken, Action <double, string> progress = null)
        {
            if (object3D.Mesh == Object3D.FileMissingMesh)
            {
                return;
            }

            var memoryStream = new MemoryStream();

            // Save the embedded asset to a memory stream
            bool savedSuccessfully = StlProcessing.Save(
                object3D.Mesh,
                memoryStream,
                CancellationToken.None,
                new MeshOutputSettings(MeshOutputSettings.OutputType.Binary),
                true);

            if (savedSuccessfully)
            {
                // reset the memory stream to the start
                memoryStream.Position = 0;
                // save the asset to the asset store
                string assetPath = await this.StoreStream(memoryStream, ".stl", publishAfterSave, cancellationToken, progress);

                // Update MeshPath with Assets relative filename
                object3D.MeshPath = Path.GetFileName(assetPath);
            }

            memoryStream.Close();
        }
Пример #4
0
        public void SliceLayersGeneratingCorrectSegments()
        {
            // TODO: Make tests work on Mac as well as Windows
            if (OsInformation.OperatingSystem == OSType.Mac)
            {
                return;
            }

            string pathToMesh   = Path.Combine("..", "..", "..", "TestData", "TestMeshes", "SliceLayers");
            string meshFileName = Path.Combine(pathToMesh, "Box20x20x10.stl");
            Mesh   cubeMesh     = StlProcessing.Load(meshFileName);

            AxisAlignedBoundingBox bounds = cubeMesh.GetAxisAlignedBoundingBox();

            Assert.IsTrue(bounds.ZSize == 10);

            SliceLayers layers = new SliceLayers();

            layers.GetPerimetersForAllLayers(cubeMesh, .2, .2);
            Assert.IsTrue(layers.AllLayers.Count == 50);

            foreach (SliceLayer layer in layers.AllLayers)
            {
                Assert.IsTrue(layer.UnorderedSegments.Count == 8);

                // work in progress
                //Assert.IsTrue(layer.Perimeters.Count == 1);
                //Assert.IsTrue(layer.Perimeters[0].Count == 8);
            }

            layers.GetPerimetersForAllLayers(cubeMesh, .2, .1);
            Assert.IsTrue(layers.AllLayers.Count == 99);
        }
Пример #5
0
        //[Test]
        public void SliceLayersGeneratingCorrectSegments()
        {
            // TODO: Make tests work on Mac as well as Windows
            if (AggContext.OperatingSystem == OSType.Mac)
            {
                return;
            }

            string meshFileName = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestMeshes", "SliceLayers", "Box20x20x10.stl");
            Mesh   cubeMesh     = StlProcessing.Load(meshFileName, CancellationToken.None);

            AxisAlignedBoundingBox bounds = cubeMesh.GetAxisAlignedBoundingBox();

            Assert.IsTrue(bounds.ZSize == 10);

            SliceLayers layers = new SliceLayers();

            layers.GetPerimetersForAllLayers(cubeMesh, .2, .2);
            Assert.IsTrue(layers.AllLayers.Count == 50);

            foreach (SliceLayer layer in layers.AllLayers)
            {
                Assert.IsTrue(layer.UnorderedSegments.Count == 8);

                // work in progress
                //Assert.IsTrue(layer.Perimeters.Count == 1);
                //Assert.IsTrue(layer.Perimeters[0].Count == 8);
            }

            layers.GetPerimetersForAllLayers(cubeMesh, .2, .1);
            Assert.IsTrue(layers.AllLayers.Count == 99);
        }
Пример #6
0
        public async Task StoreMesh(IObject3D object3D, bool publishAfterSave, CancellationToken cancellationToken, Action <double, string> progress = null)
        {
            if (object3D.Mesh == Object3D.FileMissingMesh)
            {
                return;
            }

            // In memory mesh is always saved to stl
            string tempStlPath = CreateNewLibraryPath(".stl");

            // Save the embedded asset to disk
            bool savedSuccessfully = StlProcessing.Save(
                object3D.Mesh,
                tempStlPath,
                CancellationToken.None,
                new MeshOutputSettings(MeshOutputSettings.OutputType.Binary));

            if (savedSuccessfully)
            {
                // There's currently no way to know the actual mesh file hashcode without saving it to disk, thus we save at least once in
                // order to compute the hash but then throw away the duplicate file if an existing copy exists in the assets directory
                string assetPath = await this.StoreFile(tempStlPath, publishAfterSave, cancellationToken, progress);

                // Remove the temp file
                if (File.Exists(tempStlPath))
                {
                    File.Delete(tempStlPath);
                }

                // Update MeshPath with Assets relative filename
                object3D.MeshPath = Path.GetFileName(assetPath);
            }
        }
Пример #7
0
        public void AddItem(PrintItemWrapper item, ValidateSizeOn32BitSystems checkSize = ValidateSizeOn32BitSystems.Required, int indexToInsert = -1)
        {
            if (Is32Bit())
            {
                // Check if the part we are adding is BIG. If it is warn the user and
                // possibly don't add it
                bool warnAboutFileSize  = false;
                long estimatedMemoryUse = 0;
                if (File.Exists(item.FileLocation) &&
                    checkSize == ValidateSizeOn32BitSystems.Required)
                {
                    switch (Path.GetExtension(item.FileLocation).ToUpper())
                    {
                    case ".STL":
                        estimatedMemoryUse = StlProcessing.GetEstimatedMemoryUse(item.FileLocation);
                        break;

                    case ".AMF":
                        estimatedMemoryUse = AmfProcessing.GetEstimatedMemoryUse(item.FileLocation);
                        break;
                    }

                    if (OsInformation.OperatingSystem == OSType.Android)
                    {
                        if (estimatedMemoryUse > 100000000)
                        {
                            warnAboutFileSize = true;
                        }
                    }
                    else
                    {
                        if (estimatedMemoryUse > 500000000)
                        {
                            warnAboutFileSize = true;
                        }
                    }
                }

                if (warnAboutFileSize)
                {
                    partUnderConsideration = item;
                    // Show a dialog and only load the part to the queue if the user clicks yes.
                    UiThread.RunOnIdle((state) =>
                    {
                        string memoryWarningMessage = "Are you sure you want to add this part ({0}) to the Queue?\nThe 3D part you are trying to load may be too complicated and cause performance or stability problems.\n\nConsider reducing the geometry before proceeding.".Localize().FormatWith(item.Name);
                        StyledMessageBox.ShowMessageBox(UserSaidToAllowAddToQueue, memoryWarningMessage, "File May Cause Problems".Localize(), StyledMessageBox.MessageType.YES_NO, "Add To Queue", "Do Not Add");
                        // show a dialog to tell the user there is an update
                    });
                    return;
                }
                else
                {
                    DoAddItem(item, indexToInsert);
                }
            }
            else
            {
                DoAddItem(item, indexToInsert);
            }
        }
Пример #8
0
        public void LoadMesh(string meshPathAndFileName)
        {
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.WorkerReportsProgress      = true;
            backgroundWorker.WorkerSupportsCancellation = true;

            backgroundWorker.ProgressChanged    += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);

            bool loadingMeshFile = false;

            switch (Path.GetExtension(meshPathAndFileName).ToUpper())
            {
            case ".STL":
            {
                StlProcessing stlLoader = new StlProcessing();
                stlLoader.LoadInBackground(backgroundWorker, meshPathAndFileName);
                loadingMeshFile = true;
            }
            break;

            case ".AMF":
            {
                AmfProcessing amfLoader = new AmfProcessing();
                amfLoader.LoadInBackground(backgroundWorker, meshPathAndFileName);
                loadingMeshFile = true;
            }
            break;

            default:
                loadingMeshFile = false;
                break;
            }

            if (loadingMeshFile)
            {
                meshLoadingStateInfoText         = new TextWidget("Loading Mesh...");
                meshLoadingStateInfoText.HAnchor = HAnchor.ParentCenter;
                meshLoadingStateInfoText.VAnchor = VAnchor.ParentCenter;
                meshLoadingStateInfoText.AutoExpandBoundsToText = true;

                GuiWidget labelContainer = new GuiWidget();
                labelContainer.AnchorAll();
                labelContainer.AddChild(meshLoadingStateInfoText);
                labelContainer.Selectable = false;

                this.AddChild(labelContainer);
            }
            else
            {
                TextWidget no3DView = new TextWidget(string.Format("No 3D view for this file type '{0}'.", Path.GetExtension(meshPathAndFileName).ToUpper()));
                no3DView.Margin  = new BorderDouble(0, 0, 0, 0);
                no3DView.VAnchor = Agg.UI.VAnchor.ParentCenter;
                no3DView.HAnchor = Agg.UI.HAnchor.ParentCenter;
                this.AddChild(no3DView);
            }
        }
Пример #9
0
        void createThumbnailWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            PartThumbnailWidget thumbnailWidget = e.Argument as PartThumbnailWidget;

            if (thumbnailWidget != null)
            {
                if (thumbnailWidget.printItem == null)
                {
                    thumbnailWidget.image = new ImageBuffer(thumbnailWidget.noThumbnailImage);
                }
                else // generate the image
                {
                    Mesh loadedMesh = StlProcessing.Load(thumbnailWidget.printItem.FileLocation);

                    thumbnailWidget.image = new ImageBuffer(thumbnailWidget.buildingThumbnailImage);
                    thumbnailWidget.Invalidate();

                    if (loadedMesh != null)
                    {
                        ImageBuffer tempImage      = new ImageBuffer(thumbnailWidget.image.Width, thumbnailWidget.image.Height, 32, new BlenderBGRA());
                        Graphics2D  partGraphics2D = tempImage.NewGraphics2D();

                        List <MeshEdge> nonManifoldEdges = loadedMesh.GetNonManifoldEdges();
                        if (nonManifoldEdges.Count > 0)
                        {
                            if (File.Exists("RunUnitTests.txt"))
                            {
                                partGraphics2D.Circle(4, 4, 4, RGBA_Bytes.Red);
                            }
                        }
                        nonManifoldEdges = null;

                        AxisAlignedBoundingBox aabb = loadedMesh.GetAxisAlignedBoundingBox();
                        double          maxSize     = Math.Max(aabb.XSize, aabb.YSize);
                        double          scale       = thumbnailWidget.image.Width / (maxSize * 1.2);
                        RectangleDouble bounds2D    = new RectangleDouble(aabb.minXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.x, aabb.maxXYZ.y);
                        PolygonMesh.Rendering.OrthographicZProjection.DrawTo(partGraphics2D, loadedMesh,
                                                                             new Vector2((thumbnailWidget.image.Width / scale - bounds2D.Width) / 2 - bounds2D.Left,
                                                                                         (thumbnailWidget.image.Height / scale - bounds2D.Height) / 2 - bounds2D.Bottom),
                                                                             scale,
                                                                             thumbnailWidget.FillColor);

                        thumbnailWidget.image = new ImageBuffer(tempImage);
                        loadedMesh            = new Mesh();
                    }
                    else
                    {
                        thumbnailWidget.image = new ImageBuffer(thumbnailWidget.noThumbnailImage);
                    }
                }
                thumbnailWidget.Invalidate();
            }
        }
        private void LoadStl_Click(object sender, EventArgs e)
        {
            OpenFileDialogParams opeParams = new OpenFileDialogParams("STL Files|*.stl");

            FileDialog.OpenFileDialog(opeParams, (openParams) =>
            {
                var streamToLoadFrom = File.Open(openParams.FileName, FileMode.Open);

                if (streamToLoadFrom != null)
                {
                    var loadedFileName = openParams.FileName;

                    meshToRender = StlProcessing.Load(streamToLoadFrom);

                    ImageBuffer plateInventory = new ImageBuffer((int)(300 * 8.5), 300 * 11, 32, new BlenderBGRA());
                    Graphics2D plateGraphics   = plateInventory.NewGraphics2D();
                    plateGraphics.Clear(RGBA_Bytes.White);

                    double inchesPerMm          = 0.0393701;
                    double pixelsPerInch        = 300;
                    double pixelsPerMm          = inchesPerMm * pixelsPerInch;
                    AxisAlignedBoundingBox aabb = meshToRender.GetAxisAlignedBoundingBox();
                    Vector2 lowerLeftInMM       = new Vector2(-aabb.minXYZ.x, -aabb.minXYZ.y);
                    Vector3 centerInMM          = (aabb.maxXYZ - aabb.minXYZ) / 2;
                    Vector2 offsetInMM          = new Vector2(20, 30);

                    {
                        RectangleDouble bounds = new RectangleDouble(offsetInMM.x * pixelsPerMm,
                                                                     offsetInMM.y * pixelsPerMm,
                                                                     (offsetInMM.x + aabb.maxXYZ.x - aabb.minXYZ.x) * pixelsPerMm,
                                                                     (offsetInMM.y + aabb.maxXYZ.y - aabb.minXYZ.y) * pixelsPerMm);
                        bounds.Inflate(3 * pixelsPerMm);
                        RoundedRect rect = new RoundedRect(bounds, 3 * pixelsPerMm);
                        plateGraphics.Render(rect, RGBA_Bytes.LightGray);
                        Stroke rectOutline = new Stroke(rect, .5 * pixelsPerMm);
                        plateGraphics.Render(rectOutline, RGBA_Bytes.DarkGray);
                    }

                    OrthographicZProjection.DrawTo(plateGraphics, meshToRender, lowerLeftInMM + offsetInMM, pixelsPerMm);
                    plateGraphics.DrawString(Path.GetFileName(openParams.FileName), (offsetInMM.x + centerInMM.x) * pixelsPerMm, (offsetInMM.y - 10) * pixelsPerMm, 50, Agg.Font.Justification.Center);

                    //ImageBuffer logoImage = new ImageBuffer();
                    //ImageIO.LoadImageData("Logo.png", logoImage);
                    //plateGraphics.Render(logoImage, (plateInventory.Width - logoImage.Width) / 2, plateInventory.Height - logoImage.Height - 10 * pixelsPerMm);

                    //ImageIO.SaveImageData("plate Inventory.jpeg", plateInventory);
                }
            });
        }
Пример #11
0
        public LogoSpinner(GuiWidget widget, double scale = 1.6, double spinSpeed = 0.6, double yOffset = 0.5, double rotateX = -0.1)
        {
            // loading animation stuff
            LightingData lighting = new LightingData();

            Mesh logoMesh;

            using (var logoStream = StaticData.Instance.OpenStream(Path.Combine("Stls", "MH Logo.stl")))
            {
                logoMesh = StlProcessing.Load(logoStream, CancellationToken.None);
            }

            // Position
            var aabb = logoMesh.GetAxisAlignedBoundingBox();

            logoMesh.Transform(Matrix4X4.CreateTranslation(-aabb.Center));

            logoMesh.Transform(Matrix4X4.CreateScale(scale / aabb.XSize));

            var anglePerDraw = 1 / MathHelper.Tau * spinSpeed;
            var angle        = 0.0;

            widget.BeforeDraw += (s, e) =>
            {
                var       screenSpaceBounds = widget.TransformToScreenSpace(widget.LocalBounds);
                WorldView world             = new WorldView(screenSpaceBounds.Width, screenSpaceBounds.Height);
                world.Translate(new Vector3(0, yOffset, 0));
                world.Rotate(Quaternion.FromEulerAngles(new Vector3(rotateX, 0, 0)));

                GLHelper.SetGlContext(world, screenSpaceBounds, lighting);
                GLHelper.Render(logoMesh, this.MeshColor, Matrix4X4.CreateRotationY(angle), RenderTypes.Shaded);
                GLHelper.UnsetGlContext();
            };

            Animation spinAnimation = new Animation()
            {
                DrawTarget      = widget,
                FramesPerSecond = 20
            };

            spinAnimation.Update += (s, time) =>
            {
                if (this.SpinLogo)
                {
                    angle += anglePerDraw;
                }
            };
            spinAnimation.Start();
        }
Пример #12
0
        public MeasureToolObject3D()
        {
            Name  = "Measure Tool".Localize();
            Color = Color.FromHSL(.11, .98, .76);

            if (shape == null)
            {
                using (Stream measureAmfStream = StaticData.Instance.OpenStream(Path.Combine("Stls", "measure_tool.stl")))
                {
                    shape = StlProcessing.Load(measureAmfStream, CancellationToken.None);
                }
            }

            Mesh = shape;
        }
Пример #13
0
        public static long GetEstimatedMemoryUse(string fileLocation)
        {
            switch (Path.GetExtension(fileLocation).ToUpper())
            {
            case ".STL":
                return(StlProcessing.GetEstimatedMemoryUse(fileLocation));

            case ".AMF":
                return(AmfDocument.GetEstimatedMemoryUse(fileLocation));

            case ".OBJ":
                throw new NotImplementedException();
            }

            return(0);
        }
Пример #14
0
        static void CreateThumbnailsThread()
        {
            while (true)
            {
                if (listOfWidgetsNeedingThumbnails.Count > 0)
                {
                    LibraryThumbnailWidget thumbnailWidget = listOfWidgetsNeedingThumbnails[0];
                    if (thumbnailWidget.printItem == null)
                    {
                        thumbnailWidget.image = new ImageBuffer(thumbnailWidget.noThumbnailImage);
                    }
                    else // generate the image
                    {
                        Mesh loadedMesh = StlProcessing.Load(thumbnailWidget.printItem.FileLocation);

                        thumbnailWidget.image = new ImageBuffer(thumbnailWidget.buildingThumbnailImage);
                        thumbnailWidget.Invalidate();

                        if (loadedMesh != null)
                        {
                            ImageBuffer tempImage      = new ImageBuffer(thumbnailWidget.image.Width, thumbnailWidget.image.Height, 32, new BlenderBGRA());
                            Graphics2D  partGraphics2D = tempImage.NewGraphics2D();

                            List <MeshEdge> nonManifoldEdges = loadedMesh.GetNonManifoldEdges();
                            if (nonManifoldEdges.Count > 0)
                            {
                                if (File.Exists("RunUnitTests.txt"))
                                {
                                    partGraphics2D.Circle(4, 4, 4, RGBA_Bytes.Red);
                                }
                            }

                            AxisAlignedBoundingBox aabb = loadedMesh.GetAxisAlignedBoundingBox();
                            double          maxSize     = Math.Max(aabb.XSize, aabb.YSize);
                            double          scale       = thumbnailWidget.image.Width / (maxSize * 1.2);
                            RectangleDouble bounds2D    = new RectangleDouble(aabb.minXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.x, aabb.maxXYZ.y);
                            PolygonMesh.Rendering.OrthographicZProjection.DrawTo(partGraphics2D, loadedMesh,
                                                                                 new Vector2((thumbnailWidget.image.Width / scale - bounds2D.Width) / 2 - bounds2D.Left,
                                                                                             (thumbnailWidget.image.Height / scale - bounds2D.Height) / 2 - bounds2D.Bottom),
                                                                                 scale,
                                                                                 thumbnailWidget.FillColor);

                            thumbnailWidget.image = new ImageBuffer(tempImage);
                        }
                        else
                        {
                            thumbnailWidget.image = new ImageBuffer(thumbnailWidget.noThumbnailImage);
                        }
                    }
                    thumbnailWidget.Invalidate();

                    using (TimedLock.Lock(listOfWidgetsNeedingThumbnails, "CreateThumbnailsThread()"))
                    {
                        listOfWidgetsNeedingThumbnails.RemoveAt(0);

                        foreach (LibraryThumbnailWidget part in listOfWidgetsNeedingThumbnails)
                        {
                            // mark them so we try to add them again if needed
                            part.thumbNailHasBeenRequested = false;
                        }

                        listOfWidgetsNeedingThumbnails.Clear();
                    }
                }
                Thread.Sleep(100);
            }
        }
Пример #15
0
        private static void CreateSlicedPartsThread()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            while (!haltSlicingThread)
            {
                if (listOfSlicingItems.Count > 0)
                {
                    PrintItemWrapper itemToSlice     = listOfSlicingItems[0];
                    bool             doMergeInSlicer = false;
                    string           mergeRules      = "";
                    doMergeInSlicer = ActiveSliceSettings.Instance.ActiveSliceEngineType() == SlicingEngineTypes.MatterSlice;
                    string[] stlFileLocations = GetStlFileLocations(itemToSlice.FileLocation, doMergeInSlicer, ref mergeRules);
                    string   fileToSlice      = stlFileLocations[0];
                    // check that the STL file is currently on disk
                    if (File.Exists(fileToSlice))
                    {
                        itemToSlice.CurrentlySlicing = true;

                        string currentConfigurationFileAndPath = Path.Combine(ApplicationDataStorage.Instance.GCodeOutputPath, "config_" + ActiveSliceSettings.Instance.GetLongHashCode().ToString() + ".ini");
                        ActiveSliceSettings.Instance.GenerateConfigFile(currentConfigurationFileAndPath, true);

                        string gcodePathAndFileName = itemToSlice.GetGCodePathAndFileName();
                        bool   gcodeFileIsComplete  = itemToSlice.IsGCodeFileComplete(gcodePathAndFileName);

                        if (!File.Exists(gcodePathAndFileName) || !gcodeFileIsComplete)
                        {
                            string commandArgs = "";

                            switch (ActiveSliceSettings.Instance.ActiveSliceEngineType())
                            {
                            case SlicingEngineTypes.Slic3r:
                                commandArgs = "--load \"" + currentConfigurationFileAndPath + "\" --output \"" + gcodePathAndFileName + "\" \"" + fileToSlice + "\"";
                                break;

                            case SlicingEngineTypes.CuraEngine:
                                commandArgs = "-v -o \"" + gcodePathAndFileName + "\" " + EngineMappingCura.GetCuraCommandLineSettings() + " \"" + fileToSlice + "\"";
                                break;

                            case SlicingEngineTypes.MatterSlice:
                            {
                                EngineMappingsMatterSlice.WriteMatterSliceSettingsFile(currentConfigurationFileAndPath);
                                if (mergeRules == "")
                                {
                                    commandArgs = "-v -o \"" + gcodePathAndFileName + "\" -c \"" + currentConfigurationFileAndPath + "\"";
                                }
                                else
                                {
                                    commandArgs = "-b {0} -v -o \"".FormatWith(mergeRules) + gcodePathAndFileName + "\" -c \"" + currentConfigurationFileAndPath + "\"";
                                }
                                foreach (string filename in stlFileLocations)
                                {
                                    commandArgs = commandArgs + " \"" + filename + "\"";
                                }
                            }
                            break;
                            }

#if false
                            Mesh        loadedMesh = StlProcessing.Load(fileToSlice);
                            SliceLayers layers     = new SliceLayers();
                            layers.GetPerimetersForAllLayers(loadedMesh, .2, .2);
                            layers.DumpSegmentsToGcode("test.gcode");
#endif

                            if (OsInformation.OperatingSystem == OSType.Android ||
                                ((OsInformation.OperatingSystem == OSType.Mac || runInProcess) &&
                                 ActiveSliceSettings.Instance.ActiveSliceEngineType() == SlicingEngineTypes.MatterSlice))
                            {
                                itemCurrentlySlicing = itemToSlice;
                                MatterHackers.MatterSlice.LogOutput.GetLogWrites += SendProgressToItem;
                                MatterSlice.MatterSlice.ProcessArgs(commandArgs);
                                MatterHackers.MatterSlice.LogOutput.GetLogWrites -= SendProgressToItem;
                                itemCurrentlySlicing = null;
                            }
                            else
                            {
                                slicerProcess = new Process();
                                slicerProcess.StartInfo.Arguments = commandArgs;
                                string slicerFullPath = getSlicerFullPath();

                                slicerProcess.StartInfo.CreateNoWindow         = true;
                                slicerProcess.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                                slicerProcess.StartInfo.RedirectStandardError  = true;
                                slicerProcess.StartInfo.RedirectStandardOutput = true;

                                slicerProcess.StartInfo.FileName        = slicerFullPath;
                                slicerProcess.StartInfo.UseShellExecute = false;

                                slicerProcess.OutputDataReceived += (sender, args) =>
                                {
                                    if (args.Data != null)
                                    {
                                        string message = args.Data;
                                        message = message.Replace("=>", "").Trim();
                                        if (message.Contains(".gcode"))
                                        {
                                            message = "Saving intermediate file";
                                        }
                                        message += "...";
                                        UiThread.RunOnIdle(() =>
                                        {
                                            itemToSlice.OnSlicingOutputMessage(new StringEventArgs(message));
                                        });
                                    }
                                };

                                slicerProcess.Start();
                                slicerProcess.BeginOutputReadLine();
                                string stdError = slicerProcess.StandardError.ReadToEnd();

                                slicerProcess.WaitForExit();
                                lock (slicerProcess)
                                {
                                    slicerProcess = null;
                                }
                            }
                        }

                        try
                        {
                            if (File.Exists(gcodePathAndFileName) &&
                                File.Exists(currentConfigurationFileAndPath))
                            {
                                // make sure we have not already written the settings onto this file
                                bool fileHaseSettings = false;
                                int  bufferSize       = 32000;
                                using (Stream fileStream = File.OpenRead(gcodePathAndFileName))
                                {
                                    byte[] buffer = new byte[bufferSize];
                                    fileStream.Seek(Math.Max(0, fileStream.Length - bufferSize), SeekOrigin.Begin);
                                    int    numBytesRead = fileStream.Read(buffer, 0, bufferSize);
                                    string fileEnd      = System.Text.Encoding.UTF8.GetString(buffer);
                                    if (fileEnd.Contains("GCode settings used"))
                                    {
                                        fileHaseSettings = true;
                                    }
                                }

                                if (!fileHaseSettings)
                                {
                                    using (StreamWriter gcodeWirter = File.AppendText(gcodePathAndFileName))
                                    {
                                        string oemName = "MatterControl";
                                        if (OemSettings.Instance.WindowTitleExtra != null && OemSettings.Instance.WindowTitleExtra.Trim().Length > 0)
                                        {
                                            oemName = oemName + " - {0}".FormatWith(OemSettings.Instance.WindowTitleExtra);
                                        }

                                        gcodeWirter.WriteLine("; {0} Version {1} Build {2} : GCode settings used".FormatWith(oemName, VersionInfo.Instance.ReleaseVersion, VersionInfo.Instance.BuildVersion));
                                        gcodeWirter.WriteLine("; Date {0} Time {1}:{2:00}".FormatWith(DateTime.Now.Date, DateTime.Now.Hour, DateTime.Now.Minute));

                                        foreach (string line in File.ReadLines(currentConfigurationFileAndPath))
                                        {
                                            gcodeWirter.WriteLine("; {0}".FormatWith(line));
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }

                    UiThread.RunOnIdle(() =>
                    {
                        itemToSlice.CurrentlySlicing = false;
                        itemToSlice.DoneSlicing      = true;
                    });

                    lock (listOfSlicingItems)
                    {
                        listOfSlicingItems.RemoveAt(0);
                    }
                }

                Thread.Sleep(100);
            }
        }
Пример #16
0
        public void SavingFunction()
        {
            currentlySaving        = true;
            countThatHaveBeenSaved = 0;
            // first create images for all the parts
            foreach (string stlFileName in stlFilesToPrint)
            {
                Mesh loadedMesh = StlProcessing.Load(stlFileName);
                if (loadedMesh != null)
                {
                    AxisAlignedBoundingBox aabb     = loadedMesh.GetAxisAlignedBoundingBox();
                    RectangleDouble        bounds2D = new RectangleDouble(aabb.minXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.x, aabb.maxXYZ.y);
                    double widthInMM   = bounds2D.Width + PartMarginMM * 2;
                    double textSpaceMM = 5;
                    double heightMM    = textSpaceMM + bounds2D.Height + PartMarginMM * 2;

                    string          partName        = System.IO.Path.GetFileName(System.IO.Path.GetFileName(stlFileName));
                    TypeFacePrinter typeFacePrinter = new TypeFacePrinter(partName, 28, Vector2.Zero, Justification.Center, Baseline.BoundsCenter);
                    double          sizeOfNameX     = typeFacePrinter.GetSize().x + PartMarginPixels * 2;
                    Vector2         sizeOfRender    = new Vector2(widthInMM * PixelPerMM, heightMM * PixelPerMM);

                    ImageBuffer imageOfPart = new ImageBuffer((int)(Math.Max(sizeOfNameX, sizeOfRender.x)), (int)(sizeOfRender.y), 32, new BlenderBGRA());
                    typeFacePrinter.Origin = new Vector2(imageOfPart.Width / 2, (textSpaceMM / 2) * PixelPerMM);

                    Graphics2D partGraphics2D = imageOfPart.NewGraphics2D();

                    RectangleDouble rectBounds  = new RectangleDouble(0, 0, imageOfPart.Width, imageOfPart.Height);
                    double          strokeWidth = .5 * PixelPerMM;
                    rectBounds.Inflate(-strokeWidth / 2);
                    RoundedRect rect = new RoundedRect(rectBounds, PartMarginMM * PixelPerMM);
                    partGraphics2D.Render(rect, RGBA_Bytes.LightGray);
                    Stroke rectOutline = new Stroke(rect, strokeWidth);
                    partGraphics2D.Render(rectOutline, RGBA_Bytes.DarkGray);

                    PolygonMesh.Rendering.OrthographicZProjection.DrawTo(partGraphics2D, loadedMesh, new Vector2(-bounds2D.Left + PartMarginMM, -bounds2D.Bottom + textSpaceMM + PartMarginMM), PixelPerMM, RGBA_Bytes.Black);
                    partGraphics2D.Render(typeFacePrinter, RGBA_Bytes.Black);

                    partImagesToPrint.Add(new PartImage(imageOfPart));
                }
                countThatHaveBeenSaved++;
                if (UpdateRemainingItems != null)
                {
                    UpdateRemainingItems(this, new StringEventArgs(Path.GetFileName(stlFileName)));
                }
            }

            partImagesToPrint.Sort(BiggestToLittlestImages);

            PdfDocument document = new PdfDocument();

            document.Info.Title    = "MatterHackers Parts Sheet";
            document.Info.Author   = "MatterHackers Inc.";
            document.Info.Subject  = "This is a list of the parts that are in a queue from MatterControl.";
            document.Info.Keywords = "MatterControl, STL, 3D Printing";

            int  nextPartToPrintIndex = 0;
            int  plateNumber          = 1;
            bool done = false;

            while (!done && nextPartToPrintIndex < partImagesToPrint.Count)
            {
                PdfPage pdfPage = document.AddPage();
                CreateOnePage(plateNumber++, ref nextPartToPrintIndex, pdfPage);
            }
            try
            {
                document.Save(pathAndFileToSaveTo);
                Process.Start(pathAndFileToSaveTo);
            }
            catch {
            }

            OnDoneSaving();
            currentlySaving = false;
        }
Пример #17
0
        public MoveInZControl(IInteractionVolumeContext context)
            : base(context)
        {
            theme = AppContext.Theme;
            Name  = "MoveInZControl";
            zHeightDisplayInfo = new InlineEditControl()
            {
                ForceHide = () =>
                {
                    var selectedItem = RootSelection;
                    // if the selection changes
                    if (selectedItem != ActiveSelectedItem)
                    {
                        return(true);
                    }

                    // if another control gets a hover
                    if (InteractionContext.HoveredInteractionVolume != this &&
                        InteractionContext.HoveredInteractionVolume != null)
                    {
                        return(true);
                    }

                    // if we clicked on the control
                    if (HadClickOnControl)
                    {
                        return(false);
                    }

                    return(false);
                }
                ,
                GetDisplayString = (value) => "{0:0.0#}mm".FormatWith(value)
            };

            zHeightDisplayInfo.VisibleChanged += (s, e) =>
            {
                if (!zHeightDisplayInfo.Visible)
                {
                    HadClickOnControl = false;
                }
            };

            zHeightDisplayInfo.EditComplete += (s, e) =>
            {
                var selectedItem = RootSelection;

                Matrix4X4 startingTransform = selectedItem.Matrix;

                var newZPosition = zHeightDisplayInfo.Value;

                if (InteractionContext.SnapGridDistance > 0)
                {
                    // snap this position to the grid
                    double snapGridDistance = InteractionContext.SnapGridDistance;

                    // snap this position to the grid
                    newZPosition = ((int)((newZPosition / snapGridDistance) + .5)) * snapGridDistance;
                }

                AxisAlignedBoundingBox originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                var moveAmount = newZPosition - originalSelectedBounds.MinXYZ.Z;

                if (moveAmount != 0)
                {
                    selectedItem.Matrix = selectedItem.Matrix * Matrix4X4.CreateTranslation(0, 0, moveAmount);
                    Invalidate();
                }

                context.Scene.AddTransformSnapshot(startingTransform);
            };

            InteractionContext.GuiSurface.AddChild(zHeightDisplayInfo);

            DrawOnTop = true;

            using (Stream arrowStream = AggContext.StaticData.OpenStream(Path.Combine("Stls", "up_pointer.stl")))
            {
                upArrowMesh = StlProcessing.Load(arrowStream, CancellationToken.None);
            }

            CollisionVolume = upArrowMesh.CreateBVHData();

            InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw;
        }
Пример #18
0
        public GuiWidget Create(IObject3D object3D, UndoBuffer undoBuffer, ThemeConfig theme)
        {
            this.item = object3D as OpenScadObject3D;

            var mainContainer = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Absolute,
                Width   = 225
            };

            FlowLayoutWidget actionButtons = new FlowLayoutWidget();

            mainContainer.AddChild(actionButtons);

            // TODO: This should use the same renaming and asset system as stl/amf assets
            string assetInfoPath = Path.ChangeExtension(item.ScriptPath, ".json");

            bool isGenerator = File.Exists(assetInfoPath);

            if (isGenerator)
            {
                BuildGeneratorUI(theme, mainContainer, item.ScriptPath, assetInfoPath);
            }
            else
            {
                var editButton = new TextButton("Edit".Localize(), theme)
                {
                    Margin      = 5,
                    ToolTipText = "Edit OpenSCAD script".Localize()
                };
                editButton.Click += (s, e) =>
                {
                    Process.Start(item.ScriptPath);
                };
                actionButtons.AddChild(editButton);

                var updateButton = new TextButton("Update".Localize(), theme)
                {
                    Margin      = 5,
                    ToolTipText = "Compile model".Localize()
                };
                if (!File.Exists(compilerPath))
                {
                    updateButton.Enabled     = false;
                    updateButton.ToolTipText = "OpenSCAD not installed".Localize();
                }
                updateButton.Click += async(s, e) =>
                {
                    using (var meshStream = AggContext.StaticData.OpenStream(Path.Combine("Stls", "openscad_logo.stl")))
                    {
                        this.item.Mesh = Object3D.Load(meshStream, ".stl", CancellationToken.None).Mesh;
                    }

                    // TODO: Use assets system
                    string outputPath = Path.ChangeExtension(item.ScriptPath, ".stl");
                    int    err        = await Task.Run(() => ExecuteScript(item.ScriptPath, outputPath));

                    if (err == 0)
                    {
                        // Reload the mesh
                        this.item.Mesh = StlProcessing.Load(outputPath, CancellationToken.None);
                    }
                };
                actionButtons.AddChild(updateButton);
            }

            return(mainContainer);
        }
        public static Mesh Do(Mesh transformedKeep, Mesh transformedRemove, int opperation, IProgress <ProgressStatus> reporter, double amountPerOperation, double percentCompleted, ProgressStatus progressStatus, CancellationToken cancellationToken)
        {
            var libiglExe = "libigl_boolean.exe";

            if (File.Exists(libiglExe) &&
                IntPtr.Size == 8)                    // only try to run the improved booleans if we are 64 bit and it is there
            {
                string folderToSaveStlsTo = Path.Combine(ApplicationDataStorage.Instance.ApplicationTempDataPath, "amf_to_stl");
                // Create directory if needed
                Directory.CreateDirectory(folderToSaveStlsTo);

                string stlFileA = Path.Combine(folderToSaveStlsTo, Path.ChangeExtension(Path.GetRandomFileName(), ".stl"));
                StlProcessing.Save(transformedKeep, stlFileA, CancellationToken.None);

                string stlFileB = Path.Combine(folderToSaveStlsTo, Path.ChangeExtension(Path.GetRandomFileName(), ".stl"));
                StlProcessing.Save(transformedRemove, stlFileB, CancellationToken.None);

                // wait for files to close
                Thread.Sleep(1000);

                string stlFileResult = Path.Combine(folderToSaveStlsTo, Path.ChangeExtension(Path.GetRandomFileName(), ".stl"));

                // if we have the libigl_boolean.exe
                var opperationString = "-";
                switch (opperation)
                {
                case 0:
                    opperationString = "+";
                    break;

                case 1:
                    opperationString = "-";
                    break;

                case 2:
                    opperationString = "&";
                    break;
                }

                var slicerProcess = new Process()
                {
                    StartInfo = new ProcessStartInfo()
                    {
                        Arguments              = "{0} {1} {2} {3}".FormatWith(stlFileA, stlFileB, stlFileResult, opperationString),
                        CreateNoWindow         = true,
                        WindowStyle            = ProcessWindowStyle.Hidden,
                        RedirectStandardError  = true,
                        RedirectStandardOutput = true,
                        FileName        = libiglExe,
                        UseShellExecute = false
                    }
                };
                slicerProcess.Start();
                slicerProcess.WaitForExit();

                // wait for file to close
                Thread.Sleep(1000);

                // load up the
                var result = StlProcessing.Load(stlFileResult, CancellationToken.None);
                if (result != null)
                {
                    return(result);
                }
            }

            switch (opperation)
            {
            case 0:
                return(PolygonMesh.Csg.CsgOperations.Union(transformedKeep, transformedRemove, (status, progress0To1) =>
                {
                    // Abort if flagged
                    cancellationToken.ThrowIfCancellationRequested();

                    progressStatus.Status = status;
                    progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1;
                    reporter.Report(progressStatus);
                }, cancellationToken));

            case 1:
                return(PolygonMesh.Csg.CsgOperations.Subtract(transformedKeep, transformedRemove, (status, progress0To1) =>
                {
                    // Abort if flagged
                    cancellationToken.ThrowIfCancellationRequested();

                    progressStatus.Status = status;
                    progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1;
                    reporter?.Report(progressStatus);
                }, cancellationToken));

            case 2:
                return(PolygonMesh.Csg.CsgOperations.Intersect(transformedKeep, transformedRemove, (status, progress0To1) =>
                {
                    // Abort if flagged
                    cancellationToken.ThrowIfCancellationRequested();

                    progressStatus.Status = status;
                    progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1;
                    reporter.Report(progressStatus);
                }, cancellationToken));
            }

            return(null);
        }
Пример #20
0
        void createThumbnailWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            PartThumbnailWidget thumbnailWidget = e.Argument as PartThumbnailWidget;

            if (thumbnailWidget != null)
            {
                if (thumbnailWidget.printItem == null)
                {
                    thumbnailWidget.tumbnailImage = new ImageBuffer(thumbnailWidget.noThumbnailImage);
                    thumbnailWidget.Invalidate();
                    return;
                }

                string stlHashCode = thumbnailWidget.PrintItem.StlFileHashCode.ToString();

                Point2D     bigRenderSize = new Point2D(460, 460);
                ImageBuffer bigRender     = LoadImageFromDisk(thumbnailWidget, stlHashCode, bigRenderSize);
                if (bigRender == null)
                {
                    Mesh loadedMesh = StlProcessing.Load(thumbnailWidget.PrintItem.FileLocation);

                    thumbnailWidget.tumbnailImage = new ImageBuffer(thumbnailWidget.buildingThumbnailImage);
                    thumbnailWidget.tumbnailImage.NewGraphics2D().Clear(new RGBA_Bytes(255, 255, 255, 0));
                    bigRender = BuildImageFromSTL(loadedMesh, stlHashCode, bigRenderSize);
                    if (bigRender == null)
                    {
                        bigRender = new ImageBuffer(thumbnailWidget.noThumbnailImage);
                    }
                }

                switch (thumbnailWidget.Size)
                {
                case ImageSizes.Size50x50:
                {
                    ImageBuffer halfWay1 = new ImageBuffer(200, 200, 32, new BlenderBGRA());
                    halfWay1.NewGraphics2D().Clear(new RGBA_Bytes(255, 255, 255, 0));
                    halfWay1.NewGraphics2D().Render(bigRender, 0, 0, 0, (double)halfWay1.Width / bigRender.Width, (double)halfWay1.Height / bigRender.Height);

                    ImageBuffer halfWay2 = new ImageBuffer(100, 100, 32, new BlenderBGRA());
                    halfWay2.NewGraphics2D().Clear(new RGBA_Bytes(255, 255, 255, 0));
                    halfWay2.NewGraphics2D().Render(halfWay1, 0, 0, 0, (double)halfWay2.Width / halfWay1.Width, (double)halfWay2.Height / halfWay1.Height);

                    thumbnailWidget.tumbnailImage = new ImageBuffer(50, 50, 32, new BlenderBGRA());
                    thumbnailWidget.tumbnailImage.NewGraphics2D().Clear(new RGBA_Bytes(255, 255, 255, 0));
                    thumbnailWidget.tumbnailImage.NewGraphics2D().Render(halfWay2, 0, 0, 0, (double)thumbnailWidget.tumbnailImage.Width / halfWay2.Width, (double)thumbnailWidget.tumbnailImage.Height / halfWay2.Height);
                }
                break;

                case ImageSizes.Size115x115:
                {
                    ImageBuffer halfWay1 = new ImageBuffer(230, 230, 32, new BlenderBGRA());
                    halfWay1.NewGraphics2D().Clear(new RGBA_Bytes(255, 255, 255, 0));
                    halfWay1.NewGraphics2D().Render(bigRender, 0, 0, 0, (double)halfWay1.Width / bigRender.Width, (double)halfWay1.Height / bigRender.Height);

                    thumbnailWidget.tumbnailImage = new ImageBuffer(115, 115, 32, new BlenderBGRA());
                    thumbnailWidget.tumbnailImage.NewGraphics2D().Clear(new RGBA_Bytes(255, 255, 255, 0));
                    thumbnailWidget.tumbnailImage.NewGraphics2D().Render(halfWay1, 0, 0, 0, (double)thumbnailWidget.tumbnailImage.Width / halfWay1.Width, (double)thumbnailWidget.tumbnailImage.Height / halfWay1.Height);
                }
                break;

                default:
                    throw new NotImplementedException();
                }

                UiThread.RunOnIdle(thumbnailWidget.EnsureImageUpdated);
            }
        }