0028599: Replacement of old Boolean operations with new ones in BRepProj_Projection...
[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 myFirstPole(1.0,0.0e0),
40 myLastPole(1.0e0,0.0e0)
41 {
42   
43
44   Standard_Integer ii,
45     num_poles ;
46   Standard_Real tangent_magnitude,
47     value,
48     angular_value,
49     factor,
50     vector_magnitude ;
51   num_poles = Curve->NbPoles() ;
52   if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
53     
54     gp_Vec2d tangent,
55       diff,
56       a_vector;
57     for (ii = 1 ; ii <= 2 ; ii++) {
58       tangent.SetCoord(ii,myCurve->Pole(2).Coord(ii) - myCurve->Pole(1).Coord(ii))  ;
59       a_vector.SetCoord(ii, myCurve->Pole(3).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
60     }
61     tangent_magnitude = tangent.Magnitude() ;
62     vector_magnitude = a_vector.Magnitude() ;
63     if (tangent_magnitude > myTolerance &&
64         vector_magnitude > myTolerance)
65       {
66         value = tangent.Dot(a_vector) ;
67         if ( value < 0.0e0) {
68           for (ii = 1 ; ii <= 2 ; ii++) {
69             diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ; 
70           } 
71           angular_value = 
72             diff.Magnitude() ;
73           if (angular_value < myAngularTolerance) {
74             myFixFirstTangent = Standard_True ;
75             factor = 1.0e0 ;
76             if (tangent_magnitude > 0.5e0 * vector_magnitude) {
77               factor = 0.5e0 *  vector_magnitude / tangent_magnitude ;
78             }
79             for (ii = 1 ; ii <= 2 ; ii++) {
80               myFirstPole.SetCoord(ii, myCurve->Pole(1).Coord(ii)  - factor * tangent.Coord(ii))  ;
81             }
82           }
83           
84         }
85       }
86     for (ii = 1 ; ii <= 2 ; ii++) {
87       tangent.SetCoord(ii,myCurve->Pole(num_poles-1).Coord(ii) - myCurve->Pole(num_poles).Coord(ii))  ;
88       a_vector.SetCoord(ii, myCurve->Pole(num_poles-2).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
89     }
90     tangent_magnitude = tangent.Magnitude() ;
91     vector_magnitude = a_vector.Magnitude() ;
92     
93     if (tangent_magnitude > myTolerance &&
94         vector_magnitude > myTolerance)
95       {
96         value = tangent.Dot(a_vector) ;
97         if (value < 0.0e0) {
98           for (ii = 1 ; ii <= 2 ; ii++) {
99             diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ; 
100           } 
101           angular_value = 
102             diff.Magnitude() ;
103           if ( angular_value < myAngularTolerance) {
104             myFixLastTangent = Standard_True ;
105             factor = 1.0e0 ;
106             if (tangent_magnitude > 0.5e0 * vector_magnitude) {
107               factor = 0.5e0 *  vector_magnitude / tangent_magnitude ;
108             }
109             for (ii = 1 ; ii <= 2 ; ii++) {
110               myLastPole.SetCoord(ii, myCurve->Pole(num_poles).Coord(ii)  - factor * tangent.Coord(ii))  ;
111             }
112           }
113           
114         }
115       }
116     
117   }
118   else {
119     myDone = Standard_True ;
120   }
121 }
122   
123 //=======================================================================
124 //function : NeedTangentFix
125 //purpose  : 
126 //=======================================================================
127
128 void GeomLib_Check2dBSplineCurve::NeedTangentFix(Standard_Boolean & FirstFlag,
129                                                Standard_Boolean & LastFlag) const 
130 {
131   FirstFlag = myFixFirstTangent ;
132   LastFlag = myFixLastTangent ;
133 }
134 //=======================================================================
135 //function : FixTangent
136 //purpose  : 
137 //=======================================================================
138
139 Handle(Geom2d_BSplineCurve)  GeomLib_Check2dBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
140                                                                  const Standard_Boolean LastFlag)
141
142   Handle(Geom2d_BSplineCurve) new_curve ;
143   if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
144     new_curve =
145       Handle(Geom2d_BSplineCurve)::DownCast(myCurve->Copy()) ;
146     
147   }
148   if (myFixFirstTangent && FirstFlag) {
149     new_curve->SetPole(2,
150                      myFirstPole) ;
151   }
152   if (myFixLastTangent && LastFlag) {
153     Standard_Integer num_poles = myCurve->NbPoles() ;
154     new_curve->SetPole(num_poles-1,
155                      myLastPole) ;
156   }
157   
158   myDone = Standard_True ;
159   return new_curve ;
160 }                                  
161 //=======================================================================
162 //function : FixTangent
163 //purpose  : 
164 //=======================================================================
165
166 void GeomLib_Check2dBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
167                                                                  const Standard_Boolean LastFlag)
168
169
170   if (myFixFirstTangent && FirstFlag) {
171     myCurve->SetPole(2,
172                      myFirstPole) ;
173   }
174   if (myFixLastTangent && LastFlag) {
175     Standard_Integer num_poles = myCurve->NbPoles() ;
176     myCurve->SetPole(num_poles-1,
177                      myLastPole) ;
178   }
179   
180   myDone = Standard_True ;
181 }