0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[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 : myTol(0.0),
41   myAlong(1,4)    
42 {
43   myAlong.Init(Standard_False);
44 }
45 //=======================================================================
46 //function : Geom_OffsetOsculatingSurface
47 //purpose  : 
48 //=======================================================================
49
50 Geom_OsculatingSurface::Geom_OsculatingSurface(const Handle(Geom_Surface)& BS, 
51   const Standard_Real Tol)
52   : myAlong(1,4)
53 {
54   Init(BS,Tol);
55 }
56
57 //=======================================================================
58 //function : Init
59 //purpose  : 
60 //=======================================================================
61
62 void Geom_OsculatingSurface::Init(const Handle(Geom_Surface)& BS,
63   const Standard_Real Tol)
64 {
65   ClearOsculFlags();
66   myTol=Tol; 
67   Standard_Real TolMin=0.;//consider all singularities below Tol, not just above 1.e-12 (id23943)
68   Standard_Boolean OsculSurf = Standard_True;
69   myBasisSurf = Handle(Geom_Surface)::DownCast(BS->Copy());
70   myOsculSurf1 = new Geom_HSequenceOfBSplineSurface();
71   myOsculSurf2 = new Geom_HSequenceOfBSplineSurface();
72   if ((BS->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) || 
73     (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface)))) 
74   {
75     Standard_Real U1=0,U2=0,V1=0,V2=0;
76
77     Standard_Integer i = 1;
78     BS->Bounds(U1,U2,V1,V2);
79     myAlong.SetValue(1,IsQPunctual(BS,V1,GeomAbs_IsoV,TolMin,Tol));
80     myAlong.SetValue(2,IsQPunctual(BS,V2,GeomAbs_IsoV,TolMin,Tol));
81     myAlong.SetValue(3,IsQPunctual(BS,U1,GeomAbs_IsoU,TolMin,Tol));
82     myAlong.SetValue(4,IsQPunctual(BS,U2,GeomAbs_IsoU,TolMin,Tol));
83 #ifdef OCCT_DEBUG
84     std::cout<<myAlong(1)<<std::endl<<myAlong(2)<<std::endl<<myAlong(3)<<std::endl<<myAlong(4)<<std::endl;
85 #endif
86     if (myAlong(1) || myAlong(2) || myAlong(3) || myAlong(4)) 
87     {
88       Handle(Geom_BSplineSurface) InitSurf, L,S;
89       if (BS->IsKind(STANDARD_TYPE(Geom_BezierSurface))) 
90       {
91         Handle(Geom_BezierSurface) BzS = Handle(Geom_BezierSurface)::DownCast(BS);
92         TColgp_Array2OfPnt P(1,BzS->NbUPoles(),1,BzS->NbVPoles());
93         TColStd_Array1OfReal UKnots(1,2);
94         TColStd_Array1OfReal VKnots(1,2);
95         TColStd_Array1OfInteger UMults(1,2);
96         TColStd_Array1OfInteger VMults(1,2);
97         for (i=1;i<=2;i++)
98         {
99           UKnots.SetValue(i,(i-1));
100           VKnots.SetValue(i,(i-1));
101           UMults.SetValue(i,BzS->UDegree()+1);
102           VMults.SetValue(i,BzS->VDegree()+1);
103         }
104         BzS->Poles(P);
105         InitSurf = new Geom_BSplineSurface(P,UKnots,VKnots,
106           UMults,VMults,
107           BzS->UDegree(),
108           BzS->VDegree(),
109           BzS->IsUPeriodic(),
110           BzS->IsVPeriodic());
111       }
112       else 
113       {
114         InitSurf = Handle(Geom_BSplineSurface)::DownCast(myBasisSurf);
115       }
116 #ifdef OCCT_DEBUG
117       std::cout<<"UDEG: "<<InitSurf->UDegree()<<std::endl;
118       std::cout<<"VDEG: "<<InitSurf->VDegree()<<std::endl;
119 #endif
120
121       if(IsAlongU() && IsAlongV()) ClearOsculFlags();
122       //      Standard_ConstructionError_Raise_if((IsAlongU() && IsAlongV()),"Geom_OsculatingSurface");
123       if ((IsAlongU() && InitSurf->VDegree()>1) ||
124         (IsAlongV() && InitSurf->UDegree()>1)) 
125       {
126         myKdeg = new TColStd_HSequenceOfInteger();
127         Standard_Integer k=0;
128         Standard_Boolean IsQPunc;
129         Standard_Integer UKnot,VKnot;
130         if (myAlong(1) || myAlong(2)) 
131         {
132           for (i=1;i<InitSurf->NbUKnots();i++) 
133           {
134             if (myAlong(1)) 
135             {
136               S = InitSurf; k=0; IsQPunc=Standard_True;
137               UKnot=i;
138               VKnot=1;
139               while(IsQPunc) 
140               {
141                 OsculSurf  = BuildOsculatingSurface(V1,UKnot,VKnot,S,L);
142                 if(!OsculSurf) break;
143                 k++;
144 #ifdef OCCT_DEBUG
145                 std::cout<<"1.k = "<<k<<std::endl;
146 #endif
147                 IsQPunc=IsQPunctual(L,V1,GeomAbs_IsoV,0.,Tol);
148                 UKnot=1;
149                 VKnot=1;
150                 S=L;
151
152               }
153               if (OsculSurf)
154                 myOsculSurf1->Append(L);
155               else
156                 ClearOsculFlags(); //myAlong.SetValue(1,Standard_False);
157               if (myAlong(2) && OsculSurf) 
158               {
159                 S = InitSurf; k=0; IsQPunc=Standard_True;
160                 UKnot=i;
161                 VKnot=InitSurf->NbVKnots()-1;
162
163                 while(IsQPunc) 
164                 {
165                   OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L);
166                   if(!OsculSurf) break;
167                   k++;
168 #ifdef OCCT_DEBUG
169                   std::cout<<"2.k = "<<k<<std::endl;
170 #endif
171                   IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol);
172                   UKnot=1;
173                   VKnot=1;
174                   S=L;
175                 }
176                 if(OsculSurf)
177                 {
178                   myOsculSurf2->Append(L);
179                   myKdeg->Append(k);
180                 }
181               } 
182             }
183             else 
184               //if (myAlong(2)) 
185             {
186               S = InitSurf; k=0; IsQPunc=Standard_True;
187               UKnot=i;
188               VKnot=InitSurf->NbVKnots()-1;
189               while(IsQPunc) 
190               {
191                 OsculSurf = BuildOsculatingSurface(V2,UKnot,VKnot,S,L);
192                 if(!OsculSurf) break;
193                 k++;
194 #ifdef OCCT_DEBUG
195                 std::cout<<"2.k = "<<k<<std::endl;
196 #endif
197                 IsQPunc=IsQPunctual(L,V2,GeomAbs_IsoV,0.,Tol);
198                 UKnot=1;
199                 VKnot=1;
200                 S=L;
201
202               }
203               if(OsculSurf)
204               {
205                 myOsculSurf2->Append(L);
206                 myKdeg->Append(k);
207               }
208               else
209                 ClearOsculFlags(); //myAlong.SetValue(2,Standard_False);
210             }
211           }
212         }
213         if (myAlong(3) || myAlong(4)) 
214         {
215           for (i=1;i<InitSurf->NbVKnots();i++) 
216           {
217             if (myAlong(3)) 
218             {
219               S = InitSurf; k=0; IsQPunc=Standard_True;
220               UKnot=1;
221               VKnot=i;
222               while(IsQPunc) 
223               {
224                 OsculSurf = BuildOsculatingSurface(U1,UKnot,VKnot,S,L);
225                 if(!OsculSurf) break;
226                 k++;
227 #ifdef OCCT_DEBUG
228                 std::cout<<"1.k = "<<k<<std::endl;
229 #endif
230                 IsQPunc=IsQPunctual(L,U1,GeomAbs_IsoU,0.,Tol);
231                 UKnot=1;
232                 VKnot=1;
233                 S=L;
234               }
235               if(OsculSurf)
236                 myOsculSurf1->Append(L);
237               else
238                 ClearOsculFlags(); //myAlong.SetValue(3,Standard_False);
239               if (myAlong(4) && OsculSurf )
240               {
241                 S = InitSurf; k=0; IsQPunc=Standard_True;
242                 UKnot=InitSurf->NbUKnots()-1;
243                 VKnot=i;
244                 while(IsQPunc) 
245                 {
246                   OsculSurf  = BuildOsculatingSurface(U2,UKnot,VKnot,S,L);
247                   if(!OsculSurf) break;
248                   k++;
249 #ifdef OCCT_DEBUG
250                   std::cout<<"2.k = "<<k<<std::endl;
251 #endif
252                   IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol);
253                   UKnot=1;
254                   VKnot=1;
255                   S=L;
256                 }
257                 if(OsculSurf)
258                 {
259                   myOsculSurf2->Append(L);
260                   myKdeg->Append(k);
261                 }
262               }
263             }
264             else 
265             {
266               S = InitSurf; k=0; IsQPunc=Standard_True;
267               UKnot=InitSurf->NbUKnots()-1;
268               VKnot=i;
269               while(IsQPunc) 
270               {
271                 OsculSurf  = BuildOsculatingSurface(U2,UKnot,VKnot,S,L);
272                 if(!OsculSurf) break;
273                 k++;
274 #ifdef OCCT_DEBUG
275                 std::cout<<"2.k = "<<k<<std::endl;
276 #endif
277                 IsQPunc=IsQPunctual(L,U2,GeomAbs_IsoU,0.,Tol);
278                 UKnot=1;
279                 VKnot=1;
280                 S=L;
281               }
282               if(OsculSurf)
283               {
284                 myOsculSurf2->Append(L);
285                 myKdeg->Append(k);
286               }
287               else
288                 ClearOsculFlags(); //myAlong.SetValue(4,Standard_False);
289             }
290           }
291         }
292       }
293       else
294       {
295         ClearOsculFlags();
296       } 
297     }
298   }
299   else
300     ClearOsculFlags();
301 }
302
303 //=======================================================================
304 //function : BasisSurface
305 //purpose  : 
306 //=======================================================================
307
308 Handle(Geom_Surface) Geom_OsculatingSurface::BasisSurface() const
309 {
310   return myBasisSurf;
311 }
312
313 //=======================================================================
314 //function : Tolerance
315 //purpose  : 
316 //=======================================================================
317
318 Standard_Real Geom_OsculatingSurface::Tolerance() const
319 {
320   return myTol;
321 }
322
323 //=======================================================================
324 //function : UOscSurf
325 //purpose  : 
326 //=======================================================================
327
328 Standard_Boolean Geom_OsculatingSurface::UOscSurf
329   (const Standard_Real U,
330   const Standard_Real V,
331   Standard_Boolean& t,
332   Handle(Geom_BSplineSurface)& L) const
333 {
334   Standard_Boolean along = Standard_False;
335   if (myAlong(1) || myAlong(2)) 
336   {
337     Standard_Integer NU = 1, NV = 1;
338     Standard_Real u1,u2,v1,v2;
339     t = Standard_False;
340     myBasisSurf->Bounds(u1,u2,v1,v2);
341     Standard_Integer NbUK,NbVK;
342     Standard_Boolean isToSkipSecond = Standard_False;
343     if (myBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) 
344     {
345       Handle(Geom_BSplineSurface) BSur = 
346         Handle(Geom_BSplineSurface)::DownCast (myBasisSurf);
347       NbUK = BSur->NbUKnots();
348       NbVK = BSur->NbVKnots();
349       TColStd_Array1OfReal UKnots(1,NbUK);
350       TColStd_Array1OfReal VKnots(1,NbVK);
351       BSur->UKnots(UKnots);
352       BSur->VKnots(VKnots);
353       BSplCLib::Hunt(UKnots,U,NU);
354       BSplCLib::Hunt(VKnots,V,NV);
355       if (NU < 1) NU=1;
356       if (NU >= NbUK) NU=NbUK-1;
357       if (NbVK==2 && NV==1)
358         // Need to find the closest end
359         if (VKnots(NbVK)-V > V-VKnots(1))
360           isToSkipSecond = Standard_True;
361     }
362     else {NU = 1; NV = 1 ; NbVK = 2 ;}
363
364     if (myAlong(1) && NV == 1) 
365     {
366       L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf1->Value(NU));
367       along = Standard_True;
368     }
369     if (myAlong(2) && (NV == NbVK-1) && !isToSkipSecond)
370     {
371       // t means that derivative vector of osculating surface is opposite
372       // to the original. This happens when (v-t)^k is negative, i.e.
373       // difference between degrees (k) is odd and t is the last parameter
374       if (myKdeg->Value(NU)%2) t = Standard_True;
375       L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf2->Value(NU));
376       along = Standard_True;
377     }
378   }
379   return along;
380 }
381
382 //=======================================================================
383 //function : VOscSurf
384 //purpose  : 
385 //=======================================================================
386
387 Standard_Boolean Geom_OsculatingSurface::VOscSurf
388   (const Standard_Real U,
389   const Standard_Real V,
390   Standard_Boolean& t,
391   Handle(Geom_BSplineSurface)& L) const
392 {
393   Standard_Boolean along = Standard_False;
394   if (myAlong(3) || myAlong(4)) 
395   {
396     Standard_Integer NU = 1, NV = 1;
397     Standard_Real u1,u2,v1,v2;
398     t = Standard_False;
399     myBasisSurf->Bounds(u1,u2,v1,v2);
400     Standard_Integer NbUK,NbVK;
401     Standard_Boolean isToSkipSecond = Standard_False;
402     if (myBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) 
403     {
404       Handle(Geom_BSplineSurface) BSur = 
405         Handle(Geom_BSplineSurface)::DownCast (myBasisSurf);
406       NbUK = BSur->NbUKnots();
407       NbVK = BSur->NbVKnots();
408       TColStd_Array1OfReal UKnots(1,NbUK);
409       TColStd_Array1OfReal VKnots(1,NbVK);
410       BSur->UKnots(UKnots);
411       BSur->VKnots(VKnots);
412       BSplCLib::Hunt(UKnots,U,NU);
413       BSplCLib::Hunt(VKnots,V,NV);
414       if (NV < 1) NV=1;
415       if (NV >= NbVK) NV=NbVK-1;
416       if (NbUK==2 && NU==1)
417         // Need to find the closest end
418         if (UKnots(NbUK)-U > U-UKnots(1))
419           isToSkipSecond = Standard_True;
420     }
421     else {NU = 1; NV = 1 ; NbUK = 2;}
422
423     if (myAlong(3) && NU == 1)  
424     {
425       L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf1->Value(NV));
426       along = Standard_True;
427     }
428     if (myAlong(4) && (NU == NbUK-1) && !isToSkipSecond)
429     {
430       if (myKdeg->Value(NV)%2) t = Standard_True;
431       L = *((Handle(Geom_BSplineSurface)*)& myOsculSurf2->Value(NV));
432       along = Standard_True;
433     }
434   }
435   return along;
436 }
437
438 //=======================================================================
439 //function : BuildOsculatingSurface
440 //purpose  : 
441 //=======================================================================
442
443 Standard_Boolean  Geom_OsculatingSurface::BuildOsculatingSurface
444   (const Standard_Real Param,
445   const Standard_Integer SUKnot,
446   const Standard_Integer SVKnot,
447   const Handle(Geom_BSplineSurface)& BS,
448   Handle(Geom_BSplineSurface)& BSpl) const
449 {
450   Standard_Boolean OsculSurf=Standard_True;
451 #ifdef OCCT_DEBUG
452   std::cout<<"t = "<<Param<<std::endl;
453   std::cout<<"======================================"<<std::endl<<std::endl;
454 #endif
455
456   // for cache
457   Standard_Integer MinDegree,
458     MaxDegree ;
459   Standard_Real udeg, vdeg;
460   udeg = BS->UDegree();
461   vdeg = BS->VDegree();
462   if( (IsAlongU() && vdeg <=1) || (IsAlongV() && udeg <=1))
463   {
464 #ifdef OCCT_DEBUG
465     std::cout<<" surface osculatrice nulle "<<std::endl;
466 #endif
467     //throw Standard_ConstructionError("Geom_OsculatingSurface");
468     OsculSurf=Standard_False;
469   }
470   else
471   {
472     MinDegree = (Standard_Integer ) Min(udeg,vdeg) ;
473     MaxDegree = (Standard_Integer ) Max(udeg,vdeg) ;
474
475     TColgp_Array2OfPnt cachepoles(1, MaxDegree + 1, 1, MinDegree + 1);
476     // end for cache
477
478     // for polynomial grid 
479     Standard_Integer MaxUDegree, MaxVDegree;
480     Standard_Integer UContinuity, VContinuity;
481
482     Handle(TColStd_HArray2OfInteger) NumCoeffPerSurface = 
483       new TColStd_HArray2OfInteger(1, 1, 1, 2);
484     Handle(TColStd_HArray1OfReal) PolynomialUIntervals = 
485       new TColStd_HArray1OfReal(1, 2);
486     Handle(TColStd_HArray1OfReal) PolynomialVIntervals = 
487       new TColStd_HArray1OfReal(1, 2);
488     Handle(TColStd_HArray1OfReal) TrueUIntervals = 
489       new TColStd_HArray1OfReal(1, 2);
490     Handle(TColStd_HArray1OfReal) TrueVIntervals = 
491       new TColStd_HArray1OfReal(1, 2);
492     MaxUDegree = (Standard_Integer ) udeg;
493     MaxVDegree = (Standard_Integer ) vdeg;
494
495     for (Standard_Integer i = 1; i <= 2; i++) 
496     {
497       PolynomialUIntervals->ChangeValue(i) = i-1;
498       PolynomialVIntervals->ChangeValue(i) = i-1;
499       TrueUIntervals->ChangeValue(i) = BS->UKnot(SUKnot+i-1);
500       TrueVIntervals->ChangeValue(i) = BS->VKnot(SVKnot+i-1);
501     }
502
503
504     Standard_Integer OscUNumCoeff=0, OscVNumCoeff=0;
505     if (IsAlongU()) 
506     {
507 #ifdef OCCT_DEBUG
508       std::cout<<">>>>>>>>>>> AlongU"<<std::endl;
509 #endif
510       OscUNumCoeff = (Standard_Integer ) udeg + 1;  
511       OscVNumCoeff = (Standard_Integer ) vdeg;  
512     }
513     if (IsAlongV()) 
514     {
515 #ifdef OCCT_DEBUG
516       std::cout<<">>>>>>>>>>> AlongV"<<std::endl;
517 #endif
518       OscUNumCoeff = (Standard_Integer ) udeg;  
519       OscVNumCoeff = (Standard_Integer ) vdeg + 1;  
520     }
521     NumCoeffPerSurface->ChangeValue(1,1) = OscUNumCoeff;  
522     NumCoeffPerSurface->ChangeValue(1,2) = OscVNumCoeff;  
523     Standard_Integer nbc = NumCoeffPerSurface->Value(1,1)*NumCoeffPerSurface->Value(1,2)*3;
524     //
525     if(nbc == 0)
526     {
527       return Standard_False;
528     }
529     //
530     Handle(TColStd_HArray1OfReal) Coefficients = new TColStd_HArray1OfReal(1, nbc);
531     //    end for polynomial grid
532
533     //    building the cache
534     Standard_Integer ULocalIndex, VLocalIndex;
535     Standard_Real ucacheparameter, vcacheparameter,uspanlength, vspanlength;
536     TColgp_Array2OfPnt NewPoles(1, BS->NbUPoles(), 1, BS->NbVPoles());
537
538     Standard_Integer aUfKnotsLength = BS->NbUPoles() + BS->UDegree() + 1;
539     Standard_Integer aVfKnotsLength = BS->NbVPoles() + BS->VDegree() + 1;
540
541     if(BS->IsUPeriodic())
542     {
543       TColStd_Array1OfInteger aMults(1, BS->NbUKnots());
544       BS->UMultiplicities(aMults);
545       aUfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->UDegree(), Standard_True);
546     }
547
548     if(BS->IsVPeriodic())
549     {
550       TColStd_Array1OfInteger aMults(1, BS->NbVKnots());
551       BS->VMultiplicities(aMults);
552       aVfKnotsLength = BSplCLib::KnotSequenceLength(aMults, BS->VDegree(), Standard_True);
553     }
554
555     TColStd_Array1OfReal UFlatKnots(1, aUfKnotsLength);
556     TColStd_Array1OfReal VFlatKnots(1, aVfKnotsLength);
557     BS->Poles(NewPoles);
558     BS->UKnotSequence(UFlatKnots);
559     BS->VKnotSequence(VFlatKnots);
560
561     VLocalIndex = 0;
562     ULocalIndex = 0;
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     std::cout<<"^====================================^"<<std::endl<<std::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     std::cout << " D1NormMax = " << D1NormMax << std::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     std::cout << " D1NormMax = " << D1NormMax << std::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 //function : DumpJson
802 //purpose  : 
803 //=======================================================================
804 void Geom_OsculatingSurface::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
805 {
806   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
807
808   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myBasisSurf.get())
809   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTol)
810
811   if (!myOsculSurf1.IsNull())
812     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOsculSurf1->Size())
813   if (!myOsculSurf2.IsNull())
814     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOsculSurf2->Size())
815   if (!myKdeg.IsNull())
816     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myKdeg->Size())
817
818   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAlong.Size())
819 }