#include <TColGeom_SequenceOfSurface.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_SequenceOfBoolean.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
return ResEdge;
}
+//=======================================================================
+//function : UnionPCurves
+//purpose :
+//=======================================================================
+
+static void UnionPCurves(const TopTools_SequenceOfShape& theChain,
+ TopoDS_Edge& theEdge)
+{
+ TColGeom_SequenceOfSurface aSurfSeq;
+ NCollection_Sequence<TopLoc_Location> aLocSeq;
+
+ for (Standard_Integer anIndex = 1;; anIndex++)
+ {
+ Handle(Geom2d_Curve) aCurve;
+ Handle(Geom_Surface) aSurface;
+ TopLoc_Location aLocation;
+ Standard_Real aFirst, aLast;
+ TopoDS_Edge anEdge = TopoDS::Edge(theChain.Value(1));
+ BRep_Tool::CurveOnSurface(anEdge, aCurve, aSurface, aLocation, aFirst, aLast, anIndex);
+ if (aCurve.IsNull())
+ break;
+
+ aSurfSeq.Append(aSurface);
+ aLocSeq.Append(aLocation);
+ }
+
+ TColGeom2d_SequenceOfCurve ResPCurves;
+ TColStd_SequenceOfReal ResFirsts;
+ TColStd_SequenceOfReal ResLasts;
+ TopoDS_Vertex aPrevVertex;
+ TopoDS_Edge aPrevEdge;
+ for (Standard_Integer j = 1; j <= aSurfSeq.Length(); j++)
+ {
+ TColGeom2d_SequenceOfCurve aPCurveSeq;
+ TColStd_SequenceOfReal aFirstsSeq;
+ TColStd_SequenceOfReal aLastsSeq;
+ TColStd_SequenceOfBoolean aForwardsSeq;
+ GeomAbs_CurveType aCurrentType = GeomAbs_OtherCurve;
+
+ Standard_Real aFirst, aLast;
+ for (Standard_Integer i = 1; i <= theChain.Length(); i++)
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge(theChain.Value(i));
+ Standard_Boolean isForward = (anEdge.Orientation() != TopAbs_REVERSED);
+
+ Handle(Geom2d_Curve) aPCurve =
+ BRep_Tool::CurveOnSurface(anEdge, aSurfSeq(j), aLocSeq(j), aFirst, aLast);
+ if (aPCurve.IsNull())
+ continue;
+
+ Geom2dAdaptor_Curve anAdaptor(aPCurve);
+ GeomAbs_CurveType aType = anAdaptor.GetType();
+
+ if (aPCurveSeq.IsEmpty()) {
+ aPCurveSeq.Append(aPCurve);
+ aFirstsSeq.Append(aFirst);
+ aLastsSeq.Append(aLast);
+ aForwardsSeq.Append(isForward);
+ aCurrentType = aType;
+ continue;
+ }
+ Standard_Boolean isSameCurve = Standard_False;
+ Standard_Real aNewF = aFirstsSeq.Last();
+ Standard_Real aNewL = aLastsSeq.Last();
+ if (aPCurve == aPCurveSeq.Last()) {
+ isSameCurve = Standard_True;
+ }
+ else if (aType == aCurrentType) {
+ Geom2dAdaptor_Curve aPrevAdaptor(aPCurveSeq.Last());
+ switch (aType) {
+ case GeomAbs_Line: {
+ gp_Lin2d aLin = anAdaptor.Line();
+ gp_Lin2d aPrevLin = aPrevAdaptor.Line();
+ if (aLin.Contains(aPrevLin.Location(), Precision::Confusion()) &&
+ aLin.Direction().IsParallel(aPrevLin.Direction(), Precision::Angular())) {
+ isSameCurve = Standard_True;
+ gp_Pnt2d p1 = anAdaptor.Value(aFirst);
+ gp_Pnt2d p2 = anAdaptor.Value(aLast);
+ aNewF = ElCLib::Parameter(aPrevLin, p1);
+ aNewL = ElCLib::Parameter(aPrevLin, p2);
+ }
+ break;
+ }
+ case GeomAbs_Circle: {
+ gp_Circ2d aCirc = anAdaptor.Circle();
+ gp_Circ2d aPrevCirc = aPrevAdaptor.Circle();
+ if (aCirc.Location().Distance(aPrevCirc.Location()) <= Precision::Confusion() &&
+ Abs(aCirc.Radius() - aPrevCirc.Radius()) <= Precision::Confusion()) {
+ isSameCurve = Standard_True;
+ gp_Pnt2d p1 = anAdaptor.Value(aFirst);
+ gp_Pnt2d p2 = anAdaptor.Value(aLast);
+ aNewF = ElCLib::Parameter(aPrevCirc, p1);
+ aNewL = ElCLib::Parameter(aPrevCirc, p2);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (isSameCurve) {
+ Standard_Boolean isSameDir = (isForward == aForwardsSeq.Last());
+ if (!isSameDir) {
+ Standard_Real aTmp = aNewF;
+ aNewF = aNewL;
+ aNewL = aTmp;
+ }
+ if (aForwardsSeq.Last())
+ aLastsSeq(aLastsSeq.Length()) = aNewL;
+ else
+ aFirstsSeq(aFirstsSeq.Length()) = aNewF;
+ }
+ else {
+ aPCurveSeq.Append(aPCurve);
+ aFirstsSeq.Append(aFirst);
+ aLastsSeq.Append(aLast);
+ aForwardsSeq.Append(isForward);
+ aCurrentType = aType;
+ }
+ }
+
+ Handle(Geom2d_Curve) aResPCurve;
+ Standard_Real aResFirst, aResLast;
+ if (aPCurveSeq.Length() == 1) {
+ aResPCurve = aPCurveSeq.Last();
+ aResFirst = aFirstsSeq.Last();
+ aResLast = aLastsSeq.Last();
+ }
+ else {
+ //C1 concatenation for PCurveSeq
+ TColGeom2d_Array1OfBSplineCurve tab_c2d(0, theChain.Length() - 1);
+ for (Standard_Integer i = 1; i <= theChain.Length(); i++) {
+ Handle(Geom2d_TrimmedCurve) aTrPCurve = new Geom2d_TrimmedCurve(aPCurveSeq(i), aFirstsSeq(i), aLastsSeq(i));
+ tab_c2d(i - 1) = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
+ Geom2dConvert::C0BSplineToC1BSplineCurve(tab_c2d(i - 1), Precision::Confusion());
+ if (!aForwardsSeq(i))
+ tab_c2d(i - 1)->Reverse();
+ }
+
+ TColStd_Array1OfReal tabtolvertex(0, theChain.Length() - 1);
+ Standard_Real aMaxTol = 0.0;
+ TopoDS_Edge aPrevEdge = TopoDS::Edge(theChain(1));
+ for (Standard_Integer i = 2; i <= theChain.Length(); i++) {
+ TopoDS_Edge anEdge = TopoDS::Edge(theChain(i));
+ TopoDS_Vertex aV;
+ TopExp::CommonVertex(aPrevEdge, anEdge, aV);
+ Standard_Real aTol = BRep_Tool::Tolerance(aV);
+ tabtolvertex(i - 2) = aTol;
+ if (aTol - aMaxTol > 0.0)
+ aMaxTol = aTol;
+ }
+
+ Handle(TColGeom2d_HArray1OfBSplineCurve) concatc2d; //array of the concatenated curves
+ Handle(TColStd_HArray1OfInteger) ArrayOfInd2d; //array of the remining Vertex
+ Standard_Boolean aClosedFlag = Standard_False;
+ Geom2dConvert::ConcatC1(tab_c2d,
+ tabtolvertex,
+ ArrayOfInd2d,
+ concatc2d,
+ aClosedFlag,
+ Precision::Confusion()); //C1 concatenation
+
+ if (concatc2d->Length() > 1)
+ {
+ Geom2dConvert_CompCurveToBSplineCurve Concat2d(concatc2d->Value(concatc2d->Lower()));
+
+ for (Standard_Integer i = concatc2d->Lower() + 1; i <= concatc2d->Upper(); i++)
+ Concat2d.Add(concatc2d->Value(i), aMaxTol, Standard_True);
+
+ concatc2d->SetValue(concatc2d->Lower(), Concat2d.BSplineCurve());
+ }
+ Handle(Geom2d_BSplineCurve) aBSplineCurve = concatc2d->Value(concatc2d->Lower());
+ aResPCurve = aBSplineCurve;
+ aResFirst = aBSplineCurve->FirstParameter();
+ aResLast = aBSplineCurve->LastParameter();
+ }
+ ResPCurves.Append(aResPCurve);
+ ResFirsts.Append(aResFirst);
+ ResLasts.Append(aResLast);
+ }
+
+ BRep_Builder aBuilder;
+ Standard_Real aTol = BRep_Tool::Tolerance(theEdge);
+ for (Standard_Integer j = 1; j <= ResPCurves.Length(); j++)
+ {
+ aBuilder.UpdateEdge(theEdge, ResPCurves(j), aSurfSeq(j), aLocSeq(j), aTol);
+ aBuilder.Range(theEdge, aSurfSeq(j), aLocSeq(j), ResFirsts(j), ResLasts(j));
+ }
+}
+
//=======================================================================
//function : MergeSubSeq
//purpose : Merges a sequence of edges into one edge if possible
B.Add (E,V[0]); B.Add (E,V[1]);
B.UpdateVertex(V[0], 0., E, 0.);
B.UpdateVertex(V[1], dist, E, 0.);
+ UnionPCurves(theChain, E);
OutEdge = E;
return Standard_True;
}
Standard_Real lpar = Dir1.AngleWithRef(DirLastInChain, Vdir);
if (lpar < 0.)
lpar += 2*M_PI;
-
+
Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(aNewCircle,0.,lpar);
B.MakeEdge (E,tc,Precision::Confusion());
B.Add(E,V[0]);
B.UpdateVertex(V[0], 0., E, 0.);
B.UpdateVertex(V[1], lpar, E, 0.);
}
+ UnionPCurves(theChain, E);
OutEdge = E;
return Standard_True;
}