Tutorial: Writing a plugin that draws a dovetail

Discussion forum for contributors and developers who are using the QCAD version 3 ECMAScript development platform or the C++ plugin interface or who are otherwise looking to contribute to QCAD (translations, documentation, etc).

Moderator: andrew

Tutorial: Writing a plugin that draws a dovetail

Postby matthiaswm » Thu May 23, 2013 11:53 pm

OK, so this is how I write plugins. I write C++ code for thirtysome years, learned a few other languages and do some Reverse Engineering. That may or may not explain my approach here. I had no clue about Java Script until a few weeks ago. It's easy and powerful. You can learn it!

When extending functionality, I like to base my code on a working script and then change it the way I need, verifying my steps. So first we need to find an existing script that does 90% of what we want. Drawing a rectangle from point to point is good. After searching a bit, I found a directory: .../scripts/Draw/Line/LineRectangle/ . So lets duplicate the entire directory just where it is and name the new one "LineDove".

Go into the directory and rename the following files:
Code: Select all
  LineRectangle.svg, LineRectangleInit.js, LineRectangle.js
to
  LineDove.svg, LineDoveInit.js, LineDove.js


LineDove.svg is the vector graphic for the icon in the toolbar. Leave it alone for now, or edit it, if you have time to spare.

LineDoveInit.js registers the script with the user interface. Open the file in a text editor (not MSWord! Just a plain and simple text editor) and replace all occurrences of LineRectangle with LineDove. Replace the word "&Rectangle" with "Dovetail", and change the setDefaulCommands. The code looks now like this:

function init(basePath) {
var action = new RGuiAction(qsTranslate("LineDove", "&Rectangle"),
RMainWindowQt.getMainWindow());
action.setRequiresDocument(true);
action.setScriptFile(basePath + "/LineDove.js");
action.setIcon(basePath + "/LineDove.svg");
action.setDefaultShortcut(new QKeySequence("r,v"));
action.setStatusTip(qsTranslate("LineDove", "Draw a dovetail joint"));
action.setDefaultCommands(["dovetail"]);
action.setSortOrder(500);
EAction.addGuiActionTo(action, Line, true, true, true, true);
}


LineDove.js contains the actual script. But let's first fix the names so that the original script may run. In the entire file, replace LineRectangle with LineDove. Now find the first line that contains new RVector. This line of code draws the first side of the rectangle. Replace the code snippet this.corner1.y with this.corner1.y/2 (divide the y coordinate of your first click by two).

Let's check if we did everything right!

Launch QCad and select Draw/Line. You should find *two* icons for drawing a rectangle. Try the first one and draw a rectangle. If you did everything right, you will now see a very quirky shape drawn. No dovetail yet, but at least we "wrote" our first plugin. To be continued... .

If anything went wrong and QCad is not launching anymore, or crashing or anything else, simply remove the directory we created earlier (".../scripts/Draw/Line/LineDove/"). Everything should be back to normal. Now try over ;-)
Last edited by matthiaswm on Sun Jun 02, 2013 8:10 pm, edited 1 time in total.
matthiaswm
Junior Member
 
Posts: 22
Joined: Mon Apr 29, 2013 4:34 pm

Re: Writing a plugin that draws a dovetail

Postby Clive » Fri May 24, 2013 9:19 am

Hi Matthias
This is exactly what I was talking about, your 'step by step' method is perfect. Explaining about the little things - no matter how basic they are is exactly what beginners to scripting in QCAD need.
Explaining what the different scripts do and what to change, then checking etc. etc.is brilliant and is very welcome. I will definitely try some of this out :wink:
matthiaswm wrote: No dovetail yet, but at least we "wrote" our first plugin. To be continued... .


Thank you so much for your time on this, looking forward to the next installment on this tutorial :D .

I'm hoping this will encourage others to add some 'scripting' tutorials for QCAD.
User avatar
Clive
Moderator
 
Posts: 955
Joined: Thu Aug 25, 2011 9:28 pm
Location: UK

Re: Writing a plugin that draws a dovetail

Postby matthiaswm » Sat May 25, 2013 6:10 pm

Allright, now let's finish that birds rear. We need math!

The dimensions of a dovetail joint are not fixed, so I decided to make them symmetrical, allowing multiple fingers. If the tail is 12mm at the end, and 8mm at the base, I need 6mm to the left and right of the base which gives us a base with of 20mm. Let's then make the tail 8mm long to look proportional. Of course, the CAD program know nothing about Millimetrs or inches, so we need to use fractions to make everything based on the unit 1.

So here is the formula for drawing our dove tail, starting at the left, moving to the right, pointing to the top:
  • draw 6mm to the right (the base of the slot)
  • draw 2mm to the left and 8mm up (the first diagonal, shaping the tail)
  • draw 12mm to the right (the end of the tail)
  • draw 2mm to the left and 8mm down (the second diagonal)
  • draw 6mm to the right

OK, so if we add up the numbers and we put that in code, it reads:

Code: Select all
LineDove.prototype.getOperation = function(preview) {
    var corners = new Array(
        new RVector( 0, 0),
        new RVector( 6, 0),
        new RVector( 4, 8),
        new RVector(16, 8),
        new RVector(14, 0),
        new RVector(20, 0)
    );
    var op = new RAddObjectsOperation();
    for (var i=0; i<5; ++i) {
        var lineData = new RLineData(corners[i],corners[i+1]);
        var line = new RLineEntity(this.getDocument(), lineData);
        op.addObject(line);
    }
    return op;
};


Here is a trick for testing. If you are on Linux or OS X, start QCad from the command line with additional options. You will get diagnostic output, and you can modify and test the script without quitting and relaunching QCad. In OS X, the command line is:

Code: Select all
/Applications/QCAD.app/Contents/MacOS/QCAD -always-load-scripts
  or if you are adventurous:
/Applications/QCAD.app/Contents/MacOS/QCAD -always-load-scripts -enable-script-debugger


The code above is nice, but it only puts one very specific Dovetail at 0, 0. That should be more universal! To generate the Dovetail where we clicked the first time, we add the line line.move(this.corner1);.

Wait a minute! Ho did I find out about this magic function named move()? Ah, it's all in the manual. So line is of type RLineEntity. But if we go to the documentation of RLineEntity https://www.ribbonsoft.com/doc/qcad/3.0/developer/class_r_line_entity-members.html, there is no function named move(). However, RLineEntity is derived from REntity, meaning it can do anything that REntity can do plus more. Click on List of all members, and there it is: move https://www.ribbonsoft.com/doc/qcad/3.0/developer/class_r_entity.html#a81cf2d4f32119ee4a78f421b52e8a745.

If we can move our list of vectors, we surely can rotate and scale it as well. So let's find out how long the dowetail should be, and at what angle we need to draw it:

Code: Select all
    var len = this.corner1.getDistanceTo(this.corner2);
    var ang = this.corner1.getAngleTo(this.corner2);


and we apply that to the vector list (remember that we need to scale by 1/20 because our initial calculations assumed a 20mm wide joint):

Code: Select all
LineDove.prototype.getOperation = function(preview) {
    var len = this.corner1.getDistanceTo(this.corner2);
    var ang = this.corner1.getAngleTo(this.corner2);
    var corners = new Array(
        new RVector( 0, 0),
        new RVector( 6, 0),
        new RVector( 4, 8),
        new RVector(16, 8),
        new RVector(14, 0),
        new RVector(20, 0)
    );
    var op = new RAddObjectsOperation();
    for (var i=0; i<5; ++i) {
        var lineData = new RLineData(corners[i],corners[i+1]);
        var line = new RLineEntity(this.getDocument(), lineData);
        line.scale(len/20);
        line.move(this.corner1);
        line.rotate(ang, this.corner1);
        op.addObject(line);
    }
    return op;
};


Tadaaa.... . ;-)
matthiaswm
Junior Member
 
Posts: 22
Joined: Mon Apr 29, 2013 4:34 pm

Re: Writing a plugin that draws a dovetail

Postby Clive » Sun May 26, 2013 9:59 am

Nice, thank you so much :D
User avatar
Clive
Moderator
 
Posts: 955
Joined: Thu Aug 25, 2011 9:28 pm
Location: UK

Re: Tutorial: Writing a plugin that draws a dovetail

Postby Husky » Fri Jul 12, 2013 8:36 pm

Has somebody finished this Dove Tail Plug in? Would it be possible for a "non programmer" like me to download a working script for QCAD? :oops:
User avatar
Husky
Moderator
 
Posts: 690
Joined: Wed May 11, 2011 9:25 am
Location: USA

Re: Tutorial: Writing a plugin that draws a dovetail

Postby matthiaswm » Fri Jul 12, 2013 9:34 pm

Oh, sure. Here's the archive that you will need to unpack:

adding: scripts/Draw/Line/LineDove/
adding: scripts/Draw/Line/LineDove/LineDove.js
adding: scripts/Draw/Line/LineDove/LineDove.svg
adding: scripts/Draw/Line/LineDove/LineDoveInit.js
Attachments
LineDove.zip
(4.02 KiB) Downloaded 163 times
matthiaswm
Junior Member
 
Posts: 22
Joined: Mon Apr 29, 2013 4:34 pm

Re: Tutorial: Writing a plugin that draws a dovetail

Postby Husky » Sat Jul 13, 2013 1:48 am

Very nice! Thank you! :D :D :D
User avatar
Husky
Moderator
 
Posts: 690
Joined: Wed May 11, 2011 9:25 am
Location: USA

Re: Tutorial: Writing a plugin that draws a dovetail

Postby caigner » Sun Jul 14, 2013 10:28 am

Indeed a very useful script. Thanks alot!

Because I use a router bit with 14° angle to cut the dovetail I modified the numbers slightly to achieve this angle:

Code: Select all
    var corners = new Array(
        new RVector( 0, 0),
        new RVector( 6, 0),
        new RVector( 4.0053759772545544670076804975611, 8),
        new RVector(15.994624022745445532992319502439, 8),
        new RVector(14, 0),
        new RVector(20, 0)
    );
caigner
Active Member
 
Posts: 25
Joined: Wed Jan 30, 2013 5:24 pm

Re: Tutorial: Writing a plugin that draws a dovetail

Postby matthiaswm » Sun Jul 14, 2013 12:16 pm

Sure, great! It's nice to see the script being used in real life, even though it was originally just a tutorial for writing scripts ;-)

One elegant way would be a parameter in the tool bar that takes the angle an diameter of the router bit and applies that to the drawing. Are you readers interested in that? When time permits, I can add that to the tutorial.
matthiaswm
Junior Member
 
Posts: 22
Joined: Mon Apr 29, 2013 4:34 pm

Re: Tutorial: Writing a plugin that draws a dovetail

Postby Clive » Sun Jul 14, 2013 1:11 pm

matthiaswm wrote:One elegant way would be a parameter in the tool bar that takes the angle an diameter of the router bit and applies that to the drawing. Are you readers interested in that? When time permits, I can add that to the tutorial.

Yes please, that would be great :wink: but of course in your own time.
User avatar
Clive
Moderator
 
Posts: 955
Joined: Thu Aug 25, 2011 9:28 pm
Location: UK

Re: Tutorial: Writing a plugin that draws a dovetail

Postby Husky » Sun Jul 14, 2013 6:28 pm

clive wrote:
matthiaswm wrote:One elegant way would be a parameter in the tool bar that takes the angle an diameter of the router bit and applies that to the drawing. Are you readers interested in that? When time permits, I can add that to the tutorial.

Yes please, that would be great :wink: but of course in your own time.

Yes please, for me (us) too. :D
That's what I'm really looking for to be able to work with different settings for all kinds of dove tails .... without leaving the QCAD Program surface :wink:
User avatar
Husky
Moderator
 
Posts: 690
Joined: Wed May 11, 2011 9:25 am
Location: USA

Re: Tutorial: Writing a plugin that draws a dovetail

Postby Husky » Thu Aug 15, 2013 8:22 am

matthiaswm wrote:Oh, sure. Here's the archive that you will need to unpack:

adding: scripts/Draw/Line/LineDove/
adding: scripts/Draw/Line/LineDove/LineDove.js
adding: scripts/Draw/Line/LineDove/LineDove.svg
adding: scripts/Draw/Line/LineDove/LineDoveInit.js


Do you mind if I put your script (.zip) also in our new "QCAD 3 ' script Add-On & Plug-in challenge" Forum?
Just to make sure everybody will find it ..... :wink: :wink: :wink:
User avatar
Husky
Moderator
 
Posts: 690
Joined: Wed May 11, 2011 9:25 am
Location: USA


Return to QCAD 3 Developers and Contributors

Who is online

Users browsing this forum: No registered users and 2 guests