Hi everyone,
I'm in trouble with the insertion of an autocad block coming from external dwg file.
I saw the acdbblockreference class on ObjectARX documentation.
I saw the example on block insertion
void addBlockWithAttributes() { // Get an insertion point for the block reference, // definition, and attribute definition. // AcGePoint3d basePoint; if (acedGetPoint(NULL, "\nEnter insertion point: ", asDblArray(basePoint)) != RTNORM) return; // Get the rotation angle for the attribute definition. // double textAngle; if (acedGetAngle(asDblArray(basePoint), "\nEnter rotation angle: ", &textAngle) != RTNORM) return; // Define the height used for the attribute definition text. // double textHeight; if (acedGetDist(asDblArray(basePoint), "\nEnter text height: ", &textHeight) != RTNORM) return; // Build the block definition to be inserted. // AcDbObjectId blockId; defineBlockWithAttributes(blockId, basePoint, textHeight, textAngle); // Step 1: Allocate a block reference object. // AcDbBlockReference *pBlkRef = new AcDbBlockReference; // Step 2: Set up the block reference to the newly // created block definition. // pBlkRef->setBlockTableRecord(blockId); // Give it the current UCS normal. // struct resbuf to, from; from.restype = RTSHORT; from.resval.rint = 1; // UCS to.restype = RTSHORT; to.resval.rint = 0; // WCS AcGeVector3d normal(0.0, 0.0, 1.0); acedTrans(&(normal.x), &from, &to, Adesk::kTrue, &(normal.x)); // Set the insertion point for the block reference. // pBlkRef->setPosition(basePoint); // Indicate the LCS 0.0 angle, not necessarily the UCS 0.0 angle. // pBlkRef->setRotation(0.0); pBlkRef->setNormal(normal); // Step 3: Open the current database's model space // block table record. // AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase() ->getSymbolTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRecord; pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite); pBlockTable->close(); // Append the block reference to the model space // block table record. // AcDbObjectId newEntId; pBlockTableRecord->appendAcDbEntity(newEntId, pBlkRef); pBlockTableRecord->close(); // Step 4: Open the block definition for read. // AcDbBlockTableRecord *pBlockDef; acdbOpenObject(pBlockDef, blockId, AcDb::kForRead); // Set up a block table record iterator to iterate // over the attribute definitions. // AcDbBlockTableRecordIterator *pIterator; pBlockDef->newIterator(pIterator); AcDbEntity *pEnt; AcDbAttributeDefinition *pAttdef; for (pIterator->start(); !pIterator->done(); pIterator->step()) { // Get the next entity. // pIterator->getEntity(pEnt, AcDb::kForRead); // Make sure the entity is an attribute definition // and not a constant. // pAttdef = AcDbAttributeDefinition::cast(pEnt); if (pAttdef != NULL && !pAttdef->isConstant()) { // We have a non-constant attribute definition, // so build an attribute entity. // AcDbAttribute *pAtt = new AcDbAttribute(); pAtt->setPropertiesFrom(pAttdef); pAtt->setInvisible(pAttdef->isInvisible()); // Translate the attribute by block reference. // To be really correct, the entire block // reference transform should be applied here. // basePoint = pAttdef->position(); basePoint += pBlkRef->position().asVector(); pAtt->setPosition(basePoint); pAtt->setHeight(pAttdef->height()); pAtt->setRotation(pAttdef->rotation()); pAtt->setTag("Tag"); pAtt->setFieldLength(25); char *pStr = pAttdef->tag(); pAtt->setTag(pStr); free(pStr); pAtt->setFieldLength(pAttdef->fieldLength()); // The database column value should be displayed. // INSERT prompts for this. // pAtt->setTextString("Assigned Attribute Value"); AcDbObjectId attId; pBlkRef->appendAttribute(attId, pAtt); pAtt->close(); } pEnt->close(); // use pEnt... pAttdef might be NULL } delete pIterator; pBlockDef->close(); pBlkRef->close(); }
but, in the acdbblockreference I can't specify an external dwg file name to open and load the dwg block definition.
How can I add an external block into my dwg file?
Thank you for your help.
You can't load an external file directly in a BlockReference.
You have to create a BlockTableRecord from the external file and than you have to reference this BlockTableRecord from your BlockReference...
Here is a piece of code showing you how you can create a BlockTableRecord from an external file
AcDbObjectId blockTableRec; Acad::ErrorStatus err; AcDbDatabase *pDb = new AcDbDatabase( Adesk::kFalse ); if ( (err = pDb->readDwgFile( path )) != Acad::eOk ) { delete pDb;
return; // Somehting went wrong } if ( (err = acdbCurDwg()->insert( blockTableRec, pszBlkName, pDb )) != Acad::eOk ) { delete pDb; return; // Something went wrong } delete pDb;
Now you have a Block Table Record with the Name pszBlkName and the id stored in blockTableRec containing your external drawing and you can reference it with a BlockReference.
Perfect,
in this way I insert a blocktablerecord in the database,
and what about the graphics?
Can I simulate an autocad insert command without asking to the user the parameters, but specifing only scale in code.
The only thing the user can modify is the insertion point, but I want that the user can choose an insertion point with the graphics(already scaled) of the block attached to the mouse pointer.
How can I simulate it? I have to insert the block first in the position (0,0,0) and then call a move on the acdbblockreference?
Thank you for the quick reply and for your precious help.
Massimo.
If yoiur code is executing in a document context, you can simply call the _-INSERT command via acedCommand. Use the command's _Scale option to specify the scale first.
Can't find what you're looking for? Ask the community or share your knowledge.