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);
                }
            }
        }
示例#2
0
        public PathShape ToFillPathShape(IToolContext context, IBaseShape shape)
        {
            using (var geometry = ToPath(context, shape))
            {
                if (geometry != null)
                {
                    var style = context.DocumentContainer?.StyleLibrary?.Get(shape.StyleId);
                    if (style == null)
                    {
                        style = context.DocumentContainer?.StyleLibrary?.CurrentItem;
                    }

                    using (var disposable = new CompositeDisposable())
                    {
                        var path = SkiaUtil.ToFillPath(context, style.FillPaint, shape.Effects, geometry, disposable.Disposables);
                        if (path != null)
                        {
                            disposable.Disposables.Add(path);
                            var union = SkiaUtil.Op(SKPathOp.Union, new[] { path, path });
                            if (union != null && !union.IsEmpty)
                            {
                                disposable.Disposables.Add(union);
                                return(SkiaUtil.ToPathShape(context, union, context.DocumentContainer?.StyleLibrary?.CurrentItem, context?.DocumentContainer?.PointTemplate));
                            }
                        }
                    }
                }
            }
            return(null);
        }
示例#3
0
        public void Import(IToolContext context, string path, IContainerView containerView)
        {
            try
            {
                var picture = SkiaUtil.ToSKPicture(path);
                if (picture != null)
                {
                    var image = new ImageShape()
                    {
                        Points      = new ObservableCollection <IPointShape>(),
                        StartPoint  = new PointShape(0.0, 0.0, context?.DocumentContainer?.PointTemplate),
                        Point       = new PointShape(picture.CullRect.Width, picture.CullRect.Height, context?.DocumentContainer?.PointTemplate),
                        Path        = path,
                        StretchMode = StretchMode.Center,
                        Text        = new Text(),
                        StyleId     = context.DocumentContainer?.StyleLibrary?.CurrentItem?.Title,
                    };

                    image.StartPoint.Owner = image;
                    image.Point.Owner      = image;

                    picture.Dispose();

                    context.DocumentContainer?.ContainerView?.CurrentContainer.Shapes.Add(image);
                    context.DocumentContainer?.ContainerView?.InputService?.Redraw?.Invoke();
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                System.Diagnostics.Debug.WriteLine(ex.StackTrace);
            }
        }
示例#4
0
        public void DrawSymbol(SvgSymbol svgSymbol, bool ignoreDisplay)
        {
            if (!CanDraw(svgSymbol, ignoreDisplay))
            {
                return;
            }

            _skCanvas.Save();

            float x      = 0f;
            float y      = 0f;
            float width  = svgSymbol.ViewBox.Width;
            float height = svgSymbol.ViewBox.Height;

            if (svgSymbol.CustomAttributes.TryGetValue("width", out string?_widthString))
            {
                if (new SvgUnitConverter().ConvertFrom(_widthString) is SvgUnit _width)
                {
                    width = _width.ToDeviceValue(null, UnitRenderingType.Horizontal, svgSymbol);
                }
            }

            if (svgSymbol.CustomAttributes.TryGetValue("height", out string?heightString))
            {
                if (new SvgUnitConverter().ConvertFrom(heightString) is SvgUnit _height)
                {
                    height = _height.ToDeviceValue(null, UnitRenderingType.Vertical, svgSymbol);
                }
            }

            var skRectBounds = SKRect.Create(x, y, width, height);

            var skMatrixViewBox = SkiaUtil.GetSvgViewBoxTransform(svgSymbol.ViewBox, svgSymbol.AspectRatio, x, y, width, height);
            var skMatrix        = SkiaUtil.GetSKMatrix(svgSymbol.Transforms);

            SKMatrix.PreConcat(ref skMatrix, ref skMatrixViewBox);
            SetTransform(skMatrix);
            SetClipPath(svgSymbol, _disposable);

            var skPaintOpacity = SetOpacity(svgSymbol, _disposable);

            var skPaintFilter = SetFilter(svgSymbol, _disposable);

            foreach (var svgElement in svgSymbol.Children)
            {
                Draw(svgElement, ignoreDisplay);
            }

            if (skPaintFilter != null)
            {
                _skCanvas.Restore();
            }

            if (skPaintOpacity != null)
            {
                _skCanvas.Restore();
            }

            _skCanvas.Restore();
        }
示例#5
0
        private IList <SKPath> ToPaths(IToolContext context, IList <IBaseShape> shapes)
        {
            if (shapes == null || shapes.Count <= 0)
            {
                return(null);
            }

            var paths = new List <SKPath>();

            for (int i = 0; i < shapes.Count; i++)
            {
                var fillType = SKPathFillType.Winding;
                if (shapes[i] is PathShape pathShape)
                {
                    fillType = SkiaUtil.ToSKPathFillType(pathShape.FillType);
                }
                var path = new SKPath()
                {
                    FillType = fillType
                };
                var result = SkiaUtil.AddShape(context, shapes[i], 0.0, 0.0, path);
                if (result == true && path.IsEmpty == false)
                {
                    paths.Add(path);
                }
                else
                {
                    path.Dispose();
                }
            }

            return(paths);
        }
示例#6
0
        public void DrawForeignObject(SvgForeignObject svgForeignObject, bool ignoreDisplay)
        {
            if (!CanDraw(svgForeignObject, ignoreDisplay))
            {
                return;
            }

            _skCanvas.Save();

            var skMatrix = SkiaUtil.GetSKMatrix(svgForeignObject.Transforms);

            SetTransform(skMatrix);
            SetClipPath(svgForeignObject, _disposable);

            var skPaintOpacity = SetOpacity(svgForeignObject, _disposable);

            var skPaintFilter = SetFilter(svgForeignObject, _disposable);

            // TODO:

            if (skPaintFilter != null)
            {
                _skCanvas.Restore();
            }

            if (skPaintOpacity != null)
            {
                _skCanvas.Restore();
            }

            _skCanvas.Restore();
        }
示例#7
0
        private SKPath ToPath(IToolContext context, IBaseShape shape)
        {
            var fillType = SKPathFillType.Winding;

            if (shape is PathShape pathShape)
            {
                fillType = SkiaUtil.ToSKPathFillType(pathShape.FillType);
            }

            var geometry = new SKPath()
            {
                FillType = fillType
            };

            if (SkiaUtil.AddShape(context, shape, 0.0, 0.0, geometry) == true)
            {
                return(geometry);
            }
            else
            {
                geometry.Dispose();
            }

            return(null);
        }
示例#8
0
        public PathShape Op(IToolContext context, PathOp op, ICollection <IBaseShape> selected)
        {
            var path   = default(PathShape);
            var shapes = GetShapes(selected);

            if (shapes != null && shapes.Count > 0)
            {
                var paths = ToPaths(context, shapes);
                if (paths != null && paths.Count > 0)
                {
                    var result = SkiaUtil.Op(SkiaUtil.ToSKPathOp(op), paths);
                    if (result != null)
                    {
                        if (!result.IsEmpty)
                        {
                            var style = context.DocumentContainer?.StyleLibrary?.Get(shapes[0].StyleId);
                            if (style == null)
                            {
                                style = context.DocumentContainer?.StyleLibrary?.CurrentItem;
                            }
                            path = SkiaUtil.ToPathShape(context, result, style, context?.DocumentContainer?.PointTemplate);
                        }
                        result.Dispose();
                    }

                    for (int i = 0; i < paths.Count; i++)
                    {
                        paths[i].Dispose();
                    }
                }
            }
            return(path);
        }
        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);
        }
示例#10
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);
            }
        }
示例#11
0
 public PathShape ToPathShape(IToolContext context, string svgPathData)
 {
     if (!string.IsNullOrWhiteSpace(svgPathData))
     {
         using var path = SkiaUtil.ToPath(svgPathData);
         return(SkiaUtil.ToPathShape(context, path, context.DocumentContainer?.StyleLibrary?.CurrentItem, context?.DocumentContainer?.PointTemplate));
     }
     return(null);
 }
示例#12
0
        public void DrawText(object dc, TextShape text, string styleId, double dx, double dy, double scale)
        {
            var geometry = new SKPath()
            {
                FillType = SKPathFillType.Winding
            };

            SkiaUtil.AddText(null, text, dx, dy, geometry);
            _rootNodes[_currentRootNode].Children.Add(new ChildNode(text, styleId, dx, dy, scale, geometry));
        }
示例#13
0
        internal void SetClipPath(SvgVisualElement svgVisualElement, CompositeDisposable disposable)
        {
            var skPathClip = SkiaUtil.GetSvgVisualElementClipPath(svgVisualElement, disposable);

            if (skPathClip != null && !skPathClip.IsEmpty)
            {
                bool antialias = SkiaUtil.IsAntialias(svgVisualElement);
                _skCanvas.ClipPath(skPathClip, SKClipOperation.Intersect, antialias);
            }
        }
        public void Draw(object context, double width, double height, double dx, double dy, double zx, double zy, double renderScaling)
        {
            using var renderer   = new SkiaShapeRenderer(_context, _view, _view.SelectionState);
            using var disposable = new CompositeDisposable();
            using var background = SkiaUtil.ToSKPaint(_view.PrintBackground, null, zx, disposable.Disposables);
            var canvas = context as SKCanvas;

            canvas.DrawRect(SkiaUtil.ToSKRect(dx, dy, _view.Width + dx, _view.Height + dy), background);
            _view.CurrentContainer.Draw(canvas, renderer, dx, dy, zx, null, null);
        }
示例#15
0
        public void DrawArc(object dc, ArcShape arc, string styleId, double dx, double dy, double scale)
        {
            var geometry = new SKPath()
            {
                FillType = SKPathFillType.Winding
            };

            SkiaUtil.AddArc(null, arc, dx, dy, geometry);
            _rootNodes[_currentRootNode].Children.Add(new ChildNode(arc, styleId, dx, dy, scale, geometry));
        }
示例#16
0
        public void DrawCircle(object dc, CircleShape circle, string styleId, double dx, double dy, double scale)
        {
            var geometry = new SKPath()
            {
                FillType = SKPathFillType.Winding
            };

            SkiaUtil.AddCircle(null, circle, dx, dy, geometry);
            _rootNodes[_currentRootNode].Children.Add(new ChildNode(circle, styleId, dx, dy, scale, geometry));
        }
示例#17
0
        public void DrawPath(object dc, PathShape path, string styleId, double dx, double dy, double scale)
        {
            var geometry = new SKPath()
            {
                FillType = SkiaUtil.ToSKPathFillType(path.FillType)
            };

            SkiaUtil.AddPath(null, path, dx, dy, geometry);
            _rootNodes[_currentRootNode].Children.Add(new ChildNode(path, styleId, dx, dy, scale, geometry));
        }
示例#18
0
        public void DrawQuadraticBezier(object dc, QuadraticBezierShape quadraticBezier, string styleId, double dx, double dy, double scale)
        {
            var geometry = new SKPath()
            {
                FillType = SKPathFillType.Winding
            };

            SkiaUtil.AddQuad(null, quadraticBezier, dx, dy, geometry);
            _rootNodes[_currentRootNode].Children.Add(new ChildNode(quadraticBezier, styleId, dx, dy, scale, geometry));
        }
示例#19
0
        public void DrawOval(object dc, OvalShape oval, string styleId, double dx, double dy, double scale)
        {
            var geometry = new SKPath()
            {
                FillType = SKPathFillType.Winding
            };

            SkiaUtil.AddOval(null, oval, dx, dy, geometry);
            _rootNodes[_currentRootNode].Children.Add(new ChildNode(oval, styleId, dx, dy, scale, geometry));
        }
示例#20
0
        internal void DrawMarkers(SvgMarkerElement svgMarkerElement, SKPath sKPath)
        {
            var pathTypes  = SkiaUtil.GetPathTypes(sKPath);
            var pathLength = pathTypes.Count;

            if (svgMarkerElement.MarkerStart != null)
            {
                var refPoint1 = pathTypes[0].Point;
                var index     = 1;
                while (index < pathLength && pathTypes[index].Point == refPoint1)
                {
                    ++index;
                }
                var refPoint2 = pathTypes[index].Point;
                var marker    = svgMarkerElement.OwnerDocument.GetElementById <SvgMarker>(svgMarkerElement.MarkerStart.ToString());
                DrawMarker(marker, svgMarkerElement, refPoint1, refPoint1, refPoint2, true);
            }

            if (svgMarkerElement.MarkerMid != null)
            {
                var marker      = svgMarkerElement.OwnerDocument.GetElementById <SvgMarker>(svgMarkerElement.MarkerMid.ToString());
                int bezierIndex = -1;
                for (int i = 1; i <= pathLength - 2; i++)
                {
                    // for Bezier curves, the marker shall only been shown at the last point
                    if ((pathTypes[i].Type & (byte)PathPointType.PathTypeMask) == (byte)PathPointType.Bezier)
                    {
                        bezierIndex = (bezierIndex + 1) % 3;
                    }
                    else
                    {
                        bezierIndex = -1;
                    }

                    if (bezierIndex == -1 || bezierIndex == 2)
                    {
                        DrawMarker(marker, svgMarkerElement, pathTypes[i].Point, pathTypes[i - 1].Point, pathTypes[i].Point, pathTypes[i + 1].Point);
                    }
                }
            }

            if (svgMarkerElement.MarkerEnd != null)
            {
                var marker    = svgMarkerElement.OwnerDocument.GetElementById <SvgMarker>(svgMarkerElement.MarkerEnd.ToString());
                var index     = pathLength - 1;
                var refPoint1 = pathTypes[index].Point;
                --index;
                while (index > 0 && pathTypes[index].Point == refPoint1)
                {
                    --index;
                }
                var refPoint2 = pathTypes[index].Point;
                DrawMarker(marker, svgMarkerElement, refPoint1, refPoint2, pathTypes[pathLength - 1].Point, false);
            }
        }
示例#21
0
        public void DrawEllipse(SvgEllipse svgEllipse, bool ignoreDisplay)
        {
            if (!CanDraw(svgEllipse, ignoreDisplay))
            {
                return;
            }

            float cx = svgEllipse.CenterX.ToDeviceValue(null, UnitRenderingType.Horizontal, svgEllipse);
            float cy = svgEllipse.CenterY.ToDeviceValue(null, UnitRenderingType.Vertical, svgEllipse);
            float rx = svgEllipse.RadiusX.ToDeviceValue(null, UnitRenderingType.Other, svgEllipse);
            float ry = svgEllipse.RadiusY.ToDeviceValue(null, UnitRenderingType.Other, svgEllipse);

            if (rx <= 0f || ry <= 0f)
            {
                return;
            }

            var skRectBounds = SKRect.Create(cx - rx, cy - ry, rx + rx, ry + ry);

            _skCanvas.Save();

            var skMatrix = SkiaUtil.GetSKMatrix(svgEllipse.Transforms);

            SetTransform(skMatrix);
            SetClipPath(svgEllipse, _disposable);

            var skPaintOpacity = SetOpacity(svgEllipse, _disposable);

            var skPaintFilter = SetFilter(svgEllipse, _disposable);

            if (SkiaUtil.IsValidFill(svgEllipse))
            {
                var skPaintFill = SkiaUtil.GetFillSKPaint(svgEllipse, _skSize, skRectBounds, _disposable);
                _skCanvas.DrawOval(cx, cy, rx, ry, skPaintFill);
            }

            if (SkiaUtil.IsValidStroke(svgEllipse))
            {
                var skPaintStroke = SkiaUtil.GetStrokeSKPaint(svgEllipse, _skSize, skRectBounds, _disposable);
                _skCanvas.DrawOval(cx, cy, rx, ry, skPaintStroke);
            }

            if (skPaintFilter != null)
            {
                _skCanvas.Restore();
            }

            if (skPaintOpacity != null)
            {
                _skCanvas.Restore();
            }

            _skCanvas.Restore();
        }
        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();
        }
示例#23
0
 internal SKPaint?SetFilter(SvgVisualElement svgVisualElement, CompositeDisposable disposable)
 {
     if (svgVisualElement.Filter != null)
     {
         var skPaint = new SKPaint();
         skPaint.Style = SKPaintStyle.StrokeAndFill;
         SkiaUtil.SetFilter(svgVisualElement, skPaint, disposable);
         _skCanvas.SaveLayer(skPaint);
         disposable.Add(skPaint);
         return(skPaint);
     }
     return(null);
 }
示例#24
0
        internal SKPicture Load(SvgFragment svgFragment)
        {
            var skSize   = SkiaUtil.GetDimensions(svgFragment);
            var cullRect = SKRect.Create(skSize);

            using (var skPictureRecorder = new SKPictureRecorder())
                using (var skCanvas = skPictureRecorder.BeginRecording(cullRect))
                    using (var renderer = new SKSvgRenderer(skCanvas, skSize))
                    {
                        renderer.DrawFragment(svgFragment, false);
                        return(skPictureRecorder.EndRecording());
                    }
        }
示例#25
0
        public void DrawPolygon(SvgPolygon svgPolygon, bool ignoreDisplay)
        {
            if (!CanDraw(svgPolygon, ignoreDisplay))
            {
                return;
            }

            _skCanvas.Save();

            var skMatrix = SkiaUtil.GetSKMatrix(svgPolygon.Transforms);

            SetTransform(skMatrix);
            SetClipPath(svgPolygon, _disposable);

            var skPaintOpacity = SetOpacity(svgPolygon, _disposable);

            var skPaintFilter = SetFilter(svgPolygon, _disposable);

            var skPath = SkiaUtil.ToSKPath(svgPolygon.Points, svgPolygon.FillRule, true, _disposable);

            if (skPath != null && !skPath.IsEmpty)
            {
                var skBounds = skPath.Bounds;

                if (SkiaUtil.IsValidFill(svgPolygon))
                {
                    var skPaint = SkiaUtil.GetFillSKPaint(svgPolygon, _skSize, skBounds, _disposable);
                    _skCanvas.DrawPath(skPath, skPaint);
                }

                if (SkiaUtil.IsValidStroke(svgPolygon))
                {
                    var skPaint = SkiaUtil.GetStrokeSKPaint(svgPolygon, _skSize, skBounds, _disposable);
                    _skCanvas.DrawPath(skPath, skPaint);
                }

                DrawMarkers(svgPolygon, skPath);
            }

            if (skPaintFilter != null)
            {
                _skCanvas.Restore();
            }

            if (skPaintOpacity != null)
            {
                _skCanvas.Restore();
            }

            _skCanvas.Restore();
        }
示例#26
0
        public string ToSvgPathData(IToolContext context, ICollection <IBaseShape> selected)
        {
            var sb     = new StringBuilder();
            var shapes = GetShapes(selected);

            if (shapes != null && shapes.Count > 0)
            {
                foreach (var shape in shapes)
                {
                    SkiaUtil.ToSvgPathData(context, shape, sb);
                }
            }
            return(sb.ToString());
        }
示例#27
0
        private void GetSKPaintFill(IPaint fillPaint, IPaintEffects effects, double scale, out SKPaint brush)
        {
            if (fillPaint.IsTreeDirty() || !_paintCache.TryGetValue(fillPaint, out var brushCached))
            {
                fillPaint.Invalidate();
                brushCached            = SkiaUtil.ToSKPaint(fillPaint, effects, scale, _disposable.Disposables);
                _paintCache[fillPaint] = brushCached;
            }
            else
            {
                SkiaUtil.ToSKPaintUpdate(brushCached, fillPaint, effects, scale, _disposable.Disposables);
            }

            brush = brushCached;
        }
示例#28
0
 public PathShape ToPathShape(IToolContext context, IBaseShape shape)
 {
     using (var geometry = ToPath(context, shape))
     {
         if (geometry != null)
         {
             var style = context.DocumentContainer?.StyleLibrary?.Get(shape.StyleId);
             if (style == null)
             {
                 style = context.DocumentContainer?.StyleLibrary?.CurrentItem;
             }
             return(SkiaUtil.ToPathShape(context, geometry, style, context?.DocumentContainer?.PointTemplate));
         }
     }
     return(null);
 }
        /// <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);
            }
        }