У меня есть два типа листовых CAD-моделей Faces: ModelFace (Лица с ПЛАНАРНЫМИ гранями) и ModelBend (Не ПЛАНАРНЫЙ, существуют между Лицами ModelFaces и представляют собой изгибы листа). Эти грани хранятся в отдельных векторах. Что я хочу сделать, так это найти грани, с которыми соединяется каждый изгиб. Каждой грани и изгибу присваивается положительный и ненулевой целочисленный идентификатор. Желаемый результат - что-то вроде этого :
F1----B1-----F2 Angle : 90 Radius : 4
F2----B2-----F3 Angle : 90 Radius : 4
Это означает, что изгиб 1 радиусом 4 мм соединяет грань 1 и грань 2 под углом 90 градусов и так далее. Тем не менее, я получаю результат, показанный ниже для большинства моделей, независимо от их формата (шаг/игра) :
F1---B1---F2 Angle : 90 Radius : 4
F3---B2---F0 Angle : 0 Radius : 4
F4---B3---F5 Angle : 90 Radius : 1
F0---B4---F0 Angle : 0 Radius : 1
Подобный F3---B2---F0
результат означает, что программа обнаружила, что B2 подключен к лицевой стороне 3, но не смогла идентифицировать другую подключенную сторону, следовательно, значение F0. Также для некоторой модели может быть получен выходF0---B2---F0
, что означает, что не найдено лицо, которое бы соединялось с изгибом 2.
Похоже, что грани, общие для обеих граней, и изгибы не обнаружены, т.е. конечные точки линий граней не совпадают или разделены пробелом больше, чем толерантность. Я нарисовал модели с помощью Autodesk Inventor и SolidWorks. Я просмотрел их даже в FreeCad и неважно, насколько сильно я увеличиваю изображение подключенных краев.
Изгиб имеет две прямые грани, которые соединяются со сторонами, как показано на диаграмме ниже:
Это было мое первоначальное решение buts, оно не захватывает все соединения, например, я получаю информацию о том, что некоторые изгибы соединены с лицом на одном краю, а не на другом:
for (auto& bend: mModelBends){
for (auto& edge: bend.getFaceEdges()){
if (edge.getEdgeType() == EdgeType::LINE) {
TopoDS_Edge anEdge = edge.getTModelEdge(); // returns a TopoDS_Edge from the edge object
for (auto& face: mModelFaces)
{
if (face.getFaceType() == FaceType::NONE) {
TopoDS_Face aFace = face.getTModelFace(); // returns a TopoDS_Face from the face object
for( TopExp_Explorer anExp(aFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
if(anExp.Current().IsSame(anEdge)) {
// Do something.........
}
}
}
}
}
}
}
Другое решение найдено на форуме OpenCascade:
TopTools_IndexedDataMapOfShapeListOfShape edgeFaceMap;
// mModelShape is a TopoDS_Shape with the entire model
TopExp::MapShapesAndAncestors(mModelShape, TopAbs_EDGE, TopAbs_FACE, edgeFaceMap);
for (auto& bend: mModelBends){
for (auto& edge: bend.getFaceEdges()){
if (edge.getEdgeType() == EdgeType::LINE) {
TopoDS_Edge anEdge = edge.getTModelEdge();
TopoDS_Shape anAdjFaceObj;
// Find adjacent face
for (auto& a : mModelFaces)
{
bool faceFound = TopOpeBRepBuild_Tools::GetAdjacentFace(a.getTModelFace(), anEdge,
edgeFaceMap, anAdjFaceObj);
if (faceFound)
{
// Do something.........
}
}
}
}
}
Второе решение выходит из строя после первого выполнения GetAdjacentFace()
Возможно, проблема в том, что я не понимаю, что говорят доки о MapShapesAndUniqueAncestors() и GetAdjacentFace():
TopExp::MapShapesAndUniqueAncestors(const TopoDS_Shape &S,
const TopAbs_ShapeEnum TS,
const TopAbs_ShapeEnum TA,
TopTools_IndexedDataMapOfShapeListOfShape &M,
const Standard_Boolean useOrientation = Standard_False
)
Хранит на карте M все под-формы S типа TS для каждой из них одно приложение к списку всех уникальных предков типа TA. Например отобразить все края и привязать список граней. useOrientation = True : с учетом ориентации предков Предупреждение: Карта не Сначала очистили.
Нужна помощь с исправлением или лучшим решением и/или ясностью в документах. Заранее спасибо.