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