+
+//==================================================================================================
+static TopoDS_Wire fixParametricGaps(const TopoDS_Wire& theWire)
+{
+ TopoDS_Wire aFixedWire;
+ Handle(Geom_Curve) aPrevCurve;
+ double aPrevLastParam = 0.0;
+
+ BRep_Builder aBuilder;
+ aBuilder.MakeWire(aFixedWire);
+
+ BRepTools_WireExplorer aWExp(theWire);
+ for (; aWExp.More(); aWExp.Next()) {
+ TopoDS_Edge anEdge = aWExp.Current();
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ if (aCurve == aPrevCurve) {
+ // if parametric gap occurs, create new edge based on the copied curve
+ aCurve = Handle(Geom_Curve)::DownCast(aCurve->Copy());
+ TopoDS_Vertex aV1, aV2;
+ TopExp::Vertices(anEdge, aV1, aV2);
+ anEdge = TopoDS::Edge(anEdge.EmptyCopied());
+ aBuilder.UpdateEdge(anEdge, aCurve, BRep_Tool::Tolerance(anEdge));
+ aBuilder.Add(anEdge, aV1);
+ aBuilder.Add(anEdge, aV2);
+ }
+
+ aBuilder.Add(aFixedWire, anEdge);
+
+ aPrevCurve = aCurve;
+ aPrevLastParam = aLast;
+ }
+
+ return aFixedWire;
+}
+
+std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_ShapeTools::wireToEdge(
+ const std::shared_ptr<GeomAPI_Wire>& theWire)
+{
+ GeomEdgePtr anEdge;
+ if (theWire) {
+ TopoDS_Wire aWire = theWire->impl<TopoDS_Wire>();
+ // Workaround: when concatenate a wire consisting of two edges based on the same B-spline curve
+ // (non-periodic, but having equal start and end points), first of which is placed at the end
+ // on the curve and second is placed at the start, this workaround copies second curve to avoid
+ // treating these edges as a single curve by setting trim parameters.
+ aWire = fixParametricGaps(aWire);
+ TopoDS_Edge aNewEdge = BRepAlgo::ConcatenateWireC0(aWire);
+ anEdge = GeomEdgePtr(new GeomAPI_Edge);
+ anEdge->setImpl(new TopoDS_Edge(aNewEdge));
+ }
+ return anEdge;
+}