1 // Created on: 1997-05-28
2 // Created by: Xavier BENVENISTE
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Geom2d_BSplineCurve.hxx>
19 #include <Geom_BSplineCurve.hxx>
20 #include <GeomLib_Check2dBSplineCurve.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Vec2d.hxx>
23 #include <Standard_OutOfRange.hxx>
24 #include <StdFail_NotDone.hxx>
26 //=======================================================================
27 //function : GeomLib_Check2dBSplineCurve
29 //=======================================================================
30 GeomLib_Check2dBSplineCurve::GeomLib_Check2dBSplineCurve(const Handle(Geom2d_BSplineCurve)& Curve,
31 const Standard_Real Tolerance,
32 const Standard_Real AngularTolerance)
34 myDone(Standard_False),
35 myFixFirstTangent(Standard_False),
36 myFixLastTangent(Standard_False),
37 myAngularTolerance(Abs(AngularTolerance)),
38 myTolerance(Abs(Tolerance)),
44 Standard_Real tangent_magnitude,
47 num_poles = myCurve->NbPoles() ;
49 if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
51 gp_Vec2d tangent, tangent_normalized,
52 a_vector, avector_normalized;
54 const Standard_Real CrossProdTol = myAngularTolerance;
57 tangent = gp_Vec2d(myCurve->Pole(1), myCurve->Pole(2));
58 tangent_magnitude = tangent.Magnitude() ;
59 if (tangent_magnitude > myTolerance)
60 tangent_normalized = tangent/tangent_magnitude;
62 for (ii = 3; ii <= num_poles; ii++)
64 a_vector = gp_Vec2d(myCurve->Pole(1), myCurve->Pole(ii));
65 vector_magnitude = a_vector.Magnitude() ;
67 if (tangent_magnitude > myTolerance &&
68 vector_magnitude > myTolerance)
70 avector_normalized = a_vector/vector_magnitude;
72 Standard_Real CrossProd = tangent_normalized ^ avector_normalized;
73 if (Abs(CrossProd) > CrossProdTol)
76 value = tangent.Dot(a_vector) ;
79 myFixFirstTangent = Standard_True ;
87 tangent = gp_Vec2d(myCurve->Pole(num_poles), myCurve->Pole(num_poles-1));
88 tangent_magnitude = tangent.Magnitude() ;
89 if (tangent_magnitude > myTolerance)
90 tangent_normalized = tangent/tangent_magnitude;
92 for (ii = num_poles-2; ii >= 1; ii--)
94 a_vector = gp_Vec2d(myCurve->Pole(num_poles), myCurve->Pole(ii));
95 vector_magnitude = a_vector.Magnitude() ;
97 if (tangent_magnitude > myTolerance &&
98 vector_magnitude > myTolerance)
100 avector_normalized = a_vector/vector_magnitude;
102 Standard_Real CrossProd = tangent_normalized ^ avector_normalized;
103 if (Abs(CrossProd) > CrossProdTol)
106 value = tangent.Dot(a_vector) ;
109 myFixLastTangent = Standard_True ;
110 myIndPrelastPole = ii;
115 } //if (( ! myCurve->IsPeriodic() )&& num_poles >= 4)
117 myDone = Standard_True ;
121 //=======================================================================
122 //function : NeedTangentFix
124 //=======================================================================
126 void GeomLib_Check2dBSplineCurve::NeedTangentFix(Standard_Boolean & FirstFlag,
127 Standard_Boolean & LastFlag) const
129 FirstFlag = myFixFirstTangent ;
130 LastFlag = myFixLastTangent ;
133 //=======================================================================
134 //function : FixTangent
136 //=======================================================================
138 Handle(Geom2d_BSplineCurve) GeomLib_Check2dBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
139 const Standard_Boolean LastFlag)
141 Handle(Geom2d_BSplineCurve) new_curve ;
142 if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
144 Handle(Geom2d_BSplineCurve)::DownCast(myCurve->Copy()) ;
146 FixTangentOnCurve(new_curve, FirstFlag, LastFlag);
151 //=======================================================================
152 //function : FixTangent
154 //=======================================================================
156 void GeomLib_Check2dBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
157 const Standard_Boolean LastFlag)
159 FixTangentOnCurve(myCurve, FirstFlag, LastFlag);
162 //=======================================================================
163 //function : FixTangentOnCurve
165 //=======================================================================
167 void GeomLib_Check2dBSplineCurve::FixTangentOnCurve(Handle(Geom2d_BSplineCurve)& theCurve,
168 const Standard_Boolean FirstFlag,
169 const Standard_Boolean LastFlag)
171 if (myFixFirstTangent && FirstFlag) {
172 gp_XY XY1 = theCurve->Pole(1).XY();
173 gp_XY XY2 = theCurve->Pole(myIndSecondPole).XY();
174 Standard_Real NbSamples = myIndSecondPole - 1;
175 for (Standard_Integer i = 2; i < myIndSecondPole; i++)
177 Standard_Real ii = i-1;
178 gp_Pnt2d aNewPole((1. - ii/NbSamples)*XY1 + ii/NbSamples*XY2);
179 theCurve->SetPole(i, aNewPole);
183 if (myFixLastTangent && LastFlag) {
184 Standard_Integer num_poles = theCurve->NbPoles() ;
186 gp_XY XY1 = theCurve->Pole(num_poles).XY();
187 gp_XY XY2 = theCurve->Pole(myIndPrelastPole).XY();
188 Standard_Real NbSamples = num_poles - myIndPrelastPole;
189 for (Standard_Integer i = num_poles-1; i > myIndPrelastPole; i--)
191 Standard_Real ii = num_poles-i;
192 gp_Pnt2d aNewPole((1. - ii/NbSamples)*XY1 + ii/NbSamples*XY2);
193 theCurve->SetPole(i, aNewPole);
197 myDone = Standard_True ;