AcDbObjectId addToDataBase(AcDbEntity * pEnt, CString BlockTableName, AcDbDatabase * pDwg)
{
AcDbObjectId oId;
Acad::ErrorStatus es;
AcDbBlockTable * pTbl;
es = acdbOpenObject(pTbl, pDwg->blockTableId(), AcDb::kForRead);
if (es != Acad::eOk) return NULL;
AcDbBlockTableRecord * pRec;
es = pTbl->getAt(BlockTableName, pRec, AcDb::kForWrite);
if (es != Acad::eOk)
{
if (es == Acad::eKeyNotFound)
{
AcDbObjectId newRec;
pRec = new AcDbBlockTableRecord();
pRec->setName(BlockTableName);
pTbl->upgradeOpen();
pTbl->add(newRec, pRec);
pRec->close();
es = acdbOpenObject(pRec, newRec, AcDb::kForWrite);
}
else return NULL;
}
es = pRec->appendAcDbEntity(oId, pEnt);
es = pRec->close();
pTbl->close();
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
return oId;
}
AcDbObjectId createPoint(AcGePoint3d pt)
{
AcDbObjectPointer<AcDbPoint> pPoint;
pPoint.create();
pPoint->setPosition(pt);
pPoint->setColorIndex(6);
return addToDataBase(pPoint);
}
AcDbObjectId createPolygone()
{
AcGePoint3d strPt;
AcGePoint2d endPt;
AcDbObjectIdArray ptArray;
TCHAR result[8] = { _T("") };
int rez = RTNORM;
bool multi = false;
bool first = true;
AcDbObjectPointer<AcDbPolyline> pLine;
pLine.create();
pLine->setDatabaseDefaults();
pLine->setClosed(TRUE);
AcDbObjectId plineId = addToDataBase(pLine);
pLine->close();
while (rez != RTCAN)
{
bool can = true;
AcDbExtents ext;
if (multi)
{
int rez2 = RTNORM;
AcDbObjectIdArray ptArray2;
while (rez2 != RTCAN && rez2 != RTKWORD)
{
acedInitGet(RSG_OTHER, _T("Single Multi Undo"));
if (first)
{
rez2 = acedGetPoint(NULL, _T("\nSelect Single/Multi/Undo<Multi>:"), asDblArray(strPt));
first = false;
}
else
{
rez2 = acedGetPoint(asDblArray(strPt), _T("\nSelect Single/Multi/Undo<Multi>:"), asDblArray(strPt));
}
if(rez2==RTNORM)
{
can = false;
ext.addPoint(strPt);
ptArray2.append(createPoint(strPt));
}
}
for (int i = 0; i < ptArray2.length(); i++)
{
AcDbEntityPointer pEnt(ptArray2.at(i), AcDb::kForWrite);
if (pEnt.openStatus() == Acad::eOk)
pEnt->erase();
}
if(rez2==RTCAN && !can)
{
rez = RTNORM;
}
else
rez = rez2;
}
else
{
acedInitGet(RSG_OTHER, _T("Single Multi Undo"));
if (first)
{
rez = acedGetPoint(NULL, _T("\nSelect Single/Multi/Undo<Single>:"), asDblArray(strPt));
first = false;
}
else
{
rez = acedGetPoint(asDblArray(endPt), _T("\nSelect Single/Multi/Undo<Single>:"), asDblArray(strPt));
}
if(rez==RTNORM)
ext.addPoint(strPt);
}
switch (rez)
{
case RTCAN: break;
case RTNORM:
{
endPt = AcGePoint2d((ext.maxPoint().x + ext.minPoint().x) / 2,
(ext.maxPoint().y + ext.minPoint().y) / 2);
pLine.open(plineId, AcDb::kForWrite);
if (pLine.openStatus() == Acad::eOk)
{
pLine->addVertexAt(pLine->numVerts(), endPt);
pLine.close();
ptArray.append(createPoint(AcGePoint3d(endPt.x,endPt.y,0)));
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
}
break;
}
case RTKWORD:
{
if (acedGetInput(result) == RTNORM)
{
if (_tcscmp(result, _T("Multi")) == 0)
multi = true;
if (_tcscmp(result, _T("Single")) == 0)
multi = false;
if (_tcscmp(result, _T("Undo")) == 0)
{
pLine.open(plineId, AcDb::kForWrite);
if(pLine.openStatus()==Acad::eOk && pLine->numVerts()>0)
{
pLine->removeVertexAt(pLine->numVerts() - 1);
pLine->getPointAt(pLine->numVerts() - 1, endPt);
pLine.close();
AcDbEntityPointer pEnt(ptArray.last(), AcDb::kForWrite);
if (pEnt.openStatus() == Acad::eOk)
pEnt->erase();
}
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
}
}
break;
}
default:
break;
}
};
pLine.open(plineId, AcDb::kForWrite);
if (pLine.openStatus() == Acad::eOk)
{
if (pLine->numVerts() < 3)
pLine->erase();
pLine->close();
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
}
for (int i=0; i < ptArray.length(); i++)
{
AcDbEntityPointer pEnt(ptArray.at(i), AcDb::kForWrite);
if (pEnt.openStatus() == Acad::eOk)
pEnt->erase();
}
return plineId;
}
AcDbObjectId createHatch(AcDbObjectId oId)
{
AcDbObjectPointer<AcDbHatch> pHatch;
pHatch.create();
// Set hatch plane
AcGeVector3d normal(0.0, 0.0, 1.0);
pHatch->setDatabaseDefaults();
pHatch->setNormal(normal);
pHatch->setElevation(0.0);
pHatch->setPatternScale(5);
// Set hatch pattern to ANSI31 predefined type //
pHatch->setPattern(AcDbHatch::kPreDefined, _T("SOLID"));
// Set Associativity
pHatch->setAssociative(Adesk::kTrue);
// Construct database AcDbLines
AcDbObjectId hatchId;
AcDbObjectIdArray dbObjIds;
dbObjIds.append(oId);
// Append an external rectangular loop to hatch boundary //
pHatch->appendLoop(AcDbHatch::kExternal, dbObjIds);
// Elaborate hatch lines
pHatch->evaluateHatch();
// Get all associative source boundary object Ids for later use.
dbObjIds.setLogicalLength(0);
pHatch->getAssocObjIds(dbObjIds);
// Post hatch entity to database
hatchId = addToDataBase(pHatch);
// Attach hatchId to all source boundary
// objects for notification.
AcDbEntity *pEnt;
int numObjs = dbObjIds.length();
for (int i = 0; i < numObjs; i++)
{
if (acdbOpenAcDbEntity(pEnt, dbObjIds[i],AcDb::kForWrite) == Acad::eOk)
{
pEnt->addPersistentReactor(hatchId);
pEnt->close();
}
}
return hatchId;
}
//from modal dialog
BeginEditorCommand();
plineId = createPolygone();
CompleteEditorCommand();
if (plineId.isValid() && !plineId.isErased() && !plineId.isNull())
{
hatchId = createHatch(plineId);
}