[SOLVED] How do I display the object size in the GCode header

QCAD/CAM Version: 3.32.6

With some help from here, I can now add time, source and some other details in the header of the generated G-code:

this.header = [
“( [DATE_TIME] )”,
“( Generated with: [INFILENAME])”,
“( Tool diameter: [TD] mm )”,
“( Cutting depth: [ZD] mm )”,

];

I also like to add the object size, since I have a large number of small items that can be cut from small pieces of scrap.

I can display the variables X_MIN, X_MAX, Y_MIN, Y_MAX but what I like to display is something like:

Object size: X <X_MAX-X_MIN> Y <Y_MAX-Y_MIN>

I know little about javascript programming and finally spend 2 hours with ChatGPT, which generated a lot of useless code, never anything that indicated the X and Y envelope.

What is the way to calculate the numeric value of X_MAX - X_MIN etc and display it in the header?

Thanks, Rob

Hi,
Per example:
The variable [XߺMIN] to use in block code is registered as ‘xMin’ at script level (GCodeBase).
You address that as ‘this.xMin’ at script level.

delta X & delta Y would be 2 new registered values to use in block code for exporting G-Code:

this.deltaX = 0;
this.deltaY = 0;
...
..
.
this.registerVariable("deltaX",       "DELTAߺX",           false,  "",  "DEFAULT", "DEFAULT");
this.registerVariable("deltaY",       "DELTAߺY",           false,  "",  "DEFAULT", "DEFAULT");


In your writeFile function you can do the math before a file is exported:

this.deltaX = this.xMax - this.xMin;
this.deltaY = this.yMax - this.yMin;


Use this in your header block as for example:

...
"(Size in X: [DELTAߺX] mm )",
"(Size in Y: [DELTAߺY] mm )",
...


Avoid an ending comma in your G-Code blocks.
Such a block is an JS-script array […] with items (strings) separated by commas.
The last item would be Null or an undefined string.

Note: Replace the (special) underscores with a normal underscore.
A normal underscore seems to be start-stop formatting as Italic for me. :wink:

I don’t know of any AI bot that is well trained to write scripts based on the QCAD API.
Nor bots that are trained to write code for QCAD/CAM.
To start with: The CAM plugin is proprietary and not really documented.

Regards,
CVH

Thanks CVH,

The code runs but it does not calculate:

include("LinuxCNCOffsetMM.js");

function MyLinuxCNCOffsetMM(cadDocumentInterface, camDocumentInterface) {
    LinuxCNCOffsetMM.call(this, cadDocumentInterface, camDocumentInterface);

    this.decimals = 4;
    this.unit = RS.Millimeter;

    // register variable for date and time:
    this.dateTime = undefined;
    this.deltaX = 0;
    this.deltaY = 0;
    this.registerVariable("dateTime", "DATE_TIME", true, "",  0);
    this.registerVariable("deltaX", "DELTA_X", false,  "",  "DEFAULT", "DEFAULT");
    this.registerVariable("deltaY", "DELTA_Y", false,  "",  "DEFAULT", "DEFAULT");

    this.header = [
      "( [DATE_TIME] )",
      "( Generated with: [INFILENAME])",
      "( Tool diameter: [TD] mm )",
      "( Cutting depth: [ZD] mm )",
      "( Size parameters: [X_MIN], [X_MAX], [Y_MIN], [Y_MAX])",
      "( new vars defined: [DELTA_X], [DELTA_Y])"
        ];
}

MyLinuxCNCOffsetMM.prototype = new LinuxCNCOffsetMM();

MyLinuxCNCOffsetMM.displayName = "MyLinuxCNC (Offset) [mm]";

MyLinuxCNCOffsetMM.prototype.writeFile = function(fileName) {
    // init date / time variable:
    var today = new Date();
    this.dateTime = formatDate(today, "dd/MMM/yyyy hh:mm:ss");
    // init size calculation
    this.deltaX = this.xMax - this.xMin;
    this.deltaY = this.yMax - this.yMin;

    LinuxCNCOffsetMM.prototype.writeFile.call(this, fileName);
};

Output:

( Thu 21 May 2026 14:42:14 CEST )
( Generated with: test1.dxf)
( Tool diameter: 4 mm )
( Cutting depth: Z-4 mm )
( Size parameters: -2, 102, -2, 92)
( new vars defined: 0, 0)
N10 G10 L1 P1 R2
N20 G0 Z10
N30 G0 X0 Y-2
N40 T1 M6
N50 S5000 M03
N60 G0 Z2
N70 G1 Z-4 F600
N80 G2 X-2 Y0 I0 J2 F300
N90 G1 Y90
N100 G2 X0 Y92 I2 J0
N110 G1 X100
N120 G2 X102 Y90 I0 J-2
N130 G1 Y0
N140 G2 X100 Y-2 I-2 J0
N150 G1 X0
N160 Z2
N170 G0 Z10
N180 M30

Meaning that the size parameters are defined when writeHeader is executed …
… But not yet when (EDIT: before) writeFile is executed.

You could attempt to include the subtractions in the writeHeader function.

/**
 * Override to write the file header to the output file.
 */
MyLinuxCNCOffsetMM.prototype.writeHeader = function() {
    this.deltaX = this.xMax - this.xMin;
    this.deltaY = this.yMax - this.yMin;

    // Write regular header as defined in this.header variable:
    this.writeBlock("header");
};


Regards,
CVH

Further investigation reveals that calculating the extents is part of the original writeFile function.
This should also do the trick:

/**
 * Writes the output to the output file through the chosen configuration file (e.g. GCode.js).
 */
MyLinuxCNCOffsetMM.prototype.writeFile = function(fileName) {
    // Init date / time variable:
    var today = new Date();
    this.dateTime = formatDate(today, "dd/MMM/yyyy hh:mm:ss");

    // Call the standard implementation:
    // Delegated to CamExporterV2
    LinuxCNCOffsetMM.prototype.writeFile.call(this, fileName);

    // Init size variable:
    this.deltaX = this.xMax - this.xMin;
    this.deltaY = this.yMax - this.yMin;
};


Regards,
CVH

I’d recommend to override initExtents instead:

MyLinuxCNCOffsetMM.prototype.initExtents = function() {
    // this initializes this.xMin, this.xMax, ...:
    LinuxCNCOffsetMM.prototype.initExtents.call(this);

    // now we can compute the sizes:
    this.deltaX = this.xMax - this.xMin;
    this.deltaY = this.yMax - this.yMin;
}

Note that QCAD/CAM does not know your actual material or workpiece size. xMin/xMax and yMin/yMax are based on the maximum extents of all the toolpaths you have created.

I understand this better now.
writeFile will fully export the G-Code to an new file.
Including the first header up to the last footer.
The calculations would then be done too late.

initExtents is the most logical place (Now that we are aware of this)

Am I correct that the writeHeader method should work too?

Regards,
CVH

CVH, I tried it once without result, but not knowing anything about javascript, I might have misplaced the block. But thanks a lot for your help.

Andrew, thanks for your support, this works. I understand that it does not describe the actual size, but knowing the envelope defines the minimum rectangle in which the object can be cut.

(I have a lot of small projects that all have a number in their filename but created on my laptop or in one of two desktops, with many revised cuts. It is messy, but now all .nc files are sucked up by a backend synology. And the goal is to sort them by project number and date)

include("LinuxCNCOffsetMM.js");

function MyLinuxCNCOffsetMM(cadDocumentInterface, camDocumentInterface) {
    LinuxCNCOffsetMM.call(this, cadDocumentInterface, camDocumentInterface);

    this.decimals = 4;
    this.unit = RS.Millimeter;

    // register variable for date and time:
    this.dateTime = undefined;
    this.registerVariable("dateTime", "DATE_TIME", true, "",  0);
    this.deltaX = 0;
    this.deltaY = 0;
    this.registerVariable("deltaX", "DELTA_X", false,  "",  "DEFAULT", "DEFAULT");
    this.registerVariable("deltaY", "DELTA_Y", false,  "",  "DEFAULT", "DEFAULT");

    this.header = [
      "( [DATE_TIME] )",
      "( Generated with: [INFILENAME])",
      "( Tool diameter: [TD] mm )",
      "( Cutting depth: [ZD] mm )",
      "( Object envelope: X [DELTA_X], Y [DELTA_Y])"
        ];
}

MyLinuxCNCOffsetMM.prototype = new LinuxCNCOffsetMM();

MyLinuxCNCOffsetMM.displayName = "MyLinuxCNC (Offset) [mm]";

MyLinuxCNCOffsetMM.prototype.initExtents = function() {
    // this initializes this.xMin, this.xMax, ...:
    LinuxCNCOffsetMM.prototype.initExtents.call(this);

    // now we can compute the sizes:
    this.deltaX = this.xMax - this.xMin;
    this.deltaY = this.yMax - this.yMin;
}

MyLinuxCNCOffsetMM.prototype.writeFile = function(fileName) {

    // init date / time variable:
    var today = new Date();
    this.dateTime = formatDate(today, "dd/MMM/yyyy hh:mm:ss");

    LinuxCNCOffsetMM.prototype.writeFile.call(this, fileName);
};

Result:
( Fri 22 May 2026 11:31:30 CEST )
( Generated with: test1.dxf)
( Tool diameter: 4 mm )
( Cutting depth: Z-4 mm )
( Object envelope: X 104, Y 94)
N10 G10 L1 P1 R2
N20 G0 Z10

etc…