Exemple #1
0
 public void ParseG29()
 {
     DuetAPI.Commands.Code code = new DuetControlServer.Commands.Code("G29 S1 ; load heightmap");
     Assert.AreEqual(CodeType.GCode, code.Type);
     Assert.AreEqual(29, code.MajorNumber);
     Assert.AreEqual(null, code.MinorNumber);
     Assert.AreEqual(1, code.Parameters.Count);
     Assert.AreEqual('S', code.Parameters[0].Letter);
     Assert.IsTrue(code.Parameter('S', 0) == 1);
 }
Exemple #2
0
        /// <summary>
        /// Parse the header of a G-code file
        /// </summary>
        /// <param name="reader">Stream reader</param>
        /// <param name="partialFileInfo">G-code file information</param>
        /// <returns>Asynchronous task</returns>
        private static async Task ParseHeader(StreamReader reader, ParsedFileInfo partialFileInfo)
        {
            // Every time CTS.Token is accessed a copy is generated. Hence we cache one until this method completes
            CancellationToken token = Program.CancelSource.Token;

            Code code = new Code();
            bool inRelativeMode = false, lastLineHadInfo = false, enforcingAbsolutePosition = false;

            do
            {
                token.ThrowIfCancellationRequested();

                // Read another line
                string line = await reader.ReadLineAsync();

                if (line == null)
                {
                    break;
                }

                // See what codes to deal with
                bool gotNewInfo = false;
                using (StringReader stringReader = new StringReader(line))
                {
                    while (Code.Parse(stringReader, code, ref enforcingAbsolutePosition))
                    {
                        if (code.Type == CodeType.GCode && partialFileInfo.FirstLayerHeight == 0)
                        {
                            if (code.MajorNumber == 91)
                            {
                                // G91 code (relative positioning)
                                inRelativeMode = true;
                                gotNewInfo     = true;
                            }
                            else if (inRelativeMode)
                            {
                                // G90 (absolute positioning)
                                inRelativeMode = (code.MajorNumber != 90);
                                gotNewInfo     = true;
                            }
                            else if (code.MajorNumber == 0 || code.MajorNumber == 1)
                            {
                                // G0/G1 is a move, see if there is a Z parameter present
                                CodeParameter zParam = code.Parameter('Z');
                                if (zParam != null)
                                {
                                    float z = zParam;
                                    if (z <= Settings.MaxLayerHeight)
                                    {
                                        partialFileInfo.FirstLayerHeight = z;
                                        gotNewInfo = true;
                                    }
                                }
                            }
                        }
                        else if (!string.IsNullOrWhiteSpace(code.Comment))
                        {
                            gotNewInfo |= partialFileInfo.LayerHeight == 0 && FindLayerHeight(line, ref partialFileInfo);
                            gotNewInfo |= FindFilamentUsed(line, ref partialFileInfo);
                            gotNewInfo |= string.IsNullOrEmpty(partialFileInfo.GeneratedBy) && FindGeneratedBy(line, ref partialFileInfo);
                            gotNewInfo |= partialFileInfo.PrintTime == 0 && FindPrintTime(line, ref partialFileInfo);
                            gotNewInfo |= partialFileInfo.SimulatedTime == 0 && FindSimulatedTime(line, ref partialFileInfo);
                        }
                        code.Reset();
                    }
                }

                // Is the file info complete?
                if (!gotNewInfo && !lastLineHadInfo && IsFileInfoComplete(partialFileInfo))
                {
                    break;
                }
                lastLineHadInfo = gotNewInfo;
            }while (reader.BaseStream.Position < Settings.FileInfoReadLimitHeader + Settings.FileInfoReadBufferSize);
        }
Exemple #3
0
        /// <summary>
        /// Parse the footer of a G-code file
        /// </summary>
        /// <param name="reader">Stream reader</param>
        /// <param name="partialFileInfo">G-code file information</param>
        /// <returns>Asynchronous task</returns>
        private static async Task ParseFooter(StreamReader reader, ParsedFileInfo partialFileInfo)
        {
            CancellationToken token = Program.CancelSource.Token;

            reader.BaseStream.Seek(0, SeekOrigin.End);

            Code code = new Code();
            bool inRelativeMode = false, lastLineHadInfo = false, hadFilament = partialFileInfo.Filament.Count > 0, enforcingAbsolutePosition = false;

            char[] buffer        = new char[Settings.FileInfoReadBufferSize];
            int    bufferPointer = 0;

            do
            {
                token.ThrowIfCancellationRequested();

                // Read another line
                ReadLineFromEndResult readResult = await ReadLineFromEndAsync(reader, buffer, bufferPointer);

                if (readResult == null)
                {
                    break;
                }
                bufferPointer = readResult.BufferPointer;

                // See what codes to deal with
                bool gotNewInfo = false;
                using (StringReader stringReader = new StringReader(readResult.Line))
                {
                    while (Code.Parse(stringReader, code, ref enforcingAbsolutePosition))
                    {
                        if (code.Type == CodeType.GCode && partialFileInfo.Height == 0)
                        {
                            if (code.MajorNumber == 90)
                            {
                                // G90 code (absolute positioning) implies we were in relative mode
                                inRelativeMode = true;
                                gotNewInfo     = true;
                            }
                            else if (inRelativeMode)
                            {
                                // G91 code (relative positioning) implies we were in absolute mode
                                inRelativeMode = (code.MajorNumber != 91);
                                gotNewInfo     = true;
                            }
                            else if (code.MajorNumber == 0 || code.MajorNumber == 1)
                            {
                                // G0/G1 is an absolute move, see if there is a Z parameter present
                                CodeParameter zParam = code.Parameter('Z');
                                if (zParam != null && (code.Comment == null || !code.Comment.TrimStart().StartsWith("E")))
                                {
                                    gotNewInfo             = true;
                                    partialFileInfo.Height = zParam;
                                }
                            }
                        }
                        else if (!string.IsNullOrWhiteSpace(code.Comment))
                        {
                            gotNewInfo |= partialFileInfo.LayerHeight == 0 && FindLayerHeight(readResult.Line, ref partialFileInfo);
                            gotNewInfo |= !hadFilament && FindFilamentUsed(readResult.Line, ref partialFileInfo);
                            gotNewInfo |= string.IsNullOrEmpty(partialFileInfo.GeneratedBy) && FindGeneratedBy(readResult.Line, ref partialFileInfo);
                            gotNewInfo |= partialFileInfo.PrintTime == 0 && FindPrintTime(readResult.Line, ref partialFileInfo);
                            gotNewInfo |= partialFileInfo.SimulatedTime == 0 && FindSimulatedTime(readResult.Line, ref partialFileInfo);
                        }
                        code.Reset();
                    }
                }

                // Is the file info complete?
                if (!gotNewInfo && !lastLineHadInfo && IsFileInfoComplete(partialFileInfo))
                {
                    break;
                }
                lastLineHadInfo = gotNewInfo;
            }while (reader.BaseStream.Length - reader.BaseStream.Position < Settings.FileInfoReadLimitFooter + buffer.Length);
        }
        private static async Task ParseHeader(SeekableStreamReader reader, ParsedFileInfo partialFileInfo)
        {
            // Every time CTS.Token is accessed a copy is generated. Hence we cache one until this method completes
            CancellationToken token = Program.CancelSource.Token;

            List <float> filamentConsumption = new List <float>();
            bool         inRelativeMode = false, lastLineHadInfo = false;

            do
            {
                token.ThrowIfCancellationRequested();

                string line = await reader.ReadLineAsync();

                if (line == null)
                {
                    break;
                }
                bool gotNewInfo = false;

                // See what code to deal with
                Code code = new Code(line);
                if (code.Type == CodeType.GCode && partialFileInfo.FirstLayerHeight == 0)
                {
                    if (code.MajorNumber == 91)
                    {
                        // G91 code (relative positioning)
                        inRelativeMode = true;
                        gotNewInfo     = true;
                    }
                    else if (inRelativeMode)
                    {
                        // G90 (absolute positioning)
                        inRelativeMode = (code.MajorNumber != 90);
                        gotNewInfo     = true;
                    }
                    else if (code.MajorNumber == 0 || code.MajorNumber == 1)
                    {
                        // G0/G1 is a move, see if there is a Z parameter present
                        CodeParameter zParam = code.Parameter('Z');
                        if (zParam != null)
                        {
                            float z = zParam;
                            if (z <= Settings.MaxLayerHeight)
                            {
                                partialFileInfo.FirstLayerHeight = z;
                                gotNewInfo = true;
                            }
                        }
                    }
                }
                else if (code.Type == CodeType.Comment)
                {
                    gotNewInfo |= partialFileInfo.LayerHeight == 0 && FindLayerHeight(line, ref partialFileInfo);
                    gotNewInfo |= FindFilamentUsed(line, ref filamentConsumption);
                    gotNewInfo |= partialFileInfo.GeneratedBy == "" && FindGeneratedBy(line, ref partialFileInfo);
                    gotNewInfo |= partialFileInfo.PrintTime == 0 && FindPrintTime(line, ref partialFileInfo);
                    gotNewInfo |= partialFileInfo.SimulatedTime == 0 && FindSimulatedTime(line, ref partialFileInfo);
                }

                if (!gotNewInfo && !lastLineHadInfo && IsFileInfoComplete(partialFileInfo))
                {
                    break;
                }
                lastLineHadInfo = gotNewInfo;
            }while (reader.Position < Settings.FileInfoReadLimit);

            foreach (float filament in filamentConsumption)
            {
                partialFileInfo.Filament.Add(filament);
            }
        }
        private static async Task ParseFooter(SeekableStreamReader reader, long length, ParsedFileInfo partialFileInfo)
        {
            CancellationToken token = Program.CancelSource.Token;

            reader.Seek(0, SeekOrigin.End);

            bool         inRelativeMode = false, lastLineHadInfo = false;
            float?       lastZ               = null;
            List <float> filamentConsumption = new List <float>(partialFileInfo.Filament);

            do
            {
                token.ThrowIfCancellationRequested();

                // Read another line
                string line = await ReadLineFromEndAsync(reader);

                if (line == null)
                {
                    break;
                }
                bool gotNewInfo = false;

                // See what code to deal with
                Code code = new Code(line);
                if (code.Type == CodeType.GCode && partialFileInfo.Height == 0)
                {
                    if (code.MajorNumber == 90)
                    {
                        // G90 code (absolute positioning) implies we were in relative mode
                        inRelativeMode = true;
                        gotNewInfo     = true;
                    }
                    else if (inRelativeMode)
                    {
                        // G91 code (relative positioning) implies we were in absolute mode
                        inRelativeMode = (code.MajorNumber != 91);
                        gotNewInfo     = true;
                    }
                    else if (code.MajorNumber == 0 || code.MajorNumber == 1)
                    {
                        // G0/G1 is a move, see if there is a Z parameter present
                        // Users tend to place their own lift Z code at the end, so attempt to read two G0/G1 Z
                        // codes and check the height differene between them
                        CodeParameter zParam = code.Parameter('Z');
                        if (zParam != null && (code.Comment == null || !code.Comment.TrimStart().StartsWith("E")))
                        {
                            gotNewInfo = true;
                            if (lastZ == null)
                            {
                                lastZ = zParam;
                            }
                            else
                            {
                                float z = zParam;
                                if (lastZ - z > Settings.MaxLayerHeight)
                                {
                                    partialFileInfo.Height = z;
                                }
                                else
                                {
                                    partialFileInfo.Height = lastZ.Value;
                                }
                                break;
                            }
                        }
                    }
                }
                else if (code.Type == CodeType.Comment)
                {
                    gotNewInfo |= partialFileInfo.LayerHeight == 0 && FindLayerHeight(line, ref partialFileInfo);
                    gotNewInfo |= FindFilamentUsed(line, ref filamentConsumption);
                    // gotNewInfo |= partialFileInfo.GeneratedBy == "") && FindGeneratedBy(line, ref partialFileInfo);
                    gotNewInfo |= partialFileInfo.PrintTime == 0 && FindPrintTime(line, ref partialFileInfo);
                    gotNewInfo |= partialFileInfo.SimulatedTime == 0 && FindSimulatedTime(line, ref partialFileInfo);
                }

                if (!gotNewInfo && !lastLineHadInfo && IsFileInfoComplete(partialFileInfo))
                {
                    break;
                }
                lastLineHadInfo = gotNewInfo;
            }while (length - reader.Position < Settings.FileInfoReadLimit);

            partialFileInfo.Filament.Clear();
            foreach (float filament in filamentConsumption)
            {
                partialFileInfo.Filament.Add(filament);
            }

            if (lastZ != null && partialFileInfo.Height == 0)
            {
                partialFileInfo.Height = lastZ.Value;
            }
        }
Exemple #6
0
        /// <summary>
        /// Parse the header of a G-code file
        /// </summary>
        /// <param name="reader">Stream reader</param>
        /// <param name="partialFileInfo">G-code file information</param>
        /// <returns>Asynchronous task</returns>
        private static async Task ParseHeader(StreamReader reader, ParsedFileInfo partialFileInfo)
        {
            Code             code             = new Code();
            CodeParserBuffer codeParserBuffer = new CodeParserBuffer(Settings.FileBufferSize, true);

            bool inRelativeMode = false, lastCodeHadInfo = false, gotNewInfo = false;
            long fileReadLimit = Math.Min(Settings.FileInfoReadLimitHeader + Settings.FileBufferSize, reader.BaseStream.Length);

            while (codeParserBuffer.GetPosition(reader) < fileReadLimit)
            {
                Program.CancellationToken.ThrowIfCancellationRequested();
                if (!await DuetAPI.Commands.Code.ParseAsync(reader, code, codeParserBuffer))
                {
                    continue;
                }

                if (code.Type == CodeType.GCode && partialFileInfo.FirstLayerHeight == 0)
                {
                    if (code.MajorNumber == 91)
                    {
                        // G91 code (relative positioning)
                        inRelativeMode = true;
                        gotNewInfo     = true;
                    }
                    else if (inRelativeMode)
                    {
                        // G90 (absolute positioning)
                        inRelativeMode = (code.MajorNumber != 90);
                        gotNewInfo     = true;
                    }
                    else if (code.MajorNumber == 0 || code.MajorNumber == 1)
                    {
                        // G0/G1 is a move, see if there is a Z parameter present
                        CodeParameter zParam = code.Parameter('Z');
                        if (zParam != null)
                        {
                            float z = zParam;
                            if (z <= Settings.MaxLayerHeight)
                            {
                                partialFileInfo.FirstLayerHeight = z;
                                gotNewInfo = true;
                            }
                        }
                    }
                }
                else if (!string.IsNullOrWhiteSpace(code.Comment))
                {
                    gotNewInfo |= (partialFileInfo.LayerHeight == 0) && FindLayerHeight(code.Comment, ref partialFileInfo);
                    gotNewInfo |= FindFilamentUsed(code.Comment, ref partialFileInfo);
                    gotNewInfo |= string.IsNullOrEmpty(partialFileInfo.GeneratedBy) && FindGeneratedBy(code.Comment, ref partialFileInfo);
                    gotNewInfo |= (partialFileInfo.PrintTime == null) && FindPrintTime(code.Comment, ref partialFileInfo);
                    gotNewInfo |= (partialFileInfo.SimulatedTime == null) && FindSimulatedTime(code.Comment, ref partialFileInfo);
                }

                // Is the file info complete?
                if (!gotNewInfo && !lastCodeHadInfo && IsFileInfoComplete(partialFileInfo))
                {
                    break;
                }
                lastCodeHadInfo = gotNewInfo;
                code.Reset();
            }
        }