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