I'm trying to implement a custom Jig to Block References.
My Block have just one circle and many attributes, which just 3 of them are visible.
I had a hard time to figure out how to make the visible attributes to show during the drag, just the circle was showing up.
After reading this:
I learned that Block Reference should be on the database after the drag begin.
Now I have a jig showing my BlockReference complete, but there are two copies on the screen, one in the right place (in the cursor position) and another about 2*(X,Y), like a ghost (maybe more like a twin, because it isn't fading).
My function tha makes the Jig work:
//This is object has my block reference this->tmpPv = new PV; setDispPrompt(_T("\nClick\n")); //Solution of blog throught-the-interface //A map with attributes tags and their positions AcDbObjectId* pBlockId = PV::getBlockId(); //Get the Id of de Block Definition AcDbBlockTableRecord* pBlockTableRecord; acdbOpenObject(pBlockTableRecord, *pBlockId, AcDb::kForWrite); AcDbBlockTableRecordIterator* pBlockTableRecordIterator; pBlockTableRecord->newIterator(pBlockTableRecordIterator); pBlockTableRecord->close(); AcDbEntity *pEnt; AcDbAttributeDefinition *pAttdef; //For each attribute: include it on the MAP whit the position for(pBlockTableRecordIterator->start(); !pBlockTableRecordIterator->done(); pBlockTableRecordIterator->step()) { pBlockTableRecordIterator->getEntity(pEnt, AcDb::kForRead); pAttdef = AcDbAttributeDefinition::cast(pEnt); if (pAttdef != NULL && !pAttdef->isConstant()) { map[pAttdef->tag()] = pAttdef->position(); pAttdef->close(); } pEnt->close(); } delete pBlockTableRecordIterator; AcEdJig::DragStatus status = drag(); this->tmpPv->close(); if(status == AcEdJig::kNormal) {
return this->tmpPv; } else if(status == AcEdJig::kCancel) { acutPrintf(_T("*Cancelado*\n")); //TODO: Remove the Block from the database } return NULL; delete this->tmpPv;
Then my AcEdJig::update:
this->tmpPv is the object with the pointer to my AcDbBlockReference (getBlockReference())
this->tmpCenterPoint is my new point (from the sampler method)
if(!this->tmpPv->getBlockReference()->isWriteEnabled()) this->tmpPv->openForWrite(); this->tmpPv->getBlockReference()->setPosition(tmpCenterPt); AcDbObjectIterator* itr = this->tmpPv->getBlockReference()->attributeIterator(); AcDbAttribute *pAtt; AcGePoint3d pAuxPoint = tmpCenterPt; for(itr->start(); !itr->done(); itr->step()) { AcDbObjectId pAttId = itr->objectId(); this->tmpPv->getBlockReference()->openAttribute(pAtt, pAttId, AcDb::kForWrite); if (pAtt != NULL && !pAtt->isConstant()) { pAuxPoint = tmpCenterPt; pAuxPoint += map[pAtt->tag()].asVector(); pAtt->setPosition(pAuxPoint); pAtt->close(); } } delete itr; return Adesk::kTrue;
My main problem is that there are two blocks references showing up during the drag, when I click just the correct one stays
What you are trying to do is almost certainly not going to work. Adding the jigged object to the database introduces all sorts of problems that you haven't even encountered yet. It would be much easier to create a custom object that encapsulates your visible graphics in a single object, then jig that object. Once the jig is complete, you can delete the custom object and add an actual block reference to the database if that is what you want to end up with.
--
Owen Wengerd
ManuSoft
It does work, not as it should
The object is created and inserted in database only once. I can choose on AutoCad where to place it, the problem is that the object is showing duplicated, but at the end I have just the block reference in the right position.
I liked our suggestion, It didn't cross my mind. But i really want to solve this issue, for the honor
Same problem here.
A little suggestion: instead of using setPosition and loop on each attribute to set position, you should call transformBy. The main advantage is that you don't need to care about attributes and you can apply rotation and scale.
Regards,
Jonathan