ADN Open CIS
Сообщество программистов Autodesk в СНГ

02/03/2015

Получение упорядоченного набора ребер граней с использованием BRep

При перемещении по ребрам граней с использованием BRep API, ребра могут быть не упорядочены так, чтобы конечная точка предыдущего ребра совпадала с начальной точкой следующего ребра. Это происходит потому, что ребра разделяются между несколькими гранями, и это же ребро возвращается, когда мы снова проходим по другой грани. Так как начальные и конечные точки ребра остаются неизменными, то это будет признаком ориентации одной из граней.

Вот пример кода для получения информации о ребрах и ориентации их внутри петель при их прохождении:

Код - C++: [Выделить]
  1. void GetEdges()
  2. {
  3.   ads_name eName;
  4.   ads_point pt;
  5.  
  6.   if (RTNORM != acedEntSel( L"\nВыберите 3DSolid: " , eName, pt))
  7.     return ;
  8.  
  9.   AcDbObjectId id;
  10.   acdbGetObjectId(id, eName);
  11.  
  12.   AcDb3dSolid* pSolid;
  13.   acdbOpenObject(pSolid, id, AcDb::kForRead);
  14.  
  15.   if (pSolid == NULL ) return ;
  16.  
  17.   AcBrBrep pBrep;
  18.   pBrep.setSubentPath(AcDbFullSubentPath( id, kNullSubentId ));
  19.  
  20.   AcBr::ErrorStatus returnValue = AcBr::eOk;
  21.   AcBrBrepFaceTraverser brepFaceTrav;
  22.  
  23.   if (brepFaceTrav.setBrep(pBrep) != AcBr::eOk)
  24.   {
  25.     acutPrintf(L"\n Ошибка в AcBrBrepFaceTraverser::setBrep:" ));
  26.     return ;
  27.   }
  28.  
  29.   int  faceCount = 0;
  30.   while  (!brepFaceTrav.done() && (returnValue == AcBr::eOk))
  31.   {
  32.     faceCount++;
  33.     AcBrFace face;
  34.     if  (brepFaceTrav.getFace(face) != AcBr::ErrorStatus::eOk)
  35.     {
  36.       continue ;
  37.     }
  38.  
  39.     AcGeSurface *pGeSurface = NULL;
  40.     face.getSurface(pGeSurface);
  41.     AcGeInterval intervalU, intervalV;
  42.     pGeSurface->getEnvelope(intervalU, intervalV);
  43.     AcBrFaceLoopTraverser faLoTrav;
  44.     for ( faLoTrav.setFace(face); !faLoTrav.done(); faLoTrav.next() )
  45.     {
  46.       AcBrLoop lp;
  47.       faLoTrav.getLoop(lp);
  48.       AcBr::LoopType type;
  49.       acutPrintf(L"\nГрань: %d", faceCount);
  50.  
  51.       AcBrLoopEdgeTraverser loEdTrav;
  52.       if ( loEdTrav.setLoop(faLoTrav) == AcBr::eOk)
  53.       {
  54.         int  edgeCount = 0;
  55.         AcGePoint2dArray verts;
  56.         AcGeVoidPointerArray edgeArray;
  57.         for (;! loEdTrav.done(); loEdTrav.next())
  58.         {
  59.           edgeCount++;
  60.           AcBrEdge edge;
  61.           loEdTrav.getEdge(edge);
  62.           AcBrVertex start;     
  63.           edge.getVertex1( start );  
  64.           AcGePoint3d stPt3d;           
  65.           start.getPoint( stPt3d ); 
  66.           AcBrVertex end;
  67.           edge.getVertex2( end );  
  68.           AcGePoint3d endPt3d;           
  69.           end.getPoint( endPt3d );
  70.           Adesk::Boolean orient = Adesk::kFalse;
  71.  
  72.           loEdTrav.getEdgeOrientToLoop(orient);
  73.           if (orient) {
  74.             acutPrintf(L"\nРебро %d: (%3.1f %3.1f %3.1f) - (%3.1f %3.1f %3.1f)", edgeCount,
  75.               stPt3d.x, stPt3d.y, stPt3d.z,
  76.               endPt3d.x, endPt3d.y, endPt3d.z);
  77.           }
  78.           else
  79.           {
  80.             acutPrintf(L"\nРебро %d: (%3.1f %3.1f %3.1f) - (%3.1f %3.1f %3.1f)", edgeCount,
  81.               endPt3d.x, endPt3d.y, endPt3d.z,
  82.               stPt3d.x, stPt3d.y, stPt3d.z);
  83.           }
  84.         }
  85.       }
  86.     }
  87.     returnValue = brepFaceTrav.next();
  88.   }
  89. }

В качестве примера, вот результат прохождения цикла:

 // Учет ориентации ребер в петле 

 Грань : 3

 Ребро 1: (0,0 0,0 30,0) - (0,0 0,0 0,0)

 Ребро 2: (0,0 0,0 0,0) - (10,0 0,0 0,0)

 Ребро 3: (10,0 0,0 0,0) - (10,0 0,0 30,0)

 Ребро 4: (10,0 0,0 30,0) - (0,0 0,0 30,0)

 

 // Без учета ориентации ребер в петле 

 Грань : 3

 Ребро 1: (0,0 0,0 30,0) - (0,0 0,0 0,0)

 Ребро 2: (10,0 0,0 0,0) - (0,0 0,0 0,0)

 Ребро 3: (10,0 0,0 30,0) - (10,0 0,0 0,0)

 Ребро 4: (0,0 0,0 30,0) - (10,0 0,0 30,0)

 

Источник: http://adndevblog.typepad.com/autocad/2015/02/getting-ordered-edges-by-traversing-brep-loop-edges.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=1909

Опубликовано 02.03.2015