1 // Created on: 2001-12-20
2 // Created by: Pavel TELKOV
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
19 #include <Geom2d_BezierCurve.hxx>
20 #include <Geom2d_BSplineCurve.hxx>
21 #include <Geom2d_Curve.hxx>
22 #include <Geom2d_Line.hxx>
23 #include <gp_Dir2d.hxx>
24 #include <gp_Lin2d.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <gp_Vec2d.hxx>
27 #include <Precision.hxx>
28 #include <ShapeCustom_Curve2d.hxx>
29 #include <Standard_ErrorHandler.hxx>
31 //=======================================================================
34 //=======================================================================
35 static gp_Lin2d GetLine (const gp_Pnt2d& P1, const gp_Pnt2d& P2,
36 const Standard_Real c1, Standard_Real& cf, Standard_Real& cl)
38 gp_Vec2d avec (P1,P2);
40 gp_Lin2d alin (P1,adir);
41 alin.SetLocation (ElCLib::Value (c1, alin));
42 cf = ElCLib::Parameter (alin, P1);
43 cl = ElCLib::Parameter (alin, P2);
48 //=======================================================================
51 //=======================================================================
53 Standard_Boolean ShapeCustom_Curve2d::IsLinear(const TColgp_Array1OfPnt2d& thePoles,
54 const Standard_Real tolerance,
55 Standard_Real& Deviation)
57 Standard_Integer nbPoles = thePoles.Length();
59 return Standard_False;
61 Standard_Real dMax = 0;
62 Standard_Integer iMax1=0,iMax2=0;
65 for(i = 1; i < nbPoles; i++)
66 for(Standard_Integer j = i+1; j <= nbPoles; j++) {
67 Standard_Real dist = thePoles(i).SquareDistance(thePoles(j));
75 Standard_Real dPreci = Precision::PConfusion()*Precision::PConfusion();
77 return Standard_False;
79 Standard_Real tol2 = tolerance*tolerance;
80 gp_Vec2d avec (thePoles(iMax1),thePoles(iMax2));
82 gp_Lin2d alin (thePoles(iMax1),adir);
84 Standard_Real aMax = 0.;
85 for(i = 1; i <= nbPoles; i++) {
86 Standard_Real dist = alin.SquareDistance(thePoles(i));
88 return Standard_False;
92 Deviation = sqrt(aMax);
97 //=======================================================================
98 //function : ConvertToLine2d
100 //=======================================================================
102 Handle(Geom2d_Line) ShapeCustom_Curve2d::ConvertToLine2d (const Handle(Geom2d_Curve)& theCurve,
103 const Standard_Real c1,
104 const Standard_Real c2,
105 const Standard_Real theTolerance,
108 Standard_Real& theDeviation)
110 Handle(Geom2d_Line) aLine2d;
111 gp_Pnt2d P1 = theCurve->Value(c1);
112 gp_Pnt2d P2 = theCurve->Value(c2);
113 Standard_Real dPreci = theTolerance*theTolerance;
114 if(P1.SquareDistance(P2) < dPreci)
115 return aLine2d; // it is not a line
117 Handle(Geom2d_BSplineCurve) bsc = Handle(Geom2d_BSplineCurve)::DownCast(theCurve);
119 Standard_Integer nbPoles = bsc->NbPoles();
120 TColgp_Array1OfPnt2d Poles(1,nbPoles);
122 if(!ShapeCustom_Curve2d::IsLinear(Poles,theTolerance,theDeviation))
123 return aLine2d; // non
124 gp_Lin2d alin = GetLine (P1,P2,c1,cf,cl);
125 aLine2d = new Geom2d_Line (alin);
129 Handle(Geom2d_BezierCurve) bzc = Handle(Geom2d_BezierCurve)::DownCast(theCurve);
131 Standard_Integer nbPoles = bzc->NbPoles();
132 TColgp_Array1OfPnt2d Poles(1,nbPoles);
134 if(!ShapeCustom_Curve2d::IsLinear(Poles,theTolerance,theDeviation))
135 return aLine2d; // non
136 gp_Lin2d alin = GetLine (P1,P2,c1,cf,cl);
137 aLine2d = new Geom2d_Line (alin);
144 //=======================================================================
145 //function : SimplifyBSpline2d
147 //=======================================================================
149 Standard_Boolean ShapeCustom_Curve2d::SimplifyBSpline2d (Handle(Geom2d_BSplineCurve)& theBSpline2d,
150 const Standard_Real theTolerance)
152 Standard_Integer aInitNbK;
153 Standard_Integer NbK = aInitNbK = theBSpline2d->NbKnots();
154 // search knot to remove
155 Standard_Boolean IsToRemove = Standard_True;
156 Standard_Integer aKnotIndx = NbK-1;
157 while (IsToRemove && NbK > 2)
159 Standard_Integer aMult = theBSpline2d->Multiplicity(aKnotIndx);
160 Standard_Integer DegMult = theBSpline2d->Degree() - aMult;
161 if ((DegMult > 1) && theBSpline2d->IsCN(DegMult))
163 Standard_Real U = theBSpline2d->Knot(aKnotIndx);
164 gp_Vec2d aVec1 = theBSpline2d->LocalDN(U, aKnotIndx-1, aKnotIndx, DegMult);
165 gp_Vec2d aVec2 = theBSpline2d->LocalDN(U, aKnotIndx, aKnotIndx+1, DegMult);
166 // check the derivations are have the "same" angle
167 if (aVec1.IsParallel(aVec2, Precision::Angular()))
173 theBSpline2d->RemoveKnot(aKnotIndx,
177 catch(Standard_Failure)
184 NbK = theBSpline2d->NbKnots();
185 if (aKnotIndx == 1 || aKnotIndx == NbK)
186 IsToRemove = Standard_False;
188 return (aInitNbK > NbK);