Получение упорядоченного набора ребер граней с использованием BRep
При перемещении по ребрам граней с использованием BRep API, ребра могут быть не упорядочены так, чтобы конечная точка предыдущего ребра совпадала с начальной точкой следующего ребра. Это происходит потому, что ребра разделяются между несколькими гранями, и это же ребро возвращается, когда мы снова проходим по другой грани. Так как начальные и конечные точки ребра остаются неизменными, то это будет признаком ориентации одной из граней.
Вот пример кода для получения информации о ребрах и ориентации их внутри петель при их прохождении:
- void GetEdges()
- {
- ads_name eName;
- ads_point pt;
- if (RTNORM != acedEntSel( L"\nВыберите 3DSolid: " , eName, pt))
- return ;
- AcDbObjectId id;
- acdbGetObjectId(id, eName);
- AcDb3dSolid* pSolid;
- acdbOpenObject(pSolid, id, AcDb::kForRead);
- if (pSolid == NULL ) return ;
- AcBrBrep pBrep;
- pBrep.setSubentPath(AcDbFullSubentPath( id, kNullSubentId ));
- AcBr::ErrorStatus returnValue = AcBr::eOk;
- AcBrBrepFaceTraverser brepFaceTrav;
- if (brepFaceTrav.setBrep(pBrep) != AcBr::eOk)
- {
- acutPrintf(L"\n Ошибка в AcBrBrepFaceTraverser::setBrep:" ));
- return ;
- }
- int faceCount = 0;
- while (!brepFaceTrav.done() && (returnValue == AcBr::eOk))
- {
- faceCount++;
- AcBrFace face;
- if (brepFaceTrav.getFace(face) != AcBr::ErrorStatus::eOk)
- {
- continue ;
- }
- AcGeSurface *pGeSurface = NULL;
- face.getSurface(pGeSurface);
- AcGeInterval intervalU, intervalV;
- pGeSurface->getEnvelope(intervalU, intervalV);
- AcBrFaceLoopTraverser faLoTrav;
- for ( faLoTrav.setFace(face); !faLoTrav.done(); faLoTrav.next() )
- {
- AcBrLoop lp;
- faLoTrav.getLoop(lp);
- AcBr::LoopType type;
- acutPrintf(L"\nГрань: %d", faceCount);
- AcBrLoopEdgeTraverser loEdTrav;
- if ( loEdTrav.setLoop(faLoTrav) == AcBr::eOk)
- {
- int edgeCount = 0;
- AcGePoint2dArray verts;
- AcGeVoidPointerArray edgeArray;
- for (;! loEdTrav.done(); loEdTrav.next())
- {
- edgeCount++;
- AcBrEdge edge;
- loEdTrav.getEdge(edge);
- AcBrVertex start;
- edge.getVertex1( start );
- AcGePoint3d stPt3d;
- start.getPoint( stPt3d );
- AcBrVertex end;
- edge.getVertex2( end );
- AcGePoint3d endPt3d;
- end.getPoint( endPt3d );
- Adesk::Boolean orient = Adesk::kFalse;
- loEdTrav.getEdgeOrientToLoop(orient);
- if (orient) {
- acutPrintf(L"\nРебро %d: (%3.1f %3.1f %3.1f) - (%3.1f %3.1f %3.1f)", edgeCount,
- stPt3d.x, stPt3d.y, stPt3d.z,
- endPt3d.x, endPt3d.y, endPt3d.z);
- }
- else
- {
- acutPrintf(L"\nРебро %d: (%3.1f %3.1f %3.1f) - (%3.1f %3.1f %3.1f)", edgeCount,
- endPt3d.x, endPt3d.y, endPt3d.z,
- stPt3d.x, stPt3d.y, stPt3d.z);
- }
- }
- }
- }
- returnValue = brepFaceTrav.next();
- }
- }
В качестве примера, вот результат прохождения цикла:
// Учет ориентации ребер в петле
Грань : 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://adn-cis.org/forum/index.php?topic=1909
Опубликовано 02.03.2015