Skip to content

Commit

Permalink
Version 1.7.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
svenhb authored Feb 4, 2024
1 parent 64b41eb commit 8478778
Show file tree
Hide file tree
Showing 4 changed files with 593 additions and 50 deletions.
66 changes: 35 additions & 31 deletions GRBL-Plotter/GCodeCreation/GraphicClasses.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* GRBL-Plotter. Another GCode sender for GRBL.
This file is part of the GRBL-Plotter application.
Copyright (C) 2019-2023 Sven Hasemann contact: [email protected]
Copyright (C) 2019-2024 Sven Hasemann contact: [email protected]
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -29,12 +29,14 @@ You should have received a copy of the GNU General Public License
* 2023-05-31 add OptionSFromWidth
* 2023-08-16 l:388 f:IsSameAs pull request Speed up merge and sort #348
* 2023-08-31 l:686 f:AddArc limit stepwidth - issue #353
* 2024-02-04 l:720 f:AddArc add noise to line
*/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows;
using static System.Net.Mime.MediaTypeNames;

Expand Down Expand Up @@ -94,6 +96,7 @@ internal class GraphicInformationClass
public bool OptionDragTool { get; set; } // Path modifications
public bool OptionTangentialAxis { get; set; }
public bool OptionHatchFill { get; set; }
public bool OptionNoise { get; set; }
public bool OptionExtendPath { get; set; }

public bool OptionClipCode { get; set; } // Clipping
Expand Down Expand Up @@ -136,6 +139,7 @@ public GraphicInformationClass()
OptionZFromRadius = Properties.Settings.Default.importSVGCircleToDotZ;
OptionRepeatCode = Properties.Settings.Default.importRepeatEnable;
OptionHatchFill = Properties.Settings.Default.importGraphicHatchFillEnable;
OptionNoise = Properties.Settings.Default.importGraphicNoiseEnable;
OptionClipCode = Properties.Settings.Default.importGraphicClipEnable;
OptionNodesOnly = Properties.Settings.Default.importSVGNodesOnly;
OptionTangentialAxis = Properties.Settings.Default.importGCTangentialEnable;
Expand All @@ -149,7 +153,7 @@ public GraphicInformationClass()
OptionCodeSortDimension = Properties.Settings.Default.importGraphicSortDimension;
OptionFeedFromToolTable = Properties.Settings.Default.importGCToolTableUse;

ConvertArcToLine = Properties.Settings.Default.importGCNoArcs || OptionClipCode || OptionDragTool || OptionHatchFill;// only for SVG: || ApplyHatchFill;
ConvertArcToLine = Properties.Settings.Default.importGCNoArcs || OptionClipCode || OptionDragTool || OptionHatchFill || OptionNoise;// only for SVG: || ApplyHatchFill;
ConvertArcToLine = ConvertArcToLine || OptionSpecialWireBend || OptionSpecialDevelop || OptionRampOnPenDown || OptionDashPattern;
}
public void ResetOptions(bool enableFigures)
Expand All @@ -167,6 +171,7 @@ public void ResetOptions(bool enableFigures)
OptionCodeOffset = false;
ApplyHatchFill = false;
OptionHatchFill = false;
OptionNoise = false;
OptionClipCode = false;
OptionNodesOnly = false;
OptionTangentialAxis = false;
Expand Down Expand Up @@ -215,6 +220,7 @@ public string ListOptions()
if (Properties.Settings.Default.importGraphicMultiplyGraphicsEnable) importOptions += "<Multiply> ";
if (OptionCodeSortDistance) importOptions += "<Sort objects> ";
if (ApplyHatchFill) importOptions += "<SVG fill> ";
if (OptionNoise) importOptions += "<Noise> ";
if (OptionHatchFill) importOptions += "<Hatch fill> ";
if (OptionRepeatCode && !Properties.Settings.Default.importRepeatComplete) importOptions += "<Repeat paths> ";
if (OptionRepeatCode && Properties.Settings.Default.importRepeatComplete) importOptions += "<Repeat code> ";
Expand Down Expand Up @@ -671,29 +677,28 @@ public void AddArc(Point tmp, Point centerIJ, bool isCW, double dz, double angSt
End = tmp;
}

public void AddArc(Point tmp, Point centerIJ, double dz, bool isCW, bool convertToLine)
public void AddArc(Point tmp, Point centerIJ, double dz, bool isCW, bool convertToLine, bool addNoise)
{
GCodeMotion motion;

ArcProperties arcMove;
Point p1 = Round(End);
Point p2 = Round(tmp);
arcMove = GcodeMath.GetArcMoveProperties(p1, p2, centerIJ, isCW);
PathLength += Math.Abs(arcMove.radius * arcMove.angleDiff); // distance from last to current point
Dimension.SetDimensionArc(new XyPoint(End), new XyPoint(tmp), centerIJ.X, centerIJ.Y, isCW);

if (!convertToLine)
{
motion = new GCodeArc(tmp, centerIJ, isCW, dz);
Dimension.SetDimensionArc(new XyPoint(End), new XyPoint(tmp), centerIJ.X, centerIJ.Y, isCW);
Path.Add(motion);

ArcProperties arcMove;
Point p1 = Round(End);
Point p2 = Round(tmp);
arcMove = GcodeMath.GetArcMoveProperties(p1, p2, centerIJ, isCW);
PathLength += Math.Abs(arcMove.radius * arcMove.angleDiff); // distance from last to current point
End = tmp;
}
else
{
ArcProperties arcMove;
Point p1 = Round(End);
Point p2 = Round(tmp);
double radius;
double noiseAmplitude = (double)Properties.Settings.Default.importGraphicNoiseAmplitude/2;

double x, y;
arcMove = GcodeMath.GetArcMoveProperties(p1, p2, centerIJ, isCW);
double stepwidth = (double)Properties.Settings.Default.importGCSegment;

if (Properties.Settings.Default.importRemoveShortMovesEnable) // 2023-08-31 issue #353
Expand All @@ -702,42 +707,41 @@ public void AddArc(Point tmp, Point centerIJ, double dz, bool isCW, bool convert
if (stepwidth > arcMove.radius / 2)
{ stepwidth = arcMove.radius / 5; }
double step = Math.Asin(stepwidth / arcMove.radius); // in RAD
// double step = Math.Asin((double)Properties.Settings.Default.importGCSegment / arcMove.radius); // in RAD
if (step > Math.Abs(arcMove.angleDiff))
step = Math.Abs(arcMove.angleDiff / 2);

if (arcMove.angleDiff > 0) //(da > 0) // if delta >0 go counter clock wise
if (arcMove.angleDiff > 0) // counter clock wise
{
for (double angle = (arcMove.angleStart + step); angle < (arcMove.angleStart + arcMove.angleDiff); angle += step)
{
x = arcMove.center.X + arcMove.radius * Math.Cos(angle);
y = arcMove.center.Y + arcMove.radius * Math.Sin(angle);
if (addNoise)
radius = arcMove.radius + (Noise.CalcPixel2D(Path.Count, (int)angle, 1)* noiseAmplitude);
else
radius = arcMove.radius;
x = arcMove.center.X + radius * Math.Cos(angle);
y = arcMove.center.Y + radius * Math.Sin(angle);
motion = new GCodeLine(new Point(x, y), dz);
Dimension.SetDimensionXY(x, y);
Path.Add(motion);
PathLength += PointDistance(End, tmp); // distance from last to current point
End = tmp;
}
}
else // else go clock wise
else // else go clock wise
{
for (double angle = (arcMove.angleStart - step); angle > (arcMove.angleStart + arcMove.angleDiff); angle -= step)
{
x = arcMove.center.X + arcMove.radius * Math.Cos(angle);
y = arcMove.center.Y + arcMove.radius * Math.Sin(angle);
if (addNoise)
radius = arcMove.radius + (Noise.CalcPixel2D(Path.Count, (int)angle, 1) * noiseAmplitude);
else
radius = arcMove.radius;
x = arcMove.center.X + radius * Math.Cos(angle);
y = arcMove.center.Y + radius * Math.Sin(angle);
motion = new GCodeLine(new Point(x, y), dz);
Dimension.SetDimensionXY(x, y);
Path.Add(motion);
PathLength += PointDistance(End, tmp); // distance from last to current point
End = tmp;
}
}
motion = new GCodeLine(new Point(tmp.X, tmp.Y), dz);
Dimension.SetDimensionXY(tmp.X, tmp.Y);
Path.Add(motion);
PathLength += PointDistance(End, tmp); // distance from last to current point
End = tmp;
}
End = tmp;
if (Start == End)
IsClosed = true;
}
Expand Down
97 changes: 86 additions & 11 deletions GRBL-Plotter/GCodeCreation/GraphicCollectData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ You should have received a copy of the GNU General Public License
* 2023-08-16 l:271 f:StartPath f:UpdateGUI pull request Speed up merge and sort #348
* 2023-09-16 l:774 f:CreateGCode wrong call to RemoveOffset(minx,minx) -> miny
* 2024-01-25 l:1100 f:CreateGCode export graphics dimension, to be able to calculate point-marker-size in 2Dview
* 2024-02-04 l:426 f:AddLine add noise to line
*/

using System;
Expand Down Expand Up @@ -92,6 +93,7 @@ public static partial class Graphic

internal static Dimensions actualDimension = new Dimensions();
private static Point lastPoint = new Point(); // System.Windows
private static bool lastPointIsStart = true;
private static PathObject lastPath = new ItemPath();
private static CreationOption lastOption = CreationOption.none;

Expand All @@ -113,6 +115,10 @@ public static partial class Graphic

private static int countWarnDimNotSet = 0;

// private static bool noiseAdd = false;
private static double noiseAmplitude = 1;
private static double noiseDensity = 1;

private static int pathAddOnCount = 0;
//private static int pathAddOnPosition = 0;
//private static double pathAddOnScale = 1;
Expand Down Expand Up @@ -242,6 +248,10 @@ public static void Init(SourceType type, string filePath, BackgroundWorker worke

pathBackground = new GraphicsPath();

//noiseAdd = Properties.Settings.Default.importGraphicNoiseEnable;
noiseAmplitude = (double)Properties.Settings.Default.importGraphicNoiseAmplitude;
noiseDensity = (double)Properties.Settings.Default.importGraphicNoiseDensity;

completeGraphic = new List<PathObject>();
finalPathList = new List<PathObject>();
tileGraphicAll = new List<PathObject>();
Expand All @@ -256,6 +266,7 @@ public static void Init(SourceType type, string filePath, BackgroundWorker worke
lastPoint = new Point();
lastPath = new ItemPath();
lastOption = CreationOption.none;
lastPointIsStart = true;

for (int i = 0; i < groupPropertiesCount.Length; i++)
groupPropertiesCount[i] = new Dictionary<string, int>();
Expand Down Expand Up @@ -321,10 +332,6 @@ public static bool StartPath(Point xy, double? useZ = null)//, CreationOptions a
if (setNewId)
objectCount++;

// double z = GetActualZ(); // apply penWidth if enabled
// if (useZ != null)
// z = (double)useZ;

if (useZ != null)
actualPath = new ItemPath(xy, (double)useZ);
else
Expand All @@ -350,8 +357,7 @@ public static bool StartPath(Point xy, double? useZ = null)//, CreationOptions a
lastPoint = xy;
setNewId = false;
lastOption = CreationOption.none;

// actualPathInfo.SetGroupAttribute((int)GroupOption.ByFill, ""); // reset fill
lastPointIsStart = true;

return success;
}
Expand All @@ -372,6 +378,9 @@ public static void StopPath(string cmt)
{
if (actualPath.Dimension.IsXYSet())
{
if (graphicInformation.OptionNoise)
actualPath.Add(lastPoint, GetActualZ(), 0);

completeGraphic.Add(actualPath);
if (logCoordinates) { Logger.Trace("▲ StopPath completeGraphic.Add {0}", completeGraphic.Count); }
}
Expand All @@ -392,7 +401,7 @@ public static void StopPath(string cmt)
actualPath.Dimension.ResetDimension(); // 2020-10-31
}

public static bool AddLine(float x, float y)
public static bool AddLine(double x, double y)
{ return AddLine(new Point(x, y)); }
public static bool AddLine(Point xy, double? useZ = null)//, string cmt = "")
{
Expand All @@ -412,13 +421,79 @@ public static bool AddLine(Point xy, double? useZ = null)//, string cmt = "")
{ if (logCoordinates) Logger.Trace("⚠ AddLine SKIP, same coordinates! X:{0:0.00} Y:{1:0.00}", xy.X, xy.Y); }
else
{
actualPath.Add(xy, z, 0);
if (graphicInformation.OptionNoise)
{
AddNoiseToPath(xy, z, actualPath.Path.Count, noiseAmplitude, noiseDensity);
}
else
{
actualPath.Add(xy, z, 0);
}
if (logCoordinates) Logger.Trace("● AddLine to X:{0:0.00} Y:{1:0.00} Z:{2:0.00} new dist {3:0.00} start.X:{4:0.00} start.Y:{5:0.00}", xy.X, xy.Y, z, actualPath.PathLength, actualPath.Start.X, actualPath.Start.Y);
actualDimension.SetDimensionXY(xy.X, xy.Y);
lastPoint = xy;
}
lastPointIsStart = false;
return success;
}
private static Point AddNoiseToPath(Point end, double z, int index, double amplitude, double density)
{
double x = lastPoint.X;
double y = lastPoint.Y;
double dx = end.X - lastPoint.X;
double dy = end.Y - lastPoint.Y;
double lineLength = Math.Sqrt(dx * dx + dy * dy);
double stepWidth = density;
int step = (int)Math.Ceiling(lineLength / stepWidth);

if (step == 0)
{
actualPath.Add(end, z, 0);
return end;
}
double dix = dx / step;
double diy = dy / step;

double fx, fy;
if (dx == 0)
{ fx = 1; fy = 0; }
else if (dy == 0)
{ fx = 0; fy = 1; }
else
{
fx = dy / lineLength; fy = dx / lineLength;
}
fx *= (amplitude / 2); ;
fy *= (-amplitude / 2); ;

float scale, n, nx = 0, ny = 0;
scale = 1;// (float)stepWidth / 2000;

Logger.Trace("AddNoiseToPath step:{0}",step);

if (step <= 1)
{
n = Noise.CalcPixel2D(index, 1, scale);
nx = (float)fx * n;
ny = (float)fy * n;
actualPath.Add(new Point(x + nx, y + ny), z, 0);
//actualPath.Add(end, z, 0);
}
else
{
for (int i = 1; i < step; i++)
{
n = Noise.CalcPixel2D(index, i, scale);
nx = (float)fx * n;
ny = (float)fy * n;
x += dix;
y += diy;
actualPath.Add(new Point(x + nx, y + ny), z, 0);
}
actualPath.Add(end, z, 0);
}
return new Point(x + nx, y + ny);
}

public static bool AddDot(Point xy)//, string cmt = "")
{ return AddDot(xy.X, xy.Y); }//, cmt);
Expand Down Expand Up @@ -469,7 +544,7 @@ public static bool AddCircle(double centerX, double centerY, double radius)
{ Logger.Error("AddCircle NaN skip the circle X:{0:0.00} Y:{1:0.00} r:{2:0.00} ", centerX, centerY, radius); success = false; }
else
{
actualPath.AddArc(new Point(centerX + radius, centerY), new Point(-radius, 0), GetActualZ(), true, graphicInformation.ConvertArcToLine);// convertArcToLine);
actualPath.AddArc(new Point(centerX + radius, centerY), new Point(-radius, 0), GetActualZ(), true, graphicInformation.ConvertArcToLine, graphicInformation.OptionNoise);// convertArcToLine);
actualPath.Info.CopyData(actualPathInfo); // preset global info for GROUP
if (logCoordinates) Logger.Trace(" AddCircle to X:{0:0.00} Y:{1:0.00} r:{2:0.00} angleStep:{3}", centerX, centerY, radius, Properties.Settings.Default.importGCSegment);
}
Expand All @@ -488,7 +563,7 @@ public static bool AddArc(bool isg2, double ax, double ay, double ai, double aj)
else
{
lastPoint = new Point(ax, ay);
actualPath.AddArc(new Point(ax, ay), new Point(ai, aj), GetActualZ(), isg2, graphicInformation.ConvertArcToLine);
actualPath.AddArc(new Point(ax, ay), new Point(ai, aj), GetActualZ(), isg2, graphicInformation.ConvertArcToLine, graphicInformation.OptionNoise);
actualPath.Info.CopyData(actualPathInfo); // preset global info for GROUP
if (logCoordinates) Logger.Trace(" AddArc to X:{0:0.00} Y:{1:0.00} i:{2:0.00} j:{3:0.00} angleStep:{4} isG2:{5}", ax, ay, ai, aj, Properties.Settings.Default.importGCSegment, isg2);
}
Expand Down Expand Up @@ -975,7 +1050,7 @@ public static bool CreateGCode()//Final(BackgroundWorker backgroundWorker, DoWor
if (!cancelByWorker && (graphicInformation.ApplyHatchFill || graphicInformation.OptionHatchFill))
{
backgroundWorker?.ReportProgress(0, new MyUserState { Value = (actOpt++ * 100 / maxOpt), Content = "Generate hatch fill..." });
Logger.Info("{0} Hatch fill", loggerTag);
Logger.Info("{0} Hatch fill distance:{1:0.00} angle:{2:0.00}", loggerTag, Properties.Settings.Default.importGraphicHatchFillDistance, Properties.Settings.Default.importGraphicHatchFillAngle);
HatchFill(completeGraphic);
SetHeaderInfo(string.Format(" Option: Hatch fill distance:{0:0.00} angle:{1:0.00}", Properties.Settings.Default.importGraphicHatchFillDistance, Properties.Settings.Default.importGraphicHatchFillAngle));
}
Expand Down
Loading

0 comments on commit 8478778

Please sign in to comment.