Esempio n. 1
0
        public void AddPolygonsTest()
        {
            PlanarSlice slice = new PlanarSlice();
            Polygon2d   p2d   = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d poly = new GeneralPolygon2d(p2d);
            Polygon2d        p2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d poly2 = new GeneralPolygon2d(p2d2);

            slice.AddPolygons(new List <GeneralPolygon2d>()
            {
                poly, poly2
            });

            Assert.AreEqual(slice.InputSolids[0], poly);
            Assert.AreEqual(slice.InputSolids[1], poly2);
        }
Esempio n. 2
0
        public void AddClippedPathTest()
        {
            PlanarSlice slice = new PlanarSlice();
            PolyLine2d  line  = new PolyLine2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(-1, 0)
            });

            slice.AddClippedPath(line);

            Assert.AreEqual(slice.ClippedPaths[0], line);
        }
Esempio n. 3
0
        public void ResolveEmbeddedPathWidthExceptionTest()
        {
            PlanarSlice slice = new PlanarSlice();
            PolyLine2d  line  = new PolyLine2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(-1, 0)
            });

            slice.AddEmbeddedPath(line);

            Assert.ThrowsException <Exception>(() => slice.Resolve());
        }
Esempio n. 4
0
        public void AddSupportPolygonTest()
        {
            PlanarSlice slice = new PlanarSlice();
            Polygon2d   p2d   = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d poly = new GeneralPolygon2d(p2d);

            slice.AddSupportPolygon(poly);

            Assert.IsTrue(slice.SupportSolids[0] == poly);
        }
Esempio n. 5
0
        public void AddCropRegionTest()
        {
            PlanarSlice slice = new PlanarSlice();
            Polygon2d   p2d   = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d poly = new GeneralPolygon2d(p2d);

            slice.AddCropRegion(poly);

            Assert.IsTrue(slice.InputCropRegions[0] == poly);
        }
        private void DrawLayerSlice(PlanarSliceStack stack, SKCanvas canvas, SKPaint paint)
        {
            SKColor pathColor = SkiaUtil.Color(255, 0, 0, 255);

            paint.Color       = pathColor;
            paint.Style       = SKPaintStyle.Stroke;
            paint.StrokeWidth = 2.0f;

            if (currentLayer >= stack.Slices.Count)
            {
                return;
            }

            PlanarSlice slice = stack.Slices[currentLayer];

            foreach (GeneralPolygon2d poly in slice.Solids)
            {
                SKPath path = MakePaths(poly, SceneToSkiaF);
                canvas.DrawPath(path, paint);
            }
        }
Esempio n. 7
0
        public void ComputeOnBackgroundThread()
        {
            Deviation = null;

            DebugUtil.Log(SO.GetToolpathStats());

            ToolpathSet      paths  = SO.GetToolpaths();
            PlanarSliceStack slices = SO.GetSlices();
            var settings            = SO.GetSettings();

            // AAHHH
            double   bed_width  = settings.Machine.BedSizeXMM;
            double   bed_height = settings.Machine.BedSizeYMM;
            Vector3d origin     = new Vector3d(-bed_width / 2, -bed_height / 2, 0);

            if (settings is gs.info.MakerbotSettings)
            {
                origin = Vector3d.Zero;
            }

            List <DeviationPt>   points       = new List <DeviationPt>();
            SpinLock             pointsLock   = new SpinLock();
            Action <DeviationPt> appendPointF = (pt) => {
                bool entered = false;
                pointsLock.Enter(ref entered);
                points.Add(pt);
                pointsLock.Exit();
            };

            double tolerance = settings.Machine.NozzleDiamMM * 0.5 + DeviationToleranceMM;

            gParallel.ForEach(Interval1i.Range(slices.Count), (slicei) => {
                PlanarSlice slice = slices[slicei];

                //Interval1d zrange = (slicei < slices.Count - 1) ?
                //    new Interval1d(slice.Z, slices[slicei + 1].Z - 0.5*settings.LayerHeightMM) :
                //    new Interval1d(slice.Z, slice.Z + 0.5*settings.LayerHeightMM);
                double dz         = 0.5 * settings.LayerHeightMM;
                Interval1d zrange = new Interval1d(slice.Z - dz, slice.Z + dz);

                double cellSize = 2.0f;

                ToolpathsLayerGrid grid = new ToolpathsLayerGrid();
                grid.Build(paths, zrange, cellSize);

                foreach (GeneralPolygon2d poly in slice.Solids)
                {
                    measure_poly(poly.Outer, slice.Z, grid, tolerance, appendPointF);
                    foreach (var hole in poly.Holes)
                    {
                        measure_poly(poly.Outer, slice.Z, grid, tolerance, appendPointF);
                    }
                }
            });

            int N = points.Count;

            for (int k = 0; k < N; ++k)
            {
                DeviationPt pt = points[k];
                Vector3d    v  = origin + pt.pos;
                v         = MeshTransforms.ConvertZUpToYUp(v);
                pt.pos    = MeshTransforms.FlipLeftRightCoordSystems(v);
                points[k] = pt;
            }

            Deviation = new DeviationData();
            Deviation.DeviationPoints = points;
            OnGeometryUpdateRequired?.Invoke(this);
        }
Esempio n. 8
0
        public void DistanceSquaredExceptionTest()
        {
            PlanarSlice slice = new PlanarSlice();

            Assert.ThrowsException <Exception>(() => slice.DistanceSquared(new Vector2d(0, 0)));
        }
Esempio n. 9
0
        public void ResolveTest()
        {
            PlanarSlice slice = new PlanarSlice();
            Polygon2d   p2d   = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d poly = new GeneralPolygon2d(p2d);
            Polygon2d        p2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d poly2 = new GeneralPolygon2d(p2d2);

            slice.AddPolygons(new List <GeneralPolygon2d>()
            {
                poly, poly2
            });

            Assert.AreEqual(slice.InputSolids[0], poly);
            Assert.AreEqual(slice.InputSolids[1], poly2);

            PolyLine2d line = new PolyLine2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(-1, 0)
            });

            slice.AddEmbeddedPath(line);
            slice.EmbeddedPathWidth = 1;

            Polygon2d supportp2d = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d supportpoly = new GeneralPolygon2d(supportp2d);
            Polygon2d        supportp2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d supportpoly2 = new GeneralPolygon2d(supportp2d2);

            slice.AddSupportPolygons(new List <GeneralPolygon2d>()
            {
                supportpoly, supportpoly2
            });

            Polygon2d cavp2d = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d cavpoly = new GeneralPolygon2d(cavp2d);
            Polygon2d        cavp2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d cavpoly2 = new GeneralPolygon2d(cavp2d2);

            slice.AddCavityPolygons(new List <GeneralPolygon2d>()
            {
                cavpoly, cavpoly2
            });

            Polygon2d cropp2d = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d croppoly = new GeneralPolygon2d(cropp2d);
            Polygon2d        cropp2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d croppoly2 = new GeneralPolygon2d(cropp2d2);

            slice.AddCropRegions(new List <GeneralPolygon2d>()
            {
                croppoly, croppoly2
            });

            slice.Resolve();

            slice.BuildSpatialCaches();

            double dist = slice.DistanceSquared(new Vector2d(5, 5));

            Assert.AreEqual(41, dist);
        }
Esempio n. 10
0
        static GCodeFile generate_cnc_test(MeshPlanarMillSlicer.Result sliceSets, RepRapSettings settings, out ToolpathSet AccumulatedPaths)
        {
            int PLUNGE_SPEED = 800;

            AccumulatedPaths = new ToolpathSet();

            GCodeFileAccumulator         file_accumulator = new GCodeFileAccumulator();
            GCodeBuilder                 builder          = new GCodeBuilder(file_accumulator);
            BaseThreeAxisMillingCompiler Compiler         = new BaseThreeAxisMillingCompiler(builder, settings, GenericMillingAssembler.Factory);

            Compiler.Begin();

            /*
             * Clearing pass
             */

            PlanarSliceStack clearingSlices = sliceSets.Clearing;
            int N = clearingSlices.Count;

            // assuming origin is at top of stock so we actaully are going down in Z layers
            for (int k = 0; k < N; ++k)
            {
                clearingSlices[k].Z = -(sliceSets.TopZ - clearingSlices[k].Z);
            }

            for (int layeri = 0; layeri < N; layeri++)
            {
                PlanarSlice slice = clearingSlices[layeri];
                Compiler.AppendComment(string.Format("clearing layer {0} - {1}mm", layeri, slice.Z));

                ToolpathSetBuilder layer_builder = new ToolpathSetBuilder()
                {
                    MoveType = ToolpathTypes.Cut
                };
                layer_builder.Initialize(Compiler.ToolPosition);

                // To do a layer-change, we need to plunge down at the first scheduled cutting position.
                // However we will not know that until we schedule the first set of paths.
                // So, we configure SequentialScheduler2d to call this function when it knows this information,
                // and then we can travel to the new XY position before we plunge to new Z
                Action <List <FillCurveSet2d>, SequentialScheduler2d> DoZChangeF = (curves, scheduler) => {
                    Vector2d startPosXY = (curves[0].Loops.Count > 0) ?
                                          curves[0].Loops[0].Start : curves[0].Curves[0].Start;
                    Vector3d startPosXYZ = new Vector3d(startPosXY.x, startPosXY.y, slice.Z);
                    // TODO: we should retract at faster speed here? maybe use custom function that does this better?
                    layer_builder.AppendTravel(startPosXYZ, PLUNGE_SPEED);
                    scheduler.OnAppendCurveSetsF = null;
                };

                SequentialScheduler2d layerScheduler = new SequentialScheduler2d(layer_builder, settings)
                {
                    ExtrudeOnShortTravels = true,
                    ShortTravelDistance   = settings.Machine.NozzleDiamMM * 1.5
                };
                layerScheduler.OnAppendCurveSetsF = DoZChangeF;
                GroupScheduler2d groupScheduler = new GroupScheduler2d(layerScheduler, Compiler.ToolPosition.xy);

                foreach (GeneralPolygon2d shape in slice.Solids)
                {
                    ShellsFillPolygon shells_gen = new ShellsFillPolygon(shape)
                    {
                        PathSpacing    = settings.ShellsFillPathSpacingMM(),
                        ToolWidth      = settings.Machine.NozzleDiamMM,
                        Layers         = 10,
                        OuterShellLast = false,
                        DiscardTinyPerimterLengthMM = 1, DiscardTinyPolygonAreaMM2 = 1
                    };
                    shells_gen.Compute();

                    groupScheduler.BeginGroup();
                    groupScheduler.AppendCurveSets(shells_gen.Shells);
                    groupScheduler.EndGroup();
                }

                Compiler.AppendPaths(layer_builder.Paths, settings);
                AccumulatedPaths.Append(layer_builder.Paths);
            }



            /*
             * Horizontal finish pass
             */

            PlanarSliceStack horzSlices = sliceSets.HorizontalFinish;
            int NH = horzSlices.Count;

            // assuming origin is at top of stock so we actaully are going down in Z layers
            for (int k = 0; k < NH; ++k)
            {
                horzSlices[k].Z = -(sliceSets.TopZ - horzSlices[k].Z);
            }

            for (int layeri = 0; layeri < NH; layeri++)
            {
                PlanarSlice slice = horzSlices[layeri];
                Compiler.AppendComment(string.Format("horz finish layer {0} - {1}mm", layeri, slice.Z));

                ToolpathSetBuilder layer_builder = new ToolpathSetBuilder()
                {
                    MoveType = ToolpathTypes.Cut
                };
                layer_builder.Initialize(Compiler.ToolPosition);

                Action <List <FillCurveSet2d>, SequentialScheduler2d> DoZChangeF = (curves, scheduler) => {
                    Vector2d startPosXY = (curves[0].Loops.Count > 0) ?
                                          curves[0].Loops[0].Start : curves[0].Curves[0].Start;
                    Vector3d startPosXYZ = new Vector3d(startPosXY.x, startPosXY.y, slice.Z);
                    // TODO: we should retract at faster speed here? maybe use custom function that does this better?
                    layer_builder.AppendTravel(startPosXYZ, PLUNGE_SPEED);
                    scheduler.OnAppendCurveSetsF = null;
                };

                SequentialScheduler2d layerScheduler = new SequentialScheduler2d(layer_builder, settings)
                {
                    ExtrudeOnShortTravels = true,
                    ShortTravelDistance   = settings.Machine.NozzleDiamMM * 1.5
                };
                layerScheduler.OnAppendCurveSetsF = DoZChangeF;
                GroupScheduler2d groupScheduler = new GroupScheduler2d(layerScheduler, Compiler.ToolPosition.xy);

                foreach (GeneralPolygon2d shape in slice.Solids)
                {
                    ShellsFillPolygon shells_gen = new ShellsFillPolygon(shape)
                    {
                        //InsetFromInputPolygonX = 0.0,
                        PathSpacing                 = settings.ShellsFillPathSpacingMM(),
                        ToolWidth                   = settings.Machine.NozzleDiamMM,
                        Layers                      = 10,
                        OuterShellLast              = false,
                        PreserveInputInsetTopology  = false,
                        DiscardTinyPerimterLengthMM = 1, DiscardTinyPolygonAreaMM2 = 1
                    };
                    shells_gen.Compute();

                    groupScheduler.BeginGroup();
                    groupScheduler.AppendCurveSets(shells_gen.Shells);
                    groupScheduler.EndGroup();
                }

                Compiler.AppendPaths(layer_builder.Paths, settings);
                AccumulatedPaths.Append(layer_builder.Paths);
            }


            // return to home position
            ToolpathSetBuilder finishBuilder = new ToolpathSetBuilder()
            {
                MoveType = ToolpathTypes.Cut
            };

            finishBuilder.Initialize(Compiler.ToolPosition);
            finishBuilder.AppendTravel(Vector3d.Zero, PLUNGE_SPEED);
            Compiler.AppendPaths(finishBuilder.Paths, settings);


            Compiler.End();
            return(file_accumulator.File);
        }
Esempio n. 11
0
        void OnExpose(object sender, ExposeEventArgs args)
        {
            DrawingArea area = (DrawingArea)sender;

            Cairo.Context cr = Gdk.CairoHelper.Create(area.GdkWindow);

            int width  = area.Allocation.Width;
            int height = area.Allocation.Height;

            AxisAlignedBox3d bounds3 = Stack.Bounds;
            AxisAlignedBox2d bounds  = (bounds3 == AxisAlignedBox3d.Empty) ?
                                       new AxisAlignedBox2d(0, 0, 500, 500) :
                                       new AxisAlignedBox2d(bounds3.Min.x, bounds3.Min.y, bounds3.Max.x, bounds3.Max.y);

            double sx = (double)width / bounds.Width;
            double sy = (double)height / bounds.Height;

            float scale = (float)Math.Min(sx, sy);

            // we apply this translate after scaling to pixel coords
            Vector2f pixC      = Zoom * scale * (Vector2f)bounds.Center;
            Vector2f translate = new Vector2f(width / 2, height / 2) - pixC;

            using (var bitmap = new SKBitmap(width, height, SkiaUtil.ColorType(), SKAlphaType.Premul))
            {
                IntPtr len;
                using (var skSurface = SKSurface.Create(bitmap.Info.Width, bitmap.Info.Height, SkiaUtil.ColorType(), SKAlphaType.Premul, bitmap.GetPixels(out len), bitmap.Info.RowBytes))
                {
                    var canvas = skSurface.Canvas;
                    canvas.Clear(SkiaUtil.Color(240, 240, 240, 255));

                    Func <Vector2d, Vector2f> xformF = (pOrig) => {
                        Vector2f pNew = (Vector2f)pOrig;
                        pNew  -= (Vector2f)bounds.Center;
                        pNew   = Zoom * scale * pNew;
                        pNew  += (Vector2f)pixC;
                        pNew  += translate + Zoom * Translate;
                        pNew.y = canvas.LocalClipBounds.Height - pNew.y;
                        return(pNew);
                    };
                    Func <Vector2d, SKPoint> mapToSkiaF = (pOrig) => {
                        Vector2f p = xformF(pOrig);
                        return(new SKPoint(p.x, p.y));
                    };

                    using (var paint = new SKPaint())
                    {
                        SKBitmap sliceImg = get_slice_image(currentLayer);
                        float    w = sliceImg.Width / CurrentDPIMM, h = sliceImg.Height / CurrentDPIMM;
                        w *= Zoom * scale;
                        h *= Zoom * scale;
                        SKPoint sliceCenter = mapToSkiaF(Vector2d.Zero);
                        SKRect  drawRect    = new SKRect(
                            sliceCenter.X - w / 2, sliceCenter.Y - h / 2,
                            sliceCenter.X + w / 2, sliceCenter.Y + h / 2);
                        canvas.DrawBitmap(sliceImg, drawRect, paint);


                        paint.IsAntialias = true;
                        paint.Style       = SKPaintStyle.Stroke;

                        PlanarSlice slice = Stack.Slices[currentLayer];

                        paint.Color       = SkiaUtil.Color(255, 0, 0, 255);;
                        paint.StrokeWidth = 2;
                        foreach (GeneralPolygon2d poly in slice.Solids)
                        {
                            SKPath path = SkiaUtil.ToSKPath(poly, mapToSkiaF);
                            canvas.DrawPath(path, paint);
                        }
                    }

                    Cairo.Surface surface = new Cairo.ImageSurface(
                        bitmap.GetPixels(out len),
                        Cairo.Format.Argb32,
                        bitmap.Width, bitmap.Height,
                        bitmap.Width * 4);

                    surface.MarkDirty();
                    cr.SetSourceSurface(surface, 0, 0);
                    cr.Paint();
                }
            }

            //return true;
        }