diff --git a/GRBL-Plotter/GCodeCreation/Graphic2GCode.cs b/GRBL-Plotter/GCodeCreation/Graphic2GCode.cs index 51574803..c4d2dfb7 100644 --- a/GRBL-Plotter/GCodeCreation/Graphic2GCode.cs +++ b/GRBL-Plotter/GCodeCreation/Graphic2GCode.cs @@ -43,7 +43,7 @@ You should have received a copy of the GNU General Public License * 2023-03-14 l:610 f:StartPath importGraphicLeadInEnable optional start at GcodeZUp value * 2023-09-14 f:CreateGCode add CollectionStart /-End Tags * 2023-11-03 l:357 f:CreateGCode (figure) add proforma figure-tag if not figureEnable - + * 2023-11-27 l:465 f:ProcessPathObject call subroutine only if needed */ using System; @@ -356,9 +356,8 @@ internal static bool CreateGCode(List completeGraphic, List< if (!graphicInfo.FigureEnable) // proforma figure tag { - string figColor = "", figWidth = ""; - figColor = string.Format(" PenColor=\"{0}\"", completeGraphic[0].Info.GroupAttributes[(int)GroupOption.ByColor]); - figWidth = string.Format(" PenWidth=\"{0}\"", completeGraphic[0].Info.GroupAttributes[(int)GroupOption.ByWidth]); + string figColor = string.Format(" PenColor=\"{0}\"", completeGraphic[0].Info.GroupAttributes[(int)GroupOption.ByColor]); + string figWidth = string.Format(" PenWidth=\"{0}\"", completeGraphic[0].Info.GroupAttributes[(int)GroupOption.ByWidth]); Gcode.Comment(gcodeString, string.Format("{0} Id=\"{1}\" {2} {3}>", XmlMarker.FigureStart, 0, figColor, figWidth)); } @@ -443,7 +442,7 @@ private static void ProcessPathObject(PathObject pathObject, Graphic.GraphicInfo } else if (graphicInfo.OptionZFromWidth) { - dotCounter++; + // dotCounter++; double newZ = CalculateZFromRange(graphicInfo.PenWidthMin, graphicInfo.PenWidthMax, DotData.OptZ); if (logEnable) Logger.Trace("---Dot OptionZFromWidth: RangeMin:{0:0.00} RangeMax:{1:0.00} DotData.Z:{2:0.00} -> setZ:{3:0.00}", graphicInfo.PenWidthMin, graphicInfo.PenWidthMax, DotData.OptZ, newZ); newZ = Math.Max(origZ, newZ); // don't go deeper than set Z @@ -452,18 +451,19 @@ private static void ProcessPathObject(PathObject pathObject, Graphic.GraphicInfo } if (graphicInfo.OptionSFromWidth) { - dotCounter++; + // dotCounter++; double newS = CalculateSFromRange(graphicInfo.PenWidthMin, graphicInfo.PenWidthMax, DotData.OptZ); if (logEnable) Logger.Trace("--ProcessPathObject: penWidth:{0:0.00} -> setS:{1:0.00}", DotData.OptZ, newS); Gcode.GcodePwmDown = Gcode.GcodeSpindleSpeed = (float)newS; //??? penIsDown = false; } + dotCounter++; pathObject.FigureId = StartPath(DotData, toolNr, toolCmt, "PD"); PenDown("PD"); StopPath("PU DOT"); - if (dotCounter >= Properties.Settings.Default.importCircleToDotScriptCount) + if (Properties.Settings.Default.importSVGCircleToDot && (Properties.Settings.Default.importCircleToDotScriptCount > 0) && (dotCounter >= Properties.Settings.Default.importCircleToDotScriptCount)) { dotCounter = 0; Gcode.CallSubroutine(gcodeString, 95, "refresh stamp"); @@ -518,12 +518,12 @@ private static void ProcessPathObject(PathObject pathObject, Graphic.GraphicInfo Gcode.GcodeZDown = (float)newZ; if (!Properties.Settings.Default.importDepthFromWidthRamp) penIsDown = false; - if (logEnable) Logger.Trace("--ProcessPathObject: penWidth:{0:0.00} -> setZ:{1:0.00}", entity.Depth, newZ); + if (logEnable) Logger.Trace("--ProcessPathObject-OptionZFromWidth: penWidth:{0:0.00} -> setZ:{1:0.00} min:{2:0.00} max:{3:0.00} orig:{4:0.00}", entity.Depth, newZ, graphicInfo.PenWidthMin, graphicInfo.PenWidthMax, origZ); } if (graphicInfo.OptionSFromWidth) { newS = CalculateSFromRange(graphicInfo.PenWidthMin, graphicInfo.PenWidthMax, entity.Depth); - if (logEnable) Logger.Trace("--ProcessPathObject: penWidth:{0:0.00} -> setS:{1:0.00}", entity.Depth, newS); + if (logEnable) Logger.Trace("--ProcessPathObject-OptionSFromWidth: penWidth:{0:0.00} -> setS:{1:0.00}", entity.Depth, newS); Gcode.GcodePwmDown = Gcode.GcodeSpindleSpeed = (float)newS; //??? } @@ -643,6 +643,7 @@ private static void SetHalftoneMode(Graphic.GraphicInformationClass graphicInfo) } } + /*Input: min, max and actual pen-width value from graphics import*/ public static double CalculateZFromRange(double min, double max, double penWidth) { if (logDetailed) @@ -658,6 +659,7 @@ public static double CalculateZFromRange(double min, double max, double penWidth return (double)Properties.Settings.Default.importDepthFromWidthMin; double nPen = (Math.Abs(penWidth) - penMin) / penDelta; + /*Get desired range, where to transform the pen-width*/ double zMin = Math.Abs((double)Properties.Settings.Default.importDepthFromWidthMin); double zMax = Math.Abs((double)Properties.Settings.Default.importDepthFromWidthMax); double zDelta = (zMax - zMin); @@ -677,6 +679,7 @@ public static double CalculateZFromRange(double min, double max, double penWidth return -z; } + /*Input: min, max and actual pen-width value from graphics import*/ public static double CalculateSFromRange(double min, double max, double penWidth) { if (logDetailed) @@ -686,12 +689,13 @@ public static double CalculateSFromRange(double min, double max, double penWidth double penMin = Math.Abs(min); double penMax = Math.Abs(max); - double penDelta = (penMax - penMin); + double penDelta = Math.Abs(penMax - penMin); if (penDelta == 0) return (double)Properties.Settings.Default.importImageSMin; double nPen = (Math.Abs(penWidth) - penMin) / penDelta; + /*Get desired range, where to transform the pen-width*/ double zMin = Math.Abs((double)Properties.Settings.Default.importImageSMin); double zMax = Math.Abs((double)Properties.Settings.Default.importImageSMax); double zDelta = (zMax - zMin); @@ -708,7 +712,7 @@ public static double CalculateSFromRange(double min, double max, double penWidth if (logDetailed) Logger.Trace("---calculateSFromPenWidth: penWidth:{0:0.00} nPen:{1:0.00} SDelta:{2:0.00} S:{3:0.00}", penWidth, nPen, zDelta, z); - return z; + return Math.Abs(z); } private static string GetGroupAttributes(GroupObject groupObject, GraphicInformationClass graphicInfo) @@ -934,10 +938,11 @@ private static void MoveTo(Point coordxy, double newZ, double? newS, double tang Gcode.SetAux2DistanceCommand(setAux2FinalDistance); if (newS != null) Gcode.SetSValue((double)newS); + //Logger.Trace("MoveTo useAlternitveZ:{0} newZ:{1}", useAlternitveZ, newZ); if (useAlternitveZ) //Properties.Settings.Default.importDepthFromWidthRamp|| Properties.Settings.Default.importDXFUseZ) Gcode.Move(gcodeString, 1, coordxy.X, coordxy.Y, (float)newZ, Gcode.ApplyXYFeedRate, cmt); else if (applyDashPattern) - MoveToDashed(coordxy, cmt); + MoveToDashed(coordxy); else Gcode.MoveTo(gcodeString, coordxy, cmt); // note: Gcode.GcodeZDown is may set with newZ @@ -946,7 +951,7 @@ private static void MoveTo(Point coordxy, double newZ, double? newS, double tang - private static void MoveToDashed(Point coordxy, string cmt) + private static void MoveToDashed(Point coordxy) { if (logCoordinates) Logger.Trace(" MoveToDashed from X:{0:0.000} Y:{1:0.000} to X:{0:0.000} Y:{1:0.000}", lastGC.X, lastGC.Y, coordxy.X, coordxy.Y); diff --git a/GRBL-Plotter/GCodeCreation/Graphic2GCodeRelated.cs b/GRBL-Plotter/GCodeCreation/Graphic2GCodeRelated.cs index ac77a264..bcee9e23 100644 --- a/GRBL-Plotter/GCodeCreation/Graphic2GCodeRelated.cs +++ b/GRBL-Plotter/GCodeCreation/Graphic2GCodeRelated.cs @@ -53,6 +53,7 @@ You should have received a copy of the GNU General Public License * 2023-09-05 l:858 f:GetStrGCode allow also 3 digitis * 2023-09-23 l:1020 f:JobEnd don't send M05 if (PreventSpindle) * 2023-09-24 l:1500 f:Tool also take care of !PreventSpindle + * 2023-11-27 l:792 f:Setup add script from Properties.Settings.Default.importCircleToDotScript */ using System; @@ -506,8 +507,8 @@ public static partial class Gcode private static string gcodeSubroutine = ""; // subroutine private static int gcodeDownUp = 0; // counter for GCode Pen Down / Up - private static float gcodeTime = 0; // counter for GCode work time - private static float gcodeFigureTime = 0; // counter for GCode work time + private static double gcodeTime = 0; // counter for GCode work time + private static double gcodeFigureTime = 0; // counter for GCode work time private static int gcodePauseCounter = 0; // counter for GCode pause M0 commands private static int gcodeToolCounter = 0; // counter for GCode Tools private static string gcodeToolText = ""; // counter for GCode Tools @@ -566,7 +567,7 @@ public static partial class Gcode private static bool gcodeTangentialEnable = false; private static string gcodeTangentialName = "C"; - private static float gcodeTangentialAngle = 0; + private static double gcodeTangentialAngle = 0; private static float gcodeTangentialAngleDevi = 0; // private static float gcodeTangentialAngleLast = 0; private static string gcodeTangentialCommand = ""; @@ -756,6 +757,11 @@ public static string GetSettings() stopwatch = new Stopwatch(); stopwatch.Start(); + gcodeSValueCommand = ""; + gcodeTangentialCommand = ""; + gcodeAuxiliaryValue1Command = ""; + gcodeAuxiliaryValue2Command = ""; + if ((gcodeInsertSubroutineEnable && gcodeLineSegmentationEnable) || gcodeToolChange || Properties.Settings.Default.ctrlToolChange || (Properties.Settings.Default.importSVGCircleToDot && (Properties.Settings.Default.importCircleToDotScriptCount > 0))) { bool insertSubroutine = false; @@ -782,6 +788,12 @@ public static string GetSettings() gcodeSubroutine += "\r\n(subroutine)\r\nO92 (Pen down)\r\n"; gcodeSubroutine += tmp.ToString(); gcodeSubroutine += "M99\r\n"; + + if (Properties.Settings.Default.importSVGCircleToDot) // && File.Exists(Properties.Settings.Default.importCircleToDotScript)) + { + SetSubroutine(Properties.Settings.Default.importCircleToDotScript, 95); + } + lastz = tmp_lastz; if (GcodePWMEnable) @@ -1245,13 +1257,13 @@ public static void MoveToRapid(StringBuilder gcodeValue, Point coord, string cmt figureStart.X = coord.X; figureStart.Y = coord.Y; figureStartAlpha = gcodeTangentialCommand; if (!(GcodeZApply && repeatZ)) - { Move(gcodeValue, 0, (float)coord.X, (float)coord.Y, false, cmt); LastMovewasG0 = true; } + { Move(gcodeValue, 0, coord.X, coord.Y, false, cmt); LastMovewasG0 = true; } else { - lastx = (float)coord.X; lasty = (float)coord.Y; lastg = 0; + lastx = coord.X; lasty = coord.Y; lastg = 0; } } - public static void MoveToRapid(StringBuilder gcodeValue, float mx, float my, string cmt) + public static void MoveToRapid(StringBuilder gcodeValue, double mx, double my, string cmt) { figureStart.X = mx; figureStart.Y = my; figureStartAlpha = gcodeTangentialCommand; @@ -1598,7 +1610,7 @@ public static void Tool(StringBuilder gcodeValue, int toolnr, int objectCount, s remainingC = (float)Properties.Settings.Default.importGCLineSegmentLength; // start with full segment length - if (GcodeZApply && !gcodeSpindleToggle && !PreventSpindle) + if (GcodeZApply && !gcodeSpindleToggle && !PreventSpindle) { Gcode.SpindleOn(gcodeValue, "Start spindle - Option Z-Axis"); gcodeLines++; } } diff --git a/GRBL-Plotter/GCodeCreation/GraphicCollectData.cs b/GRBL-Plotter/GCodeCreation/GraphicCollectData.cs index 920421d6..83f7a469 100644 --- a/GRBL-Plotter/GCodeCreation/GraphicCollectData.cs +++ b/GRBL-Plotter/GCodeCreation/GraphicCollectData.cs @@ -56,7 +56,6 @@ You should have received a copy of the GNU General Public License * 2023-09-16 l:774 f:CreateGCode wrong call to RemoveOffset(minx,minx) -> miny */ -using AForge.Imaging.Filters; using System; using System.Collections.Generic; using System.ComponentModel; @@ -113,6 +112,14 @@ public static partial class Graphic private static int countWarnDimNotSet = 0; + private static int pathAddOnCount = 0; + //private static int pathAddOnPosition = 0; + //private static double pathAddOnScale = 1; + private static double pathAddOnDimx = 0; + private static double pathAddOnDimy = 0; + private static bool pathAddOnCompletion = false; + //private static string addFramelayer = ""; + internal static GraphicInformationClass graphicInformation = new GraphicInformationClass(); private static BackgroundWorker backgroundWorker = null; // will be set by GCodeFromxxx @@ -247,6 +254,13 @@ public static void Init(SourceType type, string filePath, BackgroundWorker worke setNewId = true; equalPrecision = (double)Properties.Settings.Default.importAssumeAsEqualDistance; + pathAddOnCompletion = false; + pathAddOnCount = 0; + //pathAddOnScale = 1; + pathAddOnDimx = 0; + pathAddOnDimy = 0; + //addFramelayer = ""; + stopwatch = new Stopwatch(); stopwatch.Start(); totalTime = new Stopwatch(); @@ -512,12 +526,19 @@ public static void SetLabel(string txt) // from inkscape:label, will be added to public static bool SetPenWidth(string txt) // DXF: 0 - 2.11mm = 0 - 211 SVG: 0.000 - ? Convert with to mm, then to string in importClass { - if (logProperties) Logger.Trace("Set PenWidth '{0}'", txt); + // if (logProperties) Logger.Trace("Set PenWidth '{0}'", txt); // setNewId = true; // active 2020-10-25 + + if (txt.Contains("NaN")) + { + Logger.Error("SetPenWidth contains NaN '{0}'", txt); + return true; + } int tmpIndex = (int)GroupOption.ByWidth; CountProperty(tmpIndex, txt); if (!actualPathInfo.SetGroupAttribute(tmpIndex, txt)) Logger.Error(" Error SetPenWidth '{0}'", txt); + graphicInformation.SetPenWidth(txt); // find min / max values if (!Properties.Settings.Default.importGraphicFilterEnable) @@ -547,6 +568,8 @@ public static bool SetPenColor(string txt) txt = ConvertFromRGB(txt); } if (logProperties) Logger.Trace("SetPenColor '{0}'", txt); + if (txt.ToLower().Contains("currentcolor")) + { return true; } setNewId = true; int tmpIndex = (int)GroupOption.ByColor; @@ -582,8 +605,16 @@ public static void SetPenFill(string txt) } if (logProperties) Logger.Trace("SetPenFill '{0}'", txt); - setNewId = true; int tmpIndex = (int)GroupOption.ByFill; + if (txt.ToLower().Contains("currentcolor")) + { + string tmp = actualPathInfo.GetGroupAttribute((int)GroupOption.ByColor); + if (!actualPathInfo.SetGroupAttribute(tmpIndex, tmp)) + Logger.Error(" Error SetPenFill '{0}'", txt); + return; + } + + setNewId = true; CountProperty(tmpIndex, txt); if (!actualPathInfo.SetGroupAttribute(tmpIndex, txt)) Logger.Error(" Error SetPenFill '{0}'", txt); @@ -714,6 +745,42 @@ private static void CountProperty(int index, string txt) // ####################################################################### // Do modifications, then create GCode in graphic2GCode // ####################################################################### + public static bool ImportCompletion(string tag, double scale, int position) // do thinks before adding further paths + { + //addFramelayer = tag; + + if (actualPath.Path.Count > 0) + StopPath("in CreateCode"); // save previous path + + /* add frame */ + if (Properties.Settings.Default.importGraphicAddFrameEnable) + { + Logger.Info("{0} Add frame, distance: {1} radius: {2}", "►►►", Properties.Settings.Default.importGraphicAddFrameDistance, Properties.Settings.Default.importGraphicAddFrameApplyRadius); + AddFrame(actualDimension, + (double)Properties.Settings.Default.importGraphicAddFrameDistance, + Properties.Settings.Default.importGraphicAddFrameApplyRadius); + SetHeaderInfo(string.Format(" Option: Add frame distance:{0:0.00} with radius:{1}", Properties.Settings.Default.importGraphicAddFrameDistance, Properties.Settings.Default.importGraphicAddFrameApplyRadius)); + } // distance from graphics dimension, corner radius + + pathAddOnDimx = actualDimension.dimx; + pathAddOnDimy = actualDimension.dimy; + + if (position == 1) // center + { + Scale(completeGraphic, scale, scale); + RemoveOffset(completeGraphic, actualDimension.minx + actualDimension.dimx / 2, actualDimension.miny + actualDimension.dimy / 2); // center object + } + else if (position > 0) + { + RemoveOffset(completeGraphic, actualDimension.minx, actualDimension.miny); // origin = bottom left + } + actualDimension.ResetDimension(); + pathAddOnCount = completeGraphic.Count; + //pathAddOnScale = scale; + // pathAddOnPosition = position; + pathAddOnCompletion = true; + return true; + } public static bool CreateGCode()//Final(BackgroundWorker backgroundWorker, DoWorkEventArgs e) { @@ -728,9 +795,7 @@ public static bool CreateGCode()//Final(BackgroundWorker backgroundWorker, DoWor if (actualPath.Path.Count > 1) StopPath("in CreateCode"); // save previous path - double dimX = (actualDimension.maxx - actualDimension.minx); - double dimY = (actualDimension.maxy - actualDimension.miny); - Logger.Info("▼▼▼▼ Graphic - CreateGCode count:{0} dimX:{1:0.0} dimY:{2:0.0}", completeGraphic.Count, dimX, dimY); + Logger.Info("▼▼▼▼ Graphic - CreateGCode count:{0} dimX:{1:0.0} dimY:{2:0.0}", completeGraphic.Count, actualDimension.dimx, actualDimension.dimy); if (Properties.Settings.Default.importGCRelative) { SetHeaderMessage(string.Format(" {0}-2010: GCode for relative movement commands G91 will be generated", CodeMessage.Warning)); } @@ -753,8 +818,49 @@ public static bool CreateGCode()//Final(BackgroundWorker backgroundWorker, DoWor Logger.Info("{0} NO Remove of short moves", loggerTag, Properties.Settings.Default.importRemoveShortMovesLimit); } + /* process add-on data - frame, sign, watermark */ + if (pathAddOnCompletion && Properties.Settings.Default.importSVGAddOnEnable) + { + int position = Properties.Settings.Default.importSVGAddOnPosition; + double scale = (double)Properties.Settings.Default.importSVGAddOnScale; + if (position > 1) // scale + { + Scale(completeGraphic, scale, scale, pathAddOnCount); + } + + if (position == 1) // center + { + RemoveOffset(completeGraphic, actualDimension.minx + actualDimension.dimx / 2, actualDimension.miny + actualDimension.dimy / 2, pathAddOnCount); // center object + } + else if (position == 2) // bottom left + { + RemoveOffset(completeGraphic, actualDimension.minx, actualDimension.miny, pathAddOnCount); + } + else if (position == 3) // bottom right + { + RemoveOffset(completeGraphic, actualDimension.minx - pathAddOnDimx + actualDimension.dimx, actualDimension.miny, pathAddOnCount); + } + else if (position == 4) // top left + { + RemoveOffset(completeGraphic, actualDimension.minx, actualDimension.miny - pathAddOnDimy + actualDimension.dimy, pathAddOnCount); + } + else if (position == 5) // top right + { + RemoveOffset(completeGraphic, actualDimension.minx - pathAddOnDimx + actualDimension.dimx, actualDimension.miny - pathAddOnDimy + actualDimension.dimy, pathAddOnCount); + } + Logger.Info("CreateGCode process add-on data min x:{0} y:{1} dimy:{2} dimy:{3} addx:{4} addy:{5}", actualDimension.minx, actualDimension.miny, actualDimension.dimx, actualDimension.dimy, pathAddOnDimx, pathAddOnDimy); + + if (position > 1) // reset size + { + actualDimension.minx = actualDimension.miny = 0; + actualDimension.dimx = pathAddOnDimx; + actualDimension.dimy = pathAddOnDimy; + } + Logger.Info("CreateGCode process add-on data min x:{0} y:{1} dimy:{2} dimy:{3} ", actualDimension.minx, actualDimension.miny, actualDimension.dimx, actualDimension.dimy); + } + /* add frame */ - if (Properties.Settings.Default.importGraphicAddFrameEnable) + if (!pathAddOnCompletion && Properties.Settings.Default.importGraphicAddFrameEnable) { Logger.Info("{0} Add frame, distance: {1} radius: {2}", loggerTag, Properties.Settings.Default.importGraphicAddFrameDistance, Properties.Settings.Default.importGraphicAddFrameApplyRadius); AddFrame(actualDimension, @@ -770,6 +876,8 @@ public static bool CreateGCode()//Final(BackgroundWorker backgroundWorker, DoWor double offX = GuiVariables.offsetOriginX; // (double)Properties.Settings.Default.importGraphicOffsetOriginX; double offY = GuiVariables.offsetOriginY; // (double)Properties.Settings.Default.importGraphicOffsetOriginY; double gap = (double)Properties.Settings.Default.multipleLoadGap; + double dimX = actualDimension.dimx; + double dimY = actualDimension.dimy; /*********** Adapt offset on mutlifile import ****************************/ if (Graphic2GCode.multiImport && !Properties.Settings.Default.multipleLoadLimitNo) @@ -782,15 +890,12 @@ public static bool CreateGCode()//Final(BackgroundWorker backgroundWorker, DoWor if ((offX + dimX) > limitX) { offX = (double)Graphic2GCode.multiImportOffsetX; - //Properties.Settings.Default.importGraphicOffsetOriginX = Graphic2GCode.multiImportOffsetX + (decimal)(dimX + gap); GuiVariables.offsetOriginX = (double)Graphic2GCode.multiImportOffsetX + (dimX + gap); offY = Graphic2GCode.multiImportMaxY + gap; - //Properties.Settings.Default.importGraphicOffsetOriginY = (decimal)offY; GuiVariables.offsetOriginY = offY; } else { //offX += dimX + gap; - //Properties.Settings.Default.importGraphicOffsetOriginX = (decimal)(offX + dimX + gap); GuiVariables.offsetOriginX = offX + dimX + gap; } } @@ -799,19 +904,15 @@ public static bool CreateGCode()//Final(BackgroundWorker backgroundWorker, DoWor if ((offY + dimY) > limitY) { offY = (double)Graphic2GCode.multiImportOffsetY; - //Properties.Settings.Default.importGraphicOffsetOriginY = Graphic2GCode.multiImportOffsetY + (decimal)(dimY + gap); GuiVariables.offsetOriginY = (double)Graphic2GCode.multiImportOffsetY + (dimY + gap); offX = Graphic2GCode.multiImportMaxX + gap; - //Properties.Settings.Default.importGraphicOffsetOriginX = (decimal)offX; GuiVariables.offsetOriginX = offX; } else { //offY += dimY + gap; - //Properties.Settings.Default.importGraphicOffsetOriginY = (decimal)(offY + dimY + gap); GuiVariables.offsetOriginY = offY + dimY + gap; } } - Properties.Settings.Default.Save(); } Logger.Info("{0} Remove offset: X:{1:0.000} Y:{2:0.000} new origin: X:{3:0.00} Y:{4:0.00}", loggerTag, actualDimension.minx, actualDimension.miny, offX, offY); SetHeaderInfo(string.Format(" Graphic offset: {0:0.00} {1:0.00} new origin: {2:0.00} {3:0.00}", -actualDimension.minx, -actualDimension.miny, offX, offY)); diff --git a/GRBL-Plotter/GCodeCreation/GraphicCollectText.cs b/GRBL-Plotter/GCodeCreation/GraphicCollectText.cs index 6f1ac1f0..f8ac17c9 100644 --- a/GRBL-Plotter/GCodeCreation/GraphicCollectText.cs +++ b/GRBL-Plotter/GCodeCreation/GraphicCollectText.cs @@ -51,15 +51,13 @@ public static void AddText(string text, StringAlignment alignment) float yOffset = 0; float rotation = 0; - RectangleF box = GetTextBounds(text, alignment); + //RectangleF box = GetTextBounds(text, alignment); List pathsPerChar = new List(); SetHeaderInfo(string.Format(" Used font:'{0}', Size:{1}", fontFamily.Name, fontSize)); if (true) /* do whole conversion in one - disadvantage: each path gernerates a figure = 2 figures for '0', 'A', 'P'... */ { - // ox = -box.Width;//-GetGlyphProperty(text[0], 0) * fontSize; // get LSB - // oy = -box.Height; using (var path = new GraphicsPath()) // do whole text in one go { DrawGlyphPath(path, new PointF(ox, oy), new PointF(ox, oy + yOffset), rotation, text, alignment); @@ -68,63 +66,6 @@ public static void AddText(string text, StringAlignment alignment) ExtractGlyphPath(path, pathOffset, text, pathsPerChar); // StartPath & Graphic.StopPath } } - /* else // alternative function converts char by char - all char related paths in one figure. But kerning is not applied - { - yOffset = box.Height; - - RectangleF lineBox; - - float xOffsetBounds, xOffsetAlignment; - - float width = 0; - float tmpWidth; - - string[] lines = text.Split('\n'); - string textline; - foreach (string tl in lines) - { - textline = tl.Replace('\r', ' '); - - List posX = new List - { - 0f // first glyph starts at zero - }; - - lineBox = GetTextBounds(textline, alignment); - xOffsetAlignment = 0; - if (alignment == StringAlignment.Center) - xOffsetAlignment = (box.Width - lineBox.Width) / 2; - else if (alignment == StringAlignment.Far) - xOffsetAlignment = box.Width - lineBox.Width; - - xOffsetBounds = 0; // GetGlyphProperty(textline[0], 0) * fontSize; // get LSB - - width = 0; - for (int i = 0; i < textline.Length; i++) // get individual xOffset for each char of this line - { - tmpWidth = GetGlyphProperty(textline[i], 1) * fontSize; // AdvanceWidths - width += tmpWidth; - posX.Add(width); - } - posX.Add(width); - - using (var path = new GraphicsPath()) // do char by char to adjust e.g. dx individual - { - // int ci; - for (int i = 0; i < textline.Length; i++) - { - ox = posX[i] + xOffsetAlignment - xOffsetBounds; - oy = -yOffset; - - DrawGlyphPath(path, new PointF(ox, oy), new PointF(ox, oy + yOffset), 0, textline[i].ToString(), StringAlignment.Near); - ExtractGlyphPath(path, new PointF(0, 0), textline.Substring(i, 1), pathsPerChar, true); // StartPath & Graphic.StopPath - } - } - - yOffset -= box.Height / lines.Count(); - } - }*/ - } private static void DrawGlyphPath(GraphicsPath myPath, PointF origin, PointF originR, float angle, string text, StringAlignment alignment) @@ -196,7 +137,7 @@ private static void GetPathsPerChar(List list, string text) } } - private static void ExtractGlyphPath(GraphicsPath extractPath, PointF offset, string text, List pathsPerChar, bool onlyOneFigure = false) + private static void ExtractGlyphPath(GraphicsPath extractPath, PointF offset, string text, List pathsPerChar)//, bool onlyOneFigure = false) { if (!(extractPath.PointCount > 2)) return; diff --git a/GRBL-Plotter/GCodeCreation/GraphicGenerateHatchFill.cs b/GRBL-Plotter/GCodeCreation/GraphicGenerateHatchFill.cs index a2422362..ece34c38 100644 --- a/GRBL-Plotter/GCodeCreation/GraphicGenerateHatchFill.cs +++ b/GRBL-Plotter/GCodeCreation/GraphicGenerateHatchFill.cs @@ -21,6 +21,8 @@ You should have received a copy of the GNU General Public License * 2021-07-14 code clean up / code quality * 2022-11-04 line 57 set dash pattern to 0 * 2023-01-15 line 90 bug-fix in log-output + * 2023-08-14 l:48 f: ShrinkPaths Hatch fill extension: shrink enveloping path , delete enveloping path (Vers 1.7.0.1) + * 2023-11-07 l:369 f:ClipLineByPolygone if distance is too small, delete both intersection point */ @@ -352,18 +354,20 @@ private static void ClipLineByPolygone(Point p1, Point p2, List path d_and_a.Sort((x, y) => x.s.CompareTo(y.s)); // Remove duplicate intersections - int n = d_and_a.Count; int i_last = 1; - int i = 1; IntersectionInfo last = d_and_a[0]; - while (i < n) + + for (int i=1; i < d_and_a.Count; i++) { - if ((Math.Abs(d_and_a[i].s - last.s)) > 0.0000000001) //F_MINGAP_SMALL_VALUE) // 0.0000000001 + if ((Math.Abs(d_and_a[i].s - last.s)) > 0.0000000001) { - d_and_a[i_last] = last = d_and_a[i]; - i_last += 1; + d_and_a[i_last] = last = d_and_a[i]; // different positions - take over + i_last++; } - i += 1; + else + { + d_and_a[--i_last] = last = d_and_a[i]; // same positions - skip both 2023-11-07 + } } d_and_a = d_and_a.GetRange(0, i_last); @@ -511,9 +515,11 @@ private static void ShrinkPath(PathObject path, double distance) private static Point OffsetPoint(Point p, double angle, double radius) { - Point newP = new Point(); - newP.X = p.X + Math.Cos(angle) * radius; - newP.Y = p.Y + Math.Sin(angle) * radius; + Point newP = new Point + { + X = p.X + Math.Cos(angle) * radius, + Y = p.Y + Math.Sin(angle) * radius + }; return newP; } private static double GetAlpha(Point P1, Point P2) diff --git a/GRBL-Plotter/GCodeCreation/ImportMath.cs b/GRBL-Plotter/GCodeCreation/ImportMath.cs index ef732ca1..3946ad8b 100644 --- a/GRBL-Plotter/GCodeCreation/ImportMath.cs +++ b/GRBL-Plotter/GCodeCreation/ImportMath.cs @@ -36,8 +36,8 @@ public static class ImportMath /// /// Calculate Path-Arc-Command - Code from https://github.com/vvvv/SVG/blob/master/Source/Paths/SvgArcSegment.cs /// - public static void CalcArc(float astartX, float astartY, float radiusX, float radiusY, - float angle, float size, float sweep, float endX, float endY, Action moveTo) + public static void CalcArc(double astartX, double astartY, double radiusX, double radiusY, + double angle, double size, double sweep, double endX, double endY, Action moveTo) { // Logger.Trace(" calcArc Start: {0};{1} rx: {2} ry: {3} a: {4} size: {5} sweep: {6} End: {7};{8}", StartX, StartY, RadiusX, RadiusY, // Angle, Size, Sweep, EndX, EndY); @@ -52,8 +52,8 @@ public static void CalcArc(float astartX, float astartY, float radiusX, float ra double y1dash = -sinPhi * (astartX - endX) / 2.0 + cosPhi * (astartY - endY) / 2.0; double root; double numerator = radiusX * radiusX * radiusY * radiusY - radiusX * radiusX * y1dash * y1dash - radiusY * radiusY * x1dash * x1dash; - float rx = radiusX; - float ry = radiusY; + double rx = radiusX; + double ry = radiusY; if (numerator < 0.0) { float s = (float)Math.Sqrt(1.0 - numerator / (radiusX * radiusX * radiusY * radiusY)); @@ -368,7 +368,7 @@ public static List ApproxCubicBezier(CubicBezier bezier, int nrPointsToCh } } - public struct CubicBezier + public readonly struct CubicBezier { /// /// Start point @@ -470,7 +470,7 @@ public Tuple InflexionPoints } } - public struct BiArc + public readonly struct BiArc { public readonly Arc A1; public readonly Arc A2; @@ -559,7 +559,7 @@ public float Length } } - public struct Arc + public readonly struct Arc { /// /// Center point @@ -622,7 +622,7 @@ public float Length } } - public struct Line + public readonly struct Line { /// /// Slope diff --git a/GRBL-Plotter/GCodeCreation/XmlMarker.cs b/GRBL-Plotter/GCodeCreation/XmlMarker.cs index fe523fe0..3da62495 100644 --- a/GRBL-Plotter/GCodeCreation/XmlMarker.cs +++ b/GRBL-Plotter/GCodeCreation/XmlMarker.cs @@ -27,6 +27,7 @@ You should have received a copy of the GNU General Public License * 2023-04-15 improove GetFigure, GetGroup, GetTile * 2023-07-03 l:338 f:GetAttributeValue check if remaining length is enough * 2023-07-31 new functions FindInsertPositionFigure/Group/Next + * 2023-11-15 add figurePenColorAnyCount */ using System; @@ -115,6 +116,9 @@ internal class BlockData internal static BlockData header = new BlockData(); internal static BlockData footer = new BlockData(); + internal static int figurePenColorNoneCount = 0; + internal static int figurePenColorAnyCount = 0; + public enum SortOption { Id, Color, Width, Layer, Type, Geometry, ToolNR, ToolName, CodeSize, CodeArea, Distance }; // Trace, Debug, Info, Warn, Error, Fatal @@ -129,7 +133,9 @@ public static void Reset() listFigures.Clear(); listGroups.Clear(); listTiles.Clear(); listCollections.Clear(); header.LineStart = 0; header.LineEnd = 999999; footer.LineStart = footer.LineEnd = 0; - + figurePenColorNoneCount = 0; + figurePenColorAnyCount = 0; + logFlags = (uint)Properties.Settings.Default.importLoggerSettings; logEnable = Properties.Settings.Default.guiExtendedLoggingEnabled && ((logFlags & (uint)LogEnables.Level4) > 0); } @@ -398,9 +404,12 @@ internal static BlockData SetBlockData(int lineStart, string element, int figNr) { //Logger.Trace(" setBlockData {0} {1}", lineStart, element); header.LineEnd = Math.Min(header.LineEnd, lineStart); // lowest block-line = end of header - BlockData tmp = new BlockData(); - tmp.MyIndex = 0; - tmp.LineStart = lineStart; tmp.Reverse = false; + BlockData tmp = new BlockData + { + MyIndex = 0, + LineStart = lineStart, + Reverse = false + }; tmp.Id = tmp.ToolNr = tmp.CodeSize = tmp.CodeArea = -1; tmp.PenWidth = tmp.PathLength = tmp.PathArea = -1; tmp.Geometry = tmp.Layer = tmp.Type = tmp.PenColor = tmp.ToolName = tmp.PathId = ""; @@ -436,6 +445,13 @@ public static void FinishFigure(int lineEnd) { tmpFigure.LineEnd = lineEnd; tmpFigure.MyIndex = listFigures.Count; + + if (tmpFigure.PenColor != "") + figurePenColorAnyCount++; + + if (tmpFigure.PenColor.Contains("none")) + figurePenColorNoneCount++; + listFigures.Add(tmpFigure); footer.LineStart = footer.LineEnd = Math.Max(footer.LineStart, lineEnd); // highest block-line = start of footer }