#include <TopLoc_Location.hxx>
#include <TopExp.hxx>
+#include <TColGeom_SequenceOfCurve.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TColStd_SequenceOfReal.hxx>
+#include <GeomAbs_CurveType.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <ElCLib.hxx>
+#include <BRepLib.hxx>
+#include <TopoDS.hxx>
+#include <ShapeFix_Shape.hxx>
+#include <GeomConvert_CompCurveToBSplineCurve.hxx>
+
+//Temporary
+#//include <DrawTrSurf.hxx>
+
+
//=======================================================================
//function : ConcatenateWire
//purpose :
for (index=0 ;index<nb_curve; index++){ //main loop
edge = WExp.Current() ;
- tab(index) = GeomConvert::CurveToBSplineCurve(new //storage in a array
- Geom_TrimmedCurve(BRep_Tool::Curve(edge,L,First,Last),First,Last));
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(edge, L, First, Last);
+ Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, First, Last);
+ tab(index) = GeomConvert::CurveToBSplineCurve(aTrCurve); //storage in a array
tab(index)->Transform(L.Transformation());
GeomConvert::C0BSplineToC1BSplineCurve(tab(index),Precision::Confusion());
}
+//=======================================================================
+//function : ConcatenateWireC0
+//purpose :
+//=======================================================================
+
+TopoDS_Edge BRepAlgo::ConcatenateWireC0(const TopoDS_Wire& aWire)
+{
+ Standard_Real LinTol = Precision::Confusion();
+ Standard_Real AngTol = Precision::Angular();
+
+ TopoDS_Edge ResEdge;
+ TopoDS_Wire theWire = aWire;
+ BRepLib::BuildCurves3d(theWire);
+ Handle(ShapeFix_Shape) Fixer = new ShapeFix_Shape(theWire);
+ Fixer->SetPrecision(LinTol);
+ Fixer->SetMaxTolerance(LinTol);
+ Fixer->Perform();
+ theWire = TopoDS::Wire(Fixer->Shape());
+
+ TColGeom_SequenceOfCurve CurveSeq;
+ TopTools_SequenceOfShape LocSeq;
+ TColStd_SequenceOfReal FparSeq;
+ TColStd_SequenceOfReal LparSeq;
+ TColStd_SequenceOfReal TolSeq;
+ GeomAbs_CurveType CurType;
+ TopoDS_Vertex FirstVertex, LastVertex;
+ Standard_Boolean FinalReverse = Standard_False;
+
+ BRepTools_WireExplorer wexp(theWire) ;
+ for (; wexp.More(); wexp.Next())
+ {
+ TopoDS_Edge anEdge = wexp.Current();
+ Standard_Real fpar, lpar;
+ TopLoc_Location aLoc;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aLoc, fpar, lpar);
+ if (aCurve.IsNull())
+ continue;
+
+ BRepAdaptor_Curve BAcurve(anEdge);
+ GeomAbs_CurveType aType = BAcurve.GetType();
+
+ Handle(Geom_Curve) aBasisCurve = BAcurve.Curve().Curve();
+
+ if (aBasisCurve->IsPeriodic())
+ ElCLib::AdjustPeriodic(aBasisCurve->FirstParameter(), aBasisCurve->LastParameter(),
+ Precision::PConfusion(), fpar, lpar);
+
+ if (CurveSeq.IsEmpty())
+ {
+ CurveSeq.Append(aCurve);
+ TopoDS_Shape aLocShape;
+ aLocShape.Location(aLoc);
+ aLocShape.Orientation(wexp.Orientation());
+ LocSeq.Append(aLocShape);
+ FparSeq.Append(fpar);
+ LparSeq.Append(lpar);
+ CurType = aType;
+ FirstVertex = wexp.CurrentVertex();
+ if (anEdge.Orientation() == TopAbs_REVERSED)
+ FinalReverse = Standard_True;
+ }
+ else
+ {
+ Standard_Boolean Done = Standard_False;
+ Standard_Real NewFpar, NewLpar;
+ GeomAdaptor_Curve GAprevcurve(CurveSeq.Last());
+ TopoDS_Vertex CurVertex = wexp.CurrentVertex();
+ TopoDS_Vertex CurFirstVer = TopExp::FirstVertex(anEdge);
+ TopAbs_Orientation ConnectByOrigin = (CurVertex.IsSame(CurFirstVer))? TopAbs_FORWARD : TopAbs_REVERSED;
+ if (aCurve == CurveSeq.Last())
+ {
+ NewFpar = fpar;
+ NewLpar = lpar;
+ if (aBasisCurve->IsPeriodic())
+ {
+ if (NewLpar < NewFpar)
+ NewLpar += aBasisCurve->Period();
+ if (ConnectByOrigin == TopAbs_FORWARD)
+ ElCLib::AdjustPeriodic(FparSeq.Last(),
+ FparSeq.Last() + aBasisCurve->Period(),
+ Precision::PConfusion(), NewFpar, NewLpar);
+ else
+ ElCLib::AdjustPeriodic(FparSeq.Last() - aBasisCurve->Period(),
+ FparSeq.Last(),
+ Precision::PConfusion(), NewFpar, NewLpar);
+ }
+ Done = Standard_True;
+ }
+ else if (aType == CurType &&
+ aType != GeomAbs_BezierCurve &&
+ aType != GeomAbs_BSplineCurve &&
+ aType != GeomAbs_OtherCurve)
+ switch (aType)
+ {
+ case GeomAbs_Line:
+ {
+ gp_Lin aLine = BAcurve.Line();
+ gp_Lin PrevLine = GAprevcurve.Line();
+ if (aLine.Contains(PrevLine.Location(), LinTol) &&
+ aLine.Direction().IsParallel(PrevLine.Direction(), AngTol))
+ {
+ gp_Pnt P1 = ElCLib::Value(fpar, aLine);
+ gp_Pnt P2 = ElCLib::Value(lpar, aLine);
+ NewFpar = ElCLib::Parameter(PrevLine, P1);
+ NewLpar = ElCLib::Parameter(PrevLine, P2);
+ if (NewLpar < NewFpar)
+ {
+ Standard_Real MemNewFpar = NewFpar;
+ NewFpar = NewLpar;
+ NewLpar = MemNewFpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ Done = Standard_True;
+ }
+ break;
+ }
+ case GeomAbs_Circle:
+ {
+ gp_Circ aCircle = BAcurve.Circle();
+ gp_Circ PrevCircle = GAprevcurve.Circle();
+ if (aCircle.Location().Distance(PrevCircle.Location()) <= LinTol &&
+ Abs(aCircle.Radius() - PrevCircle.Radius()) <= LinTol &&
+ aCircle.Axis().IsParallel(PrevCircle.Axis(), AngTol))
+ {
+ if (aCircle.Axis().Direction() * PrevCircle.Axis().Direction() < 0.)
+ {
+ Standard_Real memfpar = fpar;
+ fpar = lpar;
+ lpar = memfpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ gp_Pnt P1 = ElCLib::Value(fpar, aCircle);
+ gp_Pnt P2 = ElCLib::Value(lpar, aCircle);
+ NewFpar = ElCLib::Parameter(PrevCircle, P1);
+ NewLpar = ElCLib::Parameter(PrevCircle, P2);
+ if (NewLpar < NewFpar)
+ NewLpar += 2.*M_PI;
+ //Standard_Real MemNewFpar = NewFpar, MemNewLpar = NewLpar;
+ if (ConnectByOrigin == TopAbs_FORWARD)
+ ElCLib::AdjustPeriodic(FparSeq.Last(),
+ FparSeq.Last() + 2.*M_PI,
+ Precision::PConfusion(), NewFpar, NewLpar);
+ else
+ ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*M_PI,
+ FparSeq.Last(),
+ Precision::PConfusion(), NewFpar, NewLpar);
+ Done = Standard_True;
+ }
+ break;
+ }
+ case GeomAbs_Ellipse:
+ {
+ gp_Elips anEllipse = BAcurve.Ellipse();
+ gp_Elips PrevEllipse = GAprevcurve.Ellipse();
+ if (anEllipse.Focus1().Distance(PrevEllipse.Focus1()) <= LinTol &&
+ anEllipse.Focus2().Distance(PrevEllipse.Focus2()) <= LinTol &&
+ Abs(anEllipse.MajorRadius() - PrevEllipse.MajorRadius()) <= LinTol &&
+ Abs(anEllipse.MinorRadius() - PrevEllipse.MinorRadius()) <= LinTol &&
+ anEllipse.Axis().IsParallel(PrevEllipse.Axis(), AngTol))
+ {
+ if (anEllipse.Axis().Direction() * PrevEllipse.Axis().Direction() < 0.)
+ {
+ Standard_Real memfpar = fpar;
+ fpar = lpar;
+ lpar = memfpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ gp_Pnt P1 = ElCLib::Value(fpar, anEllipse);
+ gp_Pnt P2 = ElCLib::Value(lpar, anEllipse);
+ NewFpar = ElCLib::Parameter(PrevEllipse, P1);
+ NewLpar = ElCLib::Parameter(PrevEllipse, P2);
+ if (NewLpar < NewFpar)
+ NewLpar += 2.*M_PI;
+ if (ConnectByOrigin == TopAbs_FORWARD)
+ ElCLib::AdjustPeriodic(FparSeq.Last(),
+ FparSeq.Last() + 2.*M_PI,
+ Precision::PConfusion(), NewFpar, NewLpar);
+ else
+ ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*M_PI,
+ FparSeq.Last(),
+ Precision::PConfusion(), NewFpar, NewLpar);
+ Done = Standard_True;
+ }
+ break;
+ }
+ case GeomAbs_Hyperbola:
+ {
+ gp_Hypr aHypr = BAcurve.Hyperbola();
+ gp_Hypr PrevHypr = GAprevcurve.Hyperbola();
+ if (aHypr.Focus1().Distance(PrevHypr.Focus1()) <= LinTol &&
+ aHypr.Focus2().Distance(PrevHypr.Focus2()) <= LinTol &&
+ Abs(aHypr.MajorRadius() - PrevHypr.MajorRadius()) <= LinTol &&
+ Abs(aHypr.MinorRadius() - PrevHypr.MinorRadius()) <= LinTol &&
+ aHypr.Axis().IsParallel(PrevHypr.Axis(), AngTol))
+ {
+ gp_Pnt P1 = ElCLib::Value(fpar, aHypr);
+ gp_Pnt P2 = ElCLib::Value(lpar, aHypr);
+ NewFpar = ElCLib::Parameter(PrevHypr, P1);
+ NewLpar = ElCLib::Parameter(PrevHypr, P2);
+ if (NewLpar < NewFpar)
+ {
+ Standard_Real MemNewFpar = NewFpar;
+ NewFpar = NewLpar;
+ NewLpar = MemNewFpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ Done = Standard_True;
+ }
+ break;
+ }
+ case GeomAbs_Parabola:
+ {
+ gp_Parab aParab = BAcurve.Parabola();
+ gp_Parab PrevParab = GAprevcurve.Parabola();
+ if (aParab.Location().Distance(PrevParab.Location()) <= LinTol &&
+ aParab.Focus().Distance(PrevParab.Focus()) <= LinTol &&
+ Abs(aParab.Focal() - PrevParab.Focal()) <= LinTol &&
+ aParab.Axis().IsParallel(PrevParab.Axis(), AngTol))
+ {
+ gp_Pnt P1 = ElCLib::Value(fpar, aParab);
+ gp_Pnt P2 = ElCLib::Value(lpar, aParab);
+ NewFpar = ElCLib::Parameter(PrevParab, P1);
+ NewLpar = ElCLib::Parameter(PrevParab, P2);
+ if (NewLpar < NewFpar)
+ {
+ Standard_Real MemNewFpar = NewFpar;
+ NewFpar = NewLpar;
+ NewLpar = MemNewFpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ Done = Standard_True;
+ }
+ break;
+ }
+ } //end of switch and else
+ if (Done)
+ {
+ if (NewFpar < FparSeq.Last())
+ FparSeq(FparSeq.Length()) = NewFpar;
+ else
+ LparSeq(LparSeq.Length()) = NewLpar;
+ }
+ else
+ {
+ CurveSeq.Append(aCurve);
+ TopoDS_Shape aLocShape;
+ aLocShape.Location(aLoc);
+ aLocShape.Orientation(wexp.Orientation());
+ LocSeq.Append(aLocShape);
+ FparSeq.Append(fpar);
+ LparSeq.Append(lpar);
+ TolSeq.Append(BRep_Tool::Tolerance(CurVertex));
+ CurType = aType;
+ }
+ } //end of else (not first time)
+ }
+ LastVertex = wexp.CurrentVertex();
+ TolSeq.Append(BRep_Tool::Tolerance(LastVertex));
+
+ TopoDS_Vertex FirstVtx_final = (FinalReverse)? LastVertex : FirstVertex;
+ FirstVtx_final.Orientation(TopAbs_FORWARD);
+ TopoDS_Vertex LastVtx_final = (FinalReverse)? FirstVertex : LastVertex;
+ LastVtx_final.Orientation(TopAbs_REVERSED);
+
+ if (CurveSeq.IsEmpty())
+ return ResEdge;
+ Standard_Integer nb_curve = CurveSeq.Length(); //number of curves
+ TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1); //array of the curves
+ TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2); //array of the tolerances
+ Standard_Integer i;
+
+ if (nb_curve > 1)
+ {
+ for (i = 1; i <= nb_curve; i++)
+ {
+ if (CurveSeq(i)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
+ CurveSeq(i) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve();
+
+ Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(CurveSeq(i), FparSeq(i), LparSeq(i));
+ tab(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
+ tab(i-1)->Transform(LocSeq(i).Location().Transformation());
+ GeomConvert::C0BSplineToC1BSplineCurve(tab(i-1), Precision::Confusion());
+ if (LocSeq(i).Orientation() == TopAbs_REVERSED)
+ tab(i-1)->Reverse();
+
+ //Temporary
+ //char* name = new char[100];
+ //sprintf(name, "c%d", i);
+ //DrawTrSurf::Set(name, tab(i-1));
+
+ if (i > 1)
+ tabtolvertex(i-2) = TolSeq(i-1) * 5.;
+ }
+ tabtolvertex(nb_curve-1) = TolSeq(TolSeq.Length()) * 5.;
+
+ Standard_Boolean closed_flag = Standard_False;
+ Standard_Real closed_tolerance = 0.;
+ if (FirstVertex.IsSame(LastVertex) &&
+ GeomLProp::Continuity(tab(0), tab(nb_curve-1),
+ tab(0)->FirstParameter(),
+ tab(nb_curve-1)->LastParameter(),
+ Standard_False, Standard_False, LinTol, AngTol) >= GeomAbs_G1)
+ {
+ closed_flag = Standard_True ;
+ closed_tolerance = BRep_Tool::Tolerance(FirstVertex);
+ }
+
+ Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves
+ Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex
+ GeomConvert::ConcatC1(tab,
+ tabtolvertex,
+ ArrayOfIndices,
+ concatcurve,
+ closed_flag,
+ closed_tolerance); //C1 concatenation
+
+ if (concatcurve->Length() > 1)
+ {
+ Standard_Real MaxTolVer = LinTol;
+ for (i = 1; i <= TolSeq.Length(); i++)
+ if (TolSeq(i) > MaxTolVer)
+ MaxTolVer = TolSeq(i);
+ MaxTolVer *= 5.;
+
+ GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
+
+ for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
+ Concat.Add( concatcurve->Value(i), MaxTolVer, Standard_True );
+
+ concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
+ }
+
+ ResEdge = BRepLib_MakeEdge(concatcurve->Value(concatcurve->Lower()),
+ FirstVtx_final, LastVtx_final,
+ concatcurve->Value(concatcurve->Lower())->FirstParameter(),
+ concatcurve->Value(concatcurve->Lower())->LastParameter());
+ }
+ else
+ {
+ if (CurveSeq(1)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
+ CurveSeq(1) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(1))))->BasisCurve();
+
+ CurveSeq(1)->Transform(LocSeq(1).Location().Transformation());
+ ResEdge = BRepLib_MakeEdge(CurveSeq(1),
+ FirstVtx_final, LastVtx_final,
+ FparSeq(1), LparSeq(1));
+ }
+
+ if (FinalReverse)
+ ResEdge.Reverse();
+
+ return ResEdge;
+}