[每日一码] 查找多个AcDbLine的所有交点
// These are template classes to allow AcGePoint3d do be used as a Key do CMap classconst double 采用dTol = 0.0001;
template<> UINT AFXAPI HashKey<AcGePoint3d> (AcGePoint3d key)
{
CString sPoint;
sPoint.Format(采用T("%f,%f,%f"),key.x, key.y ,key.z);
UINT iHash = (NULL == &key) ? 0 : HashKey((LPCSTR)sPoint.GetBuffer());
return iHash;
}
template<> BOOL AFXAPI CompareElements<AcGePoint3d, AcGePoint3d>
(const AcGePoint3d* pElement1, const AcGePoint3d* pElement2)
{
if ((pElement1 == NULL) || (pElement2 == NULL))
return false;
AcGeTol gTol;
gTol.setEqualPoint(采用dTol); // Point comparison tolerance
return (pElement1->isEqualTo(*pElement2,gTol));
}
Next, we will collect the AcDbLine entities in ModelSpace:
普通浏览复制代码
// Collect lines from ModelSpace
Acad::ErrorStatus es;
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
AcDbBlockTableRecordPointer pBTR(acdbSymUtil()->blockModelSpaceId(pDb),AcDb::kForWrite);
AcDbBlockTableRecordIterator *pIter = NULL;
pBTR->newIterator(pIter, true);
AcDbObjectIdArray arrLines;
while(!pIter->done())
{
AcDbEntity *pEnt = NULL;
es = pIter->getEntity(pEnt, AcDb::kForRead);
if (es == Acad::eOk)
{
if (pEnt->isKindOf(AcDbLine::desc()))
arrLines.append(pEnt->objectId());
pEnt->close();
}
pIter->step(true);
}
delete pIter;
pIter = NULL;
if (arrLines.length() == 0)
{
acutPrintf(采用T("There are no lines in Model Space!\n"));
return;
}
else
{
acutPrintf(采用T("We've found %d lines in Model Space!\nChecking intersection with tolerance %f...\n"),
arrLines.length(), 采用dTol);
}
Ok, with the lines collected we will then build our CMap with the information we need:
普通浏览复制代码
// Process lines in pairs
CMap<AcGePoint3d,AcGePoint3d,AcDbObjectIdArray,AcDbObjectIdArray&> mapLines;
acdbTransactionManager->startTransaction();
for (int i=0; i<arrLines.length()-1; i++)
{
AcDbLine* pLineA = NULL;
if (acdbTransactionManager->getObject((AcDbObject*&)pLineA,arrLines<i>, AcDb::kForRead) == Acad::eOk)
{
for (int j=i+1; j<arrLines.length(); j++)
{
AcDbLine* pLineB = NULL;
if (acdbTransactionManager->getObject((AcDbObject*&)pLineB,arrLines, AcDb::kForRead) == Acad::eOk)
{
AcGePoint3dArray arrPts;
if (pLineA->intersectWith(pLineB,AcDb::kOnBothOperands,arrPts) == Acad::eOk)
{
if (arrPts.length() > 0)
{
for (int p=0; p<arrPts.length(); p++)
{
AcDbObjectIdArray arrExist;
if (mapLines.Lookup(arrPts,arrExist) == TRUE)
{
// Existing point...
if (arrExist.contains(pLineA->objectId()) == false)
mapLines].append(pLineA->objectId());
if (arrExist.contains(pLineB->objectId()) == false)
mapLines].append(pLineB->objectId());
}
else
{
// New point...
AcDbObjectIdArray arrNewEnts;
arrNewEnts.append(pLineA->objectId());
arrNewEnts.append(pLineB->objectId());
mapLines.SetAt(arrPts,arrNewEnts);
}
}
}
}
}
}
}
}
acdbTransactionManager->endTransaction();
To demonstrate the use of this information, we then use our CMap data to create AcDbPoint entities on ModeSpace and also print a small report at the command prompt:
普通浏览复制代码
// Just as demonstration, walk through points and add an AcDbPoint entity to ModelSpace then print the info
POSITION pos = mapLines.GetStartPosition();
while (pos)
{
AcGePoint3d ptKey(0,0,0);
AcDbObjectIdArray arrEnts;
mapLines.GetNextAssoc(pos,ptKey, arrEnts);
AcDbPoint* ptEnt = new AcDbPoint(ptKey);
AcDbObjectId idPointEnt;
pBTR->appendAcDbEntity(idPointEnt,ptEnt);
ptEnt->close();
CString sEnts;
for (int e=0; e<arrEnts.length(); e++)
{
ACHAR pBuff = 采用T("");
arrEnts.handle().getIntoAsciiBuffer(pBuff);
CString sBuff;
sBuff.Format( (e==arrEnts.length()-1) ? 采用T("%s"): 采用T("%s,"), pBuff);
sEnts += sBuff;
}
CString sPromptReport;
sPromptReport.Format(采用T("Point (%.4f, %.4f, %.4f) - Entities [%s]\n"),ptKey.x, ptKey.y, ptKey.z, sEnts);
acutPrintf(sPromptReport);
}
页:
[1]