ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

insert block from external dwg block file [ACAD2013]

3 REPLIES 3
Reply
Message 1 of 4
gatti.massimo
2179 Views, 3 Replies

insert block from external dwg block file [ACAD2013]

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.

3 REPLIES 3
Message 2 of 4
Matti72
in reply to: gatti.massimo

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.

Message 3 of 4
gatti.massimo
in reply to: Matti72

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.

Message 4 of 4
owenwengerd
in reply to: gatti.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.

--
Owen Wengerd
ManuSoft

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost