Page 1 of 1

Inserting block from Part Library using a script

Posted: Fri Nov 15, 2024 12:43 pm
by luke
Hi everyone,
I'm trying to visualize some pre-calculated values from an external file (json) and I'm stuck on the option to insert a block from the Part Library into the drawing at the calculated coordinates. I haven't found a single example, so I'm wondering if this is even possible?

I have no problem using the API (or even SimpleAPI) and creating a brand new entity on the calculated coordinates, but I can't insert an entity (block) from the Library...

I'm using QCAD Pro on mac.

Thanks for any help

Re: Inserting block from Part Library using a script

Posted: Fri Nov 15, 2024 1:19 pm
by CVH
Hi, and welcome to the QCAD forum.

That is partially because the Library Browser was removed from the open source and is now part of the Pro-priatary code section.

Essentially it is like importing a DXF/DWG file.
What it does is basically handled in InsertBlockItem.js
Remark that InsertBlockItem.js and BlockInsert.js work in tandem.

I think you will manage from there. :wink:

Regards,
CVH

Re: Inserting block from Part Library using a script

Posted: Fri Nov 15, 2024 2:14 pm
by andrew
You would essentially load the part library document into a temporary, off-screen document and then "paste" that document into your drawing:

To load the library item into a temporary document:

Code: Select all

var ms = new RMemoryStorage();
var si = createSpatialIndex();
var docItem = new RDocument(ms, si);
var diItem = new RDocumentInterface(docItem);
diItem.setNotifyListeners(false);
diItem.importFile("/path/to/file.dxf", "", false);
To paste the temporary document into the drawing:

Code: Select all

var op = new RPasteOperation(docItem);
op.setText("Insert library item");
op.setOffset(new RVector(100,100));          // the position where you want to place the item
op.setBlockName("MyBlock");                  // if you want to insert the item as block, set a block name here
op.setScale(1.0);                            // set a scale if desired
op.setRotation(0.0);

var di = this.getDocumentInterface();        // this is the interface to the drawing you are working on
di.applyOperation(op);                       // apply the paste operation
You can also set block attributes for the block reference if desired with:

Code: Select all

op.setAttribute("AttributeName", "Value");

Re: Inserting block from Part Library using a script

Posted: Fri Nov 15, 2024 3:26 pm
by luke
Thanks guys! I almost had it - I just needed to use the RPasteOperation(), it's working now, but..
I need to copy dozens of Parts - wouldn't it be better to have them all in one file
and not copy the whole file, but only selected blocks?

Re: Inserting block from Part Library using a script

Posted: Sat Nov 16, 2024 7:40 am
by CVH
Hi,
First, I intentionally pointed out to InsertBlockItem.js because there are several things that are verified before importing blindly.
The file must exist, a Block name can not contain invalid characters, overwriting existent or not, numbered duplicate names ...

Then, in general a library part is intended as a DXF snippet with a complete and singular sub-part.
Similar purpose as that of a Block content.
Every sub-part is then stored as a Library Item.
From that perspective the code generates the off-screen document and paste it entirely as a new block.
Additionally, the Library Browser will create a new Block Reference entity based on that Block and insert it with user interaction.
luke wrote:
Fri Nov 15, 2024 3:26 pm
I need to copy dozens of Parts - wouldn't it be better to have them all in one file
and not copy the whole file, but only selected blocks?
From your question I understand that your library items are a collection of sub-parts.
Or files that already have some Blocks defined that you are interested in.
In that case you don't need the whole file and its content in Model_Space, you only want to extract certain Block Definitions.
And yes, beside the (Library Item) file name you need a list of Block names.

The easiest route would be to create a Block Reference in the off-screen document, cut/paste that to the target drawing.
QCAD will automatically copy the required Block content or several when stacked.
The new Block Reference can be deleted and you end up with an additional (yet unused) Block Definitions in the target.

Another route would be to select and copy the drawing entities in the intended Block Definition and ...
... paste those as part of new (yet unused) Block Definition in the target.
One can query the content of a certain Block: RDocument.queryBlockEntities(id)
Then it is important to understand that every drawing entity lives on a Layer and is part of a Block.
REntity.setLayerName(...) or REntity.setLayerId(id) sets the Layer for a new entity.
REntity.setBlockId(id) sets the Block where a new entity belongs to.
And then is Model_Space nothing else than a Block. Its id can be retrieved with RDocument.getModelSpaceBlockId().
A stacked Block(s) would be a Block Reference in the source Block, the referenced Block(s) would be copied over.

Remind that with pasting there are also the options to overwrite content or not, on current Layer and so on.
RPasteOperation Class Reference

Another approach would be a template with frequently used Block Definitions in it.
You can still purge out unused blocks afterwards.

Regards,
CVH