Adding objects in a batch
Moderator: andrew
Forum rules
Always indicate your operating system and QCAD version.
Attach drawing files, scripts and screenshots.
Post one question per topic.
Always indicate your operating system and QCAD version.
Attach drawing files, scripts and screenshots.
Post one question per topic.
- hungerburg
- Premier Member
- Posts: 160
- Joined: Fri May 28, 2010 7:35 pm
Adding objects in a batch
In my scripts I add objects one primitive by one primitive. They execute quite fast. Still I want to ask:
For performance reasons, can one join several RAddObject Operations into one RAddObjects Operation? When I switch layers inbetween those, will the entities end up in the right ones then? Or does qcad optimze already?
For performance reasons, can one join several RAddObject Operations into one RAddObjects Operation? When I switch layers inbetween those, will the entities end up in the right ones then? Or does qcad optimze already?
- hungerburg
- Premier Member
- Posts: 160
- Joined: Fri May 28, 2010 7:35 pm
Seems I am a little confused by RAddObjectsOperation and RAddObjectOperation. In fact I only use the first plural one and never the second singular one.
These operations I call from helper functions, that draw geometric primitives, that create both operation and objects internally only.
If instead I kept on adding objects to the operation, and applied it only later, then would all objects end up in the same layer? Or in the layer, that was active, at the time they were added to the operation? Could it be about useCurrentAttributes?
I know it is trivial to find out myself, but I am lazy right now, please excuse the many words too, but maybe its interesting for others too. It may prove a performance benefit, especially when the script runs in the GUI.
These operations I call from helper functions, that draw geometric primitives, that create both operation and objects internally only.
Code: Select all
var operation = new RAddObjectsOperation(false);
var linie = new RLineData(linien[l][0], linien[l][1]);
var entity = new RLineEntity(zeichnung.document, linie);
operation.addObject(entity);
zeichnung.documentInterface.applyOperation(operation);
I know it is trivial to find out myself, but I am lazy right now, please excuse the many words too, but maybe its interesting for others too. It may prove a performance benefit, especially when the script runs in the GUI.
To the layer that was the current layer when the object was added if 'useCurrentAttributes' is true (default) or to the layer explicitly set on the entity (setLayer(...)) if 'useCurrentAttributes' is false.hungerburg wrote:If instead I kept on adding objects to the operation, and applied it only later, then would all objects end up in the same layer? Or in the layer, that was active, at the time they were added to the operation? Could it be about useCurrentAttributes?
- hungerburg
- Premier Member
- Posts: 160
- Joined: Fri May 28, 2010 7:35 pm
Thank You Andrew, with this information I started to refactor. I nearly gave in, as everything would end up in the same layer. But now it works
The useCurrentAttributes flag works like this:
Code: Select all
var operation = new RAddObjectsOperation(false); // not undo-able
document.setCurrentLayer("A");
// […] create some entity
operation.addObject(entity, false); // stick it to current layer
document.setCurrentLayer("B");
// […] add some more objects to the operation
operation.addObject(entity, false); // stick it to current layer
// […] add some more objects to the operation
documentInterface.applyOperation(operation);
- false: use attributes current at the time of the "add"
true: use attributes current at the time of the "apply"
Re: Adding objects in a batch
Hi Andrew,
this is an old thread, I know... But I think, my question belongs to it.
I'm trying to insert (copies of) several (sub-)entities. So I tried:
Insertion with useCurrentAttributes==true works, but is not what is wanted. Insertion with useCurrentAttributes==false does not insert anything. I tried to use setObjectId(...INVALID) and to set LayerId manually, but that does not change anything. What am I doing wrong?
Thanks in advance
this is an old thread, I know... But I think, my question belongs to it.
I'm trying to insert (copies of) several (sub-)entities. So I tried:
Code: Select all
for (var j = 0; j < subIds.length; j++) {
var sub = document.queryEntity(subIds[j]);
var clone = sub.clone();
clone.move(this.pos);
//no changes with: storage.setObjectId(clone, RObject.INVALID_ID);
//no changes with: clone.setLayerId(sub.getLayerId());
op.addObject(clone, false); //nothing is ever inserted
//this is working but entity is on wrong layer with: op.addObject(clone, true);
}
Thanks in advance
Re: Adding objects in a batch
Can you pst a bit more code (what operation are you using, how do you apply the operation), thanks.
Re: Adding objects in a batch
Thanks for the fast reaction. I have a script that has a block-id in this.blockId. The complete getOperation function is
The getOperation is called "as usual" by pickCoordinate:
InsertExplodedBlock.prototype.getOperation = function(preview) { var document = this.getDocument(); if (isNull(document)) { return undefined; } var storage = document.getStorage(); //needed only for inserted "storage.setObjectId(clone, RObject.INVALID_ID);" var op = new RAddObjectsOperation(); var block = document.queryBlock(this.blockId); if (isNull(block)) { EAction.handleUserMessage("internal error"); this.setState(-1); this.terminate(); return; } var subIds = document.queryBlockEntities(this.blockId); for (var j = 0; j < subIds.length; j++) { var sub = document.queryEntity(subIds[j]); var clone = sub.clone(); clone.move(this.pos); op.addObject(clone, false); } return op; };
The getOperation is called "as usual" by pickCoordinate:
InsertExplodedBlock.prototype.pickCoordinate = function(event, preview) { var di = this.getDocumentInterface(); var document = this.getDocument(); this.pos = event.getModelPosition(); var op; switch (this.state) { case InsertExplodedBlock.State.SettingDestination: if (preview) { this.updatePreview(); } else { op = this.getOperation(false); if (op == undefined) { break; } di.applyOperation(op); di.setRelativeZero(this.pos); this.setState(-1); this.terminate(); } break; } };
Re: Adding objects in a batch
op.addObject(obj, false) inserts the object onto the same layer, into the same block as the original. If I understand the intention correctly, you want to insert the clone into the current block instead (?).
In this case, set the blockId of the clone to the current blockId and use op.addObject(obj, true) instead.
In this case, set the blockId of the clone to the current blockId and use op.addObject(obj, true) instead.
Re: Adding objects in a batch
andandrew wrote:into the same block as the original
Yes, that's the point. I want to insert all entities onto the original layer but the current block.andrew wrote:you want to insert the clone into the current block instead
Thank you very much, this was it. With addO..true it didn't worked, but with addO..false. Now the code is:andrew wrote:set the blockId of the clone to the current blockId and use op.addObject(obj, true) instead.
Code: Select all
var currentBlockId = document.getCurrentBlockId();
var op = new RAddObjectsOperation();
var subIds = document.queryBlockEntities(this.blockId);
if (isNull(subIds)) {
EAction.handleUserMessage("internal error");
this.setState(-1);
this.terminate();
return;
}
for (var j = 0; j < subIds.length; j++) {
var sub = document.queryEntity(subIds[j]);
var clone = sub.clone();
clone.setBlockId(currentBlockId);
clone.move(this.pos);
op.addObject(clone, false);
}
Re: Adding objects in a batch
...with the code above, the original entities are removed from the original block. After inserting "storage.setObjectId(clone, RObject.INVALID_ID)" it works as desired.