1 // Created on: 1997-11-21
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 //  Modified by skv - Fri Feb  6 11:44:48 2004 OCC5073
18 
19 #include <AdvApprox_ApproxAFunction.hxx>
20 #include <AdvApprox_PrefAndRec.hxx>
21 #include <Approx_SweepApproximation.hxx>
22 #include <ElCLib.hxx>
23 #include <ElSLib.hxx>
24 #include <Geom2d_BSplineCurve.hxx>
25 #include <Geom2d_Curve.hxx>
26 #include <Geom2d_Line.hxx>
27 #include <Geom2d_TrimmedCurve.hxx>
28 #include <Geom_BSplineSurface.hxx>
29 #include <Geom_Circle.hxx>
30 #include <Geom_ConicalSurface.hxx>
31 #include <Geom_CylindricalSurface.hxx>
32 #include <Geom_Line.hxx>
33 #include <Geom_Plane.hxx>
34 #include <Geom_RectangularTrimmedSurface.hxx>
35 #include <Geom_SphericalSurface.hxx>
36 #include <Geom_Surface.hxx>
37 #include <Geom_SurfaceOfLinearExtrusion.hxx>
38 #include <Geom_SurfaceOfRevolution.hxx>
39 #include <Geom_ToroidalSurface.hxx>
40 #include <Geom_TrimmedCurve.hxx>
41 #include <GeomAbs_CurveType.hxx>
42 #include <GeomAdaptor_Curve.hxx>
43 #include <GeomConvert_ApproxSurface.hxx>
44 #include <GeomFill_LocationLaw.hxx>
45 #include <GeomFill_LocFunction.hxx>
46 #include <GeomFill_SectionLaw.hxx>
47 #include <GeomFill_Sweep.hxx>
48 #include <GeomFill_SweepFunction.hxx>
49 #include <GeomLib.hxx>
50 #include <gp_Ax2.hxx>
51 #include <gp_Circ.hxx>
52 #include <gp_Dir.hxx>
53 #include <gp_Dir2d.hxx>
54 #include <gp_GTrsf.hxx>
55 #include <gp_Lin.hxx>
56 #include <gp_Mat.hxx>
57 #include <gp_Pnt.hxx>
58 #include <gp_Pnt2d.hxx>
59 #include <gp_Sphere.hxx>
60 #include <Precision.hxx>
61 #include <Standard_ConstructionError.hxx>
62 #include <Standard_ErrorHandler.hxx>
63 #include <Standard_OutOfRange.hxx>
64 #include <StdFail_NotDone.hxx>
65 #include <TColgp_Array1OfPnt.hxx>
66 #include <TColgp_Array2OfPnt.hxx>
67 #include <TColgp_HArray2OfPnt.hxx>
68 #include <TColStd_Array1OfInteger.hxx>
69 #include <TColStd_Array1OfReal.hxx>
70 #include <TColStd_Array2OfReal.hxx>
71 
72 //#include <GeomLib_Array1OfMat.hxx>
73 //=======================================================================
74 //class : GeomFill_Sweep_Eval
75 //purpose: The evaluator for curve approximation
76 //=======================================================================
77 class GeomFill_Sweep_Eval : public AdvApprox_EvaluatorFunction
78 {
79  public:
GeomFill_Sweep_Eval(GeomFill_LocFunction & theTool)80   GeomFill_Sweep_Eval (GeomFill_LocFunction& theTool)
81     : theAncore(theTool) {}
82 
83   virtual void Evaluate (Standard_Integer *Dimension,
84 		         Standard_Real     StartEnd[2],
85                          Standard_Real    *Parameter,
86                          Standard_Integer *DerivativeRequest,
87                          Standard_Real    *Result, // [Dimension]
88                          Standard_Integer *ErrorCode);
89 
90  private:
91   GeomFill_LocFunction& theAncore;
92 };
93 
Evaluate(Standard_Integer *,Standard_Real StartEnd[2],Standard_Real * Parameter,Standard_Integer * DerivativeRequest,Standard_Real * Result,Standard_Integer * ErrorCode)94 void GeomFill_Sweep_Eval::Evaluate (Standard_Integer *,/*Dimension*/
95                                     Standard_Real     StartEnd[2],
96                                     Standard_Real    *Parameter,
97                                     Standard_Integer *DerivativeRequest,
98                                     Standard_Real    *Result,// [Dimension]
99                                     Standard_Integer *ErrorCode)
100 {
101   theAncore.DN (*Parameter,
102 		StartEnd[0],
103 		StartEnd[1],
104 		*DerivativeRequest,
105 		Result[0],
106 		ErrorCode[0]);
107 }
108 
109 //===============================================================
110 // Function : Create
111 // Purpose :
112 //===============================================================
GeomFill_Sweep(const Handle (GeomFill_LocationLaw)& Location,const Standard_Boolean WithKpart)113 GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
114 			       const Standard_Boolean WithKpart)
115 {
116   done = Standard_False;
117 
118   myLoc =  Location;
119   myKPart =  WithKpart;
120   SetTolerance(1.e-4);
121   myForceApproxC1 = Standard_False;
122 
123   myLoc->GetDomain(First, Last);
124   SFirst = SLast = 30.081996;
125   SError = RealLast();
126 }
127 
128 //===============================================================
129 // Function : SetDomain
130 // Purpose :
131 //===============================================================
SetDomain(const Standard_Real LocFirst,const Standard_Real LocLast,const Standard_Real SectionFirst,const Standard_Real SectionLast)132  void GeomFill_Sweep::SetDomain(const Standard_Real LocFirst,
133 				const Standard_Real LocLast,
134 				const Standard_Real SectionFirst,
135 				const Standard_Real SectionLast)
136 {
137   First = LocFirst;
138   Last =  LocLast;
139   SFirst = SectionFirst;
140   SLast = SectionLast;
141 }
142 
143 //===============================================================
144 // Function : SetTolerance
145 // Purpose :
146 //===============================================================
SetTolerance(const Standard_Real Tolerance3d,const Standard_Real BoundTolerance,const Standard_Real Tolerance2d,const Standard_Real ToleranceAngular)147  void GeomFill_Sweep::SetTolerance(const Standard_Real Tolerance3d,
148 				   const Standard_Real BoundTolerance,
149 				   const Standard_Real Tolerance2d,
150 				   const Standard_Real ToleranceAngular)
151 {
152   Tol3d = Tolerance3d;
153   BoundTol = BoundTolerance;
154   Tol2d =Tolerance2d;
155   TolAngular = ToleranceAngular;
156 }
157 
158 //=======================================================================
159 //Function : SetForceApproxC1
160 //Purpose  : Set the flag that indicates attempt to approximate
161 //           a C1-continuous surface if a swept surface proved
162 //           to be C0.
163 //=======================================================================
SetForceApproxC1(const Standard_Boolean ForceApproxC1)164  void GeomFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
165 {
166   myForceApproxC1 = ForceApproxC1;
167 }
168 
169 
170 //===============================================================
171 // Function : ExchangeUV
172 // Purpose :
173 //===============================================================
ExchangeUV() const174  Standard_Boolean GeomFill_Sweep::ExchangeUV() const
175 {
176   return myExchUV;
177 }
178 
179 //===============================================================
180 // Function : UReversed
181 // Purpose :
182 //===============================================================
UReversed() const183  Standard_Boolean GeomFill_Sweep::UReversed() const
184 {
185   return isUReversed;
186 }
187 
188 //===============================================================
189 // Function : VReversed
190 // Purpose :
191 //===============================================================
VReversed() const192  Standard_Boolean GeomFill_Sweep::VReversed() const
193 {
194   return isVReversed;
195 }
196 
197 //===============================================================
198 // Function : Build
199 // Purpose :
200 //===============================================================
Build(const Handle (GeomFill_SectionLaw)& Section,const GeomFill_ApproxStyle Methode,const GeomAbs_Shape Continuity,const Standard_Integer Degmax,const Standard_Integer Segmax)201  void GeomFill_Sweep::Build(const Handle(GeomFill_SectionLaw)& Section,
202 			    const GeomFill_ApproxStyle Methode,
203 			    const GeomAbs_Shape Continuity,
204 			    const Standard_Integer Degmax,
205 			    const Standard_Integer Segmax)
206 {
207   // Inits
208   done = Standard_False;
209   myExchUV = Standard_False;
210   isUReversed = isVReversed = Standard_False;
211   mySec =  Section;
212 
213   if ((SFirst == SLast) &&  (SLast == 30.081996)) {
214     mySec->GetDomain(SFirst, SLast);
215   }
216 
217   Standard_Boolean isKPart = Standard_False,
218                    isProduct  = Standard_False;
219 
220  // Traitement des KPart
221  if (myKPart)  isKPart = BuildKPart();
222 
223  if (!isKPart)
224  {
225    myExchUV = Standard_False;
226    isUReversed = isVReversed = Standard_False;
227  }
228 
229  // Traitement des produits Formelles
230  if ((!isKPart) && (Methode == GeomFill_Location)) {
231      Handle(Geom_BSplineSurface) BS;
232      BS = mySec->BSplineSurface();
233      if (! BS.IsNull()) {
234       // Approx de la loi
235 //    isProduct = BuildProduct(Continuity, Degmax, Segmax);
236      }
237    }
238 
239  if (isKPart || isProduct) {
240  // Approx du 2d
241    done =  Build2d(Continuity, Degmax, Segmax);
242  }
243   else {
244  // Approx globale
245     done =  BuildAll(Continuity, Degmax, Segmax);
246   }
247 }
248 
249 //===============================================================
250 // Function ::Build2d
251 // Purpose :A venir...
252 //===============================================================
253 // Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape Continuity,
Build2d(const GeomAbs_Shape,const Standard_Integer,const Standard_Integer)254  Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape ,
255 //					  const Standard_Integer Degmax,
256 					  const Standard_Integer ,
257 //					  const Standard_Integer Segmax)
258 					  const Standard_Integer )
259 {
260   Standard_Boolean Ok = Standard_False;
261   if (myLoc->Nb2dCurves() == 0) {
262     Ok = Standard_True;
263   }
264   return Ok;
265 }
266 
267 //===============================================================
268 // Function : BuildAll
269 // Purpose :
270 //===============================================================
BuildAll(const GeomAbs_Shape Continuity,const Standard_Integer Degmax,const Standard_Integer Segmax)271  Standard_Boolean GeomFill_Sweep::BuildAll(const GeomAbs_Shape Continuity,
272 					   const Standard_Integer Degmax,
273 					   const Standard_Integer Segmax)
274 {
275   Standard_Boolean Ok = Standard_False;
276 
277   Handle(GeomFill_SweepFunction) Func
278     = new (GeomFill_SweepFunction) (mySec, myLoc, First, SFirst,
279 				   (SLast-SFirst)/(Last-First) );
280   Approx_SweepApproximation Approx( Func );
281 
282   Approx.Perform(First,  Last,
283 		 Tol3d,  BoundTol,  Tol2d,  TolAngular,
284 		 Continuity, Degmax,  Segmax);
285 
286   if (Approx.IsDone()) {
287     Ok = Standard_True;
288 
289 #ifdef OCCT_DEBUG
290     Approx.Dump(std::cout);
291 #endif
292 
293     // La surface
294     Standard_Integer UDegree,VDegree,NbUPoles,
295                      NbVPoles,NbUKnots,NbVKnots;
296     Approx.SurfShape(UDegree,VDegree,NbUPoles,
297                      NbVPoles,NbUKnots,NbVKnots);
298 
299     TColgp_Array2OfPnt Poles(1,NbUPoles, 1,NbVPoles);
300     TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
301     TColStd_Array1OfReal UKnots(1, NbUKnots),VKnots(1, NbVKnots);
302     TColStd_Array1OfInteger UMults(1, NbUKnots), VMults(1, NbVKnots);
303 
304     Approx.Surface(Poles, Weights,
305 		   UKnots,VKnots,
306 		   UMults,VMults);
307 
308     mySurface = new (Geom_BSplineSurface)
309                    (Poles, Weights,
310 		    UKnots,VKnots,
311 		    UMults,VMults,
312 		    Approx.UDegree(),  Approx.VDegree(),
313 		    mySec->IsUPeriodic());
314     SError = Approx. MaxErrorOnSurf();
315 
316     if (myForceApproxC1 && !mySurface->IsCNv(1))
317     {
318       Standard_Real theTol = 1.e-4;
319       GeomAbs_Shape theUCont = GeomAbs_C1, theVCont = GeomAbs_C1;
320       Standard_Integer degU = 14, degV = 14;
321       Standard_Integer nmax = 16;
322       Standard_Integer thePrec = 1;
323 
324       GeomConvert_ApproxSurface ConvertApprox(mySurface,theTol,theUCont,theVCont,
325                                               degU,degV,nmax,thePrec);
326       if (ConvertApprox.HasResult())
327       {
328         mySurface = ConvertApprox.Surface();
329         myCurve2d = new  (TColGeom2d_HArray1OfCurve) (1, 2);
330         CError =  new (TColStd_HArray2OfReal) (1,2, 1,2);
331 
332         Handle(Geom_BSplineSurface) BSplSurf (Handle(Geom_BSplineSurface)::DownCast(mySurface));
333 
334         gp_Dir2d D(0., 1.);
335         gp_Pnt2d P(BSplSurf->UKnot(1), 0);
336         Handle(Geom2d_Line) LC1 = new (Geom2d_Line) (P, D);
337         Handle(Geom2d_TrimmedCurve) TC1 =
338           new (Geom2d_TrimmedCurve) (LC1, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
339 
340         myCurve2d->SetValue(1, TC1);
341         CError->SetValue(1, 1, 0.);
342         CError->SetValue(2, 1, 0.);
343 
344         P.SetCoord(BSplSurf->UKnot(BSplSurf->NbUKnots()), 0);
345         Handle(Geom2d_Line) LC2 = new (Geom2d_Line) (P, D);
346         Handle(Geom2d_TrimmedCurve) TC2 =
347           new (Geom2d_TrimmedCurve) (LC2, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
348 
349         myCurve2d->SetValue(myCurve2d->Length(), TC2);
350         CError->SetValue(1, myCurve2d->Length(), 0.);
351         CError->SetValue(2, myCurve2d->Length(), 0.);
352 
353         SError = theTol;
354       }
355     } //if (!mySurface->IsCNv(1))
356 
357     // Les Courbes 2d
358     if (myCurve2d.IsNull())
359     {
360       myCurve2d = new  (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
361       CError =  new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
362       Standard_Integer kk,ii, ifin = 1, ideb;
363 
364       if (myLoc->HasFirstRestriction()) {
365         ideb = 1;
366       }
367       else {
368         ideb = 2;
369       }
370       ifin += myLoc->TraceNumber();
371       if (myLoc->HasLastRestriction()) ifin++;
372 
373       for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
374         Handle(Geom2d_BSplineCurve) C
375           = new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
376                                        Approx.Curves2dKnots(),
377                                        Approx.Curves2dMults(),
378                                        Approx.Curves2dDegree());
379         myCurve2d->SetValue(ii, C);
380         CError->SetValue(1, ii,  Approx.Max2dError(kk));
381         CError->SetValue(2, ii,  Approx.Max2dError(kk));
382       }
383 
384       // Si les courbes de restriction, ne sont pas calcules, on prend
385       // les iso Bords.
386       if (! myLoc->HasFirstRestriction()) {
387         gp_Dir2d D(0., 1.);
388         gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
389         Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
390         Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
391           (LC, First, Last);
392 
393         myCurve2d->SetValue(1, TC);
394         CError->SetValue(1, 1, 0.);
395         CError->SetValue(2, 1, 0.);
396       }
397 
398       if (! myLoc->HasLastRestriction()) {
399         gp_Dir2d D(0., 1.);
400         gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
401         Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
402         Handle(Geom2d_TrimmedCurve) TC =
403           new (Geom2d_TrimmedCurve) (LC, First, Last);
404         myCurve2d->SetValue(myCurve2d->Length(), TC);
405         CError->SetValue(1, myCurve2d->Length(), 0.);
406         CError->SetValue(2, myCurve2d->Length(), 0.);
407       }
408     } //if (myCurve2d.IsNull())
409   }
410   return Ok;
411 }
412 
413 //===============================================================
414 // Function : BuildProduct
415 // Purpose : A venir...
416 //===============================================================
BuildProduct(const GeomAbs_Shape Continuity,const Standard_Integer Degmax,const Standard_Integer Segmax)417  Standard_Boolean GeomFill_Sweep::BuildProduct(const GeomAbs_Shape Continuity,
418 					  const Standard_Integer Degmax,
419 					  const Standard_Integer Segmax)
420 {
421   Standard_Boolean Ok = Standard_False;
422 
423   Handle(Geom_BSplineSurface) BSurf;
424   BSurf = Handle(Geom_BSplineSurface)::DownCast(
425 	   mySec->BSplineSurface()->Copy());
426   if (BSurf.IsNull()) return Ok; // Ce mode de construction est impossible
427 
428 
429   Standard_Integer NbIntervalC2,  NbIntervalC3;
430   GeomFill_LocFunction Func(myLoc);
431 
432   NbIntervalC2 = myLoc->NbIntervals(GeomAbs_C2);
433   NbIntervalC3 = myLoc->NbIntervals(GeomAbs_C3);
434   TColStd_Array1OfReal Param_de_decoupeC2 (1, NbIntervalC2+1);
435   myLoc->Intervals(Param_de_decoupeC2, GeomAbs_C2);
436   TColStd_Array1OfReal Param_de_decoupeC3 (1, NbIntervalC3+1);
437   myLoc->Intervals(Param_de_decoupeC3, GeomAbs_C3);
438 
439 
440   AdvApprox_PrefAndRec Preferentiel(Param_de_decoupeC2,
441 				     Param_de_decoupeC3);
442 
443   Handle(TColStd_HArray1OfReal) ThreeDTol = new (TColStd_HArray1OfReal) (1,4);
444   ThreeDTol->Init(Tol3d); // A Affiner...
445 
446   GeomFill_Sweep_Eval eval (Func);
447   AdvApprox_ApproxAFunction Approx(0, 0, 4,
448 				   ThreeDTol,
449 				   ThreeDTol,
450 				   ThreeDTol,
451 				   First,
452 				   Last,
453 				   Continuity,
454 				   Degmax,
455 				   Segmax,
456 				   eval,
457 				   Preferentiel);
458 #ifdef OCCT_DEBUG
459   Approx.Dump(std::cout);
460 #endif
461 
462   Ok = Approx.HasResult();
463   if (Ok) {
464 /*    TColgp_Array1OfMat TM(1, nbpoles);
465     Handle(TColgp_HArray2OfPnt) ResPoles;
466     ResPoles = Approx.Poles();
467 
468     // Produit Tensoriel
469     for (ii=1; ii<=nbpoles; ii++) {
470       TM(ii).SetCols(ResPoles->Value(ii,2).XYZ(),
471 		     ResPoles->Value(ii,3).XYZ(),
472 		     ResPoles->Value(ii,4).XYZ());
473       TR(ii) = ResPoles->Value(ii,1);
474     }
475     GeomLib::TensorialProduct(BSurf, TM, TR,
476 			      Approx.Knots()->Array1(),
477 			      Approx.Multiplicities()->Array1());
478 
479     // Somme
480     TColgp_Array1OfPnt TPoles(1, nbpoles);
481     for (ii=1; ii<=nbpoles; ii++) {
482       TPoles(ii) = ResPoles->Value(ii,1);
483     }
484     Handle(Geom_BsplineCurve) BS =
485       new (Geom_BsplineCurve) (Poles,
486 			       Approx.Knots()->Array1(),
487 			       Approx.Multiplicities()->Array1(),
488 			       Approx.Degree());
489     for (ii=1; ii<=BSurf->NbVKnots(); ii++)
490       BS->InsertKnot( BSurf->VKnot(ii),
491 		     BSurf->VMultiplicity(ii),
492 		     Precision::Confusion());
493    TColgp_Array2OfPnt SurfPoles (1, BSurf->NbUPoles());
494    for (ii=1;
495 
496 */
497     mySurface = BSurf;
498   }
499   return Ok;
500 }
501 
502 //  Modified by skv - Thu Feb  5 18:05:03 2004 OCC5073 Begin
503 //  Conditions:
504 //     * theSec should be constant
505 //     * the type of section should be a line
506 //     * theLoc should represent a translation.
507 
IsSweepParallelSpine(const Handle (GeomFill_LocationLaw)& theLoc,const Handle (GeomFill_SectionLaw)& theSec,const Standard_Real theTol)508 static Standard_Boolean IsSweepParallelSpine (const Handle(GeomFill_LocationLaw) &theLoc,
509 			     const Handle(GeomFill_SectionLaw)  &theSec,
510 			     const Standard_Real                 theTol)
511 {
512   // Get the first and last transformations of the location
513   Standard_Real aFirst;
514   Standard_Real aLast;
515   gp_Vec        VBegin;
516   gp_Vec        VEnd;
517   gp_Mat        M;
518   gp_GTrsf      GTfBegin;
519   gp_Trsf       TfBegin;
520   gp_GTrsf      GTfEnd;
521   gp_Trsf       TfEnd;
522 
523   theLoc->GetDomain(aFirst, aLast);
524 
525 // Get the first transformation
526   theLoc->D0(aFirst, M, VBegin);
527 
528   GTfBegin.SetVectorialPart(M);
529   GTfBegin.SetTranslationPart(VBegin.XYZ());
530 
531   TfBegin.SetValues(GTfBegin(1,1), GTfBegin(1,2), GTfBegin(1,3), GTfBegin(1,4),
532 		    GTfBegin(2,1), GTfBegin(2,2), GTfBegin(2,3), GTfBegin(2,4),
533 		    GTfBegin(3,1), GTfBegin(3,2), GTfBegin(3,3), GTfBegin(3,4));
534 
535 // Get the last transformation
536   theLoc->D0(aLast, M, VEnd);
537 
538   GTfEnd.SetVectorialPart(M);
539   GTfEnd.SetTranslationPart(VEnd.XYZ());
540 
541   TfEnd.SetValues(GTfEnd(1,1), GTfEnd(1,2), GTfEnd(1,3), GTfEnd(1,4),
542 		  GTfEnd(2,1), GTfEnd(2,2), GTfEnd(2,3), GTfEnd(2,4),
543 		  GTfEnd(3,1), GTfEnd(3,2), GTfEnd(3,3), GTfEnd(3,4));
544 
545   Handle(Geom_Surface) aSurf = theSec->BSplineSurface();
546   Standard_Real Umin;
547   Standard_Real Umax;
548   Standard_Real Vmin;
549   Standard_Real Vmax;
550 
551   aSurf->Bounds(Umin, Umax, Vmin, Vmax);
552 
553   // Get and transform the first section
554   Handle(Geom_Curve) FirstSection = theSec->ConstantSection();
555   GeomAdaptor_Curve  ACFirst(FirstSection);
556 
557   Standard_Real UFirst = ACFirst.FirstParameter();
558   gp_Lin        L      = ACFirst.Line();
559 
560   L.Transform(TfBegin);
561 
562   // Get and transform the last section
563   Handle(Geom_Curve) aLastSection    = aSurf->VIso(Vmax);
564   Standard_Real      aFirstParameter = aLastSection->FirstParameter();
565   gp_Pnt             aPntLastSec     = aLastSection->Value(aFirstParameter);
566 
567   aPntLastSec.Transform(TfEnd);
568 
569   gp_Pnt        aPntFirstSec = ElCLib::Value( UFirst, L );
570   gp_Vec        aVecSec( aPntFirstSec, aPntLastSec );
571   gp_Vec        aVecSpine = VEnd - VBegin;
572 
573   Standard_Boolean isParallel = aVecSec.IsParallel(aVecSpine, theTol);
574 
575   return isParallel;
576 }
577 //  Modified by skv - Thu Feb  5 18:05:01 2004 OCC5073 End
578 
579 //===============================================================
580 // Function : BuildKPart
581 // Purpose :
582 //===============================================================
BuildKPart()583  Standard_Boolean GeomFill_Sweep::BuildKPart()
584 {
585   Standard_Boolean Ok = Standard_False;
586   Standard_Boolean isUPeriodic = Standard_False;
587   Standard_Boolean isVPeriodic = Standard_False;
588   Standard_Boolean IsTrsf = Standard_True;
589 
590   isUPeriodic = mySec->IsUPeriodic();
591   Handle(Geom_Surface) S;
592   GeomAbs_CurveType SectionType;
593   gp_Vec V;
594   gp_Mat M;
595   Standard_Real levier, error = 0 ;
596   Standard_Real UFirst=0, VFirst=First, ULast=0, VLast=Last;
597   Standard_Real Tol = Min (Tol3d, BoundTol);
598 
599   // (1) Trajectoire Rectilignes -------------------------
600   if (myLoc->IsTranslation(error)) {
601     // Donne de la translation
602     gp_Vec DP, DS;
603     myLoc->D0(1, M, DS);
604     myLoc->D0(0, M, V);
605     DP = DS - V;
606     DP.Normalize();
607     gp_GTrsf Tf;
608     gp_Trsf Tf2;
609     Tf.SetVectorialPart(M);
610     Tf.SetTranslationPart(V.XYZ());
611     try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
612       OCC_CATCH_SIGNALS
613       Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
614 		    Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
615 		    Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4));
616     }
617     catch (Standard_ConstructionError const&) {
618       IsTrsf = Standard_False;
619     }
620     if (!IsTrsf) {
621       return Standard_False;
622     }
623 
624     // (1.1) Cas Extrusion
625     if (mySec->IsConstant(error)) {
626       Handle(Geom_Curve) Section;
627       Section = mySec->ConstantSection();
628       GeomAdaptor_Curve AC(Section);
629       SectionType = AC.GetType();
630       UFirst = AC.FirstParameter();
631       ULast  = AC.LastParameter();
632   // (1.1.a) Cas Plan
633       if ( (SectionType == GeomAbs_Line) && IsTrsf) {
634 //  Modified by skv - Thu Feb  5 11:39:06 2004 OCC5073 Begin
635 	if (!IsSweepParallelSpine(myLoc, mySec, Tol))
636 	  return Standard_False;
637 //  Modified by skv - Thu Feb  5 11:39:08 2004 OCC5073 End
638 	gp_Lin L = AC.Line();
639         L.Transform(Tf2);
640 	DS.SetXYZ(L.Position().Direction().XYZ());
641 	DS.Normalize();
642         levier = Abs(DS.Dot(DP));
643         SError = error + levier * Abs(Last-First);
644 	if (SError <= Tol) {
645 	  Ok = Standard_True;
646 	  gp_Ax2 AxisOfPlane (L.Location(), DS^DP, DS);
647 	  S = new (Geom_Plane) (AxisOfPlane);
648 	}
649 	else SError = 0.;
650       }
651 
652   // (1.1.b) Cas Cylindrique
653       if ( (SectionType == GeomAbs_Circle) && IsTrsf) {
654         const Standard_Real TolProd = 1.e-6;
655 
656 	gp_Circ C = AC.Circle();
657 	C.Transform(Tf2);
658 
659 	DS.SetXYZ (C.Position().Direction().XYZ());
660 	DS.Normalize();
661         levier = Abs(DS.CrossMagnitude(DP)) * C.Radius();
662         SError = levier * Abs(Last - First);
663 	if (SError <= TolProd) {
664 	  Ok = Standard_True;
665           gp_Ax3 axe (C.Location(), DP, C.Position().XDirection());
666 	  S = new (Geom_CylindricalSurface)
667 	    (axe, C.Radius());
668 	    if (C.Position().Direction().
669 		IsOpposite(axe.Direction(), 0.1) ) {
670 	      Standard_Real f, l;
671 	      // L'orientation parametrique est inversee
672 	      l = 2*M_PI - UFirst;
673 	      f = 2*M_PI - ULast;
674 	      UFirst = f;
675 	      ULast  = l;
676 	      isUReversed = Standard_True;
677 	    }
678 	}
679 	else SError = 0.;
680       }
681 
682   // (1.1.c) C'est bien une extrusion
683       if (!Ok) {
684 	if (IsTrsf) {
685 	  Section->Transform(Tf2);
686 	  S = new (Geom_SurfaceOfLinearExtrusion)
687 	    (Section, DP);
688 	  SError = 0.;
689 	  Ok = Standard_True;
690 	}
691 	else { // extrusion sur BSpline
692 
693 	}
694       }
695     }
696 
697   // (1.2) Cas conique
698    else if (mySec->IsConicalLaw(error)) {
699 
700      gp_Pnt P1, P2, Centre0, Centre1, Centre2;
701      gp_Vec dsection;
702      Handle(Geom_Curve) Section;
703      GeomAdaptor_Curve AC;
704      gp_Circ C;
705      Standard_Real R1, R2;
706 
707 
708      Section = mySec->CirclSection(SLast);
709      Section->Transform(Tf2);
710      Section->Translate(Last*DP);
711      AC.Load(Section);
712      C = AC.Circle();
713      Centre2 = C.Location();
714      AC.D1(0, P2, dsection);
715      R2 = C.Radius();
716 
717      Section = mySec->CirclSection(SFirst);
718      Section->Transform(Tf2);
719      Section->Translate(First*DP);
720      AC.Load(Section);
721      C =  AC.Circle();
722      Centre1 = C.Location();
723      P1 = AC.Value(0);
724      R1 = C.Radius();
725 
726      Section = mySec->CirclSection(SFirst - First*(SLast-SFirst)/(Last-First));
727      Section->Transform(Tf2);
728      AC.Load(Section);
729      C =  AC.Circle();
730      Centre0 = C.Location();
731 
732      Standard_Real Angle;
733      gp_Vec  N(Centre1, P1);
734      if (N.Magnitude() < 1.e-9) {
735        gp_Vec Bis(Centre2, P2);
736        N = Bis;
737      }
738      gp_Vec  L(P1, P2), Dir(Centre1,Centre2);
739 
740      Angle = L.Angle(Dir);
741      if ((Angle > 0.01) && (Angle < M_PI/2-0.01)) {
742        if (R2<R1) Angle = -Angle;
743        SError = error;
744        gp_Ax3 Axis(Centre0, Dir, N);
745        S = new (Geom_ConicalSurface)
746 	 (Axis, Angle, C.Radius());
747        // Calcul du glissement parametrique
748        VFirst = First / Cos(Angle);
749        VLast  = Last  / Cos(Angle);
750 
751        // Bornes en U
752        UFirst = AC.FirstParameter();
753        ULast  = AC.LastParameter();
754        gp_Vec diso;
755        gp_Pnt pbis;
756        S->VIso(VLast)->D1(0, pbis, diso);
757        if (diso.Magnitude()>1.e-9 && dsection.Magnitude()>1.e-9)
758 	 isUReversed = diso.IsOpposite(dsection, 0.1);
759        if (isUReversed ) {
760 	 Standard_Real f, l;
761 	 // L'orientation parametrique est inversee
762 	 l = 2*M_PI - UFirst;
763 	 f = 2*M_PI - ULast;
764 	 UFirst = f;
765 	 ULast  = l;
766        }
767 
768        // C'est un cone
769        Ok = Standard_True;
770      }
771    }
772   }
773 
774   // (2) Trajectoire Circulaire
775   if (myLoc->IsRotation(error)) {
776     if (mySec->IsConstant(error)) {
777       // La trajectoire
778       gp_Pnt Centre;
779       isVPeriodic = (Abs(Last-First -2*M_PI) < 1.e-15);
780       Standard_Real RotRadius;
781       gp_Vec DP, DS, DN;
782       myLoc->D0(0.1, M, DS);
783       myLoc->D0(0, M, V);
784       myLoc->Rotation(Centre);
785 
786       DP = DS - V;
787       DS.SetXYZ(V.XYZ() - Centre.XYZ());
788       RotRadius = DS.Magnitude();
789       if (RotRadius > 1.e-15) DS.Normalize();
790       else return Standard_False; // Pas de KPart, rotation degeneree
791       DN = DS ^ DP;
792       DN.Normalize();
793       DP = DN ^ DS;
794       DP.Normalize();
795 
796       gp_GTrsf Tf;
797       gp_Trsf Tf2;
798       Tf.SetVectorialPart(M);
799       Tf.SetTranslationPart(V.XYZ());
800 //      try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
801 //        OCC_CATCH_SIGNALS
802 	Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
803 		      Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
804 		      Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4));
805 //      }
806 //      catch (Standard_ConstructionError) {
807 //	IsTrsf = Standard_False;
808 //      }
809       // La section
810       Handle(Geom_Curve) Section;
811       Section = mySec->ConstantSection();
812       GeomAdaptor_Curve AC(Section);
813       SectionType = AC.GetType();
814       UFirst = AC.FirstParameter();
815       ULast  = AC.LastParameter();
816 
817       // (2.1) Tore/Sphere ?
818       if ((SectionType == GeomAbs_Circle) && IsTrsf) {
819 	gp_Circ C = AC.Circle();
820         Standard_Real Radius;
821 	Standard_Boolean IsGoodSide = Standard_True;
822 	C.Transform(Tf2);
823 	gp_Vec DC;
824         // On calcul le centre eventuel
825         DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
826 	Centre.ChangeCoord() += (DC.Dot(DN))*DN.XYZ();
827 	DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
828         Radius = DC.Magnitude(); //grand Rayon du tore
829 	if ((Radius > Tol) && (DC.Dot(DS) < 0)) IsGoodSide = Standard_False;
830         if (Radius < Tol/100) DC = DS; // Pour definir le tore
831 
832 	// On verifie d'abord que le plan de la section est // a
833 	// l'axe de rotation
834 	gp_Vec NC;
835 	NC.SetXYZ (C.Position().Direction().XYZ());
836 	NC.Normalize();
837 	error =  Abs(NC.Dot(DN));
838 	// Puis on evalue l'erreur commise sur la section,
839         // en pivotant son plan ( pour contenir l'axe de rotation)
840         error += Abs(NC.Dot(DS));
841         error *= C.Radius();
842 	if (error <= Tol) {
843 	  SError = error;
844 	  error += Radius;
845           if (Radius <= Tol) {
846 	    // (2.1.a) Sphere
847 	    Standard_Real f = UFirst , l =  ULast, aRadius = 0.0;
848 	    SError = error;
849 	    Centre.BaryCenter(1.0, C.Location(), 1.0);
850 	    gp_Ax3 AxisOfSphere(Centre, DN, DS);
851             aRadius = C.Radius();
852             gp_Sphere theSphere( AxisOfSphere, aRadius );
853 	    S = new Geom_SphericalSurface(theSphere);
854 	    // Pour les spheres on ne peut pas controler le parametre
855             // V (donc U car  myExchUV = Standard_True)
856             // Il faut donc modifier UFirst, ULast...
857             Standard_Real fpar = AC.FirstParameter();
858             Standard_Real lpar = AC.LastParameter();
859             Handle(Geom_Curve) theSection = new Geom_TrimmedCurve(Section, fpar, lpar);
860             theSection->Transform(Tf2);
861             gp_Pnt FirstPoint = theSection->Value(theSection->FirstParameter());
862             gp_Pnt LastPoint  = theSection->Value(theSection->LastParameter());
863             Standard_Real UfirstOnSec, VfirstOnSec, UlastOnSec, VlastOnSec;
864             ElSLib::Parameters(theSphere, FirstPoint, UfirstOnSec, VfirstOnSec);
865             ElSLib::Parameters(theSphere, LastPoint, UlastOnSec, VlastOnSec);
866             if (VfirstOnSec < VlastOnSec)
867             {
868               f = VfirstOnSec;
869               l = VlastOnSec;
870             }
871             else
872             {
873 	      // L'orientation parametrique est inversee
874               f = VlastOnSec;
875               l = VfirstOnSec;
876 	      isUReversed = Standard_True;
877 	    }
878 
879             if (Abs(l - f) <= Precision::PConfusion() ||
880                 Abs(UlastOnSec - UfirstOnSec) > M_PI_2)
881             {
882               // l == f - "degenerated" surface
883               // UlastOnSec - UfirstOnSec > M_PI_2 - "twisted" surface,
884               // it is impossible to represent with help of trimmed sphere
885 	      isUReversed = Standard_False;
886               return Ok;
887             }
888 
889 	    if ( (f >= -M_PI/2) && (l <= M_PI/2)) {
890 	      Ok = Standard_True;
891 	      myExchUV = Standard_True;
892 	      UFirst = f;
893 	      ULast  = l;
894 	    }
895 	    else { // On restaure ce qu'il faut
896 	      isUReversed = Standard_False;
897 	    }
898 	  }
899 	  else if (IsGoodSide) {
900 	    // (2.1.b) Tore
901 	    gp_Ax3 AxisOfTore(Centre, DN, DC);
902 	    S = new (Geom_ToroidalSurface) (AxisOfTore,
903 		   Radius , C.Radius());
904 
905 	    // Pour les tores on ne peut pas controler le parametre
906             // V (donc U car  myExchUV = Standard_True)
907             // Il faut donc modifier UFirst, ULast...
908 	    Handle(Geom_Circle) Iso;
909 	    Iso =  Handle(Geom_Circle)::DownCast(S->UIso(0.));
910 	    gp_Ax2 axeiso;
911 	    axeiso = Iso->Circ().Position();
912 
913 	    if (C.Position().Direction().
914 		IsOpposite(axeiso.Direction(), 0.1) ) {
915 	      Standard_Real f, l;
916 	      // L'orientation parametrique est inversee
917 	      l = 2*M_PI - UFirst;
918 	      f = 2*M_PI - ULast;
919 	      UFirst = f;
920 	      ULast  = l;
921 	      isUReversed = Standard_True;
922 	    }
923 	    // On calcul le "glissement" parametrique.
924 	    Standard_Real rot;
925 	    rot = C.Position().XDirection().AngleWithRef
926 	      (axeiso.XDirection(), axeiso.Direction());
927 	    UFirst -= rot;
928 	    ULast  -= rot;
929 
930 	    myExchUV = Standard_True;
931             // Attention l'arete de couture dans le cas periodique
932             // n'est peut etre pas a la bonne place...
933             if (isUPeriodic && Abs(UFirst)>Precision::PConfusion())
934 	      isUPeriodic = Standard_False; //Pour trimmer la surface...
935 	    Ok = Standard_True;
936 	  }
937 	}
938 	else {
939 	  SError = 0.;
940 	}
941       }
942       // (2.2) Cone / Cylindre
943       if ((SectionType == GeomAbs_Line) && IsTrsf)  {
944 	gp_Lin L =  AC.Line();
945 	L.Transform(Tf2);
946 	gp_Vec DL;
947 	DL.SetXYZ(L.Direction().XYZ());
948 	levier = Max(Abs(AC.FirstParameter()), AC.LastParameter());
949 	// si la line est ortogonale au cercle de rotation
950 	SError = error + levier * Abs(DL.Dot(DP));
951 	if (SError <= Tol) {
952           Standard_Boolean reverse;
953 	  gp_Lin Dir(Centre, DN);
954 	  Standard_Real aux;
955 	  aux = DL.Dot(DN);
956 	  reverse = (aux < 0);  // On choisit ici le sens de parametrisation
957 
958           // Calcul du centre du vecteur supportant la "XDirection"
959 	  gp_Pnt CentreOfSurf;
960 	  gp_Vec O1O2(Centre, L.Location()), trans;
961 	  trans = DN;
962 	  trans *= DN.Dot(O1O2);
963 	  CentreOfSurf = Centre.Translated(trans);
964           DS.SetXYZ(L.Location().XYZ() - CentreOfSurf.XYZ());
965 
966 	  error = SError;
967 	  error += (DL.XYZ()).CrossMagnitude(DN.XYZ())*levier;
968 	  if (error <= Tol) {
969 	    // (2.2.a) Cylindre
970             // si la line est orthogonale au plan de rotation
971 	    SError = error;
972       //
973       gp_Ax3 Axis(CentreOfSurf, Dir.Direction());
974       if (DS.SquareMagnitude() > gp::Resolution())
975       {
976         Axis.SetXDirection(DS);
977       }
978 	    S = new (Geom_CylindricalSurface)
979 	            (Axis, L.Distance(CentreOfSurf));
980 	    Ok = Standard_True;
981             myExchUV = Standard_True;
982 	  }
983 	  else {
984 	    // On evalue l'angle du cone
985 	    Standard_Real Angle = Abs(Dir.Angle(L));
986 	    if (Angle > M_PI/2) Angle = M_PI -Angle;
987             if (reverse) Angle = -Angle;
988 	    aux = DS.Dot(DL);
989 	    if (aux < 0) {
990 	      Angle = - Angle;
991 	    }
992 	    if (Abs(Abs(Angle) - M_PI/2) > 0.01) {
993 	      // (2.2.b) Cone
994 	      // si les 2 droites ne sont pas orthogonales
995 	      Standard_Real Radius = CentreOfSurf.Distance(L.Location());
996 	      gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
997 	      S = new (Geom_ConicalSurface)
998 	            (Axis, Angle, Radius);
999 	      myExchUV = Standard_True;
1000 	      Ok = Standard_True;
1001 	    }
1002 	    else {
1003 	      // On n'as pas conclue, on remet l'erreur a 0.
1004 	      SError = 0.;
1005 	    }
1006 	  }
1007 	  if (Ok && reverse) {
1008 	    // On reverse le parametre
1009 	    Standard_Real uf, ul;
1010 	    Handle(Geom_Line) CL = new (Geom_Line)(L);
1011 	    uf = CL->ReversedParameter(ULast);
1012 	    ul = CL->ReversedParameter(UFirst);
1013 	    UFirst = uf;
1014 	    ULast = ul;
1015 	    isUReversed = Standard_True;
1016 	  }
1017 	}
1018 	else SError = 0.;
1019       }
1020 
1021       // (2.3) Revolution
1022       if (!Ok) {
1023 	if (IsTrsf) {
1024 	  Section->Transform(Tf2);
1025 	  gp_Ax1 Axis (Centre, DN);
1026 	  S = new (Geom_SurfaceOfRevolution)
1027 	    (Section, Axis);
1028 	  myExchUV = Standard_True;
1029 	  SError = 0.;
1030 	  Ok = Standard_True;
1031 	}
1032       }
1033     }
1034   }
1035 
1036 
1037   if (Ok) { // On trimme la surface
1038     if (myExchUV) {
1039       Standard_Boolean b;
1040       b = isUPeriodic; isUPeriodic = isVPeriodic;  isVPeriodic = b;
1041       Standard_Real r;
1042       r = UFirst; UFirst = VFirst; VFirst = r;
1043       r = ULast; ULast = VLast; VLast = r;
1044     }
1045 
1046     if (!isUPeriodic && !isVPeriodic)
1047       mySurface = new (Geom_RectangularTrimmedSurface)
1048 	(S, UFirst, ULast, VFirst, VLast);
1049     else if (isUPeriodic) {
1050       if (isVPeriodic) mySurface = S;
1051       else mySurface = new (Geom_RectangularTrimmedSurface)
1052 	(S, VFirst, VLast, Standard_False);
1053     }
1054     else
1055       mySurface = new (Geom_RectangularTrimmedSurface)
1056 	(S,UFirst, ULast, Standard_True);
1057 
1058 #ifdef OCCT_DEBUG
1059   if (isUPeriodic && !mySurface->IsUPeriodic())
1060     std::cout<<"Pb de periodicite en U" << std::endl;
1061   if (isUPeriodic && !mySurface->IsUClosed())
1062     std::cout<<"Pb de fermeture en U" << std::endl;
1063   if (isVPeriodic && !mySurface->IsVPeriodic())
1064     std::cout << "Pb de periodicite en V" << std::endl;
1065   if (isVPeriodic && !mySurface->IsVClosed())
1066     std::cout<<"Pb de fermeture en V" << std::endl;
1067 #endif
1068   }
1069 
1070 
1071   return Ok;
1072 }
1073 
1074 //===============================================================
1075 // Function : IsDone
1076 // Purpose :
1077 //===============================================================
IsDone() const1078  Standard_Boolean GeomFill_Sweep::IsDone() const
1079 {
1080   return done;
1081 }
1082 
1083 //===============================================================
1084 // Function :ErrorOnSurface
1085 // Purpose :
1086 //===============================================================
ErrorOnSurface() const1087  Standard_Real GeomFill_Sweep::ErrorOnSurface() const
1088 {
1089   return SError;
1090 }
1091 
1092 //===============================================================
1093 // Function ::ErrorOnRestriction
1094 // Purpose :
1095 //===============================================================
ErrorOnRestriction(const Standard_Boolean IsFirst,Standard_Real & UError,Standard_Real & VError) const1096  void GeomFill_Sweep::ErrorOnRestriction(const Standard_Boolean IsFirst,
1097 					 Standard_Real& UError,
1098 					 Standard_Real& VError) const
1099 {
1100   Standard_Integer ind;
1101   if (IsFirst) ind=1;
1102   else ind = myCurve2d->Length();
1103 
1104   UError =  CError->Value(1, ind);
1105   VError =  CError->Value(2, ind);
1106 }
1107 
1108 //===============================================================
1109 // Function :ErrorOnTrace
1110 // Purpose :
1111 //===============================================================
ErrorOnTrace(const Standard_Integer IndexOfTrace,Standard_Real & UError,Standard_Real & VError) const1112  void GeomFill_Sweep::ErrorOnTrace(const Standard_Integer IndexOfTrace,
1113 				   Standard_Real& UError,
1114 				   Standard_Real& VError) const
1115 {
1116   Standard_Integer ind = IndexOfTrace+1;
1117   if (IndexOfTrace > myLoc->TraceNumber())
1118     throw Standard_OutOfRange(" GeomFill_Sweep::ErrorOnTrace");
1119 
1120   UError =  CError->Value(1, ind);
1121   VError =  CError->Value(2, ind);
1122 }
1123 
1124 //===============================================================
1125 // Function :Surface
1126 // Purpose :
1127 //===============================================================
Handle(Geom_Surface)1128  Handle(Geom_Surface) GeomFill_Sweep::Surface() const
1129 {
1130   return mySurface;
1131 }
1132 
1133 //===============================================================
1134 // Function ::Restriction
1135 // Purpose :
1136 //===============================================================
Handle(Geom2d_Curve)1137  Handle(Geom2d_Curve) GeomFill_Sweep::Restriction(const Standard_Boolean IsFirst) const
1138 {
1139   if (IsFirst)
1140     return  myCurve2d->Value(1);
1141   return  myCurve2d->Value(myCurve2d->Length());
1142 
1143 }
1144 
1145 //===============================================================
1146 // Function :
1147 // Purpose :
1148 //===============================================================
NumberOfTrace() const1149  Standard_Integer GeomFill_Sweep::NumberOfTrace() const
1150 {
1151   return myLoc->TraceNumber();
1152 }
1153 
1154 //===============================================================
1155 // Function :
1156 // Purpose :
1157 //===============================================================
Handle(Geom2d_Curve)1158  Handle(Geom2d_Curve)
1159      GeomFill_Sweep::Trace(const Standard_Integer IndexOfTrace) const
1160 {
1161   Standard_Integer ind = IndexOfTrace+1;
1162   if (IndexOfTrace > myLoc->TraceNumber())
1163     throw Standard_OutOfRange(" GeomFill_Sweep::Trace");
1164   return  myCurve2d->Value(ind);
1165 }
1166