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