/// <summary> /// /// </summary> /// <param name="line"></param> /// <returns>index of created movement in toolpath</returns> public int ParseLine(string line) { { //cleanup int commentIndex = line.IndexOfAny(new char[] { ';', '(' }); if (commentIndex >= 0) line = line.Remove(commentIndex); if (string.IsNullOrWhiteSpace(line)) return -1; line = line.ToUpperInvariant(); } double? x = null, y = null, z = null, i = null, j = null, r = null, f = null, p = null; int LineMovementCode = -1; MatchCollection matches = GCodeSplitter.Matches(line); foreach (Match match in matches) { char Letter = match.Groups[1].Value[0]; double Arg = double.Parse(match.Groups[2].Value, GCodeCommand.NumberFormat); //no tryparse, the regex should only accept valid numbers (except for out of range) if (Letter == 'M') { if (LineMovementCode != -1) throw new Exception("GCode with parameters must be the last in a line"); ToolPath.Add(new MCode(Arg)); continue; } if (Letter == 'G') { if (LineMovementCode != -1) throw new Exception("GCode with parameters must be the last in a line"); if (Arg == (int)Arg && (int)Arg <= 4 && (int)Arg >= 0) { LineMovementCode = (int)Arg; LastGCode = LineMovementCode; continue; } if (Arg == 20) { Unit = DistanceUnit.Inches; continue; } if (Arg == 21) { Unit = DistanceUnit.MM; continue; } if (Arg == 90) { DistanceMode = ParseDistanceMode.Absolute; continue; } if (Arg == 90.1) { ArcDistanceMode = ParseDistanceMode.Absolute; continue; } if (Arg == 91) { DistanceMode = ParseDistanceMode.Incremental; continue; } if (Arg == 91.1) { ArcDistanceMode = ParseDistanceMode.Incremental; continue; } continue; //throw new Exception($"Unrecognized GCode 'G{Arg}'"); } if (PositionWords.Contains(Letter)) { if (LineMovementCode == -1) LineMovementCode = LastGCode; if (Unit == DistanceUnit.Inches) Arg *= 25.4; } if (Letter == 'X') { x = Arg; continue; } if (Letter == 'Y') { y = Arg; continue; } if (Letter == 'Z') { z = Arg; continue; } if (Letter == 'I') { i = Arg; continue; } if (Letter == 'J') { j = Arg; continue; } if (Letter == 'R') { r = Arg; continue; } if (Letter == 'F') { f = Arg; continue; } if (Letter == 'P') { p = Arg; continue; } throw new Exception($"Unrecognized word '{Letter}'"); } if (LineMovementCode == -1) return - 1; if (LineMovementCode == 4) { if (p.HasValue) { if ((x ?? y ?? z ?? i ?? j ?? r ?? f) != null) throw new Exception("Unused word in block"); ToolPath.Add(new Dwell(p.Value)); } else throw new Exception("Missing 'P' command word"); } Vector3 EndPosition = new Vector3(Position); if (x.HasValue) { EndPosition.X = (DistanceMode == ParseDistanceMode.Absolute) ? x.Value : EndPosition.X + x.Value; } if (y.HasValue) { EndPosition.Y = (DistanceMode == ParseDistanceMode.Absolute) ? y.Value : EndPosition.Y + y.Value; } if (z.HasValue) { EndPosition.Z = (DistanceMode == ParseDistanceMode.Absolute) ? z.Value : EndPosition.Z + z.Value; } if (Position == EndPosition) return -1; switch (LineMovementCode) { case 0: { if ((i ?? j ?? r ?? p ?? f) != null) throw new Exception("Unused word in block"); Straight s = new Straight(Position, EndPosition, true); ToolPath.Add(s); break; } case 1: { if ((i ?? j ?? r ?? p) != null) throw new Exception("Unused word in block"); Straight s = new Straight(Position, EndPosition, false); s.FeedRate = f; ToolPath.Add(s); break; } case 2: case 3: { if(p.HasValue) throw new Exception("Unused word in block"); Vector3 center = new Vector3(Position); if (i.HasValue) { center.X = (ArcDistanceMode == ParseDistanceMode.Absolute) ? i.Value : Position.X + i.Value; } if (j.HasValue) { center.Y = (ArcDistanceMode == ParseDistanceMode.Absolute) ? j.Value : Position.Y + j.Value; } if (r.HasValue) { if ((i ?? j).HasValue) throw new Exception("Both IJ and R notation used"); Vector3 Parallel = EndPosition - Position; Vector3 Perpendicular = Parallel.CrossProduct(new Vector3(0, 0, 1)); double PerpLength = Math.Sqrt((r.Value * r.Value) - (Parallel.Magnitude * Parallel.Magnitude / 4)); if (LineMovementCode == 3 ^ r.Value < 0) PerpLength = -PerpLength; Perpendicular *= PerpLength / Perpendicular.Magnitude; center = Position + (Parallel / 2) + Perpendicular; } if (center == Position) throw new Exception("Center of arc undefined"); Arc a = new Arc(Position, EndPosition, center, LineMovementCode == 2 ? ArcDirection.CW : ArcDirection.CCW); a.FeedRate = f; ToolPath.Add(a); break; } } Position = EndPosition; return ToolPath.Count - 1; }
public void Reset() { DistanceMode = ParseDistanceMode.Absolute; ArcDistanceMode = ParseDistanceMode.Incremental; Units = DistanceUnit.MM; Position = new Vector3(0.0f, 0.0f, 0.0f); }
public void Reset() { DistanceMode = ParseDistanceMode.Absolute; ArcDistanceMode = ParseDistanceMode.Incremental; Unit = DistanceUnit.MM; Position = new Vector3(0.0f, 0.0f, 0.0f); ToolPath = new ToolPath(); LastGCode = -1; }
public ParserState() { Position = new Vector3(); Plane = ArcPlane.XY; DistanceMode = ParseDistanceMode.Absolute; ArcDistanceMode = ParseDistanceMode.Relative; Unit = ParseUnit.Metric; LastMotionMode = -1; }
public ParserState() { Position = new Vector3(); Plane = ArcPlane.XY; Feed = 100; DistanceMode = ParseDistanceMode.Absolute; ArcDistanceMode = ParseDistanceMode.Incremental; Unit = ParseUnit.Metric; LastMotionMode = -1; }
public ParserState() { Position = Vector3.MinValue; PositionValid = new bool[] { false, false, false }; Plane = ArcPlane.XY; Feed = 0; DistanceMode = ParseDistanceMode.Absolute; ArcDistanceMode = ParseDistanceMode.Incremental; Unit = ParseUnit.Metric; LastMotionMode = -1; }
private GCodeCommand ParseLine(MatchCollection matches) { int Command; if (matches[0].Groups[1].Value == "G") { float CommandF = float.Parse(matches[0].Groups[2].Value, inv); Command = (int)CommandF; if (CommandF == 90.1) { ArcDistanceMode = ParseDistanceMode.Absolute; return(null); } if (CommandF == 91.1) { ArcDistanceMode = ParseDistanceMode.Incremental; return(null); } if (CommandF != Command) //All other 'G' commands that have a decimal point { return(new OtherCode(matches)); } LastCommand = Command; } else { if ("XYZIJKR".Contains(matches[0].Groups[1].Value)) { Command = LastCommand; } else { return(new OtherCode(matches)); } } double?X = null, Y = null, Z = null, I = null, J = null, F = null, R = null; for (int index = 0; index < matches.Count; index++) { double value = double.Parse(matches[index].Groups[2].Value, inv); if (Units == DistanceUnit.Inches) { value *= 25.4f; } switch (matches[index].Groups[1].Value) { case "X": X = value; break; case "Y": Y = value; break; case "Z": Z = value; break; case "I": I = value; break; case "J": J = value; break; case "F": F = value; break; case "R": R = value; break; } } Vector3 EndPosition = new Vector3(Position); if (X.HasValue) { EndPosition.X = (DistanceMode == ParseDistanceMode.Absolute) ? (double)X : EndPosition.X + (double)X; } if (Y.HasValue) { EndPosition.Y = (DistanceMode == ParseDistanceMode.Absolute) ? (double)Y : EndPosition.Y + (double)Y; } if (Z.HasValue) { EndPosition.Z = (DistanceMode == ParseDistanceMode.Absolute) ? (double)Z : EndPosition.Z + (double)Z; } switch (Command) { case 0: { Straight s = new Straight(Position, EndPosition, true); if (EndPosition != Position) { Position = EndPosition; return(s); } return(null); } case 1: { Straight s = new Straight(Position, EndPosition, false); s.FeedRate = F; if (EndPosition != Position) { Position = EndPosition; return(s); } return(null); } case 2: case 3: { Vector3 center = new Vector3(Position); if (I.HasValue) { center.X = (ArcDistanceMode == ParseDistanceMode.Absolute) ? (double)I : Position.X + (double)I; } if (J.HasValue) { center.Y = (ArcDistanceMode == ParseDistanceMode.Absolute) ? (double)J : Position.Y + (double)J; } if (R.HasValue) { Vector3 Parallel = EndPosition - Position; Vector3 Perpendicular = Parallel.CrossProduct(new Vector3(0, 0, 1)); double PerpLength = Math.Sqrt(((double)R * (double)R) - (Parallel.Magnitude * Parallel.Magnitude / 4)); if (Command == 3 ^ R < 0) { PerpLength = -PerpLength; } Perpendicular *= PerpLength / Perpendicular.Magnitude; center = Position + (Parallel / 2) + Perpendicular; } Arc a = new Arc(Position, EndPosition, center, Command == 2 ? ArcDirection.CW : ArcDirection.CCW); a.FeedRate = F; Position = EndPosition; return(a); } case 20: Units = DistanceUnit.Inches; return(null); case 21: Units = DistanceUnit.MM; return(null); case 90: DistanceMode = ParseDistanceMode.Absolute; return(null); case 91: DistanceMode = ParseDistanceMode.Incremental; return(null); } return(new OtherCode(matches)); }
private GCodeCommand ParseLine(MatchCollection matches) { if (matches[0].Groups[1].Value != "G") { return(new OtherCode(matches)); } if (matches[0].Groups[2].Value.Contains('.')) { return(new OtherCode(matches)); } int Command = int.Parse(matches[0].Groups[2].Value, inv); float?X = null, Y = null, Z = null, I = null, J = null, F = null, R = null; for (int index = 1; index < matches.Count; index++) { float value = float.Parse(matches[index].Groups[2].Value, inv); if (Units == DistanceUnit.Inches) { value *= 25.4f; } switch (matches[index].Groups[1].Value) { case "X": X = value; break; case "Y": Y = value; break; case "Z": Z = value; break; case "I": I = value; break; case "J": J = value; break; case "F": F = value; break; case "R": R = value; break; } } Vector3 EndPosition = new Vector3(Position); if (X.HasValue) { EndPosition.X = (DistanceMode == ParseDistanceMode.Absolute) ? (float)X : EndPosition.X + (float)X; } if (Y.HasValue) { EndPosition.Y = (DistanceMode == ParseDistanceMode.Absolute) ? (float)Y : EndPosition.Y + (float)Y; } if (Z.HasValue) { EndPosition.Z = (DistanceMode == ParseDistanceMode.Absolute) ? (float)Z : EndPosition.Z + (float)Z; } switch (Command) { case 0: { Straight s = new Straight(Position, EndPosition, true); if (EndPosition != Position) { Position = EndPosition; return(s); } return(null); } case 1: { Straight s = new Straight(Position, EndPosition, false); s.FeedRate = F; if (EndPosition != Position) { Position = EndPosition; return(s); } return(null); } case 2: case 3: { Vector3 center = new Vector3(Position); if (I.HasValue) { center.X = (ArcDistanceMode == ParseDistanceMode.Absolute) ? (float)I : Position.X + (float)I; } if (J.HasValue) { center.Y = (ArcDistanceMode == ParseDistanceMode.Absolute) ? (float)J : Position.Y + (float)J; } if (R.HasValue) { Vector3 Parallel = EndPosition - Position; Vector3 Perpendicular = Parallel.CrossProduct(new Vector3(0, 0, 1)); float PerpLength = (float)Math.Sqrt(((float)R * (float)R) - (Parallel.Magnitude * Parallel.Magnitude / 4)); if (Command == 3 ^ R < 0) { PerpLength = -PerpLength; } Perpendicular *= PerpLength / Perpendicular.Magnitude; center = Position + (Parallel / 2) + Perpendicular; } Arc a = new Arc(Position, EndPosition, center, Command == 2 ? ArcDirection.CW : ArcDirection.CCW); a.FeedRate = F; Position = EndPosition; return(a); } case 20: Units = DistanceUnit.Inches; return(null); case 21: Units = DistanceUnit.MM; return(null); case 90: DistanceMode = ParseDistanceMode.Absolute; return(null); case 91: DistanceMode = ParseDistanceMode.Incremental; return(null); } return(new OtherCode(matches)); }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <returns>index of created movement in toolpath</returns> public int ParseLine(string line) { { //cleanup int commentIndex = line.IndexOfAny(new char[] { ';', '(' }); if (commentIndex >= 0) { line = line.Remove(commentIndex); } if (string.IsNullOrWhiteSpace(line)) { return(-1); } line = line.ToUpperInvariant(); } double?x = null, y = null, z = null, i = null, j = null, r = null, f = null, p = null; int LineMovementCode = -1; MatchCollection matches = GCodeSplitter.Matches(line); foreach (Match match in matches) { char Letter = match.Groups[1].Value[0]; double Arg = double.Parse(match.Groups[2].Value, GCodeCommand.NumberFormat); //no tryparse, the regex should only accept valid numbers (except for out of range) if (Letter == 'M') { if (LineMovementCode != -1) { throw new Exception("GCode with parameters must be the last in a line"); } ToolPath.Add(new MCode(Arg)); continue; } if (Letter == 'G') { if (LineMovementCode != -1) { throw new Exception("GCode with parameters must be the last in a line"); } if (Arg == (int)Arg && (int)Arg <= 4 && (int)Arg >= 0) { LineMovementCode = (int)Arg; LastGCode = LineMovementCode; continue; } if (Arg == 20) { Unit = DistanceUnit.Inches; continue; } if (Arg == 21) { Unit = DistanceUnit.MM; continue; } if (Arg == 90) { DistanceMode = ParseDistanceMode.Absolute; continue; } if (Arg == 90.1) { ArcDistanceMode = ParseDistanceMode.Absolute; continue; } if (Arg == 91) { DistanceMode = ParseDistanceMode.Incremental; continue; } if (Arg == 91.1) { ArcDistanceMode = ParseDistanceMode.Incremental; continue; } continue; //throw new Exception($"Unrecognized GCode 'G{Arg}'"); } if (PositionWords.Contains(Letter)) { if (LineMovementCode == -1) { LineMovementCode = LastGCode; } if (Unit == DistanceUnit.Inches) { Arg *= 25.4; } } if (Letter == 'X') { x = Arg; continue; } if (Letter == 'Y') { y = Arg; continue; } if (Letter == 'Z') { z = Arg; continue; } if (Letter == 'I') { i = Arg; continue; } if (Letter == 'J') { j = Arg; continue; } if (Letter == 'R') { r = Arg; continue; } if (Letter == 'F') { f = Arg; continue; } if (Letter == 'P') { p = Arg; continue; } throw new Exception($"Unrecognized word '{Letter}'"); } if (LineMovementCode == -1) { return(-1); } if (LineMovementCode == 4) { if (p.HasValue) { if ((x ?? y ?? z ?? i ?? j ?? r ?? f) != null) { throw new Exception("Unused word in block"); } ToolPath.Add(new Dwell(p.Value)); } else { throw new Exception("Missing 'P' command word"); } } Vector3 EndPosition = new Vector3(Position); if (x.HasValue) { EndPosition.X = (DistanceMode == ParseDistanceMode.Absolute) ? x.Value : EndPosition.X + x.Value; } if (y.HasValue) { EndPosition.Y = (DistanceMode == ParseDistanceMode.Absolute) ? y.Value : EndPosition.Y + y.Value; } if (z.HasValue) { EndPosition.Z = (DistanceMode == ParseDistanceMode.Absolute) ? z.Value : EndPosition.Z + z.Value; } if (Position == EndPosition) { return(-1); } switch (LineMovementCode) { case 0: { if ((i ?? j ?? r ?? p ?? f) != null) { throw new Exception("Unused word in block"); } Straight s = new Straight(Position, EndPosition, true); ToolPath.Add(s); break; } case 1: { if ((i ?? j ?? r ?? p) != null) { throw new Exception("Unused word in block"); } Straight s = new Straight(Position, EndPosition, false); s.FeedRate = f; ToolPath.Add(s); break; } case 2: case 3: { if (p.HasValue) { throw new Exception("Unused word in block"); } Vector3 center = new Vector3(Position); if (i.HasValue) { center.X = (ArcDistanceMode == ParseDistanceMode.Absolute) ? i.Value : Position.X + i.Value; } if (j.HasValue) { center.Y = (ArcDistanceMode == ParseDistanceMode.Absolute) ? j.Value : Position.Y + j.Value; } if (r.HasValue) { if ((i ?? j).HasValue) { throw new Exception("Both IJ and R notation used"); } Vector3 Parallel = EndPosition - Position; Vector3 Perpendicular = Parallel.CrossProduct(new Vector3(0, 0, 1)); double PerpLength = Math.Sqrt((r.Value * r.Value) - (Parallel.Magnitude * Parallel.Magnitude / 4)); if (LineMovementCode == 3 ^ r.Value < 0) { PerpLength = -PerpLength; } Perpendicular *= PerpLength / Perpendicular.Magnitude; center = Position + (Parallel / 2) + Perpendicular; } if (center == Position) { throw new Exception("Center of arc undefined"); } Arc a = new Arc(Position, EndPosition, center, LineMovementCode == 2 ? ArcDirection.CW : ArcDirection.CCW); a.FeedRate = f; ToolPath.Add(a); break; } } Position = EndPosition; return(ToolPath.Count - 1); }
private GCodeCommand ParseLine(MatchCollection matches) { int Command; if (matches[0].Groups[1].Value == "G") { float CommandF = float.Parse(matches[0].Groups[2].Value, inv); Command = (int)CommandF; if (CommandF == 90.1) { ArcDistanceMode = ParseDistanceMode.Absolute; return null; } if (CommandF == 91.1) { ArcDistanceMode = ParseDistanceMode.Incremental; return null; } if (CommandF != Command) //All other 'G' commands that have a decimal point return new OtherCode(matches); LastCommand = Command; } else { if ("XYZIJKR".Contains(matches[0].Groups[1].Value)) { Command = LastCommand; } else { return new OtherCode(matches); } } float? X = null, Y = null, Z = null, I = null, J = null, F = null, R = null; for (int index = 0; index < matches.Count; index++) { float value = float.Parse(matches[index].Groups[2].Value, inv); if (Units == DistanceUnit.Inches) value *= 25.4f; switch (matches[index].Groups[1].Value) { case "X": X = value; break; case "Y": Y = value; break; case "Z": Z = value; break; case "I": I = value; break; case "J": J = value; break; case "F": F = value; break; case "R": R = value; break; } } Vector3 EndPosition = new Vector3(Position); if (X.HasValue) { EndPosition.X = (DistanceMode == ParseDistanceMode.Absolute) ? (float)X : EndPosition.X + (float)X; } if (Y.HasValue) { EndPosition.Y = (DistanceMode == ParseDistanceMode.Absolute) ? (float)Y : EndPosition.Y + (float)Y; } if (Z.HasValue) { EndPosition.Z = (DistanceMode == ParseDistanceMode.Absolute) ? (float)Z : EndPosition.Z + (float)Z; } switch (Command) { case 0: { Straight s = new Straight(Position, EndPosition, true); if (EndPosition != Position) { Position = EndPosition; return s; } return null; } case 1: { Straight s = new Straight(Position, EndPosition, false); s.FeedRate = F; if (EndPosition != Position) { Position = EndPosition; return s; } return null; } case 2: case 3: { Vector3 center = new Vector3(Position); if (I.HasValue) { center.X = (ArcDistanceMode == ParseDistanceMode.Absolute) ? (float)I : Position.X + (float)I; } if (J.HasValue) { center.Y = (ArcDistanceMode == ParseDistanceMode.Absolute) ? (float)J : Position.Y + (float)J; } if (R.HasValue) { Vector3 Parallel = EndPosition - Position; Vector3 Perpendicular = Parallel.CrossProduct(new Vector3(0, 0, 1)); float PerpLength = (float)Math.Sqrt(((float)R * (float)R) - (Parallel.Magnitude * Parallel.Magnitude / 4)); if (Command == 3 ^ R < 0) PerpLength = -PerpLength; Perpendicular *= PerpLength / Perpendicular.Magnitude; center = Position + (Parallel / 2) + Perpendicular; } Arc a = new Arc(Position, EndPosition, center, Command == 2 ? ArcDirection.CW : ArcDirection.CCW); a.FeedRate = F; Position = EndPosition; return a; } case 20: Units = DistanceUnit.Inches; return null; case 21: Units = DistanceUnit.MM; return null; case 90: DistanceMode = ParseDistanceMode.Absolute; return null; case 91: DistanceMode = ParseDistanceMode.Incremental; return null; } return new OtherCode(matches); }
public void Reset() { DistanceMode = ParseDistanceMode.Absolute; ArcDistanceMode = ParseDistanceMode.Incremental; Units = DistanceUnit.MM; Position = new Vector3(0.0f, 0.0f, 0.0f); LastCommand = -1; }