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