Script file for DXF creation with text

Discussion forum for C++ and script developers who are using the QCAD development platform or who are looking to contribute to QCAD (translations, documentation, etc).

Moderator: andrew

Forum rules

Always indicate your operating system and QCAD version.

Attach drawing files, scripts and screenshots.

Post one question per topic.

Post Reply
Todd Kusik
Newbie Member
Posts: 5
Joined: Tue Sep 12, 2017 6:10 pm

Script file for DXF creation with text

Post by Todd Kusik » Tue Sep 12, 2017 6:48 pm

Hi Everyone,

This is my first forum post. I've been using QCAD for about 10 years for 2D mechanical design and love the interface. So intuitive. Thank you all for the support.

I have also used the QCAD V2.1 Script IDE to draw intricate layouts for optical calibration targets. I wrote a program that writes a .qs file containing tens of thousands of lines and arcs to create the .DXF file needed create the optical target itself. Below is a sample .qs (QCAD script input) file with most of the repetition removed.

I'm not sure where to post this questions as there seems to be another use of the word Script in the QCAD community related to extending the user interface with plug ins and such. This questions is all about running a script to create a drawing using QCAD and the Script IDE in the banner line of QCAD V2.1.

The actual question(s):
- How do I run script files (.qs) in QCAD V3. I can't find an equivalent to the Script IDE from V2 that would allow me to load and run the example below.
- My real need is to add text to my optical calibration files and thus as commands in my script file. I can't find the document that I learned how to draw lines and arcs when I originally developed this about 8 years ago. I'm happy to continue using QCAD V2 for this if this concept is no longer supported in V3, but need the syntax for drawing text.

Thank you,
Todd


-- example script file Test.qs

function main()
{
var doc;
var view;

doc = new Document;
pen = new Pen(255, 255, 255, 0);
doc.setActivePen(pen);
view = new View;

var line = new Line(doc, -21.797096, -21.817531, -21.817531, -21.797096);
doc.addEntity(line);
var arc = new Arc(doc, +31.500000, +43.050000, +0.938000, +0.000000, +0.000000, 1);
doc.addEntity(arc);
var line = new Line(doc, +29.398050, +11.700050, +34.836050, +17.116950);
doc.addEntity(line);

.
. cut out commands for 10,000 more lines and arcs
.

var line = new Line(doc, +366.836050, +349.117050, +372.399950, +354.680950);
doc.addEntity(line);

view.redraw();
}

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: Script file for DXF creation with text

Post by andrew » Wed Sep 13, 2017 4:15 pm

Todd Kusik wrote:- How do I run script files (.qs) in QCAD V3. I can't find an equivalent to the Script IDE from V2 that would allow me to load and run the example below.
.qs files cannot be run in QCAD 3.
QCAD 3 has a much more sophisticated script interface through ECMAScript (aka "JavaScript"). I can confirm that it does no longer come with an IDE though. This was a design choice made by the Qt developers (Qt being the toolkit QCAD is based on).

A script that adds lines and text to the current drawing, could look like this in QCAD 3:

Code: Select all

addLine(0,100, 100,50);
addSimpleText("MyText", 100,50, 5.0, 0.0, "Arial", RS.VAlignTop, RS.HAlignLeft, false, false);
More commands of the QCAD simple API are documented at:
https://www.qcad.org/doc/qcad/latest/de ... imple.html

You can run such a simple script using Misc > Development > Run Script.

Or directly from the command line:

Code: Select all

qcad -exec script.js

Todd Kusik
Newbie Member
Posts: 5
Joined: Tue Sep 12, 2017 6:10 pm

Re: Script file for DXF creation with text

Post by Todd Kusik » Wed Sep 20, 2017 1:35 am

Hi Andrew,

Thanks for the feedback.

I have this mostly working, but my version of QCAD V3.14.0.1 has
Misc > Development > Script Shell
not
Misc > Development > Run Script

and qcad -exec script.js doesn't help me as I need to run different scripts on different layers without exiting between.

I also have tried just pasting my 10,000 line script into the Script Shell, but as I'm running QCAD in Linux, it's either too much for the buffer or there is a problem with windows vs linux new line characters.

Is there a way in my version to open a script file inside QCAD3?

Todd

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: Script file for DXF creation with text

Post by andrew » Wed Sep 20, 2017 9:07 am

Try this:
- run QCAD and keep it running
- from a terminal, run QCAD again with the -exec switch to launch the script:

Code: Select all

./qcad -exec myscript.js
The script should now be executed in the first (and only) instance of QCAD that was already running. QCAD will not start again. I'm not quite sure if this works in your version but it's worth a shot.

Todd Kusik
Newbie Member
Posts: 5
Joined: Tue Sep 12, 2017 6:10 pm

Re: Script file for DXF creation with text

Post by Todd Kusik » Wed Sep 20, 2017 6:23 pm

When I do:

./qcad -exec myscript.js

I get:

QCAD version 3.14.0
Warning: Application already running. Aborting...

In fact, just running QCAD once with the "-exec myscript.js" command doesn't result in any geometry being drawn.

The only way I have found to import geometry as script commands is 500 lines at a time in the Script Shell

Maybe I need a newer version than 3.14.0? "./qcad mydrawing.dxf" doesn't load the drawing like QCAD2 did. Maybe no command line arguments work in 3.14.0?

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: Script file for DXF creation with text

Post by andrew » Wed Sep 20, 2017 7:12 pm

I can confirm that

-exec myscript.js

always expects a script action in older versions (i.e. a script class called "myscript" with a beginEvent, etc). So this simple script will not work with QCAD 3.14.

You can find an example of such a script action at:
https://github.com/qcad/qcad/blob/maste ... hSpiral.js
Maybe I need a newer version than 3.14.0? "./qcad mydrawing.dxf" doesn't load the drawing like QCAD2 did. Maybe no command line arguments work in 3.14.0?
I cannot reproduce this here. ./qcad mydrawing.dxf opens QCAD 3.14 with the drawing or if QCAD is already open it opens a new document and loads mydrawing.dxf into it.

Todd Kusik
Newbie Member
Posts: 5
Joined: Tue Sep 12, 2017 6:10 pm

Re: Script file for DXF creation with text

Post by Todd Kusik » Wed Sep 20, 2017 10:54 pm

My drawing script file now looks like the following but many thousands of lines. Can it be processed as a file in any version of QCAD3?
You mentioned Menu > Development > Run Script earlier. It sounds like what I need, but 3.14.0 doesn't have that.
Maybe I can use the QCAD command: prompt to load it somehow?




addSimpleText("W66.0mm_T3.00mm_M000-006_Back", +50.000000, +5.000000, +3.000000, 0.0, "Arial", RS.VAlignTop, RS.HAlignLeft, false, false);
addArc( +82.300000, +85.750000, +1.149000, +0.000000, +0.000000, true);
addSimpleText("MarkerId:000", +65.800000, +87.070000, +1.532000, 0.0, "Arial", RS.VAlignTop, RS.HAlignLeft, false, false);
addLine( +75.960950, +85.199950, +66.299050, +85.199950);
addLine( +66.299050, +85.199950, +69.129050, +78.368050);
addLine( +69.129050, +78.368050, +75.960950, +85.199950);
addLine( +49.039050, +85.199950, +58.700950, +85.199950);
addLine( +58.700950, +85.199950, +55.870950, +78.368050);
addLine( +55.870950, +78.368050, +49.039050, +85.199950);
addLine( +31.700050, +67.860950, +31.700050, +58.199050);
addLine( +31.700050, +58.199050, +38.531950, +61.029050);
addLine( +38.531950, +61.029050, +31.700050, +67.860950);
addLine( +31.700050, +40.939050, +31.700050, +50.600950);
addLine( +31.700050, +50.600950, +38.531950, +47.770950);
addLine( +38.531950, +47.770950, +31.700050, +40.939050);
addLine( +49.039050, +23.600050, +58.700950, +23.600050);
addLine( +58.700950, +23.600050, +55.870950, +30.431950);
addLine( +55.870950, +30.431950, +49.039050, +23.600050);
addLine( +75.960950, +23.600050, +66.299050, +23.600050);
addLine( +66.299050, +23.600050, +69.129050, +30.431950);
addLine( +69.129050, +30.431950, +75.960950, +23.600050);
addLine( +93.299950, +40.939050, +93.299950, +50.600950);
addLine( +93.299950, +50.600950, +86.468050, +47.770950);
addLine( +86.468050, +47.770950, +93.299950, +40.939050);
addLine( +93.299950, +67.860950, +93.299950, +58.199050);
addLine( +93.299950, +58.199050, +86.468050, +61.029050);
addLine( +86.468050, +61.029050, +93.299950, +67.860950);
addArc( +82.300000, +151.950000, +1.149000, +0.000000, +0.000000, true);
addSimpleText("MarkerId:001", +65.800000, +153.270000, +1.532000, 0.0, "Arial", RS.VAlignTop, RS.HAlignLeft, false, false);
addLine( +49.039050, +151.399950, +58.700950, +151.399950);
addLine( +58.700950, +151.399950, +55.870950, +144.568050);
addLine( +55.870950, +144.568050, +49.039050, +151.399950);
addLine( +31.700050, +134.060950, +31.700050, +124.399050);
addLine( +31.700050, +124.399050, +38.531950, +127.229050);
addLine( +38.531950, +127.229050, +31.700050, +134.060950);
addLine( +31.700050, +107.139050, +31.700050, +116.800950);
addLine( +31.700050, +116.800950, +38.531950, +113.970950);
.
.
.

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: Script file for DXF creation with text

Post by andrew » Wed Sep 20, 2017 11:19 pm

I'm afraid you'd have to wrap it into the format of an action script to make this work in your version of QCAD (see post above). You can simply put all your code into the beginEvent of the action:

Code: Select all

include("scripts/EAction.js");

function MyScript(guiAction) {
    EAction.call(this, guiAction);
}

MyScript.prototype = new MyScript();

MyScript.prototype.beginEvent = function() {
   // your code goes here
   this.terminate();
};

MyScript.init = function(basePath) {
    var action = new RGuiAction(qsTr("&My Script"), RMainWindowQt.getMainWindow());
    action.setRequiresDocument(true);
    action.setScriptFile(basePath + "/MyScript.js");
    action.setWidgetNames(["DrawExamplesMenu"]);
};
Your script will then also appear in menu Misc > Example > Draw as "My Script" or you can trigger it using -exec (see above).

Alternatively, you could load the file using the Qt API in the Script Shell and then eval it:

Code: Select all

f = new QFile("/path/to/script.js");
f.open(new QIODevice.OpenMode(QIODevice.ReadOnly | QIODevice.Text));
eval(f.readAll());
f.close();
Note that you might have to replace all double quotes " with single quotes ' in your code to make this work.

Todd Kusik
Newbie Member
Posts: 5
Joined: Tue Sep 12, 2017 6:10 pm

Re: Script file for DXF creation with text

Post by Todd Kusik » Fri Sep 22, 2017 9:34 pm

Hi Andrew,

Here are my latest findings:

I upgraded to 3.15 from a download I had grabbed before my upgrade period expired after acquiring 3.14 last year.

QCAD3.15.5 is able to process my script file because it has:
Misc > Development > Run Script (then select script.js)

--- Simple/Small script example ---

Below is a simple example script file for others who may read this post. It draws a unit box with a unit circle inside with the letter 'x' inside it. There seems to be a bug with the RS.VAlignCenter constant when used in addSimpleText. I used RS.HAlignCenter for both vertical and horizontal alignment and got the correct result (the 'x' is aligned on center V&H). Likely fixed in newer versions?

script.js: (filename doesn't actually matter)

addLine(0, 0, 1, 0);
addLine(1, 0, 1, 1);
addLine(1, 1, 0, 1);
addLine(0, 1, 0, 0);
addArc(0.5, 0.5, 0.5, 0.0, 0.0, true);
addSimpleText("X", 0.5, 0.5, 0.5, 0.0, "Arial", RS.HAlignCenter, RS.HAlignCenter, false, false);

--- Running on my real scripts ----

My real script is many thousands of lines long. Measuring processing time on scripts of various lengths resulted in the following statistics:

A 3000 line script took 18 seconds to process.
A 6000 line script took 65 seconds to process.
A 9000 line script took 130 seconds to process.

The longer scripts are basically the same as the shorter, just more lines and arcs. Processing time does not grow linearly. I tried a 25000 line script and it hadn't finished after 10 minutes.

--- reverting to QCAD 2.2.2 ---

Adding text to my drawing was the reason I started this post originally. During the life of this post I found the syntax for adding text in a QCAD 2 input script.
The simple Q2 equivalent to the above is:

function main() {
var doc;
var view;

doc = new Document;
pen = new Pen(255, 255, 255, 0);
doc.setActivePen(pen);
view = new View;

var line = new Line(doc, 0, 0, 1, 0);
doc.addEntity(line);
var line = new Line(doc, 1, 0, 1, 1);
doc.addEntity(line);
var line = new Line(doc, 1, 1, 0, 1);
doc.addEntity(line);
var line = new Line(doc, 0, 1, 0, 0);
doc.addEntity(line);
var arc = new Arc(doc, 0.5, 0.5, 0.5, 0, 0, 0); // center x, center y, radius, start angle, end angle, reversed (0 or 1)
doc.addEntity(arc);
var text = new Text(doc, "x", "standard", 0.5, 0.5, 0.5, 0, 1, "Center", "Center"); // string, font, center x, center y, height, bold, italic, V align, H align
doc.addEntity(text);

view.redraw();
}

Running one of my production Q2 scripts with the same geometry as the 25000 line Q3 script only took 1 second.

It looks like I'll need to continue using Q2 for this work unless the most recent Q3 version has significantly faster script processing.

I'm happy to keep using Q2, but I like to keep moving forward.

Thoughts?

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: Script file for DXF creation with text

Post by andrew » Fri Sep 22, 2017 10:03 pm

Todd Kusik wrote:There seems to be a bug with the RS.VAlignCenter constant when used in addSimpleText. I used RS.HAlignCenter for both vertical and horizontal alignment and got the correct result (the 'x' is aligned on center V&H). Likely fixed in newer versions?
For vertical alignment, use RS.VAlignMiddle:
http://qcad.org/doc/qcad/latest/develop ... a99af76782

About performance: using addLine like you did in your script creates a new complete and undoable transaction for each single line added which would be slow indeed. Internally, the spatial index, the undo buffer, the graphic view, layer list, etc. are all updated after adding each single line.

To add all lines in one single transaction, you can simply wrap your code into a startTransaction() and endTransaction() block:

Code: Select all

startTransaction();
// your addLine, addText, etc. here
endTransaction();
See also:
https://www.qcad.org/doc/qcad/latest/de ... 27c71a1916

Post Reply

Return to “QCAD Programming, Script Programming and Contributing”