Я хочу сделать грань половины цилиндра, используя граничные ребра (две вертикальные линии и две дуги 180 °). Я знаю, что есть более простые способы сделать это, но моя настоящая проблема гораздо сложнее, и у меня есть ребра, в основном, сплайны. Итак, я попытался сделать очень простой пример в надежде, что кто-то может мне помочь.
С моими реальными входными данными я не знаю порядок и ориентацию краевых ребер. Все, что у меня есть, это «цилиндрическое лицо» и «ведро с краями, которые образуют замкнутую l oop». Итак, если моя ориентация плохая, как я могу автоматически это исправить?
Вот мой пример кода:
// make an ARC from 'start' to 'end', counter-clockwise around 'center'.
TopoDS_Edge mkArc(gp_Pnt start, gp_Pnt center, gp_Pnt end, double normalZ) {
gp_Circ geometricCircle = GC_MakeCircle(center
, gp_Dir(0, 0, normalZ)
, center.Distance(start)
).Value()->Circ();
return BRepBuilderAPI_MakeEdge(geometricCircle, start, end);
}
// Make half-cylinder face by using boundary edges
TopoDS_Face MakeClinderFaceTest() {
// ^Z
// _
// ,´ `.
// a c b
// | _ |
// |,´ `.|
// A C B -->X
// top nodes
gp_Pnt a = gp_Pnt(-1, 0, 0);
gp_Pnt b = gp_Pnt( 1, 0, 0);
gp_Pnt c = gp_Pnt( 0, 0, 0);
// bottom nodes
gp_Pnt A = gp_Pnt(-1, 0, -1);
gp_Pnt B = gp_Pnt( 1, 0, -1);
gp_Pnt C = gp_Pnt( 0, 0, -1);
// boundary wire
std::list<TopoDS_Edge> edges;
if (0) { // 1/0 to reverse the order and direction of edges
edges.push_back(mkArc(a, c, b, -1)); // top arc
edges.push_back(BRepBuilderAPI_MakeEdge(b, B)); // right line
edges.push_back(mkArc(B, C, A, 1)); // bottom arc
edges.push_back(BRepBuilderAPI_MakeEdge(A, a)); // left line
} else {
edges.push_back(mkArc(b, c, a, 1));
edges.push_back(BRepBuilderAPI_MakeEdge(a, A));
edges.push_back(mkArc(A, C, B, -1));
edges.push_back(BRepBuilderAPI_MakeEdge(B, b));
}
BRepBuilderAPI_MakeWire wire;
for (auto& e : edges) {
wire.Add(e);
}
auto cylinder = gp_Cylinder( gp_Ax2( C, gp_Dir(0, 0, 1) ), C.Distance(A) /* =R */ );
#if 0
// surface geometry: infinite length cylinder
BRepBuilderAPI_MakeFace cylface(cylinder, wire);
#else
// cylindrical face with limits in V direction.
TopoDS_Face cylinder_face = BRepBuilderAPI_MakeFace(cylinder, 0, 2 * M_PI, 0, 1.0).Face();
// Limit cylinder by wired edges
BRepBuilderAPI_MakeFace cylface(cylinder_face, wire);
#endif
return cylface;
}