How to get the containing rectangle of text in a DXF file

Drop in here to discuss whatever you want.

Moderator: andrew

Forum rules

Always indicate your operating system and QCAD version.

Attach drawing files and screenshots.

Post one question per topic.

WildWolfCJ
Full Member
Posts: 84
Joined: Fri Oct 20, 2023 7:21 am

How to get the containing rectangle of text in a DXF file

Post by WildWolfCJ » Sun Oct 29, 2023 5:04 am

WIN10 QCAD3.28.2 Professional Edition
How do I get the containing rectangle of each text in a DXF file through the command line? Just like the rectangle in the attachment
Attachments
VeryCapture_20231029115926.jpg
VeryCapture_20231029115926.jpg (54.42 KiB) Viewed 4643 times
VeryCapture_20231029115939.jpg
VeryCapture_20231029115939.jpg (61.4 KiB) Viewed 4643 times

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

Re: How to get the containing rectangle of text in a DXF file

Post by CVH » Sun Oct 29, 2023 7:16 am

Hi,
Question answered here: https://www.qcad.org/rsforum/viewtopic. ... 505#p42504

Based on: https://www.ribbonsoft.com/en/tutorial- ... ol-scripts
The functional core of this script (now line 66-69) would query the document for text entities.
Or text-based entities.

Code: Select all

var ids = doc.queryAllEntities(false, false, RS.EntityText);    // NOT-undone, NOT-allBlocks, Text entities
Or

Code: Select all

var ids = doc.queryAllEntities(false, false, RS.EntityTextBased);    // NOT-undone, NOT-allBlocks, Any text based entity (text, attribute def, attribute)
Then it cycles the returned entity id's, query each entity and retrieve the bounding box:

Code: Select all

for (var i=0; i<ids.length; i++) {
    var id = ids[i];
    var text = doc.queryEntity(id);
    var bbox = text.getBoundingBox();

    // Do something with the bounding box data, for example:
    var lowerL = bbox.getMinimum();
    print("Lower left position: %1 , %2".arg(lowerL.getX()).arg(lowerL.getY());
    print("Height = %1 , Width = %2".arg(bbox.getHeight()).arg(bbox.getWidth());
}
If only used for measuring up you don't need the part that saves the document again, nor the related command arguments.

All methods of RBox:
https://qcad.org/doc/qcad/3.0/developer ... r_box.html

If you are interested in adding the box as a polyline then include:

Code: Select all

    var poly = bbox.getPolyline2d();
    var vertices = poly.getVertices();
    // Add line to drawing (using QCAD Simple API):
    addPolyline(vertices);
You can add the startTransaction(di); and endTransaction(); before and after the for-loop to make it one transaction.
Otherwise it is one transaction per text .. per box what might be slower.

When altered you should export the new file of course. :wink:

Regards,
CVH

WildWolfCJ
Full Member
Posts: 84
Joined: Fri Oct 20, 2023 7:21 am

Re: How to get the containing rectangle of text in a DXF file

Post by WildWolfCJ » Sun Oct 29, 2023 11:37 am

CVH wrote:
Sun Oct 29, 2023 7:16 am
Hi,
Question answered here: https://www.qcad.org/rsforum/viewtopic. ... 505#p42504

Based on: https://www.ribbonsoft.com/en/tutorial- ... ol-scripts
The functional core of this script (now line 66-69) would query the document for text entities.
Or text-based entities.

Code: Select all

var ids = doc.queryAllEntities(false, false, RS.EntityText);    // NOT-undone, NOT-allBlocks, Text entities
Or

Code: Select all

var ids = doc.queryAllEntities(false, false, RS.EntityTextBased);    // NOT-undone, NOT-allBlocks, Any text based entity (text, attribute def, attribute)
Then it cycles the returned entity id's, query each entity and retrieve the bounding box:

Code: Select all

for (var i=0; i<ids.length; i++) {
    var id = ids[i];
    var text = doc.queryEntity(id);
    var bbox = text.getBoundingBox();

    // Do something with the bounding box data, for example:
    var lowerL = bbox.getMinimum();
    print("Lower left position: %1 , %2".arg(lowerL.getX()).arg(lowerL.getY());
    print("Height = %1 , Width = %2".arg(bbox.getHeight()).arg(bbox.getWidth());
}
If only used for measuring up you don't need the part that saves the document again, nor the related command arguments.

All methods of RBox:
https://qcad.org/doc/qcad/3.0/developer ... r_box.html

If you are interested in adding the box as a polyline then include:

Code: Select all

    var poly = bbox.getPolyline2d();
    var vertices = poly.getVertices();
    // Add line to drawing (using QCAD Simple API):
    addPolyline(vertices);
You can add the startTransaction(di); and endTransaction(); before and after the for-loop to make it one transaction.
Otherwise it is one transaction per text .. per box what might be slower.

When altered you should export the new file of course. :wink:

Regards,
CVH
Thank you for your answer. I am not very familiar with JS and am learning JS development in QCAD. Can you help me provide a complete JS to obtain the rectangular border of each TEXT (without running the QCAD interface program)? My project urgently needs this feature now

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

Re: How to get the containing rectangle of text in a DXF file

Post by CVH » Sun Oct 29, 2023 7:57 pm

WildWolfCJ wrote:
Sun Oct 29, 2023 11:37 am
Can you help me provide a complete JS to obtain the rectangular border of each TEXT (without running the QCAD interface program)?
You just need to plug in the provided code into the base script ....

The question not yet answered up to today is in what format you need the data.

The example just prints text strings to the OS Command Box without specifying what text the data belongs to.
For a few that might work but for several hundreds ....
There is no data nor number formatting involved.
And so on ....

Don't expect simple code to do exactly what is needed without knowing how and what is expected. :wink:
Almost everything is possible with scripts, just explain what.

Regards,
CVH

WildWolfCJ
Full Member
Posts: 84
Joined: Fri Oct 20, 2023 7:21 am

Re: How to get the containing rectangle of text in a DXF file

Post by WildWolfCJ » Mon Oct 30, 2023 2:10 am

CVH wrote:
Sun Oct 29, 2023 7:57 pm
WildWolfCJ wrote:
Sun Oct 29, 2023 11:37 am
Can you help me provide a complete JS to obtain the rectangular border of each TEXT (without running the QCAD interface program)?
You just need to plug in the provided code into the base script ....

The question not yet answered up to today is in what format you need the data.

The example just prints text strings to the OS Command Box without specifying what text the data belongs to.
For a few that might work but for several hundreds ....
There is no data nor number formatting involved.
And so on ....

Don't expect simple code to do exactly what is needed without knowing how and what is expected. :wink:
Almost everything is possible with scripts, just explain what.

Regards,
CVH
You just need to plug in the provided code into the base script ....

My requirement is very simple. Use the system command line to print out the rectangular box containing each TEXT or MTEXT in the DXF file. The data can be saved as a TXT file. The data format can be saved like this:
"ABC"---text rectangle1---rectangular box
"DGF"---text rectangle2---rectangular box
Or any data format you define can be used,
I'm learning JS development, but I can't master it in a short time. Can you help me complete this function? Thank you very much

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

Re: How to get the containing rectangle of text in a DXF file

Post by CVH » Mon Oct 30, 2023 6:39 am

WildWolfCJ wrote:
Mon Oct 30, 2023 2:10 am
format can be saved like this:
"ABC"---text rectangle1---rectangular box
"DGF"---text rectangle2---rectangular box
With "ABC" & "DGF" you probably mean the text itself ... Seems obvious.
If var text is the queried text entity -> var textStr = text.getEscapedText(# Optionally true #);
https://qcad.org/doc/qcad/3.0/developer ... 19cd486858
The parameter escapeUnicode is by default false, you need to set it to true when needed.
Another option is the plain text:
var textStr = text.getPlainText();

"text rectangleN" & "rectangular box" are rather abstract.
I have really no clue on what they need to contain and how to format values.

"N" seems to be a counter (1-2-...), because we are cycling only text entities 'N' can be set to the iterator i.
That is zero based so add 1 to start there.
textStr = texStr + "---" + "text rectangle" +(i+1);
Remark that I included the 3 dashes and 'text rectangle' literally adding a number.
All fine for an integer, JS will convert that to a string.
1-2-3-... will be in arbitrary order.

Another option for "text rectangleN" is the entity handle, a unique value on text entity creation.
textStr = texStr + "---" + "0x" + text.getHandle().toString(16)";
Here I retrieve the queried text handle and convert that to hexadecimal with a prefix to diversify.

If none of the above guesses are your goal then please clarify.

Further I would not know how you want to represent "rectangular box".
Should it be human readable or must it mean something to the 'lower computer'?
What does that machine take as input?

An RBox in QCAD has four corners (2D, 8 in 3D), each are RVectors, each are XYZ coordinates and in 2D Z is usually zero.
Meaning that there are 8 (12 including Z) coordinate values associated with it.
An RBox of something not null has usually a defined size in XY.
Meaning that there is a width and a height associated with it.
Text have a reference point, again an RVector, what does not need to coincide with one of the RBox corners.
Text have an alignment point what usually coincides with the reference point.

Once the string textStr is fully developed you can print that moving on to the next text entity if any.

If you call your custom tool from a *.bat file you can pipe the results to a *.txt file. :wink:

Regards,
CVH

WildWolfCJ
Full Member
Posts: 84
Joined: Fri Oct 20, 2023 7:21 am

Re: How to get the containing rectangle of text in a DXF file

Post by WildWolfCJ » Mon Oct 30, 2023 2:33 pm

CVH wrote:
Mon Oct 30, 2023 6:39 am
WildWolfCJ wrote:
Mon Oct 30, 2023 2:10 am
format can be saved like this:
"ABC"---text rectangle1---rectangular box
"DGF"---text rectangle2---rectangular box
With "ABC" & "DGF" you probably mean the text itself ... Seems obvious.
If var text is the queried text entity -> var textStr = text.getEscapedText(# Optionally true #);
https://qcad.org/doc/qcad/3.0/developer ... 19cd486858
The parameter escapeUnicode is by default false, you need to set it to true when needed.
Another option is the plain text:
var textStr = text.getPlainText();

"text rectangleN" & "rectangular box" are rather abstract.
I have really no clue on what they need to contain and how to format values.

"N" seems to be a counter (1-2-...), because we are cycling only text entities 'N' can be set to the iterator i.
That is zero based so add 1 to start there.
textStr = texStr + "---" + "text rectangle" +(i+1);
Remark that I included the 3 dashes and 'text rectangle' literally adding a number.
All fine for an integer, JS will convert that to a string.
1-2-3-... will be in arbitrary order.

Another option for "text rectangleN" is the entity handle, a unique value on text entity creation.
textStr = texStr + "---" + "0x" + text.getHandle().toString(16)";
Here I retrieve the queried text handle and convert that to hexadecimal with a prefix to diversify.

If none of the above guesses are your goal then please clarify.

Further I would not know how you want to represent "rectangular box".
Should it be human readable or must it mean something to the 'lower computer'?
What does that machine take as input?

An RBox in QCAD has four corners (2D, 8 in 3D), each are RVectors, each are XYZ coordinates and in 2D Z is usually zero.
Meaning that there are 8 (12 including Z) coordinate values associated with it.
An RBox of something not null has usually a defined size in XY.
Meaning that there is a width and a height associated with it.
Text have a reference point, again an RVector, what does not need to coincide with one of the RBox corners.
Text have an alignment point what usually coincides with the reference point.

Once the string textStr is fully developed you can print that moving on to the next text entity if any.

If you call your custom tool from a *.bat file you can pipe the results to a *.txt file. :wink:

Regards,
CVH
Further I would not know how you want to represent "rectangular box".
Thank you very much for your patient answer
I will describe my needs in more detail. If there are two texts in the DXF file ( also contain other entities), one text is "ABC" and the other text is "DEF", I hope to get one by running the script on the command line. txt file, each line of the txt file records a text containing a rectangular format as follows
"ABC" [left,top,width,heigh]

"DEF" [left,top,width,height]

WildWolfCJ
Full Member
Posts: 84
Joined: Fri Oct 20, 2023 7:21 am

Re: How to get the containing rectangle of text in a DXF file

Post by WildWolfCJ » Mon Oct 30, 2023 2:57 pm

HI CVH
How does QCAD single-step debug JS code?

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

Re: How to get the containing rectangle of text in a DXF file

Post by CVH » Mon Oct 30, 2023 3:04 pm

WildWolfCJ wrote:
Mon Oct 30, 2023 2:33 pm
"ABC" [left,top,width,heigh]
left means you need to append the X coordinate of the RBox minimum.
top means you need to append the Y coordinate of the RBox maximum.
The rest was explained above.

Code: Select all

// Get id's of all text entities in the document:
var ids = doc.queryAllEntities(false, false, RS.EntityText);    // NOT-undone, NOT-allBlocks, Text entities

// Process all text entities:
for (var i=0; i<ids.length; i++) {
    var id = ids[i];
    var entity = doc.queryEntity(id);
    // Fail when not a text entity:
    if (!isTextEntity(entity)) {
        continue;
    }
    var bbox = entity.getBoundingBox();
    // Compose export string:
    var textStr = entity.getPlainText();
    // Fail when empty:
    if (!textStr.length > 0) {
        continue;
    }
    texStr += " [" + bbox.getMinimum().getX().toPrecision(12);
    texStr += "," + bbox.getMaximum().getY().toPrecision(12);
    texStr += "," + bbox.getWidth().toPrecision(12);
    texStr += "," + bbox.getHeight().toPrecision(12);
    texStr += "]";

    // Export the composed string:
    print(texStr);
}
CVH wrote:
Sun Oct 29, 2023 7:16 am
Based on: https://www.ribbonsoft.com/en/tutorial- ... ol-scripts
The functional core of this script (now line 66-69) would query the document for text entities.
Ensure you remove any code in that example script related to the output file.
Save this script as *js file in an appropriate place for example as explained in the tutorial.

Regards,
CVH
Last edited by CVH on Mon Oct 30, 2023 3:17 pm, edited 3 times in total.

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

Re: How to get the containing rectangle of text in a DXF file

Post by CVH » Mon Oct 30, 2023 3:11 pm

WildWolfCJ wrote:
Mon Oct 30, 2023 2:57 pm
HI CVH
How does QCAD single-step debug JS code?
Lookup "-enable-script-debugger" in the forum.

Include debugger; in your script where you need the debugger to halt your script.

A word of caution: the debugger mode is not a stable environment.
BTW, never tried debugging a command line script.

Regards,
CVH

WildWolfCJ
Full Member
Posts: 84
Joined: Fri Oct 20, 2023 7:21 am

Re: How to get the containing rectangle of text in a DXF file

Post by WildWolfCJ » Tue Oct 31, 2023 7:41 am

CVH wrote:
Mon Oct 30, 2023 3:11 pm
WildWolfCJ wrote:
Mon Oct 30, 2023 2:57 pm
HI CVH
How does QCAD single-step debug JS code?
Lookup "-enable-script-debugger" in the forum.

Include debugger; in your script where you need the debugger to halt your script.

A word of caution: the debugger mode is not a stable environment.
BTW, never tried debugging a command line script.

Regards,
CVH
HI CVH thanks for your answer
I have been able to successfully run the ExTool.js file and draw a line segment in the DXF, but
qcad -autostart scripts/Tools/ExTool/ExTool.js -h Why is there no output when I execute the command line like this?
in ExTool.js
VeryCapture_20231031143954.jpg
VeryCapture_20231031143954.jpg (259.16 KiB) Viewed 4410 times
function printHelp() {
print("Usage: " + args[1] + " [OPTION]... <drawing file>");
print();
print("This tool does...");
print();
print(" -f, -force Overwrite existing output file");
print(" -h, -help Display this help");
print(" -o, -outfile=FILE Set output file to FILE");
print(" -p, -parameter Some parameter...");
print(" ...");
printGenericUsage();
print();
}
What I understand is that print should print information to the console. Where can I find the usage of the print function?

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

Re: How to get the containing rectangle of text in a DXF file

Post by andrew » Tue Oct 31, 2023 8:14 am

Windows GUI applications cannot write to stdout.

QCAD for Windows comes with two binaries:

- qcad.exe for GUI applications
- qcadcmd.com for console applications (command line tools)

Try:

Code: Select all

qcadcmd -autostart scripts/Tools/ExTool/ExTool.js -h

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

Re: How to get the containing rectangle of text in a DXF file

Post by CVH » Tue Oct 31, 2023 8:53 am

WildWolfCJ wrote:
Tue Oct 31, 2023 7:41 am
I have been able to successfully run the ExTool.js file and draw a line segment in the DXF
Nice, little steps at a time. :wink:
Now it is just the matter of including custom code instead of drawing a line (line 66-69) and save that under a custom script file name.

Without altering something to the dxf you don't need to export the off screen document.
Everything related to outfile is then useless and can be removed ... Remarked out (prefix // = remark).
More elaborated would be exporting a *.txt file in direct.

Regards,
CVH

WildWolfCJ
Full Member
Posts: 84
Joined: Fri Oct 20, 2023 7:21 am

Re: How to get the containing rectangle of text in a DXF file

Post by WildWolfCJ » Wed Nov 01, 2023 9:09 am

CVH wrote:
Tue Oct 31, 2023 8:53 am
WildWolfCJ wrote:
Tue Oct 31, 2023 7:41 am
I have been able to successfully run the ExTool.js file and draw a line segment in the DXF
Nice, little steps at a time. :wink:
Now it is just the matter of including custom code instead of drawing a line (line 66-69) and save that under a custom script file name.

Without altering something to the dxf you don't need to export the off screen document.
Everything related to outfile is then useless and can be removed ... Remarked out (prefix // = remark).
More elaborated would be exporting a *.txt file in direct.

Regards,
CVH
I have successfully implemented this function according to your instructions. Thank you very much for your help.

WildWolfCJ
Full Member
Posts: 84
Joined: Fri Oct 20, 2023 7:21 am

Re: How to get the containing rectangle of text in a DXF file

Post by WildWolfCJ » Thu Nov 02, 2023 3:41 am

CVH wrote:
Mon Oct 30, 2023 3:11 pm
WildWolfCJ wrote:
Mon Oct 30, 2023 2:57 pm
HI CVH
How does QCAD single-step debug JS code?
Lookup "-enable-script-debugger" in the forum.

Include debugger; in your script where you need the debugger to halt your script.

A word of caution: the debugger mode is not a stable environment.
BTW, never tried debugging a command line script.

Regards,
CVH
HI CVH
I did not find the usage of the -enable-script-debugger parameter. I hope that the debugging interface will appear for single-step tracking when debugging JS code.

Post Reply

Return to “Chat”