Eu tenho dois tipos de modelos CAD em chapa Faces; ModelFace (faces PLANAR) e ModelBend (NON-PLANAR, existem entre ModelFaces e representam as curvas de uma chapa de metal). Estas faces são armazenadas em vectores separados. O que eu quero fazer é encontrar as faces a que cada curva se liga. A cada face e dobra é atribuído um ID inteiro positivo e não zero. A saída desejada é algo como isto :
F1----B1-----F2 Angle : 90 Radius : 4
F2----B2-----F3 Angle : 90 Radius : 4
O que significa que a curva 1, de raio 4mm liga a face 1 e a face 2 num ângulo de 90 graus e assim por diante. No entanto, estou obtendo um resultado mostrado abaixo para a maioria dos modelos, independentemente do seu formato (passo/igs) :
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
Um resultado como F3---B2---F0
este significa que o programa detectou que B2 está ligado à face 3 mas não consegue identificar a outra face ligada, daí o valor F0. Também para alguns modelos pode ser F0---B2---F0
uma saída, o que significa que não foi encontrada nenhuma face que se ligue à curva 2.
Parece que a borda compartilhada tanto pela face quanto pelas curvas não estão sendo detectadas como borda similar, ou seja, os pontos finais das linhas de borda não são os mesmos ou estão separados por um espaço é maior que a tolarência. Eu desenhei os modelos utilizando Autodesk Inventor e SolidWorks. Eu os vi até mesmo no FreeCad e não importa o quanto eu zoom as bordas estão conectadas.
Uma curva tem duas arestas em linha reta que se conectam a faces como mostrado no diagrama abaixo:
Esta foi a minha solução inicial, mas não captura todas as ligações, por exemplo, estou a obter informações de que algumas curvas estão ligadas a um rosto numa borda e não na outra borda:
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.........
}
}
}
}
}
}
}
Outra solução encontrada no Fórum 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.........
}
}
}
}
}
A segunda solução trava após executar GetAdjacentFace() pela primeira vez
O problema pode ser porque eu não estou entendendo o que os documentos estão dizendo sobre MapShapesAndUniqueAncestors() e GetAdjacentFace():
TopExp::MapShapesAndUniqueAncestors(const TopoDS_Shape &S,
const TopAbs_ShapeEnum TS,
const TopAbs_ShapeEnum TA,
TopTools_IndexedDataMapOfShapeListOfShape &M,
const Standard_Boolean useOrientation = Standard_False
)
Armazena no mapa M toda a subforma de S do tipo TS para cada um anexo à lista de todos os antepassados únicos do tipo TA. Por exemplo mapear todas as bordas e ligar a lista de rostos. useOrientation = True : tendo em conta a orientação dos antepassados Aviso: O mapa não é ...liberado no início.
Precisa de ajuda com uma correcção ou melhor solução e/ou clareza nos documentos. Obrigado de antemão.