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