G code parser

The G code editing function created with the Adventurer3 controller has been extracted and released for independent use.

Source code from Github.


The program is written in C#, and the overall configuration is as follows.

  • rs274ngcparser
    Basic library to analyze G code file structure
  • Translator
    A library for converting various G code files used by FlashPrint, Simplify3D, and Slic3r, which are used by Adventurer3 controller, into formats that can be read by Adventurer3.
  • TranlatorToAdventurer3
    A batch program that makes it possible to use the Adevneture 3 controller G code file change at the command prompt using Translator.
  • CalcGcode
    A sample program that uses rs274ngcparser and implements a function to aggregate data.


Basic library to analyze G code.

ParseGCodeStream is the base class for analysis, and it is the class that implements the ICommandActor interface that actually performs analysis.

LineCommand reads one line from a file and stores the result of analyzing the information of the G code in that line. ICommandActor receives LineCommand and performs various processing.

Basic flow

PlantUML Syntax:</p>
<p>actor program</p>
<p>program-> ParseGCodeStream : Parse(Stream, ICommandActor)</p>
<p>activate ParseGCodeStream</p>
<p>ParseGCodeStream -> ICommandActor : PreAction</p>
<p>alt !Stream.EndOfStream</p>
<p>ParseGCodeStream -> Stream : LineRead</p>
<p>Create LineCommand</p>
<p>ParseGCodeStream -> LineCommand : Parse(LineData)</p>
<p>ParseGCodeStream -> ICommandActor : ActionLine(LineCommand )</p>
<p>ParseGCodeStream -> ICommandActor : PostAction</p>
<p>deactivate ParseGCodeStream</p>


This is a base class for analysis, mainly using Parse method.

In ParseGCodeStream, read one line from the read file, analyze the code such as comments and XYZG in the one line, and construct LineCommand. I pass the LineCommand that I built to ICommandActor.

Readable files are ASCII text files. However, FlashPrint has binary information written at the beginning of the file, so it can not be read correctly if it is passed as it is.

Therefore, since we have prepared a method called SkipXGcode, it is possible to skip the leading binary information and continue the processing by passing it in advance.

So the actual code looks like this:

var actor = new CalcLength(); // This is derived from ICommandActor.
var modifier = new ParseGCodeStream();
modifier.Parse(stream, actor);


Information that analyzes one line of G code file and makes it easy to use.

Comments beginning with ‘;’ are stored in the Comment property, and field information such as “X ????? Y ????” Keep it.

Identifiers and numerical values are managed by the ValuePosition class, and the information held includes the identifier (Key), the value (Value), the position of the field (Position), and the floating point number of digits (FP) .

You can also update ValuePosition data by using the Modify method.


Interface class for describing processing for G code, which is called from ParseGCodeStream.

In actual processing, prepare a class that inherits this interface and write it in it.

As for how to write, please use CalcGcode as a reference. Description of CalcGcode is described separately.


About utility classes.


It holds information on X, Y, Z, E and F related to distances commonly used in G codes. F is slightly different.

Temporarily, each value has the following meaning.

  • X, Y, Z
    Absolute coordinate values for each axis.
    The unit in ValueXYZEF is handled in mm.
  • E
    Filament delivery amount.
    The unit in ValueXYZEF is handled in mm.
  • F
    Information on the speed of movement.
    The unit in ValueXYZEF is handled in mm / min.

In G code, the units and handling of these coordinate values change with G91, G90, G20, and G21.
When G90 / 91 is designated, it indicates that the coordinate values thereafter are indicated by relative coordinates and absolute coordinates. When G20 / 21 is specified, it indicates that the coordinate values after that are indicated in inch mm.

In Value XYZEF, G90 / 91 and G20 / 21 are interpreted, and when G1 is specified, X, Y, Z, E and F are converted and held so as to be an absolute value of mm.

In your own ICommandActor derived class, it is better to hold ValueXYZEF and use it by calling it with PreAction () and ActionLine ().

For example, it feels like the following.

class HogeHoge: ICommandActor {
	ValueXYZEF current_ = new ValueXYZEF();

	public bool ActionLine(LineCommand line) {
		if (current_.ActionLine(line)) {
			// Original processing
			return true;
		return false;

	public void PostAction() {

	public void PreAction() {


A class that holds methods for outputting modified G code information to a file.

String information of LineCommand or ValuePosition with ToString ().

For example, you can use the following to output to the console the same contents as the read line.

public bool ActionLine(LineCommand line) {
	return true;

As for coordinate values, the number of decimal places of ValuePosition is also used. Therefore, it is possible to output, for example, the one described as X 1.00 as X 1.00 without specifying anything.

I think that OutputGCode is often used in the case of outputting the result edited by LineCommand.Modify.

For example, if you add code to correct the information to the above code.

public bool ActionLine(LineCommand line) {
	line.Modify('Z', (x) => x.Value += offsetZ);
	return true;

This is a command to output the result offset to the Z coordinate.


A library holding classes for converting G code files for Adventurer3.

Please refer to Adventurer 3 controller for the processing content.


A class that creates G code files for Adventurer 3 by modifying files generated from FlashPrint and files converted from Slic 3r.

The parameters used at the time of conversion are held in ToAdventurer3Parameter, and temporarily targeted for serialization.


Parameters are prepared as properties.

When deserializing, the check of the set parameter is performed by the Check method. The result of this check is returned in Dictionary <string, string>. The key is the parameter property name, and the setting is an error message.

When serialized in json format, it is output in the following format.


BrimSpeedTypeValue is a brim speed setting method, and it is a selection value equivalent to 0, 1 or 2 not changing, changing by an absolute value, or changing by the ratio of data output in the file.


This is the class used internally. This is for reading and holding information on slice parameters set on the header side of the file when Simplify3D file is read.

In order to use the XY axis movement speed and the Z axis movement speed at the time of data conversion for Adventurer3, we have to remember.


Data transformation body for Adventurer3.

In Modify method, ParseGCodeStream is prepared and converted by itself. After determining the file type in advance, ParseGCodeStream.Parse is performed.

The actual G code editing process is performed from the call from ActionLine.


The Z-axis movement speed in the file of Scli3r is corrected and the data is arranged to be able to pass it to ToAdventurer3.

In addition, Slic3rToBase can be serialized directly, and operation parameters are also held in this class. This was not separated into another class because there was only one parameter.

Here, as with ToAdventurer3, ParseGCodeStream is prepared and converted by itself in the Modify method. In order to read parameters to pass to ToAdventurer 3 in advance.

Unlike Simplify3D, the slice parameter of the file output by Scli3r is in the footer type, so it is read up to that beforehand to obtain the operation parameter, and then ParseGCodeStream.Parse is executed.

The actual G code editing process is performed from the call from ActionLine.

By the way, when serialized in json format, it is output in the following format.


Temporarily, keywords are different, so it can be mixed with parameters for ToAdventurer3 and can be operated with single file.



A batch program to convert G code files for Adventurer3 using ToAdventurer3 and Slic3rToBase of Translator library.

The following two files are input.

  1. G code file created by FlashPrint, Simplify3D, Slic3r.
    However, the file extensions that can be input are fixed at gx and g.

  2. A file with the extension json, which stores the operation parameters.
    The operation parameters are G code parser-3 and the summarized parameters that can be read by ToAdventurer3 and Slic3rToBase.

The file to be output is the file after data editing, and the extension is changed to gout and output.

Internal operation

It works as follows.

  1. If the analysis extension of the input parameter (file name specified by the argument) is gx or g, it is processed as a G code file, and if the extension is json it is processed as a parameter file.

  2. Preload G code files and recognize which slicer the file was created with FlashPrint, Simplify3D, Slic3r. The recognition method is determined by reading the comment at the beginning of the file.

  3. For files created with Slic3r, preprocess with Slic3rToBase. In this process, ToAdventurer3 changes it to a processable file.

  4. Convert to Adventurer3 file format with ToAdventurer3.



This is a sample program using the rs274ngcparser library, and implements the following contents.

  • Total movement of the nozzle.
    The movement amount including the movement when not discharging and the movement of the Z axis is calculated.

  • Total movement time of the nozzle.
    We calculate time based on movement amount and movement speed (information specified by F) and put out the total value.

  • Total amount of filament discharge.

About the difference between the movement time of the nozzle and the actual output time.

The results calculated by this program are, in other words, values close to the time calculated by each slicer.

That means that the calculation algorithm for time with slicer is the same as this program.

The actual output time often results longer than the time output here.

Maybe because of the following reasons.

  • The temperature setting time of the nozzle bed is not taken into consideration.

  • The time until the head comes on the bed can not be calculated For the movement to the XY origin position with the G161 command with the G161 command, and for the first Z-axis movement, the current nozzle position and the coordinates of the movement destination become unknown to the program Can not calculate.

  • The difference between the specified moving speed and the actual moving speed is not included. Perhaps the actual moving speed of the nozzle is slower than the speed specified by the G code. The top speed at the time of movement is designated by F, but it may be a little slower due to acceleration and deceleration near the start and end points. As a result, I think that the actual output time will increase compared to the calculated output time.

Internal operation

Total amount of filament discharge.

Since the value of E is reset by the G92 command, when E becomes 0 in G92, the value of E up to that point is stocked, and the total value is calculated by postAction.

Total movement of the nozzle.

If there is a G1 command, it is determined that XYZ is moved, and the distance to the current position is calculated from the previous XYZ value, and a total value is obtained.

Total movement time of the nozzle.

After the movement amount of the nozzle is determined, the movement time is calculated from the value of F at that time, and the total value is calculated.


Project for unit testing of library


The parser I made this time does not have the specs of rs274ngc properly, and has been created with reference to past experience (I have programmed with the spec rs-274x) and G-code-RepRap.

Therefore, there may be a problem in the specification of rs274ngc, but I will consider it even then.

By the way, the processing itself that rs274ngc interprets has been quite old, and has been issued by NIST.

If you are interested please refer to that.

The NIST RS274NGC Interpreter – Version 3