0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / GeomFill / GeomFill_EvolvedSection.cxx
1 // Created on: 1998-08-17
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-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 #include <stdio.h>
18
19 #include <GeomFill_EvolvedSection.ixx>
20
21 #include <GeomConvert.hxx>
22 #include <Convert_ParameterisationType.hxx>
23
24 #include <Geom_Geometry.hxx>
25 #include <Geom_Surface.hxx>
26 #include <Geom_BSplineSurface.hxx>
27 #include <GeomAdaptor_Curve.hxx>
28
29 #include <GCPnts_AbscissaPoint.hxx>
30 #include <TColgp_Array2OfPnt.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32 #include <TColStd_Array1OfInteger.hxx>
33 #include <Precision.hxx>
34
35
36 #ifdef DRAW
37 #include <DrawTrSurf.hxx>
38 static Standard_Integer NumSec = 0;
39 static Standard_Boolean Affich = 0;
40 #endif
41
42 GeomFill_EvolvedSection::GeomFill_EvolvedSection(const Handle(Geom_Curve)& C,
43                                                  const Handle(Law_Function)& L)
44 {
45   L->Bounds(First, Last);
46   mySection = Handle(Geom_Curve)::DownCast(C->Copy());
47   myLaw =  L->Trim(First, Last, 1.e-20);
48   TLaw = myLaw;
49   myCurve =  Handle(Geom_BSplineCurve)::DownCast(C);
50   if (myCurve.IsNull()) {
51     myCurve = GeomConvert::CurveToBSplineCurve(C, Convert_QuasiAngular);
52     if (myCurve->IsPeriodic()) {
53       Standard_Integer M = myCurve->Degree()/2+1;
54       myCurve->RemoveKnot(1, M, Precision::Confusion());
55     }
56   }
57
58 #if DRAW
59   if (Affich) {
60     char name[256];
61     sprintf(name,"UnifSect_%d",++NumSec);
62     DrawTrSurf::Set(name, myCurve);
63   }
64 #endif
65 }
66
67 //=======================================================
68 // Purpose :D0
69 //=======================================================
70  Standard_Boolean GeomFill_EvolvedSection::D0(const Standard_Real U,
71                                               TColgp_Array1OfPnt& Poles,
72                                               TColStd_Array1OfReal& Weights) 
73 {
74   Standard_Real val;
75   Standard_Integer ii, L =  Poles.Length();
76   val= TLaw->Value(U);
77   myCurve->Poles(Poles);
78   for (ii=1; ii<=L; ii++) {
79     Poles(ii).ChangeCoord() *= val;
80   }
81   myCurve->Weights(Weights);
82
83   return Standard_True;
84 }
85
86 //=======================================================
87 // Purpose :D1
88 //=======================================================
89  Standard_Boolean GeomFill_EvolvedSection::D1(const Standard_Real U,
90                                               TColgp_Array1OfPnt& Poles,
91                                               TColgp_Array1OfVec& DPoles,
92                                               TColStd_Array1OfReal& Weights,
93                                               TColStd_Array1OfReal& DWeights) 
94 {
95  Standard_Real val, dval;
96  Standard_Integer ii, L =  Poles.Length();
97  TLaw->D1(U, val, dval);
98
99  myCurve->Poles(Poles);
100  myCurve->Weights(Weights);
101  for (ii=1; ii<=L; ii++) {
102    DPoles(ii).SetXYZ(Poles(ii).XYZ());
103    DPoles(ii) *= dval;
104    Poles(ii).ChangeCoord() *= val;
105  }
106  DWeights.Init(0);
107
108  return Standard_True;
109 }
110
111 //=======================================================
112 // Purpose :D2
113 //=======================================================
114  Standard_Boolean GeomFill_EvolvedSection::D2(const Standard_Real U,
115                                               TColgp_Array1OfPnt& Poles,
116                                               TColgp_Array1OfVec& DPoles,
117                                               TColgp_Array1OfVec& D2Poles,
118                                               TColStd_Array1OfReal& Weights,
119                                               TColStd_Array1OfReal& DWeights,
120                                               TColStd_Array1OfReal& D2Weights) 
121
122   Standard_Real val, dval, d2val;
123   Standard_Integer ii, L =  Poles.Length();
124   TLaw->D2(U, val, dval, d2val);
125   myCurve->Poles(Poles);
126   myCurve->Weights(Weights);
127
128   for (ii=1; ii<=L; ii++) {
129     DPoles(ii).SetXYZ(Poles(ii).XYZ());
130     D2Poles(ii) = DPoles(ii);
131     D2Poles(ii) *= d2val;
132     DPoles(ii)  *= dval;
133     Poles(ii).ChangeCoord() *= val;
134   }  
135  
136   DWeights.Init(0);
137   D2Weights.Init(0);
138
139   return Standard_True;
140 }
141
142 //=======================================================
143 // Purpose :BSplineSurface()
144 //=======================================================
145  Handle(Geom_BSplineSurface) GeomFill_EvolvedSection::BSplineSurface() const
146 {
147 /*  Standard_Integer ii, NbPoles = myCurve->NbPoles();
148   TColgp_Array2OfPnt Poles( 1, NbPoles, 1, 2);
149   TColStd_Array1OfReal UKnots(1,myCurve->NbKnots()), VKnots(1,2); 
150   TColStd_Array1OfInteger UMults(1,myCurve->NbKnots()), VMults(1,2);
151   
152   for (ii=1; ii <= NbPoles; ii++) {
153     Poles(ii, 1) =  Poles(ii, 2) = myCurve->Pole(ii);
154   }
155
156   myCurve->Knots(UKnots);
157   VKnots(1) = First;
158   VKnots(2) = Last;
159
160   myCurve->Multiplicities(UMults);
161   VMults.Init(2);
162
163
164   Handle(Geom_BSplineSurface) BS = 
165     new (Geom_BSplineSurface) ( Poles,
166                                UKnots, VKnots,
167                                UMults, VMults,
168                                myCurve->Degree(), 1,
169                                myCurve->IsPeriodic());*/
170   Handle(Geom_BSplineSurface) BS;
171   BS.Nullify();
172   return BS;
173
174 }
175 //=======================================================
176 // Purpose :SectionShape
177 //=======================================================
178  void GeomFill_EvolvedSection::SectionShape(Standard_Integer& NbPoles,
179                                             Standard_Integer& NbKnots,
180                                             Standard_Integer& Degree) const
181 {
182    NbPoles = myCurve->NbPoles();
183    NbKnots = myCurve->NbKnots();
184    Degree  = myCurve->Degree();
185 }
186
187  void GeomFill_EvolvedSection::Knots(TColStd_Array1OfReal& TKnots) const
188 {
189  myCurve->Knots(TKnots);
190 }
191 //=======================================================
192 // Purpose :Mults
193 //=======================================================
194  void GeomFill_EvolvedSection::Mults(TColStd_Array1OfInteger& TMults) const
195 {
196    myCurve->Multiplicities(TMults);
197 }
198
199
200 //=======================================================
201 // Purpose :IsRational
202 //=======================================================
203  Standard_Boolean GeomFill_EvolvedSection::IsRational() const
204 {
205   return myCurve->IsRational();
206 }
207
208 //=======================================================
209 // Purpose :IsUPeriodic
210 //=======================================================
211  Standard_Boolean GeomFill_EvolvedSection::IsUPeriodic() const
212 {
213   return myCurve->IsPeriodic();
214 }
215
216 //=======================================================
217 // Purpose :IsVPeriodic
218 //=======================================================
219  Standard_Boolean GeomFill_EvolvedSection::IsVPeriodic() const
220 {
221   return 
222     (Abs(myLaw->Value(First) - myLaw->Value(Last)) < Precision::Confusion());
223 }
224
225 //=======================================================
226 // Purpose :NbIntervals
227 //=======================================================
228  Standard_Integer GeomFill_EvolvedSection::NbIntervals(const GeomAbs_Shape S) const
229 {
230   return myLaw->NbIntervals(S) ;
231 }
232
233
234 //=======================================================
235 // Purpose :Intervals
236 //=======================================================
237  void GeomFill_EvolvedSection::Intervals(TColStd_Array1OfReal& T,
238                                          const GeomAbs_Shape S) const
239 {
240   myLaw->Intervals(T, S) ; 
241 }
242
243
244 //=======================================================
245 // Purpose : SetInterval
246 //=======================================================
247  void GeomFill_EvolvedSection::SetInterval(const Standard_Real F,
248                                            const Standard_Real L) 
249 {
250  TLaw = myLaw->Trim(F, L, Precision::PConfusion());
251 }
252
253 //=======================================================
254 // Purpose : GetInterval
255 //=======================================================
256  void GeomFill_EvolvedSection::GetInterval(Standard_Real& F,
257                                            Standard_Real& L) const
258 {
259   TLaw->Bounds(F, L); 
260 }
261
262 //=======================================================
263 // Purpose : GetDomain
264 //=======================================================
265  void GeomFill_EvolvedSection::GetDomain(Standard_Real& F,
266                                          Standard_Real& L) const
267 {
268   F = First;
269   L = Last;
270 }
271
272 //=======================================================
273 // Purpose : GetTolerance
274 //=======================================================
275  void GeomFill_EvolvedSection::GetTolerance(const Standard_Real BoundTol,
276                                             const Standard_Real SurfTol,
277 //                                          const Standard_Real AngleTol,
278                                             const Standard_Real ,
279                                             TColStd_Array1OfReal& Tol3d) const
280 {
281   Tol3d.Init(SurfTol);
282   if (BoundTol<SurfTol) {
283     Tol3d(Tol3d.Lower()) = BoundTol;
284     Tol3d(Tol3d.Upper()) = BoundTol;
285   }
286 }
287
288 //=======================================================
289 // Purpose :
290 //=======================================================
291  gp_Pnt GeomFill_EvolvedSection::BarycentreOfSurf() const
292 {
293   Standard_Real U = mySection->FirstParameter(), Delta, b;
294   Standard_Integer ii;
295   gp_Pnt P, Bary;
296   
297   Delta = ( myCurve->LastParameter() - U ) / 20;
298   Bary.SetCoord(0., 0., 0.);
299   for (ii=0 ; ii <=20; ii++, U+=Delta) {
300     P = myCurve->Value(U);
301     Bary.ChangeCoord() += P.XYZ();
302   } 
303
304   U = First;
305   Delta = ( Last - First) / 20;
306   for (ii=0, b=0.0; ii <=20; ii++, U+=Delta) {
307     b += myLaw->Value(U);
308   }  
309   Bary.ChangeCoord() *= b/(21*21);
310   return Bary;
311 }
312
313  Standard_Real GeomFill_EvolvedSection::MaximalSection() const
314 {
315   Standard_Real L, val, max, U, Delta;
316   Standard_Integer ii;
317   GeomAdaptor_Curve AC (mySection);
318   L = GCPnts_AbscissaPoint::Length(AC);
319
320   Delta = ( Last - First) / 20;
321   for (ii=0, max=0.0, U = First; ii <=20; ii++, U+=Delta) {
322     val = myLaw->Value(U);
323     if (val>max) max = val;
324   }
325   return L*max;
326 }
327
328 void GeomFill_EvolvedSection::GetMinimalWeight(TColStd_Array1OfReal& Weights) const
329 {
330   if (myCurve->IsRational()) {
331     myCurve->Weights(Weights);
332   }
333   else {
334     Weights.Init(1);
335   }
336 }
337
338  Standard_Boolean GeomFill_EvolvedSection::IsConstant(Standard_Real& Error) const
339 {
340 //  Standard_Real isconst = Standard_False;
341   Standard_Boolean isconst = Standard_False;
342   Error = 0.;
343   return isconst;
344 }
345
346  Handle(Geom_Curve) GeomFill_EvolvedSection::ConstantSection() const
347 {
348   Standard_Real Err, scale;
349   if (!IsConstant(Err)) StdFail_NotDone::Raise("The Law is not Constant!");
350   gp_Trsf T;
351   gp_Pnt P(0, 0, 0);
352   scale = myLaw->Value(First) +  
353           myLaw->Value((First+Last)/2) +
354           myLaw->Value(Last);
355   T.SetScale(P, scale/3);
356   
357   Handle(Geom_Curve) C;
358   C = Handle(Geom_Curve)::DownCast( mySection->Copy());
359   C->Transform(T);
360   return C;
361 }
362
363
364