0031313: Foundation Classes - Dump improvement for classes
[occt.git] / src / GeomLib / GeomLib_CheckBSplineCurve.cxx
CommitLineData
b311480e 1// Created on: 1997-05-28
2// Created by: Xavier BENVENISTE
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
42cf5bc1 17
7fd59977 18#include <Geom_BSplineCurve.hxx>
42cf5bc1 19#include <GeomLib_CheckBSplineCurve.hxx>
7fd59977 20#include <gp_Pnt.hxx>
21#include <gp_Vec.hxx>
42cf5bc1 22#include <Standard_OutOfRange.hxx>
23#include <StdFail_NotDone.hxx>
24
7fd59977 25//=======================================================================
26//function : GeomLib_CheckBSplineCurve
27//purpose :
28//=======================================================================
7fd59977 29GeomLib_CheckBSplineCurve::GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve,
30 const Standard_Real Tolerance,
31 const Standard_Real AngularTolerance)
e67e482d 32 : myCurve(Curve),
33 myDone(Standard_False),
34 myFixFirstTangent(Standard_False),
35 myFixLastTangent(Standard_False),
36 myAngularTolerance(Abs(AngularTolerance)),
37 myTolerance(Abs(Tolerance)),
38 myIndSecondPole(-1),
39 myIndPrelastPole(-1)
7fd59977 40{
7fd59977 41 Standard_Integer ii,
42 num_poles ;
43 Standard_Real tangent_magnitude,
44 value,
7fd59977 45 vector_magnitude ;
e67e482d 46 num_poles = myCurve->NbPoles() ;
47
7fd59977 48 if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
49
e67e482d 50 gp_Vec tangent, tangent_normalized,
51 a_vector, avector_normalized;
52
53 const Standard_Real CrossProdSqTol = myAngularTolerance*myAngularTolerance;
54
55 //Near first
56 tangent = gp_Vec(myCurve->Pole(1), myCurve->Pole(2));
7fd59977 57 tangent_magnitude = tangent.Magnitude() ;
e67e482d 58 if (tangent_magnitude > myTolerance)
59 tangent_normalized = tangent/tangent_magnitude;
60
61 for (ii = 3; ii <= num_poles; ii++)
62 {
63 a_vector = gp_Vec(myCurve->Pole(1), myCurve->Pole(ii));
64 vector_magnitude = a_vector.Magnitude() ;
65
66 if (tangent_magnitude > myTolerance &&
67 vector_magnitude > myTolerance)
7fd59977 68 {
e67e482d 69 avector_normalized = a_vector/vector_magnitude;
70
71 gp_Vec CrossProd = tangent_normalized ^ avector_normalized;
72 Standard_Real CrossProdSqLength = CrossProd.SquareMagnitude();
73 if (CrossProdSqLength > CrossProdSqTol)
74 break;
75
7fd59977 76 value = tangent.Dot(a_vector) ;
e67e482d 77 if ( value < 0.0e0)
78 {
79 myFixFirstTangent = Standard_True ;
80 myIndSecondPole = ii;
81 break;
7fd59977 82 }
83 }
7fd59977 84 }
e67e482d 85
86 //Near last
87 tangent = gp_Vec(myCurve->Pole(num_poles), myCurve->Pole(num_poles-1));
7fd59977 88 tangent_magnitude = tangent.Magnitude() ;
e67e482d 89 if (tangent_magnitude > myTolerance)
90 tangent_normalized = tangent/tangent_magnitude;
91
92 for (ii = num_poles-2; ii >= 1; ii--)
93 {
94 a_vector = gp_Vec(myCurve->Pole(num_poles), myCurve->Pole(ii));
95 vector_magnitude = a_vector.Magnitude() ;
96
97 if (tangent_magnitude > myTolerance &&
98 vector_magnitude > myTolerance)
7fd59977 99 {
e67e482d 100 avector_normalized = a_vector/vector_magnitude;
101
102 gp_Vec CrossProd = tangent_normalized ^ avector_normalized;
103 Standard_Real CrossProdSqLength = CrossProd.SquareMagnitude();
104 if (CrossProdSqLength > CrossProdSqTol)
105 break;
106
7fd59977 107 value = tangent.Dot(a_vector) ;
e67e482d 108 if (value < 0.0e0)
109 {
110 myFixLastTangent = Standard_True ;
111 myIndPrelastPole = ii;
112 break;
7fd59977 113 }
114 }
e67e482d 115 }
116 } //if (( ! myCurve->IsPeriodic() )&& num_poles >= 4)
7fd59977 117 else {
118 myDone = Standard_True ;
119 }
120}
121
122//=======================================================================
123//function : NeedTangentFix
124//purpose :
125//=======================================================================
126
127void GeomLib_CheckBSplineCurve::NeedTangentFix(Standard_Boolean & FirstFlag,
128 Standard_Boolean & LastFlag) const
129{
130 FirstFlag = myFixFirstTangent ;
e67e482d 131 LastFlag = myFixLastTangent ;
7fd59977 132}
e67e482d 133
7fd59977 134//=======================================================================
e67e482d 135//function : FixedTangent
7fd59977 136//purpose :
137//=======================================================================
138
139Handle(Geom_BSplineCurve) GeomLib_CheckBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
e67e482d 140 const Standard_Boolean LastFlag)
7fd59977 141{
142 Handle(Geom_BSplineCurve) new_curve ;
143 if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
144 new_curve =
145 Handle(Geom_BSplineCurve)::DownCast(myCurve->Copy()) ;
146
e67e482d 147 FixTangentOnCurve(new_curve, FirstFlag, LastFlag);
7fd59977 148 }
7fd59977 149 return new_curve ;
e67e482d 150}
151
7fd59977 152//=======================================================================
153//function : FixTangent
154//purpose :
155//=======================================================================
156
157void GeomLib_CheckBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
e67e482d 158 const Standard_Boolean LastFlag)
159{
160 FixTangentOnCurve(myCurve, FirstFlag, LastFlag);
161}
162
163//=======================================================================
164//function : FixTangentOnCurve
165//purpose :
166//=======================================================================
167
168void GeomLib_CheckBSplineCurve::FixTangentOnCurve(Handle(Geom_BSplineCurve)& theCurve,
169 const Standard_Boolean FirstFlag,
170 const Standard_Boolean LastFlag)
7fd59977 171{
7fd59977 172 if (myFixFirstTangent && FirstFlag) {
e67e482d 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++)
177 {
178 Standard_Real ii = i-1;
179 gp_Pnt aNewPole((1. - ii/NbSamples)*XYZ1 + ii/NbSamples*XYZ2);
180 theCurve->SetPole(i, aNewPole);
181 }
7fd59977 182 }
e67e482d 183
7fd59977 184 if (myFixLastTangent && LastFlag) {
e67e482d 185 Standard_Integer num_poles = theCurve->NbPoles() ;
186
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--)
191 {
192 Standard_Real ii = num_poles-i;
193 gp_Pnt aNewPole((1. - ii/NbSamples)*XYZ1 + ii/NbSamples*XYZ2);
194 theCurve->SetPole(i, aNewPole);
195 }
7fd59977 196 }
197
198 myDone = Standard_True ;
199}