2 TPLang
2.1 About TPLang
TPLang (Tool Path Language) is a programming language that makes toolpaths for CNC machines. A TPLang program is a JavaScript program. TPLang adds functions that move the tool, set the feed rate, select tools and do other machine operations.
The output of a TPLang program is G-code. CAMotics reads this G-code in the same way as a G-code file that you write yourself. Thus, you can use all of JavaScript to calculate a toolpath: variables, loops, functions, objects and the Math object.
The authority for the language is tplang.org. This chapter tells how TPLang operates in CAMotics Online. Where CAMotics Online is different from the desktop version, this chapter tells you.
TPL files have the extension .tpl. In the project file list, a TPL file is a program, the same as a G-code file.
2.2 How a TPL program runs
When you update the toolpath, the server runs each TPL program in the project file list. The server runs the programs in a sandbox. The sandbox has no network connection and no access to other files on the server.
- The server starts the program at the first line.
- Each move function, for example
cut(), writes one or more lines of G-code. - When the program ends, the server reads the G-code that the program made.
- CAMotics makes the toolpath from this G-code, together with the other programs in the project.
The G-code always starts with G21 G90 (millimeters, absolute positions) and ends with M2. CAMotics writes all positions in millimeters, also when the program uses inches.
If the program has an error, the toolpath stops. CAMotics shows the error message with the file name and the line number. Errors in a module that you load with require() show the line in that module.
The JavaScript engine is V8. Thus, you can use modern JavaScript, for example let, const, arrow functions and template strings.
2.3 A first program
This program cuts a square of 10 mm by 10 mm, 3 mm deep. Each line has a comment that tells what it does.
units(METRIC); // Use millimeters
feed(400); // Set the feed rate to 400 mm/min
tool(1); // Select tool 1 from the tool table
rapid({z: 5}); // Move up to a safe height of 5 mm
rapid({x: 1, y: 1}); // Move to the start position
speed(2000); // Turn the spindle clockwise at 2000 RPM
cut({z: -3}); // Cut down to the depth
cut({x: 11}); // Cut to the second corner
cut({y: 11}); // Cut to the third corner
cut({x: 1}); // Cut to the fourth corner
cut({y: 1}); // Cut back to the start
rapid({z: 5}); // Move up to the safe height
speed(0); // Stop the spindleTo run this program, do these steps:
- Click Open as a project above the program.
- Update the toolpath.
- Simulate the toolpath.
2.4 Functions and arguments
Most TPLang functions have named arguments. You can give the arguments in two ways:
- In order, as in JavaScript:
rapid(5, 10, 15). - As an object with the names of the arguments:
rapid({x: 5, y: 10, z: 15}).
With an object, you can give only the arguments that you need, in any order. The other arguments keep their default values. These three calls do the same thing:
rapid(5, 10, 15);
rapid({x: 5, y: 10, z: 15});
rapid({z: 15, x: 5, y: 10});The reference gives the arguments of each function, with their names, types and default values.
2.5 Units
A TPL program starts in metric units. In metric units, lengths are in millimeters and feed rates are in millimeters per minute.
To use inches, call units(IMPERIAL). After this call, all lengths that you give and all positions that you get are in inches. Feed rates are in inches per minute. To go back to millimeters, call units(METRIC).
When you read a DXF or STL file, the numbers in the file have no units. Use the units that the file was drawn in. For example, if the drawing is in millimeters, call units(METRIC) before you cut it.
2.6 Coordinates and positions
TPLang uses the same axes as G-code. The linear axes are X, Y and Z. The rotary axes are A, B and C. U, V and W are secondary linear axes. All move functions accept the nine axes x, y, z, a, b, c, u, v and w.
Positions are absolute: cut({x: 10}) moves the tool to X = 10. An axis that you do not give stays at its current position.
The functions irapid() and icut() use incremental positions. icut({x: 10}) moves the tool 10 units in the positive X direction from its current position. You can also give incremental: true to rapid() or cut().
To get the current position, use position(). It returns an object with the nine axes, for example {x: 1, y: 1, z: -3, a: 0, ...}. This is the position in the program's coordinates, before the transforms.
A program starts at position 0 on all axes.
2.7 The tool and the tool table
The project has a tool table. Each tool in the table has a number, a shape, a diameter and a length. Edit the tool table in the project settings.
To select a tool, call tool(number). This writes M6 Tn to the G-code. The simulation uses the shape of this tool from the tool table.
tool() also returns the data of the tool from the tool table. With no argument, it returns the data of the current tool. Use this data to calculate offsets from the tool size:
tool(1);
var radius = tool().diameter / 2;If the tool table does not have the tool, tool() returns undefined.
2.8 Feed rate and spindle speed
The feed rate is the speed of the tool in cut moves. Set it with feed(rate). The feed rate stays the same until you set it again.
The spindle speed is in revolutions per minute (RPM). Set it with speed(rate). A positive speed turns the spindle clockwise (M3). A negative speed turns it counterclockwise (M4). A speed of zero stops the spindle (M5).
feed(600); // 600 mm/min
speed(12000); // 12000 RPM, clockwise2.9 Rapid moves and cut moves
A rapid move (rapid(), G0) moves the tool at the maximum speed of the machine. Use rapid moves only when the tool is out of the material.
A cut move (cut(), G1) moves the tool in a straight line at the feed rate. Use cut moves when the tool is in the material.
A typical pattern is:
- Move up to a safe height with
rapid({z: zSafe}). - Move above the start point with
rapid(x, y). - Move down into the material with
cut({z: zCut}). - Cut along the shape with
cut(),icut()orarc(). - Move up to the safe height with
rapid({z: zSafe}).
2.10 Arcs and helixes
The arc() function moves the tool on an arc or a full circle at the feed rate. If you give a Z offset, the move is a helix.
The arguments x and y give the position of the center, relative to the current position. The angle argument gives the angle of rotation in radians. Math.PI * 2 is one full turn.
feed(300);
rapid({z: 3});
rapid(-5, 0); // The center of the hole is at (0, 0)
cut({z: 0});
// Three turns down to Z = -3, then one turn at Z = -3
arc({x: 5, z: -3, angle: Math.PI * 2 * 3});
arc({x: 5, angle: Math.PI * 2});
rapid({z: 3});A positive angle makes a clockwise arc (G2). A negative angle makes a counterclockwise arc (G3). To cut part of a circle, calculate the points and use cut() for each point:
// A quarter circle, counterclockwise, radius 10, center (0, 0)
var steps = 30;
for (var i = 0; i <= steps; i++) {
var a = Math.PI / 2 * i / steps;
cut(10 * Math.cos(a), 10 * Math.sin(a));
}2.11 Transforms
A transform changes the positions of all moves that come after it. With transforms, you can write a shape one time and cut it at different positions, angles and sizes.
translate(x, y, z)moves the origin of the moves.rotate(angle)turns the moves about the Z axis through the current origin. A positive angle turns counterclockwise.scale(x, y, z)makes the moves larger or smaller.
The transforms add to each other. To go back to an earlier transform, save it with pushMatrix() and restore it with popMatrix():
function square(size, depth, safe) {
cut({z: depth}); // Cut down to the depth
icut({x: size}); // Cut to the second corner
icut({y: size}); // Cut to the third corner
icut({x: -size}); // Cut to the fourth corner
icut({y: -size}); // Cut back to the start
rapid({z: safe}); // Move up to the safe height
}
feed(400);
tool(1);
rapid({z: 5});
for (var i = 0; i < 12; i++) {
pushMatrix(); // Save the transform
rotate(Math.PI * 2 * i / 12);
translate(5, 0);
rapid(0, 0);
square(10, -1, 5);
popMatrix(); // Restore the transform
}Some rules tell how the transforms add to each other:
translate()moves the origin in the current coordinates. If you callrotate()beforetranslate(), the translation turns too.rotate()turns about an axis through the current origin. To turn about a different point, give that point in the argumentsa,bandc.scale()changes all distances from the machine origin, also the distances thattranslate()set before or after it.
The transforms change the G-code positions. They do not change the positions that you give or get in the program: position() and getXYZ() return the positions before the transform.
2.12 Offsets
The offset() function makes a polygon larger or smaller by a distance. It uses the Clipper library. Use it to calculate a toolpath at the correct distance from a shape, or to make a pocket.
A polygon is an array of points. A point is {x: 1, y: 2} or [1, 2]. offset() takes an array of polygons and returns an array of polygons. A positive distance makes the polygons larger. A negative distance makes them smaller. If the distance is too large, the result is an empty array.
This program cuts a square pocket. It cuts the outline of the pocket, then smaller outlines until nothing is left.
var zSafe = 3;
var depth = -2;
var step = 1.5; // Less than the tool diameter
var outline = [[{x: 0, y: 0}, {x: 30, y: 0}, {x: 30, y: 20},
{x: 0, y: 20}]];
feed(500);
tool(1);
rapid({z: zSafe});
// The first path is half the tool diameter inside the outline
var polys = offset(outline, -tool().diameter / 2);
while (polys.length) {
for (var poly of polys) {
rapid({z: zSafe});
rapid(poly[0].x, poly[0].y);
cut({z: depth});
for (var p of poly) cut(p.x, p.y);
cut(poly[0].x, poly[0].y); // Close the polygon
}
polys = offset(polys, -step);
}
rapid({z: zSafe});2.13 DXF files
A DXF file is a 2D drawing. To read a DXF file, load the dxf module with require('dxf'). Then call dxf.open(path).
- Add the DXF file to the project.
- In the TPL program, load the module:
var dxf = require('dxf'); - Read the file:
var layers = dxf.open('drawing.dxf'); - Cut a layer with a function of the module, for example
dxf.layer_cut().
dxf.open() returns an object with one property for each layer of the drawing. The name of the property is the name of the layer. Each layer is an array of the entities in that layer: points, lines, arcs, polylines and splines.
var dxf = require('dxf');
var layers = dxf.open('logo.dxf');
units(METRIC); // Use the units of the drawing
feed(1600);
rapid({z: 3});
// Cut the layer "Outline" 1.5 mm deep, 0.5 mm outside the lines
dxf.cut_layer_offset(layers.Outline, 0.5, 3, -1.5);
rapid({z: 3});The dxf module has functions that cut layers, change layers to polygons and offset them. See the DXF reference.
2.14 STL files
An STL file is a 3D surface made of triangles. Load the stl module with require('stl') and read a file with stl.open(path).
The module calculates contours: the lines where a horizontal plane cuts the surface. Use the contours to cut a 3D shape in layers.
var stl = require('stl');
var model = stl.open('part.stl');
var bounds = stl.bounds(model); // [[minX, minY, minZ], [maxX, maxY, maxZ]]
var levels = stl.contour({stl: model, start: bounds[1][2],
end: bounds[0][2], steps: 20});
feed(400);
for (var level of levels)
for (var c of level.contours) {
rapid({z: level.Z + 1});
rapid(c[0].X, c[0].Y);
cut({z: level.Z});
for (var p of c) cut(p.X, p.Y);
}STL files can be large. A large file can make the program slow or use too much memory. See Limits.
2.15 G-code in a TPL program
You can put G-code into a TPL program in two ways:
gcode(path)reads a G-code file from the project and runs it.gexec(code)runs the G-code in a string.
CAMotics reads the G-code and writes the moves again in its own format. It does not copy the G-code text. Thus, the codes that CAMotics does not run are lost. See the G-code chapter.
gexec('G0 X0 Y0');
gcode('engrave.nc');2.16 Modules
A module is a file of code or data that a program loads with require(). Use modules to share functions between programs.
A module can be:
- A
.tplor.jsfile. CAMotics runs the code. The module gives its values to the program inmodule.exports. - A
.jsonfile. CAMotics reads the data. - A directory with a
package.jsonfile. Themainproperty ofpackage.jsongives the file to load.
For example, a module shapes.tpl:
module.exports = {
square: function (size) {
icut({x: size}); icut({y: size});
icut({x: -size}); icut({y: -size});
}
};A program loads it with a path that starts with ./:
var shapes = require('./shapes.tpl');
shapes.square(10);In CAMotics Online, require() loads only these modules:
- Files in the project, with a path that starts with
./. - The modules of CAMotics:
dxfandstl, and the TPL library that comes with CAMotics.
If modules load each other in a loop, a value can be undefined while a module loads. See tplang.org for an example.
2.17 Comments, messages and the log
comment(text)writes a G-code comment, for example(Pocket 1).message(text)writes a G-code message,(MSG, text).console.warn()andconsole.error()write a warning. CAMotics shows it with the file name and the line number.console.log()andconsole.debug()write to the log. CAMotics Online does not show the log.
2.18 Limits
CAMotics Online sets limits on a TPL program. These limits stop a program that does not end or that is too large.
| Limit | Default value | What occurs |
|---|---|---|
| G-code lines | 50 000 000 lines | The program stops with the error "TPL program exceeded the limit of ... G-code lines". |
| Memory | 512 MB for JavaScript | The program stops with the error "TPL program ran out of memory". |
| Time | Set by the server | The job stops. |
| Files | Only the project and the TPL library | The function stops with the error "only files in the project and the TPL library are allowed". |
The server can use different values. A program that stops at a limit makes no toolpath.
2.19 Reference: tool movement
2.19.1 rapid()
rapid(x, y, z, a, b, c, u, v, w, incremental=false)Moves the tool in a straight line at the rapid speed (G0).
| Name | Type | Default | Description |
|---|---|---|---|
x … w | number | current position | The position on that axis. Give only the axes that move. |
incremental | boolean | false | If true, the values are distances from the current position. |
Returns nothing. If a value is not a finite number, the program stops with an error.
rapid(0, 0, 0); // Move to x = 0, y = 0, z = 0
rapid(10, 10); // Move to x = 10, y = 10; z stays at 0
rapid({z: 10, y: 20}); // Move to y = 20, z = 10; x stays at 102.19.2 irapid()
irapid(x, y, z, a, b, c, u, v, w, incremental=true)The same as rapid(), but the values are distances from the current position.
irapid({z: 5}); // Move up 5 units2.19.3 cut()
cut(x, y, z, a, b, c, u, v, w, incremental=false)Moves the tool in a straight line at the feed rate (G1). The arguments are the same as for rapid().
| Name | Type | Default | Description |
|---|---|---|---|
x … w | number | current position | The position on that axis. |
incremental | boolean | false | If true, the values are distances from the current position. |
Returns nothing.
feed(400);
cut({z: -1}); // Move down into the material
cut(20, 0); // Cut to x = 20, y = 02.19.4 icut()
icut(x, y, z, a, b, c, u, v, w, incremental=true)The same as cut(), but the values are distances from the current position.
icut({x: 10}); // Cut 10 units in the +X direction
icut({y: -5}); // Cut 5 units in the -Y direction2.19.5 arc()
arc(x=0, y=0, z=0, angle=Math.PI*2, plane=XY, incremental=true)Moves the tool on an arc or a helix at the feed rate (G2 or G3). See Arcs and helixes.
| Name | Type | Default | Description |
|---|---|---|---|
x, y | number | 0 | The center of the arc, relative to the current position. |
z | number | 0 | The change in height. If it is not zero, the move is a helix. |
angle | number (radians) | Math.PI * 2 | The angle of rotation. Positive is clockwise (G2). Negative is counterclockwise (G3). More than one turn is permitted. |
plane | constant | XY | The plane of the arc: XY, XZ or YZ. |
incremental | boolean | true | If false, x, y and z give the absolute position of the center. |
Returns nothing.
rapid(-10, 0);
cut({z: -1});
arc({x: 10, angle: Math.PI * 2}); // A circle of radius 10 about (0, 0)2.19.6 probe()
probe(x, y, z, a, b, c, u, v, w, port=0, active=true, error=true)Moves the tool toward a position until the probe input changes. On a real machine, this measures the position of the workpiece.
| Name | Type | Default | Description |
|---|---|---|---|
x … w | number | current position | The position to move to. |
port | number | 0 | The input to monitor. |
active | boolean | true | If true, stop on contact. If false, stop when the contact is lost. |
error | boolean | true | If true, it is an error if the input does not change. |
Returns nothing.
feed(100);
probe({z: -10}); // Move down until the probe touches2.19.7 dwell()
dwell(seconds)Stops all axes for a time (G4). The spindle continues to turn.
| Name | Type | Default | Description |
|---|---|---|---|
seconds | number | none | The time to wait, in seconds. Fractions are permitted. |
Returns nothing.
speed(10000);
dwell(2); // Wait 2 seconds for the spindle to get to its speed2.20 Reference: machine state
2.20.1 feed()
feed(rate, mode)Sets the feed rate for the cut moves that come after it (F).
| Name | Type | Default | Description |
|---|---|---|---|
rate | number | none | The feed rate, in units per minute. |
mode | constant | no change | FEED_UNITS_PER_MIN (G94), FEED_INVERSE_TIME (G93) or FEED_UNITS_PER_REV (G95). |
Returns the feed rate. With no arguments, it does not change the feed rate and returns [rate, mode].
In FEED_INVERSE_TIME mode, each move takes 1/rate minutes. In FEED_UNITS_PER_REV mode, the rate is in units per revolution of the spindle.
feed(400); // 400 units per minute
var rate = feed()[0]; // Get the feed rate2.20.2 speed()
speed(rate, surface, max)Sets the spindle speed and direction (S with M3, M4 or M5).
| Name | Type | Default | Description |
|---|---|---|---|
rate | number | none | Revolutions per minute. Positive is clockwise, negative is counterclockwise, zero stops the spindle. |
surface | any | none | If you give it, the speed is a constant surface speed (G96): rate is in meters per minute (metric) or feet per minute (imperial). |
max | number | none | With surface: the maximum RPM. |
Returns the speed. With no arguments, it returns [rate, mode], and the maximum RPM if there is one.
speed(1000); // 1000 RPM, clockwise
speed(-20000); // 20000 RPM, counterclockwise
speed(0); // Stop the spindle2.20.3 tool()
tool(number)Selects a tool from the tool table (M6 Tn).
| Name | Type | Default | Description |
|---|---|---|---|
number | number | none | The tool number. With no number, the current tool does not change. |
Returns the data of the tool, or undefined if the tool table does not have the tool:
| Property | Description |
|---|---|
number | The tool number. |
shape | CYLINDRICAL, CONICAL, BALLNOSE, SPHEROID or SNUBNOSE. |
length | The length of the tool, in the current units. |
diameter | The diameter of the tool, in the current units. |
angle | Only for CONICAL: the angle of the point, in degrees. |
snub_diameter | Only for SNUBNOSE: the diameter of the tip. |
tool(2);
var radius = tool().diameter / 2;2.20.4 units()
units(type)Sets the units of the program.
| Name | Type | Default | Description |
|---|---|---|---|
type | constant | none | METRIC (millimeters) or IMPERIAL (inches). |
With no argument, it returns the current units, METRIC or IMPERIAL. See Units.
units(IMPERIAL);
if (units() == IMPERIAL) feed(20);2.20.5 pause()
pause(optional=false)Stops the program until the operator starts it again (M0, or M1 if optional).
| Name | Type | Default | Description |
|---|---|---|---|
optional | boolean | false | If true, the machine stops only when its optional stop switch is on. |
Returns nothing.
pause(); // Stop here so that the operator can turn the workpiece2.20.6 workpiece()
workpiece()Returns the dimensions and the position of the workpiece from the project settings, in the current units:
var w = workpiece();
// {dims: {x: 100, y: 100, z: 10}, offset: {x: -50, y: -50, z: -10}}offset is the corner of the workpiece with the minimum X, Y and Z.
2.20.7 position()
position()Returns the current position as an object: {x, y, z, a, b, c, u, v, w}. The position is before the transforms.
var p = position();
cut(p.x + 10, p.y);2.21 Reference: transforms
The transform functions have an optional last argument matrix. It selects the transform of a group of axes: 0 for X, Y and Z (the default), 1 for A, B and C, 2 for U, V and W.
2.21.1 pushMatrix()
pushMatrix(matrix)Saves a copy of the current transform. popMatrix() restores it. You can save more than one transform.
pushMatrix();
translate(50, 0);
cutShape();
popMatrix(); // The origin is back at (0, 0)2.21.2 popMatrix()
popMatrix(matrix)Restores the transform that the last pushMatrix() saved. If no transform is saved, the program stops with the error "Transform stack empty".
2.21.3 loadIdentity()
loadIdentity(matrix)Removes all transforms from the current transform. The saved transforms do not change.
2.21.4 translate()
translate(x=0, y=0, z=0, matrix)Moves the origin of the moves that come after it.
| Name | Type | Default | Description |
|---|---|---|---|
x, y, z | number | 0 | The distance to move the origin. |
translate(20, 10);
cut(0, 0); // Cuts to (20, 10)2.21.5 rotate()
rotate(angle, x=0, y=0, z=1, a=0, b=0, c=0, matrix)Turns the moves that come after it about an axis.
| Name | Type | Default | Description |
|---|---|---|---|
angle | number (radians) | none | The angle. Positive is counterclockwise when you look from the positive end of the axis. |
x, y, z | number | 0, 0, 1 | The direction of the axis. The default is the Z axis. |
a, b, c | number | 0, 0, 0 | A point on the axis, in the current coordinates. |
If the direction is (0, 0, 0), the program stops with an error.
rotate(Math.PI / 2); // Turn 90 degrees counterclockwise about Z
cut(10, 0); // Cuts to (0, 10)2.21.6 scale()
scale(x=1, y=1, z=1, matrix)Makes the moves that come after it larger or smaller. The scale applies from the machine origin.
| Name | Type | Default | Description |
|---|---|---|---|
x, y, z | number | 1 | The scale on each axis. A negative value mirrors that axis. Zero is not permitted. |
scale(2, 2); // Two times larger in X and Y
scale(-1); // Mirror in X2.21.7 setMatrix()
setMatrix(m, matrix)Sets the current transform to the 4 × 4 matrix m, an array of four rows of four numbers.
setMatrix([[1, 0, 0, 5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]);2.21.8 getMatrix()
getMatrix(matrix)Returns the current transform as an array of four rows of four numbers.
var m = getMatrix(); // [[1, 0, 0, 0], [0, 1, 0, 0], ...]2.21.9 getXYZ()
getXYZ()Returns the current position of X, Y and Z as an array [x, y, z], before the transforms.
2.21.10 getX(), getY(), getZ()
getX()
getY()
getZ()Each returns the current position on one axis, before the transforms.
cut({z: getZ() - 1}); // Cut 1 unit deeper2.22 Reference: G-code and output
2.22.1 gcode()
gcode(path)Reads a G-code file and runs it. The path is relative to the TPL file. The file must be in the project.
gcode('engrave.nc');2.22.2 gexec()
gexec(code)Runs the G-code in a string.
gexec('G0 X100 Y200');2.22.3 comment()
comment(...)Writes each argument as a G-code comment on its own line.
comment('Pocket 1'); // (Pocket 1)2.22.4 message()
message(...)Writes each argument as a G-code message, (MSG, text). Some machine controllers show the message to the operator.
message('Change to tool 2');2.22.5 print()
print(...)Writes the arguments as text.
2.22.6 console.log(), console.warn()
console.log(...)
console.debug(...)
console.warn(...)
console.error(...)Writes the arguments to the log. CAMotics Online shows the output of console.warn() and console.error() as warnings, with the file name and the line number. It does not show the output of console.log() and console.debug().
console.warn('The depth is', depth);2.23 Reference: offsets and modules
2.23.1 offset()
offset(polys, delta, join, limit=1000, autoFix=true, scale=1000000)Makes polygons larger or smaller. See Offsets.
| Name | Type | Default | Description |
|---|---|---|---|
polys | array | none | An array of polygons. Each polygon is an array of points, {x, y} or [x, y]. |
delta | number | none | The distance. Positive makes the polygons larger, negative makes them smaller. |
join | constant | JOIN_ROUND | The shape of the corners: JOIN_ROUND, JOIN_MITER or JOIN_SQUARE. |
limit | number | 1000 | With JOIN_MITER: the maximum distance of a corner. |
autoFix | boolean | true | Corrects the direction of the polygons and removes points that are the same. |
scale | number | 1000000 | Clipper calculates with integers. The points are multiplied by this value. |
Returns an array of polygons, in the same point format as polys.
var square = [[[0, 0], [10, 0], [10, 10], [0, 10]]];
var inside = offset(square, -1); // [[[9, 9], [1, 9], [1, 1], [9, 1]]]2.23.2 require()
require(path)Loads a module and returns its module.exports. See Modules.
| Name | Type | Default | Description |
|---|---|---|---|
path | string | none | 'dxf', 'stl', a module of the TPL library, or a project file with a path that starts with ./. The extension .tpl, .js or .json is optional. |
var dxf = require('dxf');
var lib = require('./lib.tpl');2.24 Reference: DXF module
Load the module with var dxf = require('dxf');. The functions below are the ones that you use most. The module has more functions; see the file tpl_lib/dxf/dxf.tpl in the CAMotics source.
In this module, a polygon is an array of points {x, y, z}. A layer is an array of entities from dxf.open().
2.24.1 dxf.open()
dxf.open(path)Reads a DXF file. The path is relative to the TPL file. Returns an object with one array of entities for each layer. Each entity has a type:
| Type | Properties |
|---|---|
dxf.POINT | x, y, z |
dxf.LINE | start, end: points |
dxf.ARC | center: a point; radius; startAngle, endAngle: in degrees; clockwise |
dxf.POLYLINE | vertices: an array of points |
dxf.SPLINE | degree; ctrlPts: an array of points; knots: an array of numbers |
var layers = dxf.open('drawing.dxf');
var outline = layers.Outline; // The layer "Outline"
var first = layers[0]; // A layer with the name "0"2.24.2 dxf.layer_cut()
dxf.layer_cut(layer, zSafe, zCut, res)Cuts along all entities of a layer. It starts with the entity that is nearest to the tool and goes to the next nearest entity. Between entities that do not touch, it moves up to zSafe.
| Name | Type | Default | Description |
|---|---|---|---|
layer | array | none | The entities to cut. |
zSafe | number | none | The safe height. |
zCut | number | none | The depth of the cut. |
res | number | 1 mm | The length of the segments for splines. |
dxf.layer_cut(layers[0], 3, -1.5);2.24.3 dxf.layer_cut_step()
dxf.layer_cut_step(layer, zSafe, zCut, maxZStep, res)The same as dxf.layer_cut(), in more than one pass. Each pass cuts at most maxZStep deeper than the pass before it.
dxf.layer_cut_step(layers[0], 3, -6, 2); // Three passes, 2 mm each2.24.4 dxf.layer_to_polys()
dxf.layer_to_polys(layer)Changes the entities of a layer to polygons. Entities that touch become one polygon. Arcs become straight segments. Returns an array of polygons.
2.24.5 dxf.offset_polys()
dxf.offset_polys(polys, delta)Applies offset() to each polygon. Returns an array of polygons.
2.24.6 dxf.cut_polys()
dxf.cut_polys(polys, zSafe, zCut, zFeed, close=true, leadin=0, cut_cb)Cuts polygons. It starts with the polygon that is nearest to the tool.
| Name | Type | Default | Description |
|---|---|---|---|
polys | array | none | The polygons to cut. |
zSafe | number | none | The safe height. If you do not give it, the tool does not move up between polygons. |
zCut | number | none | The depth of the cut. |
zFeed | number | current feed rate | The feed rate to move down to zCut. |
close | boolean | true | Cuts back to the first point of each polygon. |
leadin | number | 0 | Starts each polygon at this distance inside it. |
cut_cb | function | none | Called with true before and false after each polygon. |
2.24.7 dxf.cut_layer_offset()
dxf.cut_layer_offset(layer, delta, zSafe, zCut=0, steps=1, zFeed, close, leadin, cut_cb)Changes a layer to polygons, offsets them by delta and cuts them in steps passes down to zCut. The other arguments are the same as for dxf.cut_polys().
// Cut 0.5 mm outside the lines, 1.5 mm deep
dxf.cut_layer_offset(layers.Outline, 0.5, 3, -1.5);2.24.8 dxf.cut_layer()
dxf.cut_layer(layer, config)Cuts the polygons of a layer with a ramp down into the material. It can leave tabs that hold the part.
Property of config | Default | Description |
|---|---|---|
delta | 0 | The offset of the polygons. |
zSafe | 5 | The safe height. |
zStart | 0 | The height where the ramp starts. |
zEnd | 0 | The final depth. |
zMax | 3 | The maximum depth of one pass. |
zSlope | 1/3 | The slope of the ramp. |
tabs | [] | The tabs: each one has ratio (position on the path, 0 to 1) or position, and height. |
dxf.cut_layer(layers.Outline, {zEnd: -6, tabs: [{ratio: 0.25, height: 2}]});2.24.9 dxf.layer_bounds()
dxf.layer_bounds(layer)
dxf.layer_center(layer)
dxf.layer_dims(layer)dxf.layer_bounds() returns the box around a layer: {min: {x, y, z}, max: {x, y, z}}. dxf.layer_center() returns the center of this box. dxf.layer_dims() returns its size.
var c = dxf.layer_center(layers[0]);
translate(-c.x, -c.y); // Put the center of the drawing at the origin2.25 Reference: STL module
Load the module with var stl = require('stl');.
2.25.1 stl.open()
stl.open(path)Reads an STL file. The path is relative to the TPL file. Returns {name, hash, facets}. Each facet is an array of three corner points and a normal, each [x, y, z].
2.25.2 stl.bounds()
stl.bounds(stl)Returns the box around the model: [[minX, minY, minZ], [maxX, maxY, maxZ]].
2.25.3 stl.contour()
stl.contour(stl, level, start, end, steps)Calculates the contours of the model: the closed lines where a horizontal plane cuts the surface.
| Name | Type | Default | Description |
|---|---|---|---|
stl | object | none | The model from stl.open(). |
level | number | none | One Z height. |
start, end | number | none | The first and the last Z height of a series. |
steps | number | none | The number of heights in the series, at least 2. |
With level, it returns an array of contours. Each contour is an array of points {X, Y}. With start, end and steps, it returns an array of {Z, contours}, one for each height.
var model = stl.open('part.stl');
var contours = stl.contour({stl: model, level: -2});2.26 Reference: constants
| Constant | Use |
|---|---|
METRIC, IMPERIAL | The units for units(). |
XY, XZ, YZ | The plane for arc(). Also UV, UW, VW. |
FEED_UNITS_PER_MIN, FEED_INVERSE_TIME, FEED_UNITS_PER_REV | The feed mode for feed(). |
CYLINDRICAL, CONICAL, BALLNOSE, SPHEROID, SNUBNOSE | The tool shapes that tool() returns. |
JOIN_SQUARE, JOIN_ROUND, JOIN_MITER | The corners for offset(). |
X_MIN, X_MAX … W_MIN, W_MAX, PROBE, FLOOD, MIST | The ports of the machine, for the port of probe(). |
dxf.POINT, dxf.LINE, dxf.ARC, dxf.POLYLINE, dxf.SPLINE | The entity types of dxf.open(). |
2.26.1 Math
JavaScript has a Math object with mathematical functions and constants, for example Math.PI, Math.sin(), Math.cos(), Math.sqrt(), Math.abs(), Math.min() and Math.max(). Angles are in radians.
var r = 10;
cut(r * Math.cos(Math.PI / 4), r * Math.sin(Math.PI / 4));