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