Tutorial: QCAD/CAM Postprocessor

Table of Contents

 

QCAD/CAM can export CAD drawings to various formats used in CAM (computer-aided manufacturing). These formats can be dialects of G-Code or other, completely different formats. Each supported CAM format is defined in a configuration file (or "postprocessor") which is an ECMAScript (JavaScript) file that implements the format details. All available configurations are stored inside the directory postprocessors. New format implementations can be added to the same location.

Basic Structure

Each configuration file contains an ECMAScript class with the same name as the script file. If the script file is called MyGCode.js, the class defined inside the script must be called MyGCode.

The ECMAScript class must derive directly or indirectly from class CamExporterV2, which is defined by QCAD/CAM. CamExporterV2 defines the basic structure of CAM exporter configuration classes. Various methods in CamExporterV2 are called to export the file header, the various entities in the CAD drawing and the footer. CamExporterV2 also takes care of the various features of QCAD/CAM, for example tool radius compensation, lead in / lead out, cutting inner contours before outer contours, path optimization, etc.

CamExporterV2 does not output anything by itself, but would produce an empty file on its own. CamExporterV2 offers a text stream (QTextStream) to write to the exported file. This text stream is exposed through the member variable this.stream.

If the desired output is a G-Code dialect (e.g. G1 X10 Y20 for a linear movement), the configuration can be derived from the existing configuration for G-Code called GCodeBase, which is defined in file GCodeBase.js. This is the case for most machine controllers. One such example configuration for outputting G-Code in Millimeters is defined in file GCodeMM.js and available in the user interface as the configuration called G-Code (G41/G42) [mm].

Deriving a Configuration from GCodeBase

Create a file with a unique name of your choice. For this example, we call our new configuration MyGCode and store it in a file with the same name, i.e. MyGCode.js under directory postprocessors of your QCAD/CAM installation.

You can use your favourite plain text editor to create and write the file, for example Notepad under Windows, TextEdit under macOS or vim, Emacs, etc. under Linux systems.

MyGCode.js must define a class called MyGCode to be a valid configuration for QCAD/CAM. While there are strictly speaking no classes in ECMAScript, we can create a similar concept by attaching functions to the prototype object of a constructor function. How this works exactly is beyond the scope of this documentation. However, there is a straightforward template you can use for all configuration files.

For our example, the definition of the class MyGCode looks like this (note that lines starting with // are comments and are not required):

// Include GCodeBase.js which contains the class 'GCodeBase', used as base for our own configuration:
include("GCodeBase.js");

// Constructor of our class:
function MyGCode(documentInterface, newDocumentInterface) {
// Call constructor of base class:
GCodeBase.call(this, documentInterface, newDocumentInterface);
}

// Derive our class from class GCodeBase:
MyGCode.prototype = new GCodeBase();

// Display name shown in user interface:
MyGCode.displayName = "My G-Code";

Now, we have a created a new, fully working configuration called "My G-Code" which is ready to be used in QCAD/CAM and produces basic G-Code. 

Configuration Preferences

The constructor we defined above calls the constructor of our base class GCodeBase. In the constructor, we can set some parameters for our configuration such as the desired output unit or if we want to use G41/G42 for tool radius compensation or calculate the center of the tool path.

To configure the output unit (that's the unit expected by your machine or controller), we can set the member variable unit to Inch or Millimeter, for example:

this.unit = RS.Inch;

or

this.unit = RS.Millimeter;

Other settings that can be configured in the constructor are:

Variable: Possible Values: Default: Description:
this.outputOffsetPath
true or false false Set to true to calculate tool radius compensation instead of using G41/G42.
this.lineNumber
Number 10  Initial number used for line numbering (N...).
this.lineNumberIncrement
Number 10 Line number incrementation from line to line.
this.fileExtensions
Array  [ "nc", "cnc" ] List of file extensions the user can choose from when exporting through this post processor.

A complete constructor might look like this:

function MyGCode(documentInterface, newDocumentInterface) {
GCodeBase.call(this, documentInterface, newDocumentInterface);
    this.unit = RS.Inch;
this.outputOffsetPath = true;
this.lineNumber = 1;
this.lineNumberIncrement = 1;
}

Defining the G-Code Output

Code Blocks

G-Code output is structured into code blocks which are written to the output file when using the CAM export function in QCAD/CAM. For example, the first code block that is written is the code block "header". Each code block is defined in a member variable that identifies it by name, for example "this.header" contains the code block for the file header.

Code blocks can be overridden to contain any code / text. Code blocks typically contain variables to output the current X/Y coordinates, line number, feedrate, etc.

Let's say a single line is exported to G-Code. The line is exported with tool radius compensation to the left of the line (G41). The code blocks that are written to the output file are as follows:

Code block Description Example output
header
Header of the output (always the first code block). G21 G17 G90 G40 G49 G80
 rapidMoveZ
Rapid move to safety level. G0 Z100
 rapidMove
Rapid move to the first position of the first contour (here the start of the lead in for the line). G0 X5 Y10
 toolHeader
First block when a new tool comes into action (tool change). T1
  rapidMoveZ
Rapid move down to clearance level (hovering above material). G0 Z5
  firstLinearMoveZ
Cutting into material at plunge rate. G1 Z-5 F50
  toolpathHeader
First block of a new toolpath.  
   contourHeader
First block of a new contour within a toolpath.   
    singleZPassHeader
Header for single Z pass. We're cutting the whole depth in a single pass.   
     zPassFirstHeader
First header of single or multiple Z passes.   
      linearMoveCompensationLeft
Linear move to start point of the line along lead in, switching the tool radius compensation on.  G41 X10 Y10 F500
      linearMove
Linear move along the line to the end point of the line. X30 Y10
      linearMoveCompensationOff
Linear move away from end point along lead out, switching the tool radius compensation off. G40 X35 Y10
     zPassLastFooter
Last footer of single or several Z passes.  
    singleZPassFooter
Footer for single Z pass.  
   contourFooter
End of contour.  
  toolpathFooter
End of toolpath.  
  linearMoveZ
Move out of material to clearance level. Z5
  rapidMoveZ
Move to safety level. G0 Z100
 toolFooter
End for this tool.  
footer
End of program. M30

Many of these code blocks are typically unused and produce no output (empty code block).

Variables

Member variable Variable name Description
inputFileName INFILENAME Input file name (e.g. DXF file).
inputFilePath INFILEPATH Input file name with complete path.
fileName FILENAME Output file name.
filePath FILEPATH Output file name with complete path. 
dateTime DATETIME Date and time of export. 
lineNumber N Current line number.
spindleSpeed S Spindle speed, typically rpm. 
feedRate F Feedrate. 
plungeRate FP Plunge rate. 
xHomePosition XH Home position as configured in CAM configuration. 
yHomePosition YH  
zHomePosition ZH  
zSafety ZS Z safety level for tool changes and start / end. 
zClearance ZU Z clearance level for approaching the material. 
zClearancePass ZUP Z clearance level between multiple passes. 
zCuttingDepth ZD Z cutting level (total). 
xFirstPosition XF First position of first contour in first toolpath. 
yFirstPosition YF  
xStartPosition X1 Start of entity (start point of line / arc).
yStartPosition Y1  
zStartPosition Z1  
xPosition X Current target position. End point of the current line / arc.
yPosition Y  
zPosition Z  
xRelPosition XR Current target position as relative coordinate, relative to start point. 
yRelPosition YR  
zRelPosition ZR  
iArcCenterInc I Center of arc, relative to start point. 
jArcCenterInc J  
iArcCenterAbs IA Center of arc, absolute. 
jArcCenterAbs JA  
arcRadius RADIUS Radius of arc. 
arcDiameter DIAMETER Diameter of arc. 
arcSweep SWEEP Sweep of arc (angle covered by arc in rad, negative for clockwise). 
tool T Current tool. 
toolRadius TR Tool radius. 
toolDiameter TD Tool diameter. 
toolpathOrder TOOLPATH_ORDER Toolpath order in list of toolpaths, starting with 0 for the first toolpath. 
toolCalls TOOL_CALLS Number of times this tool has been used.
toolpathName TOOLPATH_NAME Name of current toolpath (user defined). 
programName PROGRAM_NAME Program name as configured by user in CAM configuration. 
xMin X_MIN Minimum extents of drawing. 
yMin Y_MIN  
zMin Z_MIN  
xMax X_MAX Maximum extents of drawing. 
yMax Y_MAX  
zMax Z_MAX  

 

Examples

Changing the Header and Footer

To add or change G-Codes or M-Codes or other information in the header or footer, a configuration can override the member variables header and footer in the constructor, for example as follows:

this.header = [
"[N] G0 Z100"
];
this.footer = [
"[N] G0 Z100",
"[N] M30"
];

Absolute I/J

To use absolute values for I/J values for the center of arcs, you can override the arc code blocks as follows:

this.firstArcCWMove = "[N] G2 [X] [Y] [IA] [JA] [F]";
this.arcCWMove = "[N] G2 [X] [Y] [IA] [JA] [F]";

this.firstArcCCWMove = "[N] G3 [X] [Y] [IA] [JA] [F]";
this.arcCCWMove = "[N] G3 [X] [Y] [IA] [JA] [F]";