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 <Geom_BSplineCurve.hxx>
19 #include <GeomLib_CheckBSplineCurve.hxx>
22 #include <Standard_OutOfRange.hxx>
23 #include <StdFail_NotDone.hxx>
25 //=======================================================================
26 //function : GeomLib_CheckBSplineCurve
28 //=======================================================================
29 GeomLib_CheckBSplineCurve::GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve,
30 const Standard_Real Tolerance,
31 const Standard_Real AngularTolerance)
33 myDone(Standard_False),
34 myFixFirstTangent(Standard_False),
35 myFixLastTangent(Standard_False),
36 myAngularTolerance(Abs(AngularTolerance)),
37 myTolerance(Abs(Tolerance)),
43 Standard_Real tangent_magnitude,
46 num_poles = myCurve->NbPoles() ;
48 if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
50 gp_Vec tangent, tangent_normalized,
51 a_vector, avector_normalized;
53 const Standard_Real CrossProdSqTol = myAngularTolerance*myAngularTolerance;
56 tangent = gp_Vec(myCurve->Pole(1), myCurve->Pole(2));
57 tangent_magnitude = tangent.Magnitude() ;
58 if (tangent_magnitude > myTolerance)
59 tangent_normalized = tangent/tangent_magnitude;
61 for (ii = 3; ii <= num_poles; ii++)
63 a_vector = gp_Vec(myCurve->Pole(1), myCurve->Pole(ii));
64 vector_magnitude = a_vector.Magnitude() ;
66 if (tangent_magnitude > myTolerance &&
67 vector_magnitude > myTolerance)
69 avector_normalized = a_vector/vector_magnitude;
71 gp_Vec CrossProd = tangent_normalized ^ avector_normalized;
72 Standard_Real CrossProdSqLength = CrossProd.SquareMagnitude();
73 if (CrossProdSqLength > CrossProdSqTol)
76 value = tangent.Dot(a_vector) ;
79 myFixFirstTangent = Standard_True ;
87 tangent = gp_Vec(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_Vec(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 gp_Vec CrossProd = tangent_normalized ^ avector_normalized;
103 Standard_Real CrossProdSqLength = CrossProd.SquareMagnitude();
104 if (CrossProdSqLength > CrossProdSqTol)
107 value = tangent.Dot(a_vector) ;
110 myFixLastTangent = Standard_True ;
111 myIndPrelastPole = ii;
116 } //if (( ! myCurve->IsPeriodic() )&& num_poles >= 4)
118 myDone = Standard_True ;
122 //=======================================================================
123 //function : NeedTangentFix
125 //=======================================================================
127 void GeomLib_CheckBSplineCurve::NeedTangentFix(Standard_Boolean & FirstFlag,
128 Standard_Boolean & LastFlag) const
130 FirstFlag = myFixFirstTangent ;
131 LastFlag = myFixLastTangent ;
134 //=======================================================================
135 //function : FixedTangent
137 //=======================================================================
139 Handle(Geom_BSplineCurve) GeomLib_CheckBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
140 const Standard_Boolean LastFlag)
142 Handle(Geom_BSplineCurve) new_curve ;
143 if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
145 Handle(Geom_BSplineCurve)::DownCast(myCurve->Copy()) ;
147 FixTangentOnCurve(new_curve, FirstFlag, LastFlag);
152 //=======================================================================
153 //function : FixTangent
155 //=======================================================================
157 void GeomLib_CheckBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
158 const Standard_Boolean LastFlag)
160 FixTangentOnCurve(myCurve, FirstFlag, LastFlag);
163 //=======================================================================
164 //function : FixTangentOnCurve
166 //=======================================================================
168 void GeomLib_CheckBSplineCurve::FixTangentOnCurve(Handle(Geom_BSplineCurve)& theCurve,
169 const Standard_Boolean FirstFlag,
170 const Standard_Boolean LastFlag)
172 if (myFixFirstTangent && FirstFlag) {
173 gp_XYZ XYZ1 = theCurve->Pole(1).XYZ();
174 gp_XYZ XYZ2 = theCurve->Pole(myIndSecondPole).XYZ();
175 Standard_Real NbSamples = myIndSecondPole - 1;
176 for (Standard_Integer i = 2; i < myIndSecondPole; i++)
178 Standard_Real ii = i-1;
179 gp_Pnt aNewPole((1. - ii/NbSamples)*XYZ1 + ii/NbSamples*XYZ2);
180 theCurve->SetPole(i, aNewPole);
184 if (myFixLastTangent && LastFlag) {
185 Standard_Integer num_poles = theCurve->NbPoles() ;
187 gp_XYZ XYZ1 = theCurve->Pole(num_poles).XYZ();
188 gp_XYZ XYZ2 = theCurve->Pole(myIndPrelastPole).XYZ();
189 Standard_Real NbSamples = num_poles - myIndPrelastPole;
190 for (Standard_Integer i = num_poles-1; i > myIndPrelastPole; i--)
192 Standard_Real ii = num_poles-i;
193 gp_Pnt aNewPole((1. - ii/NbSamples)*XYZ1 + ii/NbSamples*XYZ2);
194 theCurve->SetPole(i, aNewPole);
198 myDone = Standard_True ;