0026252: GeomAdaptor_Surface should use inner adaptor to calculate values of complex...
[occt.git] / src / Geom / Geom_OsculatingSurface.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <BSplSLib.hxx>
16 #include <Convert_GridPolynomialToPoles.hxx>
17 #include <Geom_BezierSurface.hxx>
18 #include <Geom_BSplineSurface.hxx>
19 #include <Geom_OsculatingSurface.hxx>
20 #include <Geom_Surface.hxx>
21 #include <PLib.hxx>
22 #include <Precision.hxx>
23 #include <TColgp_Array1OfPnt.hxx>
24 #include <TColgp_Array2OfPnt.hxx>
25 #include <TColgp_Array2OfVec.hxx>
26 #include <TColgp_HArray2OfPnt.hxx>
27 #include <TColStd_Array1OfInteger.hxx>
28 #include <TColStd_Array1OfReal.hxx>
29 #include <TColStd_HArray1OfInteger.hxx>
30 #include <TColStd_HArray1OfReal.hxx>
31 #include <TColStd_HArray2OfInteger.hxx>
32
33 //=======================================================================
34 //function : Geom_OffsetOsculatingSurface
35 //purpose  : 
36 //=======================================================================
37 Geom_OsculatingSurface::Geom_OsculatingSurface()
38   : myAlong(1,4)
39 {
40   myAlong.Init(Standard_False);
41 }
42 //=======================================================================
43 //function : Geom_OffsetOsculatingSurface
44 //purpose  : 
45 //=======================================================================
46
47 Geom_OsculatingSurface::Geom_OsculatingSurface(const Handle(Geom_Surface)& BS, 
48   const Standard_Real Tol)
49   : myAlong(1,4)
50 {
51   Init(BS,Tol);
52 }
53
54 //=======================================================================
55 //function : Init
56 //purpose  : 
57 //=======================================================================
58
59 void Geom_OsculatingSurface::Init(const Handle(Geom_Surface)& BS,
60   const Standard_Real Tol)
61 {
62   ClearOsculFlags();
63   myTol=Tol; 
64   Standard_Real TolMin=0.;//consider all singularities below Tol, not just above 1.e-12 (id23943)
65   Standard_Boolean OsculSurf = Standard_True;
66   myBasisSurf = Handle(Geom_Surface)::DownCast(BS->Copy());
67   myOsculSurf1 = new Geom_HSequenceOfBSplineSurface();
68   myOsculSurf2 = new Geom_HSequenceOfBSplineSurface();
69   if ((BS->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) || 
70     (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface)))) 
71   {
72     Standard_Real U1=0,U2=0,V1=0,V2=0;
73
74     Standard_Integer i = 1;
75     BS->Bounds(U1,U2,V1,V2);
76     myAlong.SetValue(1,IsQPunctual(BS,V1,GeomAbs_IsoV,TolMin,Tol));
77     myAlong.SetValue(2,IsQPunctual(BS,V2,GeomAbs_IsoV,TolMin,Tol));
78     myAlong.SetValue(3,IsQPunctual(BS,U1,GeomAbs_IsoU,TolMin,Tol));
79     myAlong.SetValue(4,IsQPunctual(BS,U2,GeomAbs_IsoU,TolMin,Tol));
80 #ifdef OCCT_DEBUG
81     cout<<myAlong(1)<<endl<<myAlong(2)<<endl<<myAlong(3)<<endl<<myAlong(4)<<endl;
82 #endif
83     if (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4)) 
84     {
85       Handle(Geom_BSplineSurface) InitSurf, L,S;
86       if (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface))) 
87       {
88         Handle(Geom_BezierSurface) BzS = Handle(Geom_BezierSurface)::DownCast(BS);
89         TColgp_Array2OfPnt P(1,BzS->NbUPoles(),1,BzS->NbVPoles());
90         TColStd_Array1OfReal UKnots(1,2);
91         TColStd_Array1OfReal VKnots(1,2);
92         TColStd_Array1OfInteger UMults(1,2);
93         TColStd_Array1OfInteger VMults(1,2);
94         for (i=1;i<=2;i++)
95         {
96           UKnots.SetValue(i,(i-1));
97           VKnots.SetValue(i,(i-1));
98           UMults.SetValue(i,BzS->UDegree()+1);
99           VMults.SetValue(i,BzS->VDegree()+1);
100         }
101         BzS->Poles(P);
102         InitSurf = new Geom_BSplineSurface(P,UKnots,VKnots,
103           UMults,VMults,
104           BzS->UDegree(),
105           BzS->VDegree(),
106           BzS->IsUPeriodic(),
107           BzS->IsVPeriodic());
108       }
109       else 
110       {
111         InitSurf = Handle(Geom_BSplineSurface)::DownCast(myBasisSurf);
112       }
113 #ifdef OCCT_DEBUG
114       cout<<"UDEG: "<<InitSurf->UDegree()<<endl;
115       cout<<"VDEG: "<<InitSurf->VDegree()<<endl;
116 #endif
117
118       if(IsAlongU() && IsAlongV()) ClearOsculFlags();
119       //      Standard_ConstructionError_Raise_if((IsAlongU() && IsAlongV()),"Geom_OsculatingSurface");
120       if ((IsAlongU() && InitSurf->VDegree()>1) ||
121         (IsAlongV() && InitSurf->UDegree()>1)) 
122       {
123         myKdeg = new TColStd_HSequenceOfInteger();
124         Standard_Integer k=0;
125         Standard_Boolean IsQPunc;
126         Standard_Integer UKnot,VKnot;
127         if (myAlong(1) || myAlong(2)) 
128         {
129           for (i=1;i<InitSurf->NbUKnots();i++) 
130           {
131             if (myAlong(1)) 
132             {
133               S = InitSurf; k=0; IsQPunc=Standard_True;
134               UKnot=i;
135               VKnot=1;
136               while(IsQPunc) 
137               {
138                 OsculSurf  = BuildOsculatingSurface(V1,UKnot,VKnot,S,L);
139                 if(!OsculSurf) break;
140                 k++;
141 #ifdef OCCT_DEBUG
142                 cout<<"1.k = "<<k<<endl;
143 #endif
144                 IsQPunc=IsQPunctual(L,V1,GeomAbs_IsoV,0.,Tol);
145                 UKnot=1;
146                 VKnot=1;
147                 S=L;
148
149               }
150               if (OsculSurf)
151                 myOsculSurf1->Append(L);
152               else
153                 ClearOsculFlags(); //myAlong.SetValue(1,Standard_False);
154               if (myAlong(2) && OsculSurf) 
155               {
156                 S = InitSurf; k=0; IsQPunc=Standard_True;
157                 UKnot=i;
158                 VKnot=InitSurf->NbVKnots()-1;
159
160                 while(IsQPunc) 
161                 {
162                   OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L);
163                   if(!OsculSurf) break;
164                   k++;
165 #ifdef OCCT_DEBUG
166                   cout<<"2.k = "<<k<<endl;
167 #endif
168                   IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol);
169                   UKnot=1;
170                   VKnot=1;
171                   S=L;
172                 }
173                 if(OsculSurf)
174                 {
175                   myOsculSurf2->Append(L);
176                   myKdeg->Append(k);
177                 }
178               } 
179             }
180             else 
181               //if (myAlong(2)) 
182             {
183               S = InitSurf; k=0; IsQPunc=Standard_True;
184               UKnot=i;
185               VKnot=InitSurf->NbVKnots()-1;
186               while(IsQPunc) 
187               {
188                 OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L);
189                 if(!OsculSurf) break;
190                 k++;
191 #ifdef OCCT_DEBUG
192                 cout<<"2.k = "<<k<<endl;
193 #endif
194                 IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol);
195                 UKnot=1;
196                 VKnot=1;
197                 S=L;
198
199               }
200               if(OsculSurf)
201               {
202                 myOsculSurf2->Append(L);
203                 myKdeg->Append(k);
204               }
205               else
206                 ClearOsculFlags(); //myAlong.SetValue(2,Standard_False);
207             }
208           }
209         }
210         if (myAlong(3) || myAlong(4)) 
211         {
212           for (i=1;i<InitSurf->NbVKnots();i++) 
213           {
214             if (myAlong(3)) 
215             {
216               S = InitSurf; k=0; IsQPunc=Standard_True;
217               UKnot=1;
218               VKnot=i;
219               while(IsQPunc) 
220               {
221                 OsculSurf = BuildOsculatingSurface(U1,UKnot,VKnot,S,L);
222                 if(!OsculSurf) break;
223                 k++;
224 #ifdef OCCT_DEBUG
225                 cout<<"1.k = "<<k<<endl;
226 #endif
227                 IsQPunc=IsQPunctual(L,U1,GeomAbs_IsoU,0.,Tol);
228                 UKnot=1;
229                 VKnot=1;
230                 S=L;
231               }
232               if(OsculSurf)
233                 myOsculSurf1->Append(L);
234               else
235                 ClearOsculFlags(); //myAlong.SetValue(3,Standard_False);
236               if (myAlong(4) && OsculSurf )
237               {
238                 S = InitSurf; k=0; IsQPunc=Standard_True;
239                 UKnot=InitSurf->NbUKnots()-1;
240                 VKnot=i;
241                 while(IsQPunc) 
242                 {
243                   OsculSurf  = BuildOsculatingSurface(U2,UKnot,VKnot,S,L);
244                   if(!OsculSurf) break;
245                   k++;
246 #ifdef OCCT_DEBUG
247                   cout<<"2.k = "<<k<<endl;
248 #endif
249                   IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol);
250                   UKnot=1;
251                   VKnot=1;
252                   S=L;
253                 }
254                 if(OsculSurf)
255                 {
256                   myOsculSurf2->Append(L);
257                   myKdeg->Append(k);
258                 }
259               }
260             }
261             else 
262             {
263               S = InitSurf; k=0; IsQPunc=Standard_True;
264               UKnot=InitSurf->NbUKnots()-1;
265               VKnot=i;
266               while(IsQPunc) 
267               {
268                 OsculSurf  = BuildOsculatingSurface(U2,UKnot,VKnot,S,L);
269                 if(!OsculSurf) break;
270                 k++;
271 #ifdef OCCT_DEBUG
272                 cout<<"2.k = "<<k<<endl;
273 #endif
274                 IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol);
275                 UKnot=1;
276                 VKnot=1;
277                 S=L;
278               }
279               if(OsculSurf)
280               {
281                 myOsculSurf2->Append(L);
282                 myKdeg->Append(k);
283               }
284               else
285                 ClearOsculFlags(); //myAlong.SetValue(4,Standard_False);
286             }
287           }
288         }
289       }
290       else
291       {
292         ClearOsculFlags();
293       } 
294     }
295   }
296   else
297     ClearOsculFlags();
298 }
299
300 //=======================================================================
301 //function : BasisSurface
302 //purpose  : 
303 //=======================================================================
304
305 Handle(Geom_Surface) Geom_OsculatingSurface::BasisSurface() const
306 {
307   return myBasisSurf;
308 }
309
310 //=======================================================================
311 //function : Tolerance
312 //purpose  : 
313 //=======================================================================
314
315 Standard_Real Geom_OsculatingSurface::Tolerance() const
316 {
317   return myTol;
318 }
319
320 //=======================================================================
321 //function : UOscSurf
322 //purpose  : 
323 //=======================================================================
324
325 Standard_Boolean Geom_OsculatingSurface::UOscSurf
326   (const Standard_Real U,
327   const Standard_Real V,
328   Standard_Boolean& t,
329   Handle(Geom_BSplineSurface)& L) const
330 {
331   Standard_Boolean along = Standard_False;
332   if (myAlong(1) || myAlong(2)) 
333   {
334     Standard_Integer NU = 1, NV = 1;
335     Standard_Real u1,u2,v1,v2;
336     t = Standard_False;
337     myBasisSurf->Bounds(u1,u2,v1,v2);
338     Standard_Integer NbUK,NbVK;
339     Standard_Boolean isToSkipSecond = Standard_False;
340     if (myBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) 
341     {
342       Handle(Geom_BSplineSurface) BSur = 
343         Handle(Geom_BSplineSurface)::DownCast (myBasisSurf);
344       NbUK = BSur->NbUKnots();
345       NbVK = BSur->NbVKnots();
346       TColStd_Array1OfReal UKnots(1,NbUK);
347       TColStd_Array1OfReal VKnots(1,NbVK);
348       BSur->UKnots(UKnots);
349       BSur->VKnots(VKnots);
350       BSplCLib::Hunt(UKnots,U,NU);
351       BSplCLib::Hunt(VKnots,V,NV);
352       if (NU < 1) NU=1;
353       if (NU >= NbUK) NU=NbUK-1;
354       if (NbVK==2 && NV==1)
355         // Need to find the closest end
356         if (VKnots(NbVK)-V > V-VKnots(1))
357           isToSkipSecond = Standard_True;
358     }
359     else {NU = 1; NV = 1 ; NbVK = 2 ;}
360
361     if (myAlong(1) && NV == 1) 
362     {
363       L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf1->Value(NU));
364       along = Standard_True;
365     }
366     if (myAlong(2) && (NV == NbVK-1) && !isToSkipSecond)
367     {
368       // t means that derivative vector of osculating surface is opposite
369       // to the original. This happens when (v-t)^k is negative, i.e.
370       // difference between degrees (k) is odd and t is the last parameter
371       if (myKdeg->Value(NU)%2) t = Standard_True;
372       L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf2->Value(NU));
373       along = Standard_True;
374     }
375   }
376   return along;
377 }
378
379 //=======================================================================
380 //function : VOscSurf
381 //purpose  : 
382 //=======================================================================
383
384 Standard_Boolean Geom_OsculatingSurface::VOscSurf
385   (const Standard_Real U,
386   const Standard_Real V,
387   Standard_Boolean& t,
388   Handle(Geom_BSplineSurface)& L) const
389 {
390   Standard_Boolean along = Standard_False;
391   if (myAlong(3) || myAlong(4)) 
392   {
393     Standard_Integer NU = 1, NV = 1;
394     Standard_Real u1,u2,v1,v2;
395     t = Standard_False;
396     myBasisSurf->Bounds(u1,u2,v1,v2);
397     Standard_Integer NbUK,NbVK;
398     Standard_Boolean isToSkipSecond = Standard_False;
399     if (myBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) 
400     {
401       Handle(Geom_BSplineSurface) BSur = 
402         Handle(Geom_BSplineSurface)::DownCast (myBasisSurf);
403       NbUK = BSur->NbUKnots();
404       NbVK = BSur->NbVKnots();
405       TColStd_Array1OfReal UKnots(1,NbUK);
406       TColStd_Array1OfReal VKnots(1,NbVK);
407       BSur->UKnots(UKnots);
408       BSur->VKnots(VKnots);
409       BSplCLib::Hunt(UKnots,U,NU);
410       BSplCLib::Hunt(VKnots,V,NV);
411       if (NV < 1) NV=1;
412       if (NV >= NbVK) NV=NbVK-1;
413       if (NbUK==2 && NU==1)
414         // Need to find the closest end
415         if (UKnots(NbUK)-U > U-UKnots(1))
416           isToSkipSecond = Standard_True;
417     }
418     else {NU = 1; NV = 1 ; NbUK = 2;}
419
420     if (myAlong(3) && NU == 1)  
421     {
422       L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf1->Value(NV));
423       along = Standard_True;
424     }
425     if (myAlong(4) && (NU == NbUK-1) && !isToSkipSecond)
426     {
427       if (myKdeg->Value(NV)%2) t = Standard_True;
428       L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf2->Value(NV));
429       along = Standard_True;
430     }
431   }
432   return along;
433 }
434
435 //=======================================================================
436 //function : BuildOsculatingSurface
437 //purpose  : 
438 //=======================================================================
439
440 Standard_Boolean  Geom_OsculatingSurface::BuildOsculatingSurface
441   (const Standard_Real Param,
442   const Standard_Integer SUKnot,
443   const Standard_Integer SVKnot,
444   const Handle(Geom_BSplineSurface)& BS,
445   Handle(Geom_BSplineSurface)& BSpl) const
446 {
447   Standard_Integer i, j;
448   Standard_Boolean OsculSurf=Standard_True;
449 #ifdef OCCT_DEBUG
450   cout<<"t = "<<Param<<endl;
451   cout<<"======================================"<<endl<<endl;
452 #endif
453
454   // for cache
455   Standard_Integer MinDegree,
456     MaxDegree ;
457   Standard_Real udeg, vdeg;
458   udeg = BS->UDegree();
459   vdeg = BS->VDegree();
460   if( (IsAlongU() && vdeg <=1) || (IsAlongV() && udeg <=1))
461   {
462 #ifdef OCCT_DEBUG
463     cout<<" surface osculatrice nulle "<<endl;
464 #endif
465     //Standard_ConstructionError::Raise("Geom_OsculatingSurface");
466     OsculSurf=Standard_False;
467   }
468   else
469   {
470     MinDegree = (Standard_Integer ) Min(udeg,vdeg) ;
471     MaxDegree = (Standard_Integer ) Max(udeg,vdeg) ;
472
473     TColgp_Array2OfPnt cachepoles(1, MaxDegree + 1, 1, MinDegree + 1);
474     // end for cache
475
476     // for polynomial grid 
477     Standard_Integer MaxUDegree, MaxVDegree;
478     Standard_Integer UContinuity, VContinuity;
479
480     Handle(TColStd_HArray2OfInteger) NumCoeffPerSurface = 
481       new TColStd_HArray2OfInteger(1, 1, 1, 2);
482     Handle(TColStd_HArray1OfReal) PolynomialUIntervals = 
483       new TColStd_HArray1OfReal(1, 2);
484     Handle(TColStd_HArray1OfReal) PolynomialVIntervals = 
485       new TColStd_HArray1OfReal(1, 2);
486     Handle(TColStd_HArray1OfReal) TrueUIntervals = 
487       new TColStd_HArray1OfReal(1, 2);
488     Handle(TColStd_HArray1OfReal) TrueVIntervals = 
489       new TColStd_HArray1OfReal(1, 2);
490     MaxUDegree = (Standard_Integer ) udeg;
491     MaxVDegree = (Standard_Integer ) vdeg;
492
493     for (i=1;i<=2;i++) 
494     {
495       PolynomialUIntervals->ChangeValue(i) = i-1;
496       PolynomialVIntervals->ChangeValue(i) = i-1;
497       TrueUIntervals->ChangeValue(i) = BS->UKnot(SUKnot+i-1);
498       TrueVIntervals->ChangeValue(i) = BS->VKnot(SVKnot+i-1);
499     }
500
501
502     Standard_Integer OscUNumCoeff=0, OscVNumCoeff=0;
503     if (IsAlongU()) 
504     {
505 #ifdef OCCT_DEBUG
506       cout<<">>>>>>>>>>> AlongU"<<endl;
507 #endif
508       OscUNumCoeff = (Standard_Integer ) udeg + 1;  
509       OscVNumCoeff = (Standard_Integer ) vdeg;  
510     }
511     if (IsAlongV()) 
512     {
513 #ifdef OCCT_DEBUG
514       cout<<">>>>>>>>>>> AlongV"<<endl;
515 #endif
516       OscUNumCoeff = (Standard_Integer ) udeg;  
517       OscVNumCoeff = (Standard_Integer ) vdeg + 1;  
518     }
519     NumCoeffPerSurface->ChangeValue(1,1) = OscUNumCoeff;  
520     NumCoeffPerSurface->ChangeValue(1,2) = OscVNumCoeff;  
521     Standard_Integer nbc = NumCoeffPerSurface->Value(1,1)*NumCoeffPerSurface->Value(1,2)*3;
522     //
523     if(nbc == 0)
524     {
525       return Standard_False;
526     }
527     //
528     Handle(TColStd_HArray1OfReal) Coefficients = new TColStd_HArray1OfReal(1, nbc);
529     //    end for polynomial grid
530
531     //    building the cache
532     Standard_Integer ULocalIndex, VLocalIndex;
533     Standard_Real ucacheparameter, vcacheparameter,uspanlength, vspanlength;
534     TColgp_Array2OfPnt NewPoles(1, BS->NbUPoles(), 1, BS->NbVPoles());
535
536     Standard_Integer aUfKnotsLength = BS->NbUPoles() + BS->UDegree() + 1;
537     Standard_Integer aVfKnotsLength = BS->NbVPoles() + BS->VDegree() + 1;
538
539     if(BS->IsUPeriodic())
540     {
541       TColStd_Array1OfInteger aMults(1, BS->NbUKnots());
542       BS->UMultiplicities(aMults);
543       aUfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->UDegree(), Standard_True);
544     }
545
546     if(BS->IsVPeriodic())
547     {
548       TColStd_Array1OfInteger aMults(1, BS->NbVKnots());
549       BS->VMultiplicities(aMults);
550       aVfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->VDegree(), Standard_True);
551     }
552
553     TColStd_Array1OfReal UFlatKnots(1, aUfKnotsLength);
554     TColStd_Array1OfReal VFlatKnots(1, aVfKnotsLength);
555     BS->Poles(NewPoles);
556     BS->UKnotSequence(UFlatKnots);
557     BS->VKnotSequence(VFlatKnots);
558
559     VLocalIndex = 0;
560     ULocalIndex = 0;
561     for(j = 1; j <= SVKnot; j++) VLocalIndex += BS->VMultiplicity(j);
562     for(i = 1; i <= SUKnot; i++) ULocalIndex += BS->UMultiplicity(i);
563     ucacheparameter = BS->UKnot(SUKnot);
564     vcacheparameter = BS->VKnot(SVKnot);
565     vspanlength = BS->VKnot(SVKnot + 1) - BS->VKnot(SVKnot);
566     uspanlength = BS->UKnot(SUKnot + 1) - BS->UKnot(SUKnot);
567
568     // On se ramene toujours a un parametrage tel que localement ce soit l'iso 
569     // u=0 ou v=0 qui soit degeneree
570
571     Standard_Boolean IsVNegative = Param > vcacheparameter + vspanlength/2;
572     Standard_Boolean IsUNegative = Param > ucacheparameter + uspanlength/2;
573
574     if (IsAlongU() && (Param > vcacheparameter + vspanlength/2))
575       vcacheparameter = vcacheparameter +  vspanlength;
576     if (IsAlongV() && (Param > ucacheparameter + uspanlength/2))
577       ucacheparameter = ucacheparameter +  uspanlength;
578
579     BSplSLib::BuildCache(ucacheparameter,   
580       vcacheparameter,   
581       uspanlength,         
582       vspanlength,         
583       BS->IsUPeriodic(),
584       BS->IsVPeriodic(),
585       BS->UDegree(),       
586       BS->VDegree(),       
587       ULocalIndex,         
588       VLocalIndex,         
589       UFlatKnots,
590       VFlatKnots,
591       NewPoles,
592       BSplSLib::NoWeights(),
593       cachepoles,
594       BSplSLib::NoWeights());
595     Standard_Integer m, n, index;
596     TColgp_Array2OfPnt OscCoeff(1,OscUNumCoeff , 1, OscVNumCoeff);
597
598     if (IsAlongU()) 
599     {
600       if (udeg > vdeg) 
601       {
602         for(n = 1; n <= udeg + 1; n++) 
603           for(m = 1; m <= vdeg; m++)
604             OscCoeff(n,m) = cachepoles(n,m+1) ;
605       }
606       else
607       {
608         for(n = 1; n <= udeg + 1; n++) 
609           for(m = 1; m <= vdeg; m++)
610             OscCoeff(n,m) = cachepoles(m+1,n) ;
611       }
612       if (IsVNegative) PLib::VTrimming(-1,0,OscCoeff,PLib::NoWeights2());
613
614       index=1;
615       for(n = 1; n <= udeg + 1; n++) 
616         for(m = 1; m <= vdeg; m++)
617         {
618           Coefficients->ChangeValue(index++) = OscCoeff(n,m).X();
619           Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y();
620           Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z();
621         }
622     }
623
624     if (IsAlongV()) 
625     {
626       if (udeg > vdeg) 
627       {
628         for(n = 1; n <= udeg; n++) 
629           for(m = 1; m <= vdeg + 1; m++)
630             OscCoeff(n,m) = cachepoles(n+1,m);
631       }
632       else
633       {
634         for(n = 1; n <= udeg; n++) 
635           for(m = 1; m <= vdeg + 1; m++)
636             OscCoeff(n,m) = cachepoles(m,n+1);
637       }
638       if (IsUNegative) PLib::UTrimming(-1,0,OscCoeff,PLib::NoWeights2());
639       index=1;
640       for(n = 1; n <= udeg; n++) 
641         for(m = 1; m <= vdeg + 1; m++)
642         {
643           Coefficients->ChangeValue(index++) = OscCoeff(n,m).X();
644           Coefficients->ChangeValue(index++) = OscCoeff(n,m).Y();
645           Coefficients->ChangeValue(index++) = OscCoeff(n,m).Z();
646         }
647     }
648
649     if (IsAlongU()) MaxVDegree--;
650     if (IsAlongV()) MaxUDegree--;
651     UContinuity = - 1;
652     VContinuity = - 1;
653
654     Convert_GridPolynomialToPoles Data(1,1,
655       UContinuity,
656       VContinuity,
657       MaxUDegree,
658       MaxVDegree,
659       NumCoeffPerSurface,
660       Coefficients,
661       PolynomialUIntervals,
662       PolynomialVIntervals,
663       TrueUIntervals,
664       TrueVIntervals);
665
666     //      Handle(Geom_BSplineSurface) BSpl = 
667     BSpl =new Geom_BSplineSurface(Data.Poles()->Array2(),
668       Data.UKnots()->Array1(),
669       Data.VKnots()->Array1(),
670       Data.UMultiplicities()->Array1(),
671       Data.VMultiplicities()->Array1(),
672       Data.UDegree(),
673       Data.VDegree(),
674       0, 0);
675 #ifdef OCCT_DEBUG
676     cout<<"^====================================^"<<endl<<endl;
677 #endif
678
679     //      L=BSpl;
680   }
681   return OsculSurf;
682 }
683
684 //=======================================================================
685 //function : IsQPunctual
686 //purpose  : 
687 //=======================================================================
688
689 Standard_Boolean Geom_OsculatingSurface::IsQPunctual
690   (const Handle(Geom_Surface)& S,
691   const Standard_Real         Param,
692   const GeomAbs_IsoType       IT,
693   const Standard_Real         TolMin,
694   const Standard_Real         TolMax) const
695 {
696   Standard_Real U1=0,U2=0,V1=0,V2=0,T;
697   Standard_Boolean Along = Standard_True;
698   S->Bounds(U1,U2,V1,V2);
699   gp_Vec D1U,D1V;
700   gp_Pnt P;
701   Standard_Real Step,D1NormMax;
702   if (IT == GeomAbs_IsoV) 
703   {
704     Step = (U2 - U1)/10;
705     D1NormMax=0.;
706     for (T=U1;T<=U2;T=T+Step) 
707     {
708       S->D1(T,Param,P,D1U,D1V);
709       D1NormMax=Max(D1NormMax,D1U.Magnitude());
710     }
711
712 #ifdef OCCT_DEBUG
713     cout << " D1NormMax = " << D1NormMax << endl;
714 #endif
715     if (D1NormMax >TolMax || D1NormMax < TolMin ) 
716       Along = Standard_False;
717   }
718   else 
719   {
720     Step = (V2 - V1)/10;
721     D1NormMax=0.;
722     for (T=V1;T<=V2;T=T+Step) 
723     {
724       S->D1(Param,T,P,D1U,D1V);
725       D1NormMax=Max(D1NormMax,D1V.Magnitude());
726     }
727 #ifdef OCCT_DEBUG
728     cout << " D1NormMax = " << D1NormMax << endl;
729 #endif
730     if (D1NormMax >TolMax || D1NormMax < TolMin ) 
731       Along = Standard_False;
732
733
734   }
735   return Along;
736 }
737
738 //=======================================================================
739 //function : HasOscSurf
740 //purpose  : 
741 //=======================================================================
742
743 Standard_Boolean Geom_OsculatingSurface::HasOscSurf() const
744 {
745   return (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4));
746 }
747
748 //=======================================================================
749 //function : IsAlongU
750 //purpose  : 
751 //=======================================================================
752
753 Standard_Boolean Geom_OsculatingSurface::IsAlongU() const
754 {
755   return (myAlong(1) || myAlong(2));
756 }
757 //=======================================================================
758 //function : IsAlongV
759 //purpose  : 
760 //=======================================================================
761
762 Standard_Boolean Geom_OsculatingSurface::IsAlongV() const
763 {
764   return (myAlong(3) || myAlong(4));
765 }
766
767
768 //=======================================================================
769 //function : IsGetSeqOfL1
770 //purpose  : 
771 //=======================================================================
772
773 const Geom_SequenceOfBSplineSurface& Geom_OsculatingSurface::GetSeqOfL1() const
774 {
775   return myOsculSurf1->Sequence();
776 }
777 //=======================================================================
778 //function : IsGetSeqOfL2
779 //purpose  : 
780 //=======================================================================
781
782 const Geom_SequenceOfBSplineSurface& Geom_OsculatingSurface::GetSeqOfL2() const
783 {
784   return myOsculSurf2->Sequence();
785 }
786 //=======================================================================
787 //function : ClearOsculFlags
788 //purpose  : 
789 //=======================================================================
790
791 void Geom_OsculatingSurface::ClearOsculFlags()
792 {
793   myAlong.SetValue(1,Standard_False);
794   myAlong.SetValue(2,Standard_False);
795   myAlong.SetValue(3,Standard_False);
796   myAlong.SetValue(4,Standard_False);
797
798 }
799
800
801