The Simple API
Introduction
Section titled “Introduction”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.
Using the Simple API
Section titled “Using the Simple API”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.
Conventions
Section titled “Conventions”Coordinates
Section titled “Coordinates”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.
Entity References
Section titled “Entity References”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]orRVector): 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 objectmove(l.getId(), [0,10]); // by entity IDmove([50,20], [0,10]); // by position: the entity closest to 50,20Click Positions
Section titled “Click Positions”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);Return Values
Section titled “Return Values”- Creation functions return the added entity. The entity can be passed to other functions or queried for information (for example
getId(),getLength()orgetStartPoint()). - 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 orundefinedif 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.”.
Creating Entities
Section titled “Creating Entities”addPoint
Section titled “addPoint”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
Section titled “addLine”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
Section titled “addXLine”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
Section titled “addArc”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
Section titled “addCircle”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
Section titled “addEllipse”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
Section titled “addPolyline”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.
bulgedefines the shape of the segment that starts at this vertex:0(default) for a straight segment,1for a half circle counterclockwise,-1for a half circle clockwise. Other values create arc segments in between (the bulge is the tangent of a quarter of the arc angle).relative:trueif the coordinates of this vertex are relative to the previous vertex.closed:trueto close the polyline (default isfalse).relative:trueto treat the coordinates of all vertices as relative to the previous vertex (default isfalse).
// 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
Section titled “addSpline”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
Section titled “addSimpleText”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 (default1)angle: text angle in degrees (default0)font: font name (default"Standard")vAlign: vertical alignment:RS.VAlignTop(default),RS.VAlignMiddle,RS.VAlignBaseorRS.VAlignBottomhAlign: horizontal alignment:RS.HAlignLeft(default),RS.HAlignCenterorRS.HAlignRightbold,italic:truefor 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
Section titled “addSolid”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]);Adding Shapes, Entities and Objects
Section titled “Adding Shapes, Entities and Objects”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
Section titled “addShape”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
Section titled “addShapes”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
Section titled “addEntity”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
Section titled “addObject”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
Section titled “deleteObject”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);Layers and Attributes
Section titled “Layers and Attributes”addLayer
Section titled “addLayer”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
Section titled “hasLayer”hasLayer(name)Returns true if a layer with the given name exists in the drawing.
if (!hasLayer("Holes")) { addLayer("Holes", "red");}setCurrentLayer
Section titled “setCurrentLayer”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
Section titled “setCurrentColor”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);Querying Entities
Section titled “Querying Entities”getEntity
Section titled “getEntity”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 20getShape
Section titled “getShape”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 150getClosestEntity
Section titled “getClosestEntity”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,0getClosestEntity([50,25], 5); // returns undefinedgetEntityShape
Section titled “getEntityShape”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 120getIntersectionPoints
Section titled “getIntersectionPoints”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 and toVector
Section titled “isPosition and toVector”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 trueisPosition("abc"); // returns falseModifying Entities
Section titled “Modifying Entities”Transformations
Section titled “Transformations”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
Section titled “rotate”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
Section titled “mirror”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]);Trimming and Lengthening
Section titled “Trimming and Lengthening”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,0trimBoth
Section titled “trimBoth”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
Section titled “lengthen”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,0lengthen(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 pointbreakOut
Section titled “breakOut”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
Section titled “autoTrim”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
Section titled “divide”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 circlesCorners
Section titled “Corners”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 and chamfer
Section titled “bevel and chamfer”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
Section titled “offset”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 outsidereverse
Section titled “reverse”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,0explode
Section titled “explode”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 arcstretch
Section titled “stretch”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
Section titled “deleteEntity”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 entitydeleteEntity(l2.getId()); // by entity IDdeleteEntity(50,20); // by positionpaste(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:trueto flip the contentstoCurrentLayer:trueto paste all entities onto the current layeroverwriteLayers,overwriteBlocks:trueto 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);}Transactions
Section titled “Transactions”startTransaction and endTransaction
Section titled “startTransaction and endTransaction”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
trimorroundcannot 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
endTransactionis 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 trueendTransaction();getOperation
Section titled “getOperation”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
Section titled “autoZoom”autoZoom()Zooms the current view so that the whole drawing is visible.
addCircle(1000,1000, 500);autoZoom();zoomTo
Section titled “zoomTo”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]);Documents and Application
Section titled “Documents and Application”getMainWindow
Section titled “getMainWindow”getMainWindow()Returns the QCAD application window (RMainWindowQt).
getMainWindow().windowTitle;getDocumentInterface
Section titled “getDocumentInterface”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 againgetDocument
Section titled “getDocument”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 drawinggetGraphicsView
Section titled “getGraphicsView”getGraphicsView()Returns the current or last active view (RGraphicsView) of the current drawing.
addCircle(0,0, 50);getGraphicsView().autoZoom();createDocument
Section titled “createDocument”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 2createDocumentInterface
Section titled “createDocumentInterface”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
Section titled “update”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
Section titled “warning”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.");}User Input
Section titled “User Input”The following functions show a simple dialog to ask the user for a value. If the user cancels the dialog, undefined is returned.
getInt
Section titled “getInt”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
Section titled “getDouble”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
Section titled “getText”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
Section titled “getItem”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);}Example: A Flange
Section titled “Example: A Flange”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.