Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Examples of Working with Multi-Polygons

Example of Creating a Multi-Polygon

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();

Example of Changing Loop Directions

Manually change loop directions by using the tree and the following methods:

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);

See Also

Working with Multi-Polygons

Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.