protected override void DrawScene(SKCanvas canvas, Func <Vector2d, Vector2f> ViewTransformF)
        {
            Random          jitter  = new Random(313377);
            Func <Vector2d> jitterF = () => { return(Vector2d.Zero); };

            //{ return 0.1 * new Vector2d(jitter.NextDouble(), jitter.NextDouble()); };

            canvas.Clear(SkiaUtil.Color(255, 255, 255, 255));


            Func <Vector2d, SKPoint> SceneToSkiaF = (v) => {
                Vector2f p = ViewTransformF(v);
                return(new SKPoint(p.x, p.y));
            };


            using (var paint = new SKPaint()) {
                paint.IsAntialias = true;

                paint.StrokeWidth = 1;
                paint.Style       = SKPaintStyle.Stroke;

                foreach (var g in GPolygons)
                {
                    DrawPolygon(canvas, paint, g, SceneToSkiaF);
                }
                foreach (var g in Graphs)
                {
                    DrawGraph(canvas, paint, g, SceneToSkiaF);
                }
            }
        }
        public List <PolyLine2d> GetPolylinesForLayer(int layer)
        {
            ToolpathSet pathSetIn = Paths;

            SKColor    extrudeColor = SkiaUtil.Color(0, 0, 0, 255);
            Interval1d layer_zrange = Layers.GetLayerZInterval(layer);

            List <PolyLine2d> polylines = new List <PolyLine2d>();

            Action <LinearToolpath3 <PrintVertex> > drawPath3F = (polyPath) => {
                Vector3d v0 = polyPath.Start.Position;
                if (layer_zrange.Contains(v0.z) == false)
                {
                    return;
                }
                if (polyPath.Type != ToolpathTypes.Deposition)
                {
                    return;
                }

                PolyLine2d pline = new PolyLine2d();
                for (int i = 0; i < polyPath.VertexCount; ++i)
                {
                    pline.AppendVertex(polyPath[i].Position.xy);
                }

                polylines.Add(pline);
            };

            ProcessLinearPaths(pathSetIn, drawPath3F);

            return(polylines);
        }
Exemplo n.º 3
0
        protected override void DrawScene(SKCanvas canvas, Func <Vector2d, Vector2f> ViewTransformF)
        {
            Random          jitter  = new Random(313377);
            Func <Vector2d> jitterF = () =>
            { return(Vector2d.Zero); };

            //{ return 0.1 * new Vector2d(jitter.NextDouble(), jitter.NextDouble()); };

            canvas.Clear(SkiaUtil.Color(255, 255, 255, 255));

            // update scene xform
            SceneXFormF = (pOrig) => {
                pOrig += jitterF();
                return(ViewTransformF(pOrig));
            };

            // figure out dimension scaling factor
            Vector2f a = SceneXFormF(Vector2d.Zero), b = SceneXFormF(Vector2d.AxisX);

            dimensionScale = (b.x - a.x);

            using (var paint = new SKPaint())
            {
                paint.IsAntialias = true;

                paint.StrokeWidth = 1;
                paint.Style       = SKPaintStyle.Stroke;

                if (Slices != null)
                {
                    DrawLayerSlice(Slices, canvas, paint);
                }

                if (ShowDepositMoves)
                {
                    DrawLayerPaths(Paths, canvas, paint);
                }

                if (ShowFillArea)
                {
                    //DrawFill(Paths, canvas);
                    DrawFillOverlaps(Paths, canvas);
                    //DrawFillOverlapsIntegrate(Paths, canvas);
                }

                if (ShowAllPathPoints)
                {
                    DrawLayerPoints(Paths, canvas, paint);
                }

                if (NumberMode == NumberModes.PathNumbers)
                {
                    DrawPathLabels(Paths, canvas, paint);
                }

                DrawLayerInfo(canvas, paint);
            }
        }
        private void DrawFill(ToolpathSet pathSetIn, SKCanvas baseCanvas)
        {
            SKColor fillColor = SkiaUtil.Color(255, 0, 255, 255);

            SKRect bounds = baseCanvas.LocalClipBounds;

            SKBitmap blitBitmap = new SKBitmap(PixelDimensions.x, PixelDimensions.y, SkiaUtil.ColorType(), SKAlphaType.Premul);
            IntPtr   len;

            using (var skSurface = SKSurface.Create(blitBitmap.Info.Width, blitBitmap.Info.Height, SkiaUtil.ColorType(), SKAlphaType.Premul, blitBitmap.GetPixels(out len), blitBitmap.Info.RowBytes)) {
                var canvas = skSurface.Canvas;

                canvas.Clear(SkiaUtil.Color(255, 255, 255, 255));

                using (var paint = new SKPaint()) {
                    paint.IsAntialias = true;
                    paint.StrokeWidth = dimensionScale * PathDiameterMM;
                    paint.Style       = SKPaintStyle.Stroke;
                    paint.StrokeCap   = SKStrokeCap.Round;
                    paint.StrokeJoin  = SKStrokeJoin.Round;
                    paint.Color       = fillColor;

                    Action <LinearToolpath3 <PrintVertex> > drawPath3F = (polyPath) => {
                        if (polyPath.Type != ToolpathTypes.Deposition)
                        {
                            return;
                        }
                        Vector3d v0          = polyPath.Start.Position;
                        byte     layer_alpha = LayerFilterF(v0);
                        if (layer_alpha != 255)
                        {
                            return;
                        }
                        SKPath path = MakePath(polyPath, SceneToSkiaF);
                        canvas.DrawPath(path, paint);
                    };

                    ProcessLinearPaths(pathSetIn, drawPath3F);
                }
            }


            SKPaint blitPaint = new SKPaint();

            blitPaint.IsAntialias = false;
            blitPaint.BlendMode   = SKBlendMode.SrcOver;
            blitPaint.Color       = SkiaUtil.Color(0, 0, 0, 64);

            baseCanvas.DrawBitmap(blitBitmap, 0, 0, blitPaint);

            blitPaint.Dispose();
            blitBitmap.Dispose();
        }
        /// <summary>
        /// Point of this function is to be same as DrawFill (ie draw 'tubes') but to draw
        /// in such a way that overlap regions are highlighted. However it does not work yet,
        /// need to draw continuous SKPaths as much as possible but break at direction changes.
        /// </summary>
        private void DrawFillOverlapsIntegrate(ToolpathSet pathSetIn, SKCanvas baseCanvas)
        {
            SKColor fillColor = SkiaUtil.Color(255, 0, 255, 5);
            float   path_diam = dimensionScale * PathDiameterMM;
            float   spot_r    = path_diam * 0.5f;
            float   spacing   = 1.0f / dimensionScale;

            using (var paint = new SKPaint()) {
                paint.IsAntialias = true;
                paint.StrokeWidth = 1.0f;
                paint.Style       = SKPaintStyle.Fill;
                paint.Color       = fillColor;

                Action <LinearToolpath3 <PrintVertex> > drawPath3F = (polyPath) => {
                    if (polyPath.Type != ToolpathTypes.Deposition)
                    {
                        return;
                    }
                    Vector3d v0          = polyPath.Start.Position;
                    byte     layer_alpha = LayerFilterF(v0);
                    if (layer_alpha != 255)
                    {
                        return;
                    }

                    // draw each segment separately. results in lots of duplicate-circles, no good
                    for (int i = 1; i < polyPath.VertexCount; i++)
                    {
                        Vector2d a    = polyPath[i - 1].Position.xy;
                        Vector2d b    = polyPath[i].Position.xy;
                        double   len  = a.Distance(b);
                        int      n    = (int)(len / spacing) + 1;
                        int      stop = (i == polyPath.VertexCount - 1) ? n : n - 1;
                        for (int k = 0; k <= stop; ++k)
                        {
                            double   t  = (double)k / (double)n;
                            Vector2d p  = Vector2d.Lerp(a, b, t);
                            SKPoint  pk = SceneToSkiaF(p);
                            baseCanvas.DrawCircle(pk.X, pk.Y, spot_r, paint);
                        }
                    }
                };

                ProcessLinearPaths(pathSetIn, drawPath3F);
            }
        }
        /// <summary>
        /// Point of this function is to be same as DrawFill (ie draw 'tubes') but to draw
        /// in such a way that overlap regions are highlighted. However it does not work yet,
        /// need to draw continuous SKPaths as much as possible but break at direction changes.
        /// </summary>
        private void DrawFillOverlaps(ToolpathSet pathSetIn, SKCanvas baseCanvas)
        {
            SKColor fillColor = SkiaUtil.Color(255, 0, 255, 64);

            using (var paint = new SKPaint()) {
                paint.IsAntialias = true;
                paint.StrokeWidth = dimensionScale * PathDiameterMM;
                paint.Style       = SKPaintStyle.Stroke;
                paint.StrokeCap   = SKStrokeCap.Round;
                paint.StrokeJoin  = SKStrokeJoin.Round;
                paint.Color       = fillColor;

                Action <LinearToolpath3 <PrintVertex> > drawPath3F = (polyPath) => {
                    if (polyPath.Type != ToolpathTypes.Deposition)
                    {
                        return;
                    }
                    Vector3d v0          = polyPath.Start.Position;
                    byte     layer_alpha = LayerFilterF(v0);
                    if (layer_alpha != 255)
                    {
                        return;
                    }

                    // draw each segment separately. results in lots of duplicate-circles, no good
                    //for (int i = 1; i < polyPath.VertexCount; i++) {
                    //    SKPoint a = SceneToSkiaF(polyPath[i - 1].Position.xy);
                    //    SKPoint b = SceneToSkiaF(polyPath[i].Position.xy);
                    //    baseCanvas.DrawLine(a.X, a.Y, b.X, b.Y, paint);
                    //}

                    // draw full path in one shot. Only shows overlaps between separate paths.
                    //SKPath path = MakePath(polyPath, SceneToSkiaF);
                    //baseCanvas.DrawPath(path, paint);

                    // draw w/ angle threshold
                    List <SKPath> paths = MakePathSegments(polyPath, SceneToSkiaF, 45);
                    foreach (var path in paths)
                    {
                        baseCanvas.DrawPath(path, paint);
                    }
                };

                ProcessLinearPaths(pathSetIn, drawPath3F);
            }
        }
        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);
            }
        }
        private void DrawLayerPoints(ToolpathSet pathSetIn, SKCanvas canvas, SKPaint paint)
        {
            SKColor pointColor = SkiaUtil.Color(0, 0, 0, 255);
            float   pointR     = 1.5f;

            Action <LinearToolpath3 <PrintVertex> > drawPathPoints = (polyPath) => {
                if (LayerFilterF(polyPath.Start.Position) < 255)
                {
                    return;
                }
                paint.Color       = SkiaUtil.Color(pointColor, 255);
                paint.StrokeWidth = 1;
                for (int vi = 0; vi < polyPath.VertexCount; vi++)
                {
                    Vector2f pt = (Vector2f)SceneXFormF(polyPath[vi].Position.xy);
                    paint.Style = SKPaintStyle.Fill;
                    canvas.DrawCircle(pt.x, pt.y, pointR, paint);
                }
            };

            ProcessLinearPaths(pathSetIn, drawPathPoints);
        }
        void DrawGraph(SKCanvas canvas, SKPaint paint, DGraph2 graph, Func <Vector2d, SKPoint> mapF)
        {
            Colorf color = Colorf.Red;

            if (Colors.ContainsKey(graph))
            {
                color = Colors[graph];
            }
            paint.Color = SkiaUtil.Color(color);

            SKPath path = SkiaUtil.ToSKPath(graph, mapF);

            paint.StrokeWidth = 2;
            canvas.DrawPath(path, paint);

            paint.StrokeWidth = 1;
            //paint.Color = SKColors.Black;
            foreach (Vector2d v in graph.Vertices())
            {
                SKPoint c = mapF(v);
                canvas.DrawCircle(c.X, c.Y, 3.0f, paint);
            }
        }
        void DrawPolygon(SKCanvas canvas, SKPaint paint, GeneralPolygon2d poly, Func <Vector2d, SKPoint> mapF)
        {
            Colorf color = Colorf.Red;

            if (Colors.ContainsKey(poly))
            {
                color = Colors[poly];
            }
            paint.Color = SkiaUtil.Color(color);

            SKPath path = SkiaUtil.ToSKPath(poly, mapF);

            paint.StrokeWidth = 2;
            canvas.DrawPath(path, paint);

            //paint.Color = SKColors.Orange;
            paint.StrokeWidth = 1;
            foreach (Vector2d v in poly.AllVerticesItr())
            {
                SKPoint c = mapF(v);
                canvas.DrawCircle(c.X, c.Y, 3.0f, paint);
            }
        }
        private void DrawLayerPaths(ToolpathSet pathSetIn, SKCanvas canvas, SKPaint paint)
        {
            SKColor extrudeColor = SkiaUtil.Color(0, 0, 0, 255);
            SKColor travelColor  = SkiaUtil.Color(0, 255, 0, 128);
            SKColor supportColor = SkiaUtil.Color(0, 200, 200, 255);
            SKColor bridgeColor  = SkiaUtil.Color(200, 100, 0, 255);
            SKColor startColor   = SkiaUtil.Color(255, 0, 0, 128);
            SKColor planeColor   = SkiaUtil.Color(0, 0, 255, 128);
            float   pointR       = 3f;

            Action <LinearToolpath3 <PrintVertex> > drawPath3F = (polyPath) => {
                Vector3d v0          = polyPath.Start.Position;
                byte     layer_alpha = LayerFilterF(v0);
                if (layer_alpha == 0)
                {
                    return;
                }
                bool is_below = (layer_alpha < 255);

                SKPath path = MakePath(polyPath, SceneToSkiaF);
                if (polyPath.Type == ToolpathTypes.Deposition)
                {
                    if ((polyPath.TypeModifiers & FillTypeFlags.SupportMaterial) != 0)
                    {
                        paint.Color = supportColor;
                    }
                    else if ((polyPath.TypeModifiers & FillTypeFlags.BridgeSupport) != 0)
                    {
                        paint.Color = bridgeColor;
                    }
                    else
                    {
                        paint.Color = extrudeColor;
                    }
                    paint.StrokeWidth = 1.5f;
                }
                else if (polyPath.Type == ToolpathTypes.Travel)
                {
                    if (is_below)
                    {
                        return;
                    }
                    if (ShowTravels == false)
                    {
                        return;
                    }
                    paint.Color       = travelColor;
                    paint.StrokeWidth = 3;
                }
                else if (polyPath.Type == ToolpathTypes.PlaneChange)
                {
                    if (is_below)
                    {
                        return;
                    }
                    if (ShowTravels == false)
                    {
                        return;
                    }
                    paint.StrokeWidth = 0.5f;
                    paint.Color       = planeColor;
                }
                else
                {
                    if (is_below)
                    {
                        return;
                    }
                    paint.Color = startColor;
                }
                paint.Color = SkiaUtil.Color(paint.Color, layer_alpha);

                if (is_below)
                {
                    paint.StrokeWidth = 6;
                }
                canvas.DrawPath(path, paint);

                paint.StrokeWidth = 1;

                if (is_below == false && ShowPathStartPoints)
                {
                    Vector2f pt = SceneXFormF(polyPath.Start.Position.xy);
                    if (polyPath.Type == ToolpathTypes.Deposition)
                    {
                        canvas.DrawCircle(pt.x, pt.y, pointR, paint);
                    }
                    else if (polyPath.Type == ToolpathTypes.Travel)
                    {
                        canvas.DrawCircle(pt.x, pt.y, pointR, paint);
                    }
                    else if (polyPath.Type == ToolpathTypes.PlaneChange)
                    {
                        paint.Style = SKPaintStyle.Fill;
                        canvas.DrawCircle(pt.x, pt.y, 4f, paint);
                        paint.Style = SKPaintStyle.Stroke;
                    }
                }
            };

            ProcessLinearPaths(pathSetIn, drawPath3F);
        }