How to get the containing rectangle of text in a DXF file
Moderator: andrew
Forum rules
Always indicate your operating system and QCAD version.
Attach drawing files and screenshots.
Post one question per topic.
Always indicate your operating system and QCAD version.
Attach drawing files and screenshots.
Post one question per topic.
-
- Full Member
- Posts: 84
- Joined: Fri Oct 20, 2023 7:21 am
How to get the containing rectangle of text in a DXF file
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
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 (54.42 KiB) Viewed 4655 times
-
- VeryCapture_20231029115939.jpg (61.4 KiB) Viewed 4655 times
Re: How to get the containing rectangle of text in a DXF file
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.
Or
Then it cycles the returned entity id's, query each entity and retrieve the bounding box:
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:
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.
Regards,
CVH
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
Code: Select all
var ids = doc.queryAllEntities(false, false, RS.EntityTextBased); // NOT-undone, NOT-allBlocks, Any text based entity (text, attribute def, attribute)
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());
}
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);
Otherwise it is one transaction per text .. per box what might be slower.
When altered you should export the new file of course.
Regards,
CVH
-
- 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
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 nowCVH wrote: ↑Sun Oct 29, 2023 7:16 amHi,
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.OrCode: Select all
var ids = doc.queryAllEntities(false, false, RS.EntityText); // NOT-undone, NOT-allBlocks, Text entities
Then it cycles the returned entity id's, query each entity and retrieve the bounding box:Code: Select all
var ids = doc.queryAllEntities(false, false, RS.EntityTextBased); // NOT-undone, NOT-allBlocks, Any text based entity (text, attribute def, attribute)
If only used for measuring up you don't need the part that saves the document again, nor the related command arguments.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()); }
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:You can add the startTransaction(di); and endTransaction(); before and after the for-loop to make it one transaction.Code: Select all
var poly = bbox.getPolyline2d(); var vertices = poly.getVertices(); // Add line to drawing (using QCAD Simple API): addPolyline(vertices);
Otherwise it is one transaction per text .. per box what might be slower.
When altered you should export the new file of course.
Regards,
CVH
Re: How to get the containing rectangle of text in a DXF file
You just need to plug in the provided code into the base script ....WildWolfCJ wrote: ↑Sun Oct 29, 2023 11:37 amCan you help me provide a complete JS to obtain the rectangular border of each TEXT (without running the QCAD interface program)?
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.
Almost everything is possible with scripts, just explain what.
Regards,
CVH
-
- 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
CVH wrote: ↑Sun Oct 29, 2023 7:57 pmYou just need to plug in the provided code into the base script ....WildWolfCJ wrote: ↑Sun Oct 29, 2023 11:37 amCan you help me provide a complete JS to obtain the rectangular border of each TEXT (without running the QCAD interface program)?
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.
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
Re: How to get the containing rectangle of text in a DXF file
With "ABC" & "DGF" you probably mean the text itself ... Seems obvious.WildWolfCJ wrote: ↑Mon Oct 30, 2023 2:10 amformat can be saved like this:
"ABC"---text rectangle1---rectangular box
"DGF"---text rectangle2---rectangular box
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.
Regards,
CVH
-
- 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
CVH wrote: ↑Mon Oct 30, 2023 6:39 amWith "ABC" & "DGF" you probably mean the text itself ... Seems obvious.WildWolfCJ wrote: ↑Mon Oct 30, 2023 2:10 amformat can be saved like this:
"ABC"---text rectangle1---rectangular box
"DGF"---text rectangle2---rectangular box
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.
Regards,
CVH
Thank you very much for your patient answerFurther I would not know how you want to represent "rectangular box".
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]
-
- 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
HI CVH
How does QCAD single-step debug JS code?
How does QCAD single-step debug JS code?
Re: How to get the containing rectangle of text in a DXF file
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);
}
Ensure you remove any code in that example script related to the output file.CVH wrote: ↑Sun Oct 29, 2023 7:16 amBased 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.
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.
Re: How to get the containing rectangle of text in a DXF file
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
-
- 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
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 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?
Re: How to get the containing rectangle of text in a DXF file
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:
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
Re: How to get the containing rectangle of text in a DXF file
Nice, little steps at a time.WildWolfCJ wrote: ↑Tue Oct 31, 2023 7:41 amI have been able to successfully run the ExTool.js file and draw a line segment in the DXF
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
-
- 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
I have successfully implemented this function according to your instructions. Thank you very much for your help.CVH wrote: ↑Tue Oct 31, 2023 8:53 amNice, little steps at a time.WildWolfCJ wrote: ↑Tue Oct 31, 2023 7:41 amI have been able to successfully run the ExTool.js file and draw a line segment in the DXF
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
-
- 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
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.