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); }
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); }