1 // File:        GeomLib_CheckBSplineCurve.cxx
2 // Created:     Wed May 28 17:26:47 1997
3 // Author:      Xavier BENVENISTE
4 //              <xab@zozox.paris1.matra-dtv.fr>
7 #include <GeomLib_CheckBSplineCurve.ixx>
8 #include <Geom_BSplineCurve.hxx>
9 #include <gp_Pnt.hxx>
10 #include <gp_Vec.hxx>
11 //=======================================================================
12 //function : GeomLib_CheckBSplineCurve
13 //purpose  :
14 //=======================================================================
16 GeomLib_CheckBSplineCurve::GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve,
17                                                      const Standard_Real Tolerance,
18                                                      const Standard_Real AngularTolerance)
19 :myCurve(Curve),
20 myDone(Standard_False),
21 myFixFirstTangent(Standard_False),
22 myFixLastTangent(Standard_False),
23 myAngularTolerance(Abs(AngularTolerance)),
24 myTolerance(Abs(Tolerance)),
25 myFirstPole(1.0,0.0e0,0.e0),
26 myLastPole(1.0e0,0.0e0,0.e0)
27 {
30   Standard_Integer ii,
31     num_poles ;
32   Standard_Real tangent_magnitude,
33     value,
34     angular_value,
35     factor,
36     vector_magnitude ;
37   num_poles = Curve->NbPoles() ;
38   if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
40     gp_Vec tangent,
41       diff,
42       a_vector;
43     for (ii = 1 ; ii <= 3 ; ii++) {
44       tangent.SetCoord(ii,myCurve->Pole(2).Coord(ii) - myCurve->Pole(1).Coord(ii))  ;
45       a_vector.SetCoord(ii, myCurve->Pole(3).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
46     }
47     tangent_magnitude = tangent.Magnitude() ;
48     vector_magnitude = a_vector.Magnitude() ;
49     if (tangent_magnitude > myTolerance &&
50         vector_magnitude > myTolerance)
51       {
52         value = tangent.Dot(a_vector) ;
53         if ( value < 0.0e0) {
54           for (ii = 1 ; ii <= 3 ; ii++) {
55             diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ;
56           }
57           angular_value =
58             diff.Magnitude() ;
59           if (angular_value < myAngularTolerance) {
60             myFixFirstTangent = Standard_True ;
61             factor = 1.0e0 ;
62             if (tangent_magnitude > 0.5e0 * vector_magnitude) {
63               factor = 0.5e0 *  vector_magnitude / tangent_magnitude ;
64             }
65             for (ii = 1 ; ii <= 3 ; ii++) {
66               myFirstPole.SetCoord(ii, myCurve->Pole(1).Coord(ii)  - factor * tangent.Coord(ii))  ;
67             }
68           }
70         }
71       }
72     for (ii = 1 ; ii <= 3 ; ii++) {
73       tangent.SetCoord(ii,myCurve->Pole(num_poles-1).Coord(ii) - myCurve->Pole(num_poles).Coord(ii))  ;
74       a_vector.SetCoord(ii, myCurve->Pole(num_poles-2).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
75     }
76     tangent_magnitude = tangent.Magnitude() ;
77     vector_magnitude = a_vector.Magnitude() ;
79     if (tangent_magnitude > myTolerance &&
80         vector_magnitude > myTolerance)
81       {
82         value = tangent.Dot(a_vector) ;
83         if (value < 0.0e0) {
84           for (ii = 1 ; ii <= 3 ; ii++) {
85             diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ;
86           }
87           angular_value =
88             diff.Magnitude() ;
89           if ( angular_value < myAngularTolerance) {
90             myFixLastTangent = Standard_True ;
91             factor = 1.0e0 ;
92             if (tangent_magnitude > 0.5e0 * vector_magnitude) {
93               factor = 0.5e0 *  vector_magnitude / tangent_magnitude ;
94             }
95             for (ii = 1 ; ii <= 3 ; ii++) {
96               myLastPole.SetCoord(ii, myCurve->Pole(num_poles).Coord(ii)  - factor * tangent.Coord(ii))  ;
97             }
98           }
100         }
101       }
103   }
104   else {
105     myDone = Standard_True ;
106   }
107 }
109 //=======================================================================
110 //function : NeedTangentFix
111 //purpose  :
112 //=======================================================================
114 void GeomLib_CheckBSplineCurve::NeedTangentFix(Standard_Boolean & FirstFlag,
115                                                Standard_Boolean & LastFlag) const
116 {
117   FirstFlag = myFixFirstTangent ;
118   LastFlag = myFixLastTangent ;
119 }
120 //=======================================================================
121 //function : FixTangent
122 //purpose  :
123 //=======================================================================
125 Handle(Geom_BSplineCurve)  GeomLib_CheckBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
126                                                                  const Standard_Boolean LastFlag)
127
128   Handle(Geom_BSplineCurve) new_curve ;
129   if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
130     new_curve =
131       Handle(Geom_BSplineCurve)::DownCast(myCurve->Copy()) ;
133   }
134   if (myFixFirstTangent && FirstFlag) {
135     new_curve->SetPole(2,
136                      myFirstPole) ;
137   }
138   if (myFixLastTangent && LastFlag) {
139     Standard_Integer num_poles = myCurve->NbPoles() ;
140     new_curve->SetPole(num_poles-1,
141                      myLastPole) ;
142   }
144   myDone = Standard_True ;
145   return new_curve ;
146 }
147 //=======================================================================
148 //function : FixTangent
149 //purpose  :
150 //=======================================================================
152 void GeomLib_CheckBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
153                                            const Standard_Boolean LastFlag)
154
156   if (myFixFirstTangent && FirstFlag) {
157     myCurve->SetPole(2,
158                      myFirstPole) ;
159   }
160   if (myFixLastTangent && LastFlag) {
161     Standard_Integer num_poles = myCurve->NbPoles() ;
162     myCurve->SetPole(num_poles-1,
163                      myLastPole) ;
164   }
166   myDone = Standard_True ;
167 }