static AcDbRegion* GetRegion(AcGePoint3d cenPt)
{
AcDbRegion* pRegion = NULL;
AcDbCircle* pCircle = new AcDbCircle(cenPt,AcGeVector3d::kZAxis,10);
AcDbVoidPtrArray curveSegments;curveSegments.append(pCircle);
AcDbVoidPtrArray regions;
Acad::ErrorStatus es = AcDbRegion::createFromCurves(curveSegments,regions);
delete pCircle;pCircle = NULL;
if(Acad::eOk == es && regions.length()>0)
{
AcDbRegion* pTmpRegion = (AcDbRegion*)regions[0];
if(pTmpRegion)
{
pRegion = (AcDbRegion*)pTmpRegion->clone();
}
}
for(int i=0;i<regions.length();++i)
{
delete (AcRxObject*)regions[i];
}
return pRegion;
}
static AcDbObjectId PostToModelSpace(AcDbEntity* pEnt,AcDbDatabase *pDb = acdbCurDwg())
{
Acad::ErrorStatus es;
AcDbObjectId entId = AcDbObjectId::kNull;
AcDbBlockTable * pBlockTable = NULL;
pEnt->setDatabaseDefaults(pDb);
es = pDb->getBlockTable(pBlockTable, AcDb::kForRead);
if (es != Acad::eOk)
{
return entId;
}
AcDbBlockTableRecord *pBlockTableRecord = NULL;
es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForWrite);
pBlockTable->close();
if (es != Acad::eOk)
{
return entId;
}
es = pBlockTableRecord->appendAcDbEntity(entId, pEnt);
pBlockTableRecord->close();
pEnt->close();
return entId;
}
Acad::ErrorStatus es;
AcDbRegion* pRegion1 = GetRegion(AcGePoint3d(0,0,0));
AcDbRegion* pRegion2 = GetRegion(AcGePoint3d(10,0,0));
if(pRegion1 && pRegion2)
{
es = pRegion1->booleanOper(AcDb::kBoolUnite,pRegion2);
if(Acad::eOk == es && pRegion2->isNull())
{
delete pRegion2;pRegion2 = NULL;
}
}
AcDbRegion* pTmp = (AcDbRegion*)pRegion1->clone();
AcDbObjectId id1 = PostToModelSpace(pTmp,acdbCurDwg());
AcDbDatabase* pDb = new AcDbDatabase(true,false);
pRegion1->setDatabaseDefaults(pDb);
AcDbObjectId id2 = PostToModelSpace(pRegion1,pDb);
pDb->saveAs(_T("D:\\Region.dwg"));delete pDb;
return;
id1 is ok.id2 is null;
@tbrammer @daniel_cadext @Alexander.Rivilis
Solved! Go to Solution.
Solved by tbrammer. Go to Solution.
AcDbObject::clone() creates a "shallow copy" of the AcDbObject. So it is not safe to append clones to a different database. Your code works for simple entities like AcDbLine - but I would not recomment to do this anyway.
You should use AcDbDatabase::wblockCloneObjects(..) to copy objects from one DB to another.
AcDbRegion* pTmp = (AcDbRegion*)pRegion1->clone();
AcDbObjectId id1 = PostToModelSpace(pTmp,acdbCurDwg());
These two lines prove that they can be added to the current database normally. Even without these two lines, pRegion1 cannot be added to pDb normally.
Correct. A clone is a clone. It doesn't matter which one you add to the DB.
But since it is a shallow clone, some internal references of the regions point to the same internal data.
So as soon as you add one of the two regions to the database you must delete the second one.
This is what happens when you clone() region 1 and append the clone to the DB :
Region 1 depends on the internal data that is now tied to region2 and the DB.
It makes no difference whether you add region 1 or region 2 to the DB. In both cases you must delete the other region. Some simple entities like AcDbLine don't have references like this. But you can't rely on this.
The safe way is to use deep cloning. This guarantees that all internal data is copied as well.
Can't find what you're looking for? Ask the community or share your knowledge.