コード例 #1
1
ファイル: GCodeParser.cs プロジェクト: martin2250/CNCTool
        /// <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;
        }
コード例 #2
0
ファイル: Arc.cs プロジェクト: martin2250/CNCTool
        public override IEnumerable<Movement> Split(double length)
        {
            if (Length <= length)
            {
                yield return this;
                yield break;
            }
            else
            {
                int divisions = (int)Math.Ceiling(Length / length);

                Vector3 start = new Vector3(Start);

                for (int i = 0; i < divisions; i++)
                {
                    Vector3 end = Interpolate(((double)i + 1) / divisions);

                    Arc a = new Arc(start, end, Center, Direction);

                    if (i == 0)
                        a.FeedRate = FeedRate;

                    start = end;

                    yield return a;
                }
            }
        }