diff --git a/GRBL-Plotter/MachineControl/GCode2DViewpaths.cs b/GRBL-Plotter/MachineControl/GCode2DViewpaths.cs index 859f5fcb6..c4984723d 100644 --- a/GRBL-Plotter/MachineControl/GCode2DViewpaths.cs +++ b/GRBL-Plotter/MachineControl/GCode2DViewpaths.cs @@ -228,7 +228,7 @@ private static bool CreateDrawingPathFromGCode(GcodeByLine newL, GcodeByLine old ArcProperties arcMove; arcMove = GcodeMath.GetArcMoveProperties((XyPoint)oldL.actualPos, (XyPoint)newL.actualPos, newL.i, newL.j, (newL.motionMode == 2)); - centerList.Add(new CoordByLine(newL.lineNumber, figureCount, new XyzPoint(arcMove.center, 0), 0, true)); + centerList.Add(new CoordByLine(newL.lineNumber, figureCount, new XyzPoint(arcMove.center, 0), new XyzPoint(arcMove.center, 0), newL.motionMode, 0, true)); newL.distance = Math.Abs(arcMove.radius * arcMove.angleDiff); @@ -381,7 +381,7 @@ public static void SetPathAsLandMark(bool clear) foreach (CoordByLine gcline in coordList) // copy coordList and add WCO { isArc = ((newLine.motionMode == 2) || (newLine.motionMode == 3)); - coordListLandMark.Add(new CoordByLine(0, -1, gcline.actualPos + Grbl.posWCO, gcline.alpha, isArc)); + coordListLandMark.Add(new CoordByLine(0, -1, gcline.lastPos + Grbl.posWCO, gcline.actualPos + Grbl.posWCO, gcline.actualG, gcline.alpha, isArc)); } origWCOLandMark = (XyPoint)Grbl.posWCO; } diff --git a/GRBL-Plotter/MachineControl/GCodeAnalyze.cs b/GRBL-Plotter/MachineControl/GCodeAnalyze.cs index 239265f13..faf553b05 100644 --- a/GRBL-Plotter/MachineControl/GCodeAnalyze.cs +++ b/GRBL-Plotter/MachineControl/GCodeAnalyze.cs @@ -267,7 +267,8 @@ public static bool GetGCodeLines(IList oldCode, BackgroundWorker worker, int progressSub; int progressSubOld = 0; - + int count2 = 0; + /*********************************************************************/ for (int lineNr = 0; lineNr < GCode.Length; lineNr++) // go through all gcode lines { @@ -324,7 +325,8 @@ public static bool GetGCodeLines(IList oldCode, BackgroundWorker worker, } if (singleLine.Contains("<")) - { ProcessXmlTagStart(GCode[lineNr], lineNr); } // Original line transferred because of uppercase lowercase + { ProcessXmlTagStart(GCode[lineNr], lineNr); + } // Original line transferred because of uppercase lowercase // collect halftone data if (halfToneEnable) // S or Z are calculated from gray-value - range 0-255 @@ -332,7 +334,7 @@ public static bool GetGCodeLines(IList oldCode, BackgroundWorker worker, if ((modal.mWord == 98) && processSubs) - { newLine.codeLine = "(" + GCode[lineNr] + ")"; } + { newLine.codeLine = "(" + GCode[lineNr] + ")"; } else { if (processSubs && programEnd) @@ -366,13 +368,14 @@ public static bool GetGCodeLines(IList oldCode, BackgroundWorker worker, else newLine.alpha = 0; + isArc = ((newLine.motionMode == 2) || (newLine.motionMode == 3)); + + coordList.Add(new CoordByLine(lineNr, newLine.figureNumber, (XyzPoint)oldLine.actualPos, (XyzPoint)newLine.actualPos, newLine.motionMode, newLine.alpha, isArc)); + oldLine = new GcodeByLine(newLine); // get copy of newLine gcodeList.Add(new GcodeByLine(newLine)); // add parsed line to list simuList.Add(new GcodeByLine(newLine)); // add parsed line to list - isArc = ((newLine.motionMode == 2) || (newLine.motionMode == 3)); - coordList.Add(new CoordByLine(lineNr, newLine.figureNumber, (XyzPoint)newLine.actualPos, newLine.alpha, isArc)); - if (updateFigureLineNeeded && xyPosChanged) { updateFigureLineNeeded = false; @@ -393,7 +396,8 @@ public static bool GetGCodeLines(IList oldCode, BackgroundWorker worker, } if (singleLine.Contains(" 0) || (newLine.z != null)) && !((newLine.x == Grbl.posWork.X) && (newLine.y == Grbl.posWork.Y))) xyzSize.SetDimensionXYZ(newLine.actualPos.X, newLine.actualPos.Y, newLine.actualPos.Z); // calculate max dimensions } // add data to drawing path @@ -702,7 +706,6 @@ private static void ProcessHalftoneData() if (width >= 0) { - //Logger.Trace("set path width:{0} line:{1} code:{2} lastS:{3} diff:{4} width:{5}",width, lineNr, GCode[lineNr], lastS, diff, showHalftoneWidth); if (showHalftonePath.ContainsKey(width)) // if pen-width was used before, continue path { int index = showHalftonePath[width]; diff --git a/GRBL-Plotter/MachineControl/GCodeParser.cs b/GRBL-Plotter/MachineControl/GCodeParser.cs index c2b593a53..ddf0ec892 100644 --- a/GRBL-Plotter/MachineControl/GCodeParser.cs +++ b/GRBL-Plotter/MachineControl/GCodeParser.cs @@ -25,6 +25,7 @@ You should have received a copy of the GNU General Public License * 2021-03-26 add wasSetF/S/XY/Z * 2021-07-26 code clean up / code quality * 2021-07-29 line 306 add G28 to ismachineCoordG53 = true; + * 2021-08-02 calc distance to line */ @@ -43,22 +44,70 @@ internal class CoordByLine { public int lineNumber; // line number in fCTBCode public int figureNumber; + public int actualG; internal XyzPoint actualPos; // accumulates position + internal XyzPoint lastPos; // accumulates position public double alpha; // angle between old and this position public double distance; // distance to specific point public bool isArc; - internal CoordByLine(int line, int figure, XyzPoint p, double a, bool isarc) - { lineNumber = line; figureNumber = figure; actualPos = p; alpha = a; distance = -1; isArc = isarc; } + internal CoordByLine(int line, int figure, XyzPoint pOld, XyzPoint pNew, int g, double a, bool isarc) + { lineNumber = line; figureNumber = figure; lastPos = pOld; actualPos = pNew; actualG = g; alpha = a; distance = -1; isArc = isarc; } - internal CoordByLine(int line, int figure, XyzPoint p, double a, double dist) - { lineNumber = line; figureNumber = figure; actualPos = p; alpha = a; distance = dist; isArc = false; } + internal CoordByLine(int line, int figure, XyzPoint pOld, XyzPoint pNew, int g, double a, double dist) + { lineNumber = line; figureNumber = figure; lastPos = pOld; actualPos = pNew; actualG = g; alpha = a; distance = dist; isArc = false; } internal void CalcDistance(XyPoint tmp) { XyPoint delta = new XyPoint(tmp - (XyPoint)actualPos); - distance = Math.Sqrt(delta.X * delta.X + delta.Y * delta.Y); + double distancePoint = Math.Sqrt(delta.X * delta.X + delta.Y * delta.Y); + double distanceLine = -1; + if (actualG == 1) + distanceLine = CalcDistanceToLine(tmp); + if (distanceLine >= 0) + distance = Math.Min(distancePoint, distanceLine); + else + distance = distancePoint; + } + + //https://stackoverflow.com/questions/34171073/how-do-i-detect-click-on-a-line-in-windows-forms + //https://forums.codeguru.com/showthread.php?412856-How-do-I-recognize-a-mouse-click-on-a-line + + internal double CalcDistanceToLine(XyPoint tmp) // + { + if ((Math.Abs(lastPos.X - actualPos.X) < 1) && (Math.Abs(lastPos.Y - actualPos.Y) < 1)) + return -1; // if too short + if ((tmp.X <= Math.Max(lastPos.X, actualPos.X)) && (tmp.X >= Math.Min(lastPos.X, actualPos.X)) || + (tmp.Y <= Math.Max(lastPos.Y, actualPos.Y)) && (tmp.Y >= Math.Min(lastPos.Y, actualPos.Y))) + { + XyPoint da = new XyPoint(tmp - (XyPoint)lastPos); + double a = Math.Sqrt(da.X * da.X + da.Y * da.Y); + XyPoint db = new XyPoint(tmp - (XyPoint)actualPos); + double b = Math.Sqrt(db.X * db.X + db.Y * db.Y); + XyPoint dc = new XyPoint((XyPoint)actualPos - (XyPoint)lastPos); + double c = Math.Sqrt(dc.X * dc.X + dc.Y * dc.Y); + if (c <= 0) return -1; + double s = (a + b + c) / 2; + double h = 2 / c * Math.Sqrt(s * (s - a) * (s - b) * (s - c)); + return h; + } + else + return -1; + } + + internal double CalcDistanceToLine1(XyPoint tmp) + { + double DelX = actualPos.X - lastPos.X; + double DelY = actualPos.Y - lastPos.Y; + double D = Math.Sqrt(DelX * DelX + DelY * DelY); + if (D < 0.1) return -1; + + double Ratio = (double)((tmp.X - lastPos.X) * DelX + (tmp.Y - lastPos.Y) * DelY) / (DelX * DelX + DelY * DelY); + if (Ratio * (1 - Ratio) < 0) + return -1; + return (double)Math.Abs(DelX * (tmp.Y - lastPos.Y) - DelY * (tmp.X - lastPos.X)) / D; } + } internal struct XyzabcuvwPoint diff --git a/GRBL-Plotter/MachineControl/GCodeSynthesize.cs b/GRBL-Plotter/MachineControl/GCodeSynthesize.cs index 6d126c8ff..59528b1e3 100644 --- a/GRBL-Plotter/MachineControl/GCodeSynthesize.cs +++ b/GRBL-Plotter/MachineControl/GCodeSynthesize.cs @@ -243,7 +243,7 @@ private static string CreateGCodeProg(bool replaceG23, bool splitMoves, bool app } isArc = ((gcline.motionMode == 2) || (gcline.motionMode == 3)); - coordList.Add(new CoordByLine(iCode, gcline.figureNumber, (XyzPoint)gcline.actualPos, gcline.alpha, isArc)); + coordList.Add(new CoordByLine(iCode, gcline.figureNumber, (XyzPoint)gcline.actualPos, (XyzPoint)gcline.actualPos, gcline.motionMode, gcline.alpha, isArc)); } return newCode.ToString().Replace(',', '.'); } diff --git a/GRBL-Plotter/MachineControl/GCodeVisuAndTransform.cs b/GRBL-Plotter/MachineControl/GCodeVisuAndTransform.cs index e804f0734..3168dad97 100644 --- a/GRBL-Plotter/MachineControl/GCodeVisuAndTransform.cs +++ b/GRBL-Plotter/MachineControl/GCodeVisuAndTransform.cs @@ -178,8 +178,10 @@ public static void SetPosMarkerLine(int line, bool markFigure) CreateMarkerPath(showCenter, center, (XyPoint)coordList[line].actualPos);// line-1 figureNr = coordList[line].figureNumber; if ((figureNr != lastFigureNumber) && (markFigure)) + { MarkSelectedFigure(figureNr); - lastFigureNumber = figureNr; + lastFigureNumber = figureNr; + } } else { @@ -201,8 +203,10 @@ public static void SetPosMarkerLine(int line, bool markFigure) CreateMarkerPath(showCenter, center, last); figureNr = coordList[line].figureNumber; if ((figureNr != lastFigureNumber) && (markFigure)) + { MarkSelectedFigure(figureNr); - lastFigureNumber = figureNr; + lastFigureNumber = figureNr; + } break; } @@ -214,10 +218,11 @@ public static void SetPosMarkerLine(int line, bool markFigure) catch (Exception er) { Logger.Error(er, " setPosMarkerLine"); } } + /// /// find gcode line with xy-coordinates near by given coordinates /// - internal static int SetPosMarkerNearBy(XyPoint pos, bool toggleHighlight = true) + internal static int SetPosMarkerNearBy(XyPoint pos, bool toggleHighlight) { if (logDetailed) Logger.Trace(" setPosMarkerNearBy x:{0:0.00} y:{1:0.00}", pos.X, pos.Y); List tmpList = new List(); // get all coordinates (also subroutines) @@ -226,17 +231,29 @@ internal static int SetPosMarkerNearBy(XyPoint pos, bool toggleHighlight = true) bool showCenter = false; /* fill list with coordByLine with actual distance to given point */ - foreach (CoordByLine gcline in coordList) + double minDist = double.MaxValue; + foreach (CoordByLine gcline in coordList) // from actual figures { - gcline.CalcDistance(pos); // calculate distance work coordinates - tmpList.Add(gcline); // add to new list + if (gcline.figureNumber >= 0) + { + gcline.CalcDistance(pos); // calculate distance work coordinates + if (gcline.distance < minDist) + { + minDist = gcline.distance; + tmpList.Add(gcline); // add to new list + } + } } - if (Properties.Settings.Default.guiBackgroundShow && (coordListLandMark.Count > 1)) + if (Properties.Settings.Default.guiBackgroundShow && (coordListLandMark.Count > 0)) { - foreach (CoordByLine gcline in coordListLandMark) + foreach (CoordByLine gcline in coordListLandMark) // from background figures { gcline.CalcDistance(pos + (XyPoint)Grbl.posWCO); // calculate distance machine coordinates - tmpList.Add(new CoordByLine(0, gcline.figureNumber, gcline.actualPos - Grbl.posWCO, gcline.alpha, gcline.distance)); // add as work coord. + if (gcline.distance < minDist) + { + minDist = gcline.distance; + tmpList.Add(new CoordByLine(0, gcline.figureNumber, gcline.lastPos - Grbl.posWCO, gcline.actualPos - Grbl.posWCO, gcline.actualG, gcline.alpha, gcline.distance)); // add as work coord. + } } } @@ -257,7 +274,6 @@ internal static int SetPosMarkerNearBy(XyPoint pos, bool toggleHighlight = true) } } - /* highlight */ CreateMarkerPath(showCenter, center); if ((figureNr != lastFigureNumber) || !toggleHighlight) { @@ -266,7 +282,7 @@ internal static int SetPosMarkerNearBy(XyPoint pos, bool toggleHighlight = true) } else { - MarkSelectedFigure(-1); // deselcet + MarkSelectedFigure(-1); // deselect lastFigureNumber = -1; } diff --git a/GRBL-Plotter/MachineControl/GCodeVisuWorker.cs b/GRBL-Plotter/MachineControl/GCodeVisuWorker.cs index 89db74518..5ef685693 100644 --- a/GRBL-Plotter/MachineControl/GCodeVisuWorker.cs +++ b/GRBL-Plotter/MachineControl/GCodeVisuWorker.cs @@ -21,11 +21,12 @@ You should have received a copy of the GNU General Public License * 2021-07-08 code clean up / code quality */ +using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; -#pragma warning disable CA1303 +//pragma warning disable CA1303 namespace GrblPlotter { @@ -37,6 +38,9 @@ public class VisuWorker : System.Windows.Forms.Form private System.Windows.Forms.Label resultLabel; private System.ComponentModel.BackgroundWorker backgroundWorker1; + // This event handler is where the actual, potentially time-consuming work is done. + internal IList tmpGCode = new List(); + public VisuWorker() { InitializeComponent(); InitializeBackgroundWorker(); @@ -56,7 +60,8 @@ public void SetTmpGCode(IList tmp) backgroundWorker1.RunWorkerAsync(); } public void SetTmpGCode() - { tmpGCode = Graphic.GCode.ToString().Split(System.Environment.NewLine.ToCharArray()); + { tmpGCode = Graphic.GCode.ToString().Split(System.Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + // System.IO.File.WriteAllText(Datapath.AppDataFolder + "\\visuworker.nc", Graphic.GCode.ToString()); // clear file backgroundWorker1.RunWorkerAsync(); } @@ -66,8 +71,6 @@ private void CancelAsyncButton_Click(System.Object sender, System.EventArgs e) this.backgroundWorker1.CancelAsync(); } - // This event handler is where the actual, potentially time-consuming work is done. - internal IList tmpGCode = new List(); private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker;