Tengo dos tipos de caras de modelos CAD de chapa metálica; ModelFace (caras PLANAS) y ModelBend (NO PLANAS, existen entre ModelFaces y representan los pliegues de una chapa metálica). Estas caras se almacenan en vectores separados. Lo que quiero hacer es encontrar las caras con las que cada pliegue se conecta. A cada cara y a cada pliegue se le asigna un número entero positivo y no cero. La salida deseada es algo como esto :
F1----B1-----F2 Angle : 90 Radius : 4
F2----B2-----F3 Angle : 90 Radius : 4
Lo que significa que la curva 1, de radio 4mm conecta la cara 1 y la cara 2 en un ángulo de 90 grados y así sucesivamente. Sin embargo, estoy obteniendo un resultado que se muestra a continuación para la mayoría de los modelos, independientemente de su formato (paso/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
Un resultado como F3---B2---F0
este significa que el programa ha detectado que B2 está conectado a la cara 3 pero no identifica la otra cara conectada, por lo tanto el valor F0. También para algunos modelos una salida puede ser F0---B2---F0
que significa que no se encontró ninguna cara que se conecta a la curva 2.
Parece que el borde compartido por la cara y las curvas no se detectan como borde similar, es decir, los puntos finales de las líneas de borde no son los mismos o están separados por un espacio mayor que la tolarencia. He dibujado los modelos usando Autodesk Inventor y SolidWorks. Los he visto incluso en FreeCad y no importa cuánto me acerque los bordes están conectados.
Una curva tiene dos bordes en línea recta que se conectan a las caras como se muestra en el siguiente diagrama:
Esta fue mi solución inicial, pero no captura todas las conexiones, por ejemplo, estoy obteniendo información de que algunas curvas están conectadas a una cara en un borde y no en el otro:
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.........
}
}
}
}
}
}
}
Otra solución encontrada en el Foro 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.........
}
}
}
}
}
La segunda solución falla después de ejecutar GetAdjacentFace() por primera vez
El problema podría deberse a que no entiendo lo que los doctores dicen sobre MapShapesAndUniqueAncestors() y GetAdjacentFace():
TopExp::MapShapesAndUniqueAncestors(const TopoDS_Shape &S,
const TopAbs_ShapeEnum TS,
const TopAbs_ShapeEnum TA,
TopTools_IndexedDataMapOfShapeListOfShape &M,
const Standard_Boolean useOrientation = Standard_False
)
Almacena en el mapa M toda la subforma de S de tipo TS para cada un apéndice a la lista de todos los ancestros únicos del tipo TA. Por ejemplo mapea todos los bordes y encuaderna la lista de caras. useOrientación = Verdadero : teniendo en cuenta la orientación de los antepasados Advertencia: El mapa no es despejado al principio.
Necesito ayuda con una corrección o una mejor solución y/o claridad en los documentos. Gracias de antemano.