Create a multi-polygon with intersecting loops using the following methods:
OdDbDatabasePtr pDb = pHostApp->createDatabase();
OdDbBlockTableRecordPtr pModelSpace = pDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite);
OdDbMPolygonPtr pMPolygon = OdDbMPolygon::createObject();
pMPolygon->setDatabaseDefaults(pDb);
pMPolygon->setPattern(OdDbHatch::kPreDefined, L"SOLID");
pModelSpace->appendOdDbEntity(pMPolygon);
OdGeDoubleArray bugles;
bugles.resize(4, 0);
OdGePoint2dArray vertexArr;
vertexArr.append(OdGePoint2d(0, 0));
vertexArr.append(OdGePoint2d(10, 0));
vertexArr.append(OdGePoint2d(10, 10));
vertexArr.append(OdGePoint2d(0, 10));
pMPolygon->appendMPolygonLoop(vertexArr, bugles);
vertexArr.clear();
vertexArr.append(OdGePoint2d(2, 2));
vertexArr.append(OdGePoint2d(2, 8));
vertexArr.append(OdGePoint2d(6, 8));
vertexArr.append(OdGePoint2d(6, 2));
pMPolygon->appendMPolygonLoop(vertexArr, bugles);
vertexArr.clear();
vertexArr.append(OdGePoint2d(7, 2));
vertexArr.append(OdGePoint2d(5, 6));
vertexArr.append(OdGePoint2d(9, 6));
vertexArr.append(OdGePoint2d(9, 2));
pMPolygon->appendMPolygonLoop(vertexArr, bugles, false);
Use the balanceDisplay()
method to mark one of the loops as
invalid and to not draw it.
pMPolygon->balanceDisplay();
Get the data of loop #1 (drawn as a hole) to store it before removing the
loop and to restore it later. Execute the balanceDisplay()
method
again to make invalid loops valid again.
OdGePoint2dArray storeVertex;
OdGeDoubleArray storeBulges;
pMPolygon->getMPolygonLoopAt(1, storeVertex, storeBulges);
pMPolygon->removeMPolygonLoopAt(1);
pMPolygon->balanceDisplay();
Insert the stored loop to the multi-polygon and call the
balanceDisplay()
method to mark it as invalid. In this case only
edges are drawn (shown in the figure as an only a black edge on a white
hole).
pMPolygon->appendMPolygonLoop(storeVertex, storeBulges, false);
pMPolygon->balanceDisplay();
Manually change loop directions by using the tree and the following methods:
createLoopsFromBoundaries()
getLoopDirection()
setLoopDirection()
getMPolygonTree()
deleteMPolygonTree()
getArea()
void recursiveCheckTreeDirection(OdDbMPolygonPtr pMPolygon, const OdDbMPolygonNode* node, bool bClockWise)
{
if (node->mLoopIndex >= 0)
{
OdDbMPolygon::loopDir loopDirection;
pMPolygon->getLoopDirection(node->mLoopIndex, loopDirection);
if (bClockWise && loopDirection == OdDbMPolygon::kExterior)
pMPolygon->setLoopDirection(node->mLoopIndex, OdDbMPolygon::kInterior);
else if(!bClockWise && loopDirection == OdDbMPolygon::kInterior)
pMPolygon->setLoopDirection(node->mLoopIndex, OdDbMPolygon::kExterior);
for (int i = 0; i < node->mChildren.size(); ++i)
{
recursiveCheckTreeDirection(pMPolygon, node->mChildren[i], !bClockWise);
}
}
}
OdDbDatabasePtr pDb = pHostApp->createDatabase();
OdDbBlockTableRecordPtr pModelSpace = pDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite);
OdDbMPolygonPtr pMPolygon = OdDbMPolygon::createObject();
pMPolygon->setDatabaseDefaults(pDb);
pMPolygon->setPattern(OdDbHatch::kPreDefined, L"SOLID");
pModelSpace->appendOdDbEntity(pMPolygon);
OdDbPolylinePtr pPolyline = OdDbPolyline::createObject();
pPolyline->addVertexAt(0, OdGePoint2d(0, 0));
pPolyline->addVertexAt(1, OdGePoint2d(0, 10));
pPolyline->addVertexAt(2, OdGePoint2d(10, 10));
pPolyline->addVertexAt(3, OdGePoint2d(10, 0));
pPolyline->addVertexAt(4, OdGePoint2d(0, 0));
pPolyline->setClosed(true);
OdDbCirclePtr pCircle = OdDbCircle::createObject();
pCircle->setCenter(OdGePoint3d(5, 5, 0));
pCircle->setRadius(4);
OdDbEllipsePtr pEllipse = OdDbEllipse::createObject();
pEllipse->set(OdGePoint3d(5, 5, 0), OdGeVector3d::kZAxis, OdGeVector3d::kXAxis, 1.0);
pModelSpace->appendOdDbEntity(pPolyline);
pModelSpace->appendOdDbEntity(pCircle);
pModelSpace->appendOdDbEntity(pEllipse);
OdDbObjectIdArray idArr;
idArr.append(pPolyline->id());
idArr.append(pCircle->id());
idArr.append(pEllipse->id());
OdIntArray rejectedObjsArr;
pMPolygon->createLoopsFromBoundaries(idArr, rejectedObjsArr);
double area = 0;
pMPolygon->getArea(area); //area == -46.5929 - it is not correct. Change of the loops direction is required
OdDbMPolygonNode* root = NULL;
pMPolygon->getMPolygonTree(root);
if (root)
{
for (int i = 0; i < root->mChildren.size(); ++i)
{
recursiveCheckTreeDirection(pMPolygon, root->mChildren[i], false);
}
}
pMPolygon->getArea(area); //area == 52.8761 - it is correct
pMPolygon->deleteMPolygonTree(root);
Copyright © 2002 – 2021. Open Design Alliance. All rights reserved.
|