Skip to content

Commit 4c2fc55

Browse files
committed
Bring back some v0.7 logic for sweeps over continuous wires #5473
1 parent 36a0a0f commit 4c2fc55

1 file changed

Lines changed: 55 additions & 3 deletions

File tree

src/ifcgeom/kernels/opencascade/sweep_along_curve.cpp

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,61 @@
2626
#include <BRepBuilderAPI_Transform.hxx>
2727
#include <ShapeFix_Edge.hxx>
2828
#include <BRepBuilderAPI_MakeFace.hxx>
29+
#include <TopExp.hxx>
30+
#include <Geom_Circle.hxx>
2931

3032
using namespace ifcopenshell::geometry;
3133
using namespace ifcopenshell::geometry::kernels;
3234
using namespace IfcGeom;
3335
using namespace IfcGeom::util;
3436

37+
namespace {
38+
bool wire_is_c1_continuous(const TopoDS_Wire& w, double tol) {
39+
// NB Note that c0 continuity is NOT checked!
40+
41+
TopTools_IndexedDataMapOfShapeListOfShape map;
42+
TopExp::MapShapesAndAncestors(w, TopAbs_VERTEX, TopAbs_EDGE, map);
43+
for (int i = 1; i <= map.Extent(); ++i) {
44+
const auto& li = map.FindFromIndex(i);
45+
if (li.Extent() == 2) {
46+
const TopoDS_Vertex& v = TopoDS::Vertex(map.FindKey(i));
47+
48+
const TopoDS_Edge& e0 = TopoDS::Edge(li.First());
49+
const TopoDS_Edge& e1 = TopoDS::Edge(li.Last());
50+
51+
double u0 = BRep_Tool::Parameter(v, e0);
52+
double u1 = BRep_Tool::Parameter(v, e1);
53+
54+
double _, __;
55+
Handle(Geom_Curve) c0 = BRep_Tool::Curve(e0, _, __);
56+
Handle(Geom_Curve) c1 = BRep_Tool::Curve(e1, _, __);
57+
58+
gp_Pnt p;
59+
gp_Vec v0, v1;
60+
c0->D1(u0, p, v0);
61+
c1->D1(u1, p, v1);
62+
63+
if (1. - std::abs(v0.Normalized().Dot(v1.Normalized())) > tol) {
64+
return false;
65+
}
66+
}
67+
}
68+
return true;
69+
}
70+
71+
bool contains_circular_segments(const TopoDS_Wire& w) {
72+
for (TopoDS_Iterator it(w); it.More(); it.Next()) {
73+
const auto& e = TopoDS::Edge(it.Value());
74+
double _, __;
75+
auto crv = BRep_Tool::Curve(e, _, __);
76+
if (crv && crv->DynamicType() == STANDARD_TYPE(Geom_Circle)) {
77+
return true;
78+
}
79+
}
80+
return false;
81+
}
82+
}
83+
3584
bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, TopoDS_Shape& result) {
3685
auto w = convert_curve(scs->curve);
3786
if (w.which() != 2) {
@@ -76,8 +125,11 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
76125
}
77126

78127
{
79-
TopExp_Explorer exp(wire, TopAbs_EDGE);
80-
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
128+
TopoDS_Vertex v0, v1;
129+
TopExp::Vertices(wire, v0, v1);
130+
TopTools_IndexedDataMapOfShapeListOfShape m;
131+
TopExp::MapShapesAndAncestors(wire, TopAbs_VERTEX, TopAbs_EDGE, m);
132+
const TopoDS_Edge& edge = TopoDS::Edge(m.FindFromKey(v0).First());
81133
double u0, u1;
82134
Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u0, u1);
83135
crv->D1(u0, directrix_origin, directrix_tangent);
@@ -130,7 +182,7 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
130182
}
131183

132184
builder.Add(section);
133-
builder.SetTransitionMode(BRepBuilderAPI_RightCorner);
185+
builder.SetTransitionMode(contains_circular_segments(wire) && wire_is_c1_continuous(wire, 1.e-2) ? BRepBuilderAPI_Transformed : BRepBuilderAPI_RightCorner);
134186
if (directrix_on_plane) {
135187
builder.SetMode(pln.Axis().Direction());
136188
} else if (!is_plane) {

0 commit comments

Comments
 (0)