Integration of OCCT 6.5.0 from SVN
[occt.git] / src / GeomFill / GeomFill_CircularBlendFunc.cxx
1 // File:        GeomFill_CircularBlendFunc.cxx
2 // Created:     Fri Jul 11 15:54:00 1997
3 // Author:      Philippe MANGIN
4 //              <pmn@sgi29>
5
6
7 #include <GeomFill_CircularBlendFunc.ixx>
8 #include <GeomFill.hxx>
9
10 #include <GCPnts_QuasiUniformDeflection.hxx>
11 #include <Precision.hxx>
12 #include <Adaptor3d_HCurve.hxx>
13
14 #include <TColStd_SequenceOfReal.hxx>
15 #include <TColStd_Array1OfReal.hxx>
16
17 #if DRAW
18 #include <GeomAdaptor_HCurve.hxx>
19 #include <Geom_BSplineCurve.hxx>
20 #include <DrawTrSurf.hxx>
21 static Standard_Integer NbSections = 0;
22 #endif
23
24 GeomAbs_Shape GeomFillNextShape(const GeomAbs_Shape S)
25 {
26   switch (S) {
27   case GeomAbs_C0 :
28     return  GeomAbs_C1;
29   case GeomAbs_C1 :
30     return  GeomAbs_C2;
31   case GeomAbs_C2 :
32     return  GeomAbs_C3;
33   case GeomAbs_C3 :
34     return  GeomAbs_CN;
35   default :
36     return  GeomAbs_CN;
37   }
38 }
39
40 void GeomFillFusInt(const TColStd_Array1OfReal& I1,
41                     const TColStd_Array1OfReal& I2,
42                     TColStd_SequenceOfReal& Seq)
43 {
44   Standard_Integer ind1=1, ind2=1;
45   Standard_Real    Epspar = Precision::PConfusion()*0.99;
46   // en suposant que le positionement fonctionne a PConfusion()/2
47   Standard_Real    v1, v2;
48 // Initialisations : les IND1 et IND2 pointent sur le 1er element
49 // de chacune des 2 tables a traiter.
50
51
52 //--- On remplit TABSOR en parcourant TABLE1 et TABLE2 simultanement ---
53 //------------------ en eliminant les occurrences multiples ------------
54
55  while ((ind1<=I1.Upper()) && (ind2<=I2.Upper())) {
56       v1 = I1(ind1);
57       v2 = I2(ind2);
58       if (Abs(v1-v2)<= Epspar) {
59 // Ici les elements de I1 et I2 conviennent .
60          Seq.Append((v1+v2)/2);
61          ind1++;
62          ind2++;
63        }
64       else if (v1 < v2) {
65         // Ici l' element de I1 convient.
66          Seq.Append(v1);
67          ind1++;
68        }
69       else {
70 // Ici l' element de TABLE2 convient.
71          Seq.Append(v2);
72          ind2++;
73        }
74     }
75
76   if (ind1>I1.Upper()) { 
77 //----- Ici I1 est epuise, on complete avec la fin de TABLE2 -------
78
79     for (; ind2<=I2.Upper(); ind2++) {
80       Seq.Append(I2(ind2));
81     }
82   }
83
84   if (ind2>I2.Upper()) { 
85 //----- Ici I2 est epuise, on complete avec la fin de I1 -------
86
87     for (; ind1<=I1.Upper(); ind1++) {
88       Seq.Append(I1(ind1));
89     }
90   }
91 }
92
93
94 GeomFill_CircularBlendFunc::
95 GeomFill_CircularBlendFunc(const Handle(Adaptor3d_HCurve)& Path,
96                            const Handle(Adaptor3d_HCurve)& Curve1,
97                            const Handle(Adaptor3d_HCurve)& Curve2,
98                            const Standard_Real Radius,
99                            const Standard_Boolean Polynomial) 
100                            : maxang(RealFirst()), 
101                              minang(RealLast()),
102                              distmin(RealLast())
103 {
104   // Recopie des arguments
105   myPath = myTPath = Path;
106   myCurve1 = myTCurve1 = Curve1;
107   myCurve2 = myTCurve2 = Curve2;
108   myRadius =  Radius;
109
110   // Estimations numeriques
111   Discret();
112
113   // Type de convertion ?
114   if (Polynomial) myTConv=Convert_Polynomial;
115   else if(maxang > 0.65*PI) 
116     myTConv=Convert_QuasiAngular; //car c'est Continue
117   else   myTConv = Convert_TgtThetaOver2; 
118                   //car c'est le plus performant 
119
120   // On en deduit la structure 
121   GeomFill::GetShape(maxang, 
122                      myNbPoles, myNbKnots, 
123                      myDegree, myTConv); 
124 }
125
126 void GeomFill_CircularBlendFunc::Discret()
127 {
128   Standard_Real TFirst =  myPath->FirstParameter();
129   Standard_Real TLast =  myPath->LastParameter(), T;
130   Standard_Integer ii;
131   Standard_Real L1, L2, L;
132   Handle(Adaptor3d_HCurve) C;
133   gp_Pnt P1, P2, P3, Center;
134   gp_Vec DCenter;
135  
136   P1 = myCurve1->Value(TFirst);
137   P2 = myCurve1->Value((TFirst+TLast)/2.);
138   P3 = myCurve1->Value(TLast);
139   L1 = P1.Distance(P2) + P2.Distance(P3);
140
141   P1 = myCurve2->Value(TFirst);
142   P2 = myCurve2->Value((TFirst+TLast)/2.);
143   P3 = myCurve2->Value(TLast);
144   L2 = P1.Distance(P2) + P2.Distance(P3);
145
146   if (L1>L2) { 
147     L = L1;
148     C = myCurve1;
149   }
150   else {
151    L = L2;
152    C = myCurve2;    
153   }
154
155   Standard_Real Fleche = 1.e-2 * L;
156   Standard_Real Angle, Cosa, Percent;
157   GCPnts_QuasiUniformDeflection Samp;
158   Samp.Initialize(C->GetCurve(), Fleche);
159   myBary.SetCoord(0.,0.,0.);
160   gp_Vec ns1, ns2;
161
162   if (Samp.IsDone()) {
163     Percent = ((Standard_Real)1)/(2*Samp.NbPoints());
164 //    char name[100];
165     for (ii=1; ii<=Samp.NbPoints(); ii++) {
166       T = Samp.Parameter(ii); 
167       myCurve1->D0(T, P1);
168       myCurve2->D0(T, P2);
169 /*
170       sprintf(name,"PNT_%d",NbSections++);
171       DrawTrSurf::Set(name, P1);
172       sprintf(name,"PNT_%d",NbSections++);
173       DrawTrSurf::Set(name, P2);*/
174       myPath->D0(T, Center);      
175       ns1.SetXYZ( Center.XYZ() - P1.XYZ());
176       ns2.SetXYZ( Center.XYZ() - P2.XYZ());
177       ns1.Normalize();
178       ns2.Normalize();
179       Cosa = ns1.Dot(ns2);
180       if(Cosa > 1.) {Cosa = 1.;}
181       Angle = Abs(ACos(Cosa));
182       if (Angle>maxang) maxang = Angle;
183       if (Angle<minang) minang = Angle;
184       distmin = Min( distmin, P1.Distance(P2));
185       myBary.ChangeCoord() += (P1.XYZ()+P2.XYZ());
186     }
187   }
188   else {  
189     Standard_Real Delta = (TLast-TFirst)/20;
190     Percent = ((Standard_Real)1)/42;
191     for (ii=0, T=TFirst; ii<=20; ii++, T+=Delta) {
192       myCurve1->D0(T, P1);
193       myCurve2->D0(T, P2); 
194       myPath->D0(T, Center); 
195      
196       ns1.SetXYZ( Center.XYZ() - P1.XYZ());
197       ns2.SetXYZ( Center.XYZ() - P2.XYZ());
198       ns1.Normalize();
199       ns2.Normalize();
200       Cosa = ns1.Dot(ns2);
201       if(Cosa > 1.) Cosa = 1.;
202       Angle = Abs(ACos(Cosa));
203
204       if (Angle>maxang) maxang = Angle;
205       if (Angle<minang) minang = Angle;
206       distmin = Min( distmin, P1.Distance(P2));
207       myBary.ChangeCoord() += (P1.XYZ()+P2.XYZ());
208     }
209   } 
210   myBary.ChangeCoord() *= Percent;
211
212   // Faut il inverser la trajectoire ?
213   T = (TFirst + TLast)/2;
214   myCurve1->D0(T, P1);
215   myCurve2->D0(T, P2);
216   myPath->D1(T, Center, DCenter);
217  
218   ns1.SetXYZ( Center.XYZ() - P1.XYZ());
219   ns2.SetXYZ( Center.XYZ() - P2.XYZ());     
220
221   myreverse = (DCenter.Dot(ns1.Crossed(ns2)) < 0);    
222 }
223
224
225
226 Standard_Boolean GeomFill_CircularBlendFunc::D0(const Standard_Real Param,
227                                                 const Standard_Real,
228                                                 const Standard_Real,
229                                                 TColgp_Array1OfPnt& Poles,
230                                                 TColgp_Array1OfPnt2d&,
231                                                 TColStd_Array1OfReal& Weigths) 
232 {
233   gp_Pnt P1, P2, Center;
234   gp_Vec ns1, ns2, nplan;
235   gp_XYZ temp;
236
237 // Positionnement
238   myTPath->D0(Param, Center);
239   myTCurve1->D0(Param, P1);
240   myTCurve2->D0(Param, P2);
241   ns1.SetXYZ( Center.XYZ() - P1.XYZ());
242   ns2.SetXYZ( Center.XYZ() - P2.XYZ());
243   if (!ns1.IsParallel(ns2,1.e-9))  nplan = ns1.Crossed(ns2);
244   else {
245     myTPath->D1(Param, Center, nplan);
246     if (myreverse) nplan.Reverse();
247   }
248
249 // Normalisation
250   ns1.Normalize();
251   ns2.Normalize();
252   nplan.Normalize(); 
253
254   temp.SetLinearForm(myRadius, ns1.XYZ(),
255                      myRadius, ns2.XYZ(),
256                      1, P1.XYZ(),
257                      P2.XYZ());
258   Center.ChangeCoord() = 0.5*temp;
259     
260   // Section
261   GeomFill::GetCircle(myTConv, 
262                       ns1, ns2, nplan,
263                       P1, P2, 
264                       myRadius, Center,
265                       Poles,  Weigths);  
266
267 #if DRAW
268 //  Handle(Geom_BSplineCurve) BS = 
269 //    new Geom_BSplineCurve(Poles,Weights,Knots,Mults,Degree);
270 //  sprintf(name,"SECT_%d",NbSections++);
271 //  DrawTrSurf::Set(name,BS);
272 #endif
273   return Standard_True;
274 }
275
276
277 Standard_Boolean GeomFill_CircularBlendFunc::D1(const Standard_Real Param,
278 //                                              const Standard_Real First,
279                                                 const Standard_Real ,
280 //                                              const Standard_Real Last,
281                                                 const Standard_Real ,
282                                                 TColgp_Array1OfPnt& Poles,
283                                                 TColgp_Array1OfVec& DPoles,
284 //                                              TColgp_Array1OfPnt2d& Poles2d,
285                                                 TColgp_Array1OfPnt2d& ,
286 //                                              TColgp_Array1OfVec2d& DPoles2d,
287                                                 TColgp_Array1OfVec2d& ,
288                                                 TColStd_Array1OfReal& Weigths,
289                                                 TColStd_Array1OfReal& DWeigths) 
290 {
291   gp_Pnt P1, P2, Center;
292   Standard_Real invnorm1, invnorm2, invnormp;
293 //  gp_Vec DCenter, D2Center, nplan, dnplan, DP1, DP2;
294   gp_Vec DCenter, nplan, dnplan, DP1, DP2;
295 //  gp_Vec ns1, ns2, Dns1, Dns2, vtmp;
296   gp_Vec ns1, ns2, Dns1, Dns2;
297   gp_XYZ temp;
298
299 // Positionemment
300   myTPath  ->D1(Param, Center, DCenter);
301   myTCurve1->D1(Param, P1, DP1);
302   myTCurve2->D1(Param, P2, DP2);
303
304   ns1.SetXYZ( Center.XYZ() - P1.XYZ());
305   ns2.SetXYZ( Center.XYZ() - P2.XYZ());
306   Dns1 = DCenter - DP1;
307   Dns2 = DCenter - DP2;
308  
309   if (!ns1.IsParallel(ns2,1.e-9)) {
310     nplan = ns1.Crossed(ns2);
311     dnplan =  Dns1.Crossed(ns2).Added( ns1.Crossed(Dns2));
312   }
313   else {
314     myTPath->D2(Param, Center, nplan, dnplan);
315     if (myreverse) {
316       nplan.Reverse();
317       dnplan.Reverse();
318     }
319   }
320
321 // Normalisation
322   invnorm1 = ((Standard_Real) 1) / ns1.Magnitude();
323   invnorm2 = ((Standard_Real) 1) / ns2.Magnitude(); 
324
325   ns1 *= invnorm1;
326   Dns1.SetLinearForm( -Dns1.Dot(ns1), ns1, Dns1);
327   Dns1 *= invnorm1; 
328       
329   ns2 *= invnorm2;
330   Dns2.SetLinearForm(-Dns2.Dot(ns2), ns2, Dns2);
331   Dns2 *= invnorm2;
332
333   temp.SetLinearForm(myRadius, ns1.XYZ(),
334                      myRadius, ns2.XYZ(),
335                      1, P1.XYZ(), P2.XYZ());       
336   Center.ChangeCoord() = 0.5*temp;
337   DCenter.SetLinearForm(myRadius, Dns1,
338                         myRadius, Dns2,
339                         1, DP1, DP2);
340   DCenter *= 0.5;
341     
342   invnormp = ((Standard_Real)1) / nplan.Magnitude();
343   nplan *= invnormp;
344   dnplan.SetLinearForm(-dnplan.Dot(nplan), nplan, dnplan);
345   dnplan *= invnormp;
346  
347   GeomFill::GetCircle(myTConv, 
348                       ns1, ns2, 
349                       Dns1, Dns2,
350                       nplan, dnplan,
351                       P1, P2,
352                       DP1, DP2,
353                       myRadius, 0,
354                       Center, DCenter,
355                       Poles,  DPoles,
356                       Weigths, DWeigths);
357   return Standard_True;
358 }
359
360 Standard_Boolean GeomFill_CircularBlendFunc::D2(const Standard_Real Param,
361 //                                              const Standard_Real First,
362                                                 const Standard_Real ,
363 //                                              const Standard_Real Last,
364                                                 const Standard_Real ,
365                                                 TColgp_Array1OfPnt& Poles,
366                                                 TColgp_Array1OfVec& DPoles,
367                                                 TColgp_Array1OfVec& D2Poles,
368 //                                              TColgp_Array1OfPnt2d& Poles2d,
369                                                 TColgp_Array1OfPnt2d& ,
370 //                                              TColgp_Array1OfVec2d& DPoles2d,
371                                                 TColgp_Array1OfVec2d& ,
372 //                                              TColgp_Array1OfVec2d& D2Poles2d,
373                                                 TColgp_Array1OfVec2d& ,
374                                                 TColStd_Array1OfReal& Weigths,
375                                                 TColStd_Array1OfReal& DWeigths,
376                                                 TColStd_Array1OfReal& D2Weigths) 
377 {
378   gp_Pnt P1, P2, Center;
379   Standard_Real invnorm1, invnorm2, invnormp, sc;
380   gp_Vec DCenter, D2Center, DP1, DP2, D2P1, D2P2;
381   gp_Vec nplan, dnplan, d2nplan;
382   gp_Vec ns1, ns2, Dns1, Dns2, D2ns1, D2ns2;
383   gp_XYZ temp;
384
385   // Positionement
386   myTPath  ->D2(Param, Center, DCenter, D2Center);
387   myTCurve1->D2(Param, P1, DP1, D2P1);
388   myTCurve2->D2(Param, P2, DP2, D2P2);
389
390   ns1.SetXYZ( Center.XYZ() - P1.XYZ());
391   Dns1 = DCenter - DP1;
392   D2ns1 =  D2Center - D2P1;  
393   ns2.SetXYZ( Center.XYZ() - P2.XYZ());
394   Dns2 = DCenter - DP2;
395   D2ns2 =  D2Center - D2P2;
396
397   if (!ns1.IsParallel(ns2,1.e-9)) {
398     nplan = ns1.Crossed(ns2);
399     dnplan = Dns1.Crossed(ns2).Added( ns1.Crossed(Dns2));
400     d2nplan.SetLinearForm(1, D2ns1.Crossed(ns2),
401                           2, Dns1.Crossed(Dns2),
402                           ns1.Crossed(D2ns2));
403   }
404   else {
405     myTPath->D3(Param, Center, nplan, dnplan, d2nplan);
406     if (myreverse) {
407       nplan.Reverse();
408       dnplan.Reverse();
409       d2nplan.Reverse();
410     }
411   }
412
413   // Normalisation
414   invnorm1 = ((Standard_Real) 1) / ns1.Magnitude();
415   invnorm2 = ((Standard_Real) 1) / ns2.Magnitude(); 
416
417   ns1 *= invnorm1;
418   sc = Dns1.Dot(ns1);
419   D2ns1.SetLinearForm( 3*sc*sc*invnorm1 - D2ns1.Dot(ns1)
420                       - invnorm1*Dns1.SquareMagnitude(), ns1, 
421                       -2*sc*invnorm1 , Dns1,
422                       D2ns1);
423   Dns1.SetLinearForm( -Dns1.Dot(ns1), ns1, Dns1);
424   D2ns1 *= invnorm1;
425   Dns1 *= invnorm1;
426
427   
428      
429   ns2 *= invnorm2;
430   sc = Dns2.Dot(ns2);
431   D2ns2.SetLinearForm( 3*sc*sc*invnorm2 - D2ns2.Dot(ns2)
432                       - invnorm2*Dns2.SquareMagnitude(), ns2, 
433                       -2*sc*invnorm2 , Dns2,
434                       D2ns2);
435   Dns2.SetLinearForm(-sc, ns2, Dns2);
436   D2ns2 *= invnorm2;
437   Dns2 *= invnorm2;
438
439
440   temp.SetLinearForm(myRadius, ns1.XYZ(),
441                      myRadius, ns2.XYZ(),
442                      1, P1.XYZ(), P2.XYZ());       
443   Center.ChangeCoord() = 0.5*temp;
444   DCenter.SetLinearForm(myRadius, Dns1,
445                         myRadius, Dns2,
446                         1, DP1, DP2);
447   DCenter *= 0.5;
448   D2Center.SetLinearForm(myRadius, D2ns1,
449                          myRadius, D2ns2,
450                          1, D2P1, D2P2);
451   D2Center *= 0.5;
452  
453   invnormp = ((Standard_Real)1) / nplan.Magnitude();
454   nplan *= invnormp;   
455   sc = dnplan.Dot(nplan);
456   d2nplan.SetLinearForm( 3*sc*sc*invnormp - d2nplan.Dot(nplan)
457                       - invnormp*dnplan.SquareMagnitude(), nplan, 
458                       -2*sc*invnormp , dnplan,
459                       d2nplan); 
460   dnplan.SetLinearForm(-sc, nplan, dnplan);
461   dnplan *= invnormp;  
462   d2nplan *= invnormp;
463
464   GeomFill::GetCircle(myTConv, 
465                       ns1, ns2, 
466                       Dns1, Dns2,
467                       D2ns1, D2ns2,
468                       nplan, dnplan, d2nplan,
469                       P1, P2,
470                       DP1, DP2,
471                       D2P1, D2P2,
472                       myRadius, 0, 0,
473                       Center, DCenter, D2Center,
474                       Poles,  DPoles, D2Poles,
475                       Weigths, DWeigths, D2Weigths);
476   return Standard_True;
477 }
478
479  Standard_Integer GeomFill_CircularBlendFunc::Nb2dCurves() const
480 {
481   return 0;
482 }
483
484 void GeomFill_CircularBlendFunc::SectionShape(Standard_Integer& NbPoles,
485                                               Standard_Integer& NbKnots,
486                                               Standard_Integer& Degree) const
487 {
488   NbPoles = myNbPoles;
489   NbKnots = myNbKnots;
490   Degree  = myDegree; 
491 }
492
493  void GeomFill_CircularBlendFunc::Knots(TColStd_Array1OfReal& TKnots) const
494 {
495   GeomFill::Knots(myTConv, TKnots);
496 }
497
498 void GeomFill_CircularBlendFunc::Mults(TColStd_Array1OfInteger& TMults) const
499 {
500   GeomFill::Mults(myTConv, TMults);
501 }
502
503 Standard_Boolean GeomFill_CircularBlendFunc::IsRational() const
504 {
505   return (myTConv != Convert_Polynomial);
506 }
507
508 Standard_Integer GeomFill_CircularBlendFunc::
509 NbIntervals(const GeomAbs_Shape S) const
510 {
511  Standard_Integer NbI_Center, NbI_Cb1, NbI_Cb2, ii;
512  NbI_Center =  myPath->NbIntervals(GeomFillNextShape(S));
513  NbI_Cb1    =  myCurve1->NbIntervals(S);
514  NbI_Cb2    =  myCurve2->NbIntervals(S);
515
516  TColStd_Array1OfReal ICenter(1, NbI_Center+1);
517  TColStd_Array1OfReal ICb1(1, NbI_Cb1+1);
518  TColStd_Array1OfReal ICb2(1, NbI_Cb2+1);
519  TColStd_SequenceOfReal    Inter;
520
521  myPath->Intervals(ICenter, GeomFillNextShape(S));
522  myCurve1->Intervals(ICb1, S);
523  myCurve2->Intervals(ICb2, S);
524 /* cout << "Intervals : " << S << endl;
525  cout << "-- Center-> " << endl;
526  for (ii=1; ii<=ICenter.Length(); ii++) cout << " , "<< ICenter(ii);
527  cout << endl; cout << endl;
528  cout << "-- Cb1-> " << endl;
529  for (ii=1; ii<=ICb1.Length(); ii++) cout << " , "<< ICb1(ii);
530  cout << endl; cout << endl;
531  cout << "-- Cb2-> " << endl;
532  for (ii=1; ii<=ICb2.Length(); ii++) cout << " , "<< ICb1(ii);
533  cout << endl; cout << endl;*/
534
535  GeomFillFusInt(ICb1, ICb2, Inter);
536
537  TColStd_Array1OfReal ICbs (1, Inter.Length());
538  for (ii=1; ii<=ICbs.Length(); ii++) ICbs(ii) = Inter(ii);
539
540  Inter.Clear();
541  GeomFillFusInt(ICenter, ICbs, Inter);
542  
543  return Inter.Length()-1;  
544 }
545
546 void GeomFill_CircularBlendFunc::
547 Intervals(TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
548 {
549  Standard_Integer NbI_Center, NbI_Cb1, NbI_Cb2, ii;
550  NbI_Center =  myPath->NbIntervals(GeomFillNextShape(S));
551  NbI_Cb1    =  myCurve1->NbIntervals(S);
552  NbI_Cb2    =  myCurve2->NbIntervals(S);
553
554  TColStd_Array1OfReal ICenter(1, NbI_Center+1);
555  TColStd_Array1OfReal ICb1(1, NbI_Cb1+1);
556  TColStd_Array1OfReal ICb2(1, NbI_Cb2+1);
557  TColStd_SequenceOfReal    Inter;
558
559  myPath->Intervals(ICenter, GeomFillNextShape(S));
560  myCurve1->Intervals(ICb1, S);
561  myCurve2->Intervals(ICb2, S);
562
563  GeomFillFusInt(ICb1, ICb2, Inter);
564
565  TColStd_Array1OfReal ICbs (1, Inter.Length());
566  for (ii=1; ii<=ICbs.Length(); ii++) ICbs(ii) = Inter(ii);
567
568  Inter.Clear();
569  GeomFillFusInt(ICenter, ICbs, Inter);
570
571  // Recopie du resultat
572  for (ii=1; ii<=Inter.Length(); ii++) T(ii) = Inter(ii);
573 }
574
575  void GeomFill_CircularBlendFunc::SetInterval(const Standard_Real First,
576                                               const Standard_Real Last) 
577 {
578   Standard_Real Eps = Precision::PConfusion();
579   myTPath = myPath->Trim(First, Last, Eps);
580   myTCurve1 = myCurve1->Trim(First, Last, Eps);
581   myTCurve2 = myCurve2->Trim(First, Last, Eps); 
582 }
583
584
585 void GeomFill_CircularBlendFunc::GetTolerance(const Standard_Real BoundTol,
586                                               const Standard_Real SurfTol,
587                                               const Standard_Real AngleTol,
588                                               TColStd_Array1OfReal& Tol3d) const
589 {
590  Standard_Integer low = Tol3d.Lower() , up=Tol3d.Upper();
591  Standard_Real Tol;
592
593  Tol= GeomFill::GetTolerance(myTConv, minang, 
594                              myRadius,  AngleTol, SurfTol);
595  Tol3d.Init(SurfTol);
596  Tol3d(low+1) = Tol3d(up-1) = Min(Tol, SurfTol);
597  Tol3d(low) = Tol3d(up) = Min(Tol, BoundTol);   
598 }
599
600
601  void GeomFill_CircularBlendFunc::SetTolerance(const Standard_Real, 
602                                                const Standard_Real) 
603 {
604  // y rien a faire !
605 }
606
607  gp_Pnt GeomFill_CircularBlendFunc::BarycentreOfSurf() const
608 {
609   return myBary;
610 }
611
612  Standard_Real GeomFill_CircularBlendFunc::MaximalSection() const
613 {
614   return maxang*myRadius;
615 }
616
617 void GeomFill_CircularBlendFunc::
618 GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
619 {
620   GeomFill::GetMinimalWeights(myTConv, minang, maxang, Weigths); 
621 }
622