Custom tool design

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.

kdwoll
Newbie Member
Posts: 8
Joined: Wed Oct 26, 2022 12:51 pm

Custom tool design

Post by kdwoll » Wed Oct 26, 2022 1:17 pm

Hi guys, I am working on a project that requires me the generate a list of x-y coordinates based on a dxf file. We need to mark a spot on the truss where to place nails. (see photo). I'm used cad/cam pro and the output will be to a g-code file.
Trusspng.png
Trusspng.png (4.14 KiB) Viewed 14837 times
The idea is that I would select a line from the view and click generate. That script would generate a pattern of point along the axis with offset and spacing according to the settings. writing to code and the math isn't the problem. (Even though I will come back to you for help.) The issue is how to incorporate the tools into Qcad. Where do I start to build a plugin with required toolbar and dialog windows to set parameters.

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

Re: Custom tool design

Post by andrew » Wed Oct 26, 2022 2:01 pm

A good starting point are the script tutorials at:
https://www.qcad.org/en/tutorial-script-programming

Since you are most likely interested in creating an interactive tool, this tutorial applies:
https://www.qcad.org/en/tutorial-intera ... pt-actions

Once you are familiar with the basics, I'd recommend to browse or search existing QCAD scripts to find similar use cases:
https://github.com/qcad/qcad/tree/master/scripts

For example, to learn how to let the user choose an entity, you might want to have a look at one of the many tools that do this, for example to draw a line with a relative angle to an existing line:
https://github.com/qcad/qcad/blob/maste ... veAngle.js

kdwoll
Newbie Member
Posts: 8
Joined: Wed Oct 26, 2022 12:51 pm

Re: Custom tool design

Post by kdwoll » Mon Nov 07, 2022 3:43 pm

After a couple hours I was able to build this (see Zip) to add points to the drawing. I want to know best practices to have global settings. I have the menu structure the way I want it, but I want to menu items to show up as buttons on the toolbar too. Code is still messy to don't read to much into it.
TrusspngNails.png
TrusspngNails.png (8.98 KiB) Viewed 14504 times

steps.
Load File (80TRUSS_Import.dxf)
Init Truss (To make sure drawing is exploded)
Select Truss Top Chord and click button. (draw points along top chord.)
Select Truss Web and click button. (draw point along truss webs.)
deselect all.
click menu item Truss bottom Chord / Select left bottom point / move mouse along bottom line and add point as needed.
Attachments
nTruss.zip
(34.21 KiB) Downloaded 361 times

CVH
Premier Member
Posts: 3470
Joined: Wed Sep 27, 2017 4:17 pm

Re: Custom tool design

Post by CVH » Mon Nov 07, 2022 8:44 pm

Hi,
kdwoll wrote:
Mon Nov 07, 2022 3:43 pm
I want to menu items to show up as buttons on the toolbar too.
What ToolBar, ToolsPanel and/or MatrixPanel?
This can be done by including the widgets names:

Code: Select all

action.setWidgetNames(["nTrussMenu"]);    // An Array of widgets names
However, I foresee issues because you don't follow the common QCAD orders for groups and items. e_geek

One could also include them in one of the two custom ToolBars. :wink:
See App.Prefs. > General > Tool Settings
kdwoll wrote:
Mon Nov 07, 2022 3:43 pm
I want to know best practices to have global settings.
The thing with gobals is that they may already exist. :wink:
nTrussBottom.State is an example of a global.
kdwoll wrote:
Mon Nov 07, 2022 3:43 pm
Init Truss (To make sure drawing is exploded)
Why is that required? :roll:
Altering a drawing to be able to run a tool is not best practice.
It is the same effort to retrieve Line segments from a nearby Polyline.

To verify that a document entity is a Line segment see Library.js:
isLineEntity(obj)

It is rather common to call EAction for messages:
EAction.handleUserMessage("Nothing Selected");

Regards,
CVH

kdwoll
Newbie Member
Posts: 8
Joined: Wed Oct 26, 2022 12:51 pm

Re: Custom tool design

Post by kdwoll » Tue Nov 08, 2022 3:22 am

Hey, Thanks for the feedback... I think I have the menu / toolbar thing figured out now, and everything works like I want it to. I wasn't aware that the setWidgetNames is a list.

On the Global Setting, Is it possible to use the option dialog to set some values? and they will be available when I use one of the other scripts in the same tree? Does the declared var have to be on the root like nTruss?


You referenced the library.js. I will have to look into using that....

Kevin

CVH
Premier Member
Posts: 3470
Joined: Wed Sep 27, 2017 4:17 pm

Re: Custom tool design

Post by CVH » Tue Nov 08, 2022 6:19 am

kdwoll wrote:
Tue Nov 08, 2022 3:22 am
I wasn't aware that the setWidgetNames is a list.
The hint would be that it is in plural. :wink:
https://qcad.org/doc/qcad/3.0/developer ... db9d4e34b2
kdwoll wrote:
Tue Nov 08, 2022 3:22 am
Is it possible to use the option dialog to set some values?
Yes
kdwoll wrote:
Tue Nov 08, 2022 3:22 am
and they will be available when I use one of the other scripts in the same tree?
All depends ... Vars have block scope.
That ends at the function closing curly bracket. :wink:

For example:
var Corner1 in function nTrussBottom is not the same as
this.corner1 in nTrussBottom.prototype.coordinateEvent.
It would be different if there were this.corner1 = undefined; in nTrussBottom.
Remark here that Vars under QCAD start with a lower case.

So yes, Script Object Properties can be shared.
In your case nTruss would be the place to set/create the nTruss property(ies).
Everthing based on nTruss would then be able to access that.

Regards,
CVH

kdwoll
Newbie Member
Posts: 8
Joined: Wed Oct 26, 2022 12:51 pm

Re: Custom tool design

Post by kdwoll » Sun Nov 13, 2022 3:27 pm

I finally got to the output of the points that I need. How do I sort this list to DrawOrder Column?

"RVector(14.134990, 42.932505, 0.000000, 1)" Draworder: 1006
"RVector(-28.797516, 64.398758, 0.000000, 1)" Draworder: 1009
"RVector(-14.486680, 57.243340, 0.000000, 1)" Draworder: 1008
"RVector(-57.419186, 78.709593, 0.000000, 1)" Draworder: 1011

First Column is X
Second Column is Y
Third Column is DrawOrder

184 - 0, 1001
104 - 0, 1006
88 - 0, 1007
136 - 0, 1004
120 - 0, 1005
40 - 0, 1010
24 - 0, 1011
72 - 0, 1008
56 - 0, 1009

CVH
Premier Member
Posts: 3470
Joined: Wed Sep 27, 2017 4:17 pm

Re: Custom tool design

Post by CVH » Sun Nov 13, 2022 5:12 pm

Hi,

The code in your initial scripts did not export anything.
Can you explain what the source is and how it is exported.

The use of the Drawing Order is perhaps not a good idea.
This can become renumbered on save & reload.

Lists, or better arrays, can be sorted before exporting them and that can be based on a function:
https://developer.mozilla.org/en-US/doc ... Array/sort
https://www.w3schools.com/jsref/jsref_sort.asp

The compare function is evaluated on this element 'a' and the next element 'b' and that until no change occurs anymore.
If each element of the array is an array itself then you need a function on 'a' & 'b' that returns the order (-, + or 0) depending a certain value in the sub-arrays. In a similar way we can sort an array of objects but then on property values.

Regards,
CVH

kdwoll
Newbie Member
Posts: 8
Joined: Wed Oct 26, 2022 12:51 pm

Re: Custom tool design

Post by kdwoll » Sun Nov 13, 2022 7:28 pm

Hi, thanks for the reply. but first things first.... Is it possible to add a custom property to each entity I could use to sort?

Kevin.

CVH
Premier Member
Posts: 3470
Joined: Wed Sep 27, 2017 4:17 pm

Re: Custom tool design

Post by CVH » Sun Nov 13, 2022 8:21 pm

kdwoll wrote:
Sun Nov 13, 2022 7:28 pm
Is it possible to add a custom property to each entity I could use to sort?
Object based or entity based?
The first exist in runtime, the second is stored with the entity in dxf.

Regards,
CVH

kdwoll
Newbie Member
Posts: 8
Joined: Wed Oct 26, 2022 12:51 pm

Re: Custom tool design

Post by kdwoll » Sun Nov 13, 2022 8:32 pm

Stored with the entity in dxf... If the customer saves the file the values will reload correctly.

Kevin

CVH
Premier Member
Posts: 3470
Joined: Wed Sep 27, 2017 4:17 pm

Re: Custom tool design

Post by CVH » Sun Nov 13, 2022 8:54 pm

kdwoll wrote:
Sun Nov 13, 2022 8:32 pm
Stored with the entity in dxf
For that you create a document entity.
Add a custom property before adding it to an operation.

Code: Select all

var point = new RPointEntity(this.getDocument(),new RPointData(new RVector(this.corner1.x + (j * 48) + 2 , this.corner1.y + 2 )));
point.setCustomProperty("QCAD", "nameTag", anyValue);
op.addObject(point);
Your entity will have the custom property listed in the Property Editor.

Reading is as easy as this:

Code: Select all

var point = doc.queryEntity(entityId);
var anyValue = point.getCustomProperty("QCAD", "nameTag", undefined);
Best is to verify if that returned a valid value.
If you change the queried value you need to store it back in the document with an operation.
kdwoll wrote:
Sun Nov 13, 2022 7:28 pm
But first things first....
Here I would like to suggest to first read the forum rules above. :wink:

Regards,
CVH

kdwoll
Newbie Member
Posts: 8
Joined: Wed Oct 26, 2022 12:51 pm

Re: Custom tool design

Post by kdwoll » Mon Nov 14, 2022 2:42 am

So, Thanks for your help on creating this tool. I forgot has much fun it is to write code. Anyways, I will be sending this to the customer to find bugs. :) (trust me they will) But it should get the job done. Overall I'd say it's a great platform for custom dxf based tools.

So if anyone wants to test it, I included a dxf file from the said customer, 495_test.dxf.

Step one. Open the file.
Step two. Click the INIT button to create nails layer and hide / lock others.
Step three. Add nails to bottom chords with Chord buttons... mirrored works great. (adds custom property for sort order.)
Step four. Add webs nails with web tools. (mirrored tool has to make one line down to middle and then mirrors out from there.
Step five. Set the Zero point and export to CVS file.
TrussNailed.png
TrussNailed.png (20.38 KiB) Viewed 13871 times
:D

Kevin
Attachments
nTruss.zip
(64.33 KiB) Downloaded 331 times

User avatar
Husky
Moderator/Drawing Help/Testing
Posts: 4939
Joined: Wed May 11, 2011 9:25 am
Location: USA

Re: Custom tool design

Post by Husky » Mon Nov 14, 2022 3:14 am

Hi,
may I ask you a few questions?
1. If I place this script below C:\Program Files\qcad-3.27.8-pro-win64\scripts QCAD will not start anymore. What is the reason to locate it higher up in the QCAD paths hierarchy?

2.
kdwoll wrote:
Mon Nov 14, 2022 2:42 am
Step two. Click the INIT button to create nails layer and hide / lock others.
What is and where is to find this "INIT button"?

3. The drawing has 1294 duplicates and 152 Zero-length entities. Is that on purpose?
Work smart, not hard: QCad Pro
Win10/64, QcadPro, QcadCam version: Current.
If a thread is considered as "solved" please change the title of the first post to "[solved] Title..."

kdwoll
Newbie Member
Posts: 8
Joined: Wed Oct 26, 2022 12:51 pm

Re: Custom tool design

Post by kdwoll » Mon Nov 14, 2022 3:58 am

1. I have Qcad/cam version 3.27.8.0 (3.27.8) and I have the nTruss Folder in the scripts folder.....
QCAD-debug.png
QCAD-debug.png (23.45 KiB) Viewed 13858 times
if you run debug you will see the problem.


2. You have to unhide the nTruss toolbar....

3. The drawing came that way from the supplier..... I will have to work with it the way it is....
(Is a point zero length?)

Kevin.

Post Reply

Return to “QCAD Programming, Script Programming and Contributing”