I am trying to draw a cirle in an already running instance of AutoCAD, append it to the existing drawing.
Is that possible? What is the easiest way?
Thx
As you mentioned "an already running instance of AutoCAD", I'm assuming you want to automate AutoCAD, usually via ActiveX COM Automation. You should use AcadApplication interface (and cannot use AcDb or .NET Mgd references).
Here is a ActiveX C++ generic code sample from this blog post. Note the acac19enu.tlb reference, where 19 stands for the AutoCAD version. The current one is AutoCAD 2017 (library version: 21).
#import "acax19ENU.tlb" no_namespace
#include <rxmfcapi.h>
#include <axpnt3d.h>
void fAddAttribute()
{
try
{
// get the ActiveX application object from AutoCAD, inc ref count
IAcadApplicationPtr pAcadApp = acedGetAcadWinApp()->GetIDispatch(TRUE);
// now get the active doc
IAcadDocumentPtr pActiveDoc = pAcadApp->ActiveDocument;
IAcadBlockPtr pBlock = NULL;
TCHAR *pBlkName = _T("some_block_name");
// create an activex compatible insertion point3d
AcAxPoint3d axInsPnt(0,0,0);
// now add the block name
pBlock = pActiveDoc->Blocks->Add(axInsPnt.asVariantPtr(),_bstr_t(pBlkName));
// now add an Attribute to the block
IAcadAttributePtr pAttDef;
pAttDef = pBlock->AddAttribute(1.0, (AcAttributeMode)0 ,
_bstr_t("Type the employee name"), axInsPnt.asVariantPtr(),
_bstr_t("empname"),_bstr_t(""));
//attribute added
}
catch(_com_error &es)
{
acutPrintf(L"\nError : %s", es.ErrorMessage());
}
}
Couldn't find anything in C but here's a C# example from the Developer Guide:
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
[CommandMethod("AddCircle")]
public static void AddCircle()
{
// Get the current document and database
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
// Start a transaction
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Open the Block table for read
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for write
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
// Create a circle that is at 2,3 with a radius of 4.25
Circle acCirc = new Circle();
acCirc.SetDatabaseDefaults();
acCirc.Center = new Point3d(2, 3, 0);
acCirc.Radius = 4.25;
// Add the new object to the block table record and the transaction
acBlkTblRec.AppendEntity(acCirc);
acTrans.AddNewlyCreatedDBObject(acCirc, true);
// Save the new object to the database
acTrans.Commit();
}
}
In pure C it may be complicated, so good luck. But if you use C++ and ARX try this:
Acad::ErrorStatus AddCircle(AcGePoint3d center , double r , AcDbObjectId& id , AcDbBlockTableRecord* pBlock)
{
AcDbCircle* pCirEnt = NULL;
pCirEnt = new AcDbCircle();
pCirEnt->setCenter(center);
pCirEnt->setRadius(r);
Acad::ErrorStatus es = Add(pCirEnt , pBlock);
es = pCirEnt->close();
id = pCirEnt->objectId();
return es ;
}
Acad::ErrorStatus Add( AcDbEntity * pEnt, AcDbBlockTableRecord* Blok)
{
if ( !pEnt ) {
return Acad::eNullEntityPointer ;
}
Acad::ErrorStatus es;
if (!Blok)
{
Blok = getModelSpace(AcDb::kForWrite);
if (!Blok) return Acad::eInvalidOwnerObject;
}
if (Blok->isWriteEnabled() == Adesk::kFalse )
{
AcDbObject* pObj = NULL;
es = acdbOpenObject(pObj,Blok->objectId (),AcDb::kForWrite) ;
Blok = AcDbBlockTableRecord::cast(pObj);
}
if ((es = Blok->appendAcDbEntity(pEnt)) != Acad::eOk ) // eAlreadyInDb = wcześniej wstawione do innego bloku.
{
Blok->close();
return es;
}
Blok->close();
return Acad::eOk;
}
AcDbBlockTableRecord* getModelSpace(AcDb::OpenMode mode)
{
AcDbBlockTableRecord* Blok = NULL;
Acad::ErrorStatus es;
AcDbDatabase * pDb = acdbHostApplicationServices()->workingDatabase();
if (!pDb) return NULL;
AcDbBlockTable* pTbl = NULL;
if ((es= pDb->getBlockTable(pTbl, AcDb::kForRead) ) != Acad::eOk )
return NULL;
if ((es = pTbl->getAt(ACDB_MODEL_SPACE, Blok, mode)) != Acad::eOk )
{
pTbl->close();
return NULL;
}
pTbl->close();
return Blok;
}