Skip to content

The Simple API

The QCAD Simple API is a small set of global script functions that simplify common tasks such as adding entities to a drawing, querying entities and modifying them (moving, trimming, rounding, offsetting, …). It is mainly designed for use in the Script Shell and for short procedural scripts that are run from a file, but it can be used from any script.

The Simple API covers only a small part of the complete QCAD API. Since it is written in ECMAScript (JavaScript) itself, it is also a good starting point to learn how the underlying QCAD API works. The source code can be found in the files scripts/simple.js and scripts/simple_*.js of the QCAD source code.

In the Script Shell (Misc > Development > Script Shell) and in scripts launched with Misc > Development > Run Script, all Simple API functions are available directly. Type for example:

addLine(0,0, 100,100);

In your own script files, for example in interactive script actions or command line tools, include the file simple.js first:

include("scripts/simple.js");
addLine(0,0, 100,100);

All functions operate on the drawing that is currently open in the QCAD application window, unless a transaction is used to redirect them to another document (see Transactions).

All examples on this page can be pasted into the Script Shell of an empty drawing. Each example creates the entities it needs. Use View > Auto Zoom or the function autoZoom() to see the result.

Positions can be passed in three different ways:

  • As two separate numbers: addLine(0,0, 100,100)
  • As an array of two numbers: addLine([0,0], [100,100])
  • As vector object: addLine(new RVector(0,0), new RVector(100,100))

Angles are always given in degrees, except for the start and end parameters of ellipses which are given in radians.

Functions that work with an existing entity accept the entity in various forms:

  • An entity ID (number), for example 1234.
  • An entity object as returned by the creation functions, for example the return value of addLine(...).
  • A position in the drawing ([x,y] or RVector): the entity closest to the given position is used.
  • A shape (for example new RLine(0,0, 100,0)): the operation is applied to the shape only, the drawing is not changed.
var l = addLine(0,0, 100,0);
move(l, [0,10]); // by entity object
move(l.getId(), [0,10]); // by entity ID
move([50,20], [0,10]); // by position: the entity closest to 50,20

Some operations depend on where an entity is clicked when using the equivalent tool interactively. Trimming keeps the part of the entity at the click position, rounding and beveling round the ends of the entities closest to the click positions and offsetting creates parallels on the side of the click position.

In the Simple API, a click position may follow every entity reference. If an entity is referenced by a position, that position also serves as click position. If no click position is given, the middle point of the entity is used:

var line = addLine(0,0, 100,0);
var limit = addLine(70,-20, 70,20);
// trim line to limit, keep the part of the line at 10,0:
trim(line, [10,0], limit);
  • Creation functions return the added entity. The entity can be passed to other functions or queried for information (for example getId(), getLength() or getStartPoint()).
  • Transformations (move, rotate, scale, mirror, lengthen, reverse) return the modified entity.
  • Other modification functions (trim, round, bevel, offset, breakOut, autoTrim, divide, explode, stretch) return the transaction that was applied to the drawing or undefined if the operation failed.
  • If shapes are passed instead of entities, transformations modify the given shapes and all other functions return the resulting shapes as an array.

Failed operations do not raise an error. Instead, a warning is shown in the Script Shell, for example “Entity cannot be trimmed.”.

addPoint(x, y)
addPoint([x, y])

Adds a point entity at the given position.

for (var i=0; i<10; i++) {
addPoint(i*10, 0);
}
addLine(x1, y1, x2, y2)
addLine([x1, y1], [x2, y2])

Adds a line from the start point to the end point.

// a triangle:
addLine(0,0, 100,0);
addLine(100,0, 50,80);
addLine(50,80, 0,0);
addXLine(x, y, dx, dy)
addXLine([x, y], [dx, dy])

Adds an infinite line (construction line) through the base point x,y with the direction dx,dy. The direction is given relative to the base point.

// horizontal and 45 degree construction lines through 0,0:
addXLine(0,0, 1,0);
addXLine([0,0], [1,1]);
addArc(cx, cy, radius, startAngle, endAngle)
addArc(cx, cy, radius, startAngle, endAngle, reversed)
addArc([cx, cy], radius, startAngle, endAngle, reversed)

Adds an arc with the given center, radius, start angle and end angle. Angles are in degrees. Arcs run counterclockwise from the start angle to the end angle unless reversed is true (optional, default is false).

// quarter arc from 0 to 90 degrees:
addArc(0,0, 50, 0, 90);
// clockwise arc from 0 to 90 degrees (the other three quarters):
addArc([0,0], 40, 0, 90, true);
addCircle(cx, cy, radius)
addCircle([cx, cy], radius)

Adds a circle with the given center and radius.

// concentric circles:
for (var r=10; r<=50; r+=10) {
addCircle(0,0, r);
}
addEllipse(cx, cy, mx, my, ratio, startParam, endParam, reversed)
addEllipse([cx, cy], [mx, my], ratio, startParam, endParam, reversed)

Adds an ellipse or elliptical arc. mx,my is the end point of the major axis, relative to the center. ratio is the ratio between the minor and the major axis. startParam and endParam are the ellipse parameters in radians where the ellipse starts and ends. Use 0 and 2*Math.PI for a full ellipse.

// full ellipse with a major radius of 50 and a minor radius of 25:
addEllipse(0,0, 50,0, 0.5, 0, 2*Math.PI, false);
// upper half of a rotated ellipse:
addEllipse([0,0], [30,30], 0.3, 0, Math.PI, false);
addPolyline(points, closed, relative)

Adds a polyline through the given vertices. points is an array of vertices, each given as [x, y], [x, y, bulge] or [x, y, bulge, relative]. Instead of x, y, an RVector can be used.

  • bulge defines the shape of the segment that starts at this vertex: 0 (default) for a straight segment, 1 for a half circle counterclockwise, -1 for a half circle clockwise. Other values create arc segments in between (the bulge is the tangent of a quarter of the arc angle).
  • relative: true if the coordinates of this vertex are relative to the previous vertex.
  • closed: true to close the polyline (default is false).
  • relative: true to treat the coordinates of all vertices as relative to the previous vertex (default is false).
// closed rectangle:
addPolyline([[0,0], [100,0], [100,50], [0,50]], true);
// slot shape with two half circles:
addPolyline([[0,60], [80,60,1], [80,80], [0,80,1]], true);
// zigzag line with relative coordinates:
addPolyline([[0,100], [10,10], [10,-10], [10,10], [10,-10]], false, true);
addSpline(fitPoints, closed)

Adds a spline through the given fit points. fitPoints is an array of [x, y] arrays or RVector objects. If closed is true, the spline is closed (periodic).

// open spline:
addSpline([[0,0], [30,40], [60,0], [90,40]], false);
// closed spline:
addSpline([[0,60], [40,80], [80,60], [40,100]], true);

The tutorial Running Scripts from a File shows another example that plots a Lissajous curve as spline.

addSimpleText(text, x, y)
addSimpleText(text, x, y, height, angle, font, vAlign, hAlign, bold, italic)
addSimpleText(text, [x, y], height, angle, font, vAlign, hAlign, bold, italic)

Adds a single line text at the given position. All arguments after the position are optional:

  • height: text height (default 1)
  • angle: text angle in degrees (default 0)
  • font: font name (default "Standard")
  • vAlign: vertical alignment: RS.VAlignTop (default), RS.VAlignMiddle, RS.VAlignBase or RS.VAlignBottom
  • hAlign: horizontal alignment: RS.HAlignLeft (default), RS.HAlignCenter or RS.HAlignRight
  • bold, italic: true for bold or italic text (TrueType fonts only)
addSimpleText("Hello World", 0,0);
addSimpleText("Title", [0,20], 10);
addSimpleText("Centered", [50,-20], 5, 0, "Standard", RS.VAlignMiddle, RS.HAlignCenter);
addSimpleText("Rotated", 100,0, 5, 45);
addSolid(x1, y1, x2, y2, x3, y3, x4, y4)
addSolid([x1, y1], [x2, y2], [x3, y3], [x4, y4])

Adds a solid fill area with three or four corners. Note that the corners of a four sided solid are given in a zigzag order: first corner, second corner, then the corner opposite the second corner and the corner opposite the first corner. To create a triangle, pass the third corner twice.

// filled square:
addSolid(0,0, 50,0, 0,50, 50,50);
// filled triangle:
addSolid([60,0], [110,0], [85,50], [85,50]);

The following functions add objects that were created with the full QCAD API to the drawing. They are useful when the specialized creation functions above do not cover a certain case.

addShape(shape)
addShape(shape, color, linetype, lineweight)

Adds the given shape (RLine, RArc, RCircle, REllipse, RPolyline, RSpline, RPoint, …) as new entity on the current layer. Optionally, a color (RColor), linetype (name or ID) and lineweight (for example RLineweight.Weight050) can be given. By default, the current color, linetype ByLayer and lineweight ByLayer are used.

addShape(new RLine(new RVector(0,0), new RVector(100,0)));
addShape(new RCircle(new RVector(50,0), 20), new RColor("red"));
addShape(new RLine(new RVector(0,-20), new RVector(100,-20)), new RColor("blue"), "DASHED", RLineweight.Weight050);
addShapes(shapes)

Adds all shapes in the given array as new entities.

var shapes = [];
for (var i=0; i<5; i++) {
shapes.push(new RCircle(new RVector(i*20, 0), 8));
}
addShapes(shapes);
addEntity(entity)
addEntity(entity, color, linetype, lineweight)

Adds the given entity (REntity) to the drawing. If no color is given, the current color is used.

var doc = getDocument();
var data = new RLineData(new RVector(0,0), new RVector(100,50));
var entity = new RLineEntity(doc, data);
addEntity(entity);
addObject(object)

Adds any object (entity, layer, block, …) to the drawing and returns the added object.

// add a block called "Marker" with a cross in it:
var doc = getDocument();
var block = addObject(new RBlock(doc, "Marker", new RVector(0,0)));
var l1 = new RLineEntity(doc, new RLineData(new RVector(-5,0), new RVector(5,0)));
l1.setBlockId(block.getId());
addEntity(l1);
var l2 = new RLineEntity(doc, new RLineData(new RVector(0,-5), new RVector(0,5)));
l2.setBlockId(block.getId());
addEntity(l2);
// insert the block twice:
addEntity(new RBlockReferenceEntity(doc, new RBlockReferenceData(block.getId(), new RVector(0,0), new RVector(1,1), 0.0)));
addEntity(new RBlockReferenceEntity(doc, new RBlockReferenceData(block.getId(), new RVector(50,0), new RVector(2,2), 0.0)));
deleteObject(object)

Deletes the given object from the drawing. To delete entities, the function deleteEntity is usually more convenient.

var line = addLine(0,0, 100,0);
deleteObject(line);
addLayer(name)
addLayer(name, color, linetype, lineweight)

Adds a new layer with the given name. Optionally, the color name (default "white", which is displayed black on a white background), linetype name (default "CONTINUOUS") and lineweight (default RLineweight.Weight000) can be given. Returns the new layer or undefined if a layer with the given name already exists.

addLayer("Construction", "gray", "DASHED");
addLayer("Contour", "blue", "CONTINUOUS", RLineweight.Weight050);
hasLayer(name)

Returns true if a layer with the given name exists in the drawing.

if (!hasLayer("Holes")) {
addLayer("Holes", "red");
}
setCurrentLayer(name)

Sets the current layer. All entities added afterwards are placed on this layer.

addLayer("Holes", "red");
setCurrentLayer("Holes");
addCircle(0,0, 5);
addCircle(50,0, 5);
setCurrentLayer("0");
setCurrentColor(color)
setCurrentColor(r, g, b)

Sets the color for entities that are added afterwards. The color can be given as RColor object or as red, green, blue values (0-255). Use new RColor(RColor.ByLayer) to reset the color to “By Layer”.

setCurrentColor(255, 0, 0);
addCircle(0,0, 10);
setCurrentColor(new RColor("blue"));
addCircle(30,0, 10);
setCurrentColor(new RColor(RColor.ByLayer));
addCircle(60,0, 10);
getEntity(id)
getEntity(entity)
getEntity(x, y)
getEntity([x, y])

Returns the entity for the given entity reference, i.e. the entity with the given ID, the current state of the given entity or the entity closest to the given position. Returns undefined if no entity is found.

var circle = addCircle(0,0, 20);
move(circle, [10,0]);
// circle still holds the old center, getEntity returns the current state:
getEntity(circle).getCenter(); // returns 10,0
// entity closest to 30,0:
getEntity(30,0).getRadius(); // returns 20
getShape(id)
getShape(entity)
getShape(x, y)
getShape([x, y])

Returns the geometry of the given entity as shape (RLine for a line, RArc for an arc, RPolyline for a polyline, …). Shapes can be used for geometric calculations without changing the drawing.

addPolyline([[0,0], [100,0], [100,50]], false);
var pl = getShape(50,0);
pl.getLength(); // returns 150
getClosestEntity(x, y)
getClosestEntity([x, y], range)

Returns the entity closest to the given position. If range is given, only entities within that distance of the position are considered. Returns undefined if no entity is found.

addLine(0,0, 100,0);
addLine(0,50, 100,50);
getClosestEntity(50,10).getStartPoint(); // returns 0,0
getClosestEntity([50,25], 5); // returns undefined
getEntityShape(entity, position)

Returns the shape of the given entity object. For complex entities that consist of multiple shapes (block references, hatches, dimensions, texts), the shape closest to the given position is returned. The position is optional.

// a block reference of a block with a rectangle:
var doc = getDocument();
var block = addObject(new RBlock(doc, "Box", new RVector(0,0)));
var pl = new RPolylineEntity(doc, new RPolylineData());
pl.setShape(new RPolyline([new RVector(0,0), new RVector(40,0), new RVector(40,20), new RVector(0,20)], true));
pl.setBlockId(block.getId());
addEntity(pl);
var ref = addEntity(new RBlockReferenceEntity(doc, new RBlockReferenceData(block.getId(), new RVector(0,0), new RVector(1,1), 0.0)));
// shape of the block reference near 40,10 (the rectangle):
var s = getEntityShape(getEntity(ref), new RVector(41,10));
s.getLength(); // returns 120
getIntersectionPoints(entity1, entity2)
getIntersectionPoints(entity1, entity2, limited)

Returns an array with the intersection points of the two given entities or shapes. Entities can be given as entity objects, entity IDs or shapes. If limited is false, the entities are treated as if they were infinite (lines extended, arcs as full circles). Default is true.

var line = addLine(-50,0, 50,0);
var circle = addCircle(0,0, 30);
var ips = getIntersectionPoints(line, circle);
// mark the intersections with small circles:
for (var i=0; i<ips.length; i++) {
addCircle(ips[i], 2);
}
isPosition(value)
toVector(value)

isPosition returns true if the given value is a position (RVector or array of two or three numbers). toVector converts a position given as array to an RVector. These functions are useful when writing your own functions that accept positions in the same way as the Simple API.

function addCross(pos, size) {
var p = toVector(pos);
addLine(p.x-size, p.y, p.x+size, p.y);
addLine(p.x, p.y-size, p.x, p.y+size);
}
addCross([0,0], 5);
addCross(new RVector(20,0), 5);
isPosition([1,2]); // returns true
isPosition("abc"); // returns false
move(entity, dx, dy)
move(entity, [dx, dy])

Moves the given entity by the given offset.

var c = addCircle(0,0, 10);
move(c, 50,0);
rotate(entity, angle)
rotate(entity, angle, cx, cy)
rotate(entity, angle, [cx, cy])

Rotates the given entity by the given angle in degrees around the given center. If no center is given, the entity is rotated around the origin 0,0.

// a fan of lines, rotated around 0,0:
for (var a=0; a<360; a+=30) {
var l = addLine(10,0, 50,0);
rotate(l, a);
}
// rotate a square around its center:
var sq = addPolyline([[100,0], [120,0], [120,20], [100,20]], true);
rotate(sq, 45, [110,10]);
scale(entity, factor)
scale(entity, factor, cx, cy)
scale(entity, factor, [cx, cy])
scale(entity, [sx, sy], [cx, cy])

Scales the given entity by the given factor. The focus point (the point that remains in place) defaults to the origin 0,0. Different factors for X and Y can be given as array [sx, sy]. Note that some entities such as circles and arcs cannot be scaled by different factors in X and Y.

var sq = addPolyline([[0,0], [10,0], [10,10], [0,10]], true);
scale(sq, 3);
var pl = addPolyline([[50,0], [60,0], [60,10], [50,10]], true);
scale(pl, [2,1], [50,0]);
mirror(entity, x1, y1, x2, y2)
mirror(entity, [x1, y1], [x2, y2])
mirror(entity, new RLine(...))

Mirrors the given entity at the axis defined by two points.

var pl = addPolyline([[10,0], [40,0], [40,30]], false);
// mirror at the Y axis:
mirror(pl, 0,0, 0,100);

To keep the original and create a mirrored copy, add a copy of the entity first:

var arc = addArc(20,0, 10, 0, 180);
var copy = addShape(getShape(arc));
mirror(copy, [0,-10], [0,10]);
trim(trimEntity, limitingEntity)
trim(trimEntity, trimPos, limitingEntity, limitingPos)
trim(trimEntity, trimPos, limitingEntity, limitingPos, trimBoth)
trim(trimPos, limitingPos)

Trims the entity trimEntity to the limiting entity limitingEntity. The part of the trimmed entity at the click position trimPos is kept. If the two entities do not intersect, the entity is extended to the limiting entity. If there are multiple intersections, the one closest to the click position limitingPos is used. If trimBoth is true, both entities are trimmed to each other.

var line = addLine(0,0, 100,0);
var limit = addLine(70,-20, 70,20);
// keep the left part, line ends now at 70,0:
trim(line, [10,0], limit);
// extend a line to a circle:
var line = addLine(0,0, 50,0);
var circle = addCircle(100,0, 20);
// extend to the intersection with the circle closest to 80,0:
trim(line, [25,0], circle, [80,0]); // line ends now at 80,0
trimBoth(entity1, entity2)
trimBoth(entity1, pos1, entity2, pos2)
trimBoth(pos1, pos2)

Trims or extends both entities to their intersection point. This is a shortcut for trim with trimBoth set to true.

// two lines that do not touch are extended to form a corner at 100,0:
var a = addLine(0,0, 80,0);
var b = addLine(100,20, 100,100);
trimBoth(a, b);
lengthen(entity, amount)
lengthen(entity, start, amount)
lengthen(entity, pos, amount)
lengthen(pos, amount)

Lengthens the given entity by the given amount. Negative amounts shorten the entity. By default, the entity is lengthened at its end point. Pass true for start to lengthen it at its start point instead or pass a position close to the end that should be lengthened.

var line = addLine(0,0, 100,0);
lengthen(line, 20); // line ends now at 120,0
lengthen(line, true, -10); // line starts now at 10,0
var arc = addArc(0,50, 30, 0, 90);
lengthen(arc, [30,50], 10); // lengthen the arc at its start point
breakOut(entity, pos)
breakOut(entity, pos, removeSegment)
breakOut(pos)

Breaks out the segment of the given entity at the given position. The segment ends at the closest intersections with other entities on either side of the position. If there is no intersection on one side, the segment extends to the end of the entity. If removeSegment is true (default), the segment is deleted. Otherwise it is kept as a separate entity.

var line = addLine(0,0, 100,0);
addLine(30,-10, 30,10);
addLine(70,-10, 70,10);
// remove the part of the line between 30,0 and 70,0:
breakOut(line, [50,0]);
autoTrim(entity, pos)
autoTrim(pos)

The opposite of breakOut: keeps only the segment of the given entity at the given position and removes the rest. The segment ends at the closest intersections with other entities on either side of the position.

var line = addLine(0,0, 100,0);
addLine(30,-10, 30,10);
addLine(70,-10, 70,10);
// keep only the part between 30,0 and 70,0:
autoTrim(line, [50,0]);
divide(entity, pos)
divide(entity, pos1, pos2)
divide(pos)

Divides the given entity at the given position. An open entity (line, arc, open polyline, …) is divided into two parts at one position or three parts at two positions. Closed entities (circles, full ellipses, closed polylines) require two positions and are divided into two parts.

var line = addLine(0,0, 100,0);
divide(line, [40,0]); // two lines: 0..40 and 40..100
var circle = addCircle(0,50, 20);
divide(circle, [20,50], [-20,50]); // two half circles
round(entity1, entity2, radius)
round(entity1, pos1, entity2, pos2, radius)
round(entity1, pos1, entity2, pos2, radius, trim)
round(pos1, pos2, radius)

Rounds the corner between two entities with an arc of the given radius (fillet). The click positions indicate which ends of the entities are rounded. If trim is true (default), both entities are trimmed to the rounding arc.

// a rectangle with rounded corners:
var l1 = addLine(0,0, 100,0);
var l2 = addLine(100,0, 100,50);
var l3 = addLine(100,50, 0,50);
var l4 = addLine(0,50, 0,0);
round(l1, l2, 10);
round(l2, l3, 10);
round(l3, l4, 10);
round(l4, l1, 10);

The corners of a polyline can be rounded too, by passing the same polyline twice with a click position on each of the two segments:

var pl = addPolyline([[0,0], [100,0], [100,50]], false);
round(pl, [50,0], pl, [100,25], 10);
bevel(entity1, entity2, distance)
bevel(entity1, entity2, distance1, distance2)
bevel(entity1, pos1, entity2, pos2, distance1, distance2)
bevel(entity1, pos1, entity2, pos2, distance1, distance2, trim)
bevel(pos1, pos2, distance)

Bevels the corner between two entities with a straight line (chamfer). distance1 is the distance of the bevel line from the corner along the first entity, distance2 along the second entity (defaults to distance1). If trim is true (default), both entities are trimmed to the bevel line. chamfer is an alias for bevel.

var a = addLine(0,0, 100,0);
var b = addLine(100,0, 100,50);
bevel(a, b, 10);
var c = addLine(0,100, 100,100);
var d = addLine(100,100, 100,150);
chamfer(c, d, 20, 10);
offset(entity, distance)
offset(entity, distance, number)
offset(entity, distance, number, side)
offset(entity, sidePos, distance)
offset(entity, sidePos, distance, number)

Creates parallels to lines, concentric arcs and circles or offset curves of ellipses and other entities. number is the number of parallels to create (default 1). The parallels are created on both sides of the entity unless a side is given, either as position sidePos next to the entity or as side (RS.LeftHand, RS.RightHand or RS.BothSides). Offsetting polylines and splines is only available in QCAD Professional.

var line = addLine(0,0, 100,0);
offset(line, 5); // one parallel on each side
var line2 = addLine(0,30, 100,30);
offset(line2, 5, 2, RS.LeftHand); // two parallels on the left side (above)
var circle = addCircle(50,80, 10);
offset(circle, [50,95], 3, 4); // four concentric circles outside
reverse(entity)
reverse(x, y)

Reverses the direction of the given entity, i.e. swaps its start and end point.

var line = addLine(0,0, 100,0);
line = reverse(line);
line.getStartPoint(); // returns 100,0
explode(entity)
explode(entity, options)
explode(x, y)

Explodes the given entity into simpler entities: polylines into lines and arcs, block references into their contents, texts into lines and splines, dimensions and hatches into lines, arcs, etc. The original entity is deleted.

options is an optional object with settings that are otherwise taken from the application preferences, for example { splineSegments: 64, textToPolylines: true }. Supported options are: splineTolerance, splineSegments, ellipseSegments, splinesToLineSegments, textToPolylines, textSplineToLineOrArc, multilineTextToSimpleText and circlesToPolylines.

var pl = addPolyline([[0,0], [100,0,1], [100,50], [0,50]], true);
explode(pl); // three lines and one arc
stretch(x1, y1, x2, y2, dx, dy)
stretch([x1, y1], [x2, y2], [dx, dy])
stretch(area, offset)

Stretches all entities in the rectangular area defined by two corners by the given offset. Entities that lie completely inside the area are moved, entities that cross the boundary of the area are stretched (only the end points inside the area are moved). The area can also be given as RBox or as closed RPolyline shape. If entities are selected in the drawing, only selected entities are stretched.

// a rectangle made of lines:
addLine(0,0, 100,0);
addLine(100,0, 100,50);
addLine(100,50, 0,50);
addLine(0,50, 0,0);
// make the rectangle 50 units wider by stretching its right side:
stretch([80,-10], [120,60], [50,0]);
deleteEntity(entity)
deleteEntity(id)
deleteEntity(x, y)

Deletes the given entity from the drawing.

var l1 = addLine(0,0, 100,0);
var l2 = addLine(0,10, 100,10);
addLine(0,20, 100,20);
deleteEntity(l1); // by entity
deleteEntity(l2.getId()); // by entity ID
deleteEntity(50,20); // by position
paste(sourceDocument, destination, offset, scale, rotation,
flipHorizontal, flipVertical, toCurrentLayer, overwriteLayers, overwriteBlocks)

Pastes the contents of the document sourceDocument into the document interface destination or into the current drawing if destination is undefined. The pasted contents are moved by offset, scaled by scale and rotated by rotation degrees. All arguments are required:

  • flipHorizontal, flipVertical: true to flip the contents
  • toCurrentLayer: true to paste all entities onto the current layer
  • overwriteLayers, overwriteBlocks: true to overwrite existing layers or blocks with the same name
// create a symbol in an off-screen document:
var symbol = createDocument();
startTransaction(symbol);
addCircle(0,0, 10);
addLine(-10,0, 10,0);
addLine(0,-10, 0,10);
endTransaction();
// paste it three times into the current drawing:
for (var i=0; i<3; i++) {
paste(symbol, undefined, [i*50, 0], 1+i*0.5, i*15, false, false, false, false, false);
}
startTransaction()
startTransaction(document)
endTransaction()

By default, every Simple API call is applied to the drawing immediately and can be undone individually. Between startTransaction() and endTransaction(), all changes are collected and applied together when endTransaction is called. This has two advantages:

  • It is much faster when adding many entities.
  • All changes can be undone in one single step.

If a document (RDocument) or document interface (RDocumentInterface) is passed to startTransaction, all changes are applied to that document instead of the current drawing. This is useful to create drawings in the background, for example to export them to a file (see createDocumentInterface).

startTransaction();
for (var x=0; x<=200; x+=10) {
for (var y=0; y<=200; y+=10) {
addPoint(x, y);
}
}
endTransaction();

Note the following when working with transactions:

  • Within a transaction, the changes are not yet part of the drawing. Modification functions such as trim or round cannot refer to entities added in the same transaction.
  • Entities returned by creation functions within a transaction do not have a valid ID, not even after endTransaction. To modify such entities later on, refer to them by position.
  • All entities added within a transaction are placed on the layer that is current when endTransaction is called. Set the current layer before starting the transaction and use separate transactions for different layers.
startTransaction();
addLine(0,0, 100,0);
addLine(100,0, 100,50);
endTransaction();
// refer to the new lines by position to round the corner:
round([50,0], [100,25], 10);

getTransactionDocument and getTransactionDocumentInterface

Section titled “getTransactionDocument and getTransactionDocumentInterface”
getTransactionDocument()
getTransactionDocumentInterface()

Return the document or document interface that the current transaction applies to. Outside of transactions, the current document and document interface are returned.

var doc = createDocument();
startTransaction(doc);
addLine(0,0, 10,0);
getTransactionDocument() === doc; // returns true
endTransaction();
getOperation()

Returns the operation (RAddObjectsOperation) of the current transaction. Outside of a transaction, a new operation is returned that has to be applied explicitly. This is meant for advanced use, for example to combine Simple API calls with the full QCAD API.

startTransaction();
addCircle(0,0, 10);
var doc = getTransactionDocument();
var e = new RLineEntity(doc, new RLineData(new RVector(-10,0), new RVector(10,0)));
getOperation().addObject(e);
endTransaction();
autoZoom()

Zooms the current view so that the whole drawing is visible.

addCircle(1000,1000, 500);
autoZoom();
zoomTo(entity)
zoomTo(entity, margin)
zoomTo([x1, y1], [x2, y2])
zoomTo([x1, y1], [x2, y2], margin)
zoomTo(box, margin)

Zooms to the given entity, shape or rectangular area. margin is the margin around the area in pixels (default 10).

addCircle(0,0, 100);
var small = addCircle(80,0, 2);
zoomTo(small, 50);
zoomTo([0,0], [100,100]);
getMainWindow()

Returns the QCAD application window (RMainWindowQt).

getMainWindow().windowTitle;
getDocumentInterface()

Returns the document interface (RDocumentInterface) of the current drawing. The document interface connects a document with its views and provides functions to import and export files, apply operations, undo and redo.

addLine(0,0, 100,0);
getDocumentInterface().undo(); // removes the line again
getDocument()

Returns the current document (RDocument). The document holds all entities, layers, blocks, etc. of a drawing and provides functions to query them.

addLine(0,0, 100,0);
addCircle(0,0, 10);
getDocument().queryAllEntities().length; // number of entities in the drawing
getGraphicsView()

Returns the current or last active view (RGraphicsView) of the current drawing.

addCircle(0,0, 50);
getGraphicsView().autoZoom();
createDocument()

Creates a new, empty document in memory that is not shown in a window. Such an off-screen document can be filled using a transaction and then pasted into a drawing (see paste).

var doc = createDocument();
startTransaction(doc);
addLine(0,0, 100,0);
addLine(100,0, 100,100);
endTransaction();
doc.queryAllEntities().length; // returns 2
createDocumentInterface()

Creates a new, empty document in memory together with a document interface. The document interface can be used to import or export files.

var di = createDocumentInterface();
startTransaction(di);
addCircle(0,0, 50);
addSimpleText("Created by script", [-40,-60], 5);
endTransaction();
di.exportFile(QDir.homePath() + "/simple_api_example.dxf", "R27 (2013) DXF");

disableInput, enableInput and isInputEnabled

Section titled “disableInput, enableInput and isInputEnabled”
disableInput()
enableInput()
isInputEnabled()

disableInput disables the QCAD application window to prevent user input, for example during long operations or animations. enableInput enables the application window again and isInputEnabled returns true if user input is currently enabled. Always make sure to enable input again at the end of your script.

update()

Processes pending events so that the user interface is updated during long operations. User input must be disabled with disableInput before calling update.

sleep(milliseconds)

Pauses the script for the given time in milliseconds while keeping the user interface up to date. User input must be disabled with disableInput before calling sleep.

The following example uses disableInput, sleep and enableInput to show a simple animation:

disableInput();
var c = addCircle(0,0, 10);
autoZoom();
for (var i=0; i<20; i++) {
c = move(c, 5,0);
sleep(50);
}
enableInput();
warning(message)

Shows a warning message. In the Script Shell, warnings are shown in the command history. Otherwise, warnings are printed to the console.

if (getDocument().queryAllEntities().length===0) {
warning("The drawing is empty.");
}

The following functions show a simple dialog to ask the user for a value. If the user cancels the dialog, undefined is returned.

getInt(title, prompt, value, step, min, max)

Asks the user for an integer number. value is the initial value (default 0), step the step of the spin box (default 1), min and max the allowed range.

var n = getInt("Circles", "Number of circles:", 5, 1, 1, 100);
if (isNull(n)) {
warning("Canceled.");
}
else {
for (var i=1; i<=n; i++) {
addCircle(0,0, i*10);
}
}
getDouble(title, prompt, value, decimals, min, max)

Asks the user for a number. value is the initial value (default 0), decimals the number of decimals shown (default 1), min and max the allowed range.

var r = getDouble("Circle", "Radius:", 25.0, 2, 0.01, 1000);
if (!isNull(r)) {
addCircle(0,0, r);
}
getText(title, prompt, text)

Asks the user for a text. text is the initial text (default empty).

var t = getText("Label", "Text:", "Hello");
if (!isNull(t)) {
addSimpleText(t, 0,0, 10);
}
getItem(title, prompt, items, index, separator)

Lets the user choose an item from a drop down list. items is a string with all items separated by separator (default ","). index is the index of the initially selected item (default 0). Returns the chosen item or undefined if the dialog was canceled.

var shape = getItem("Shape", "Shape to add:", "Circle,Square,Triangle", 0);
if (shape==="Circle") {
addCircle(0,0, 50);
}
else if (shape==="Square") {
addPolyline([[-50,-50], [50,-50], [50,50], [-50,50]], true);
}
else if (shape==="Triangle") {
addPolyline([[-50,-50], [50,-50], [0,50]], true);
}

This example combines several functions of the Simple API to draw a flange with a pitch circle, bolt holes on a separate layer and a rounded rectangular cut-out:

addLayer("Center Lines", "gray", "CENTER");
addLayer("Holes", "red");
// outline:
setCurrentLayer("0");
addCircle(0,0, 100);
// pitch circle and center lines:
setCurrentLayer("Center Lines");
addCircle(0,0, 75);
addLine(-110,0, 110,0);
addLine(0,-110, 0,110);
// bolt holes, added in one transaction:
setCurrentLayer("Holes");
startTransaction();
for (var a=0; a<360; a+=45) {
var angle = a * Math.PI / 180;
addCircle(75*Math.cos(angle), 75*Math.sin(angle), 8);
}
endTransaction();
// rounded square cut-out in the center:
setCurrentLayer("0");
var l1 = addLine(-30,-30, 30,-30);
var l2 = addLine(30,-30, 30,30);
var l3 = addLine(30,30, -30,30);
var l4 = addLine(-30,30, -30,-30);
round(l1, l2, 8);
round(l2, l3, 8);
round(l3, l4, 8);
round(l4, l1, 8);
autoZoom();

The lines of the cut-out are added without transaction, so that they can be passed directly to round. The bolt holes are added in a transaction, which is faster and makes them undoable in one step.