0025720: Incorrect code of math classes can lead to unpredicted behavior of algorithms
[occt.git] / src / GeomFill / GeomFill_LocationDraft.cxx
1 // Created on: 1998-04-21
2 // Created by: Stephanie HUMEAU
3 // Copyright (c) 1998-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_LocationDraft.ixx>
18
19
20 #include <GeomAdaptor_HCurve.hxx>
21 #include <GeomAdaptor_HSurface.hxx>
22
23 #include <Geom_Surface.hxx>
24 #include <Geom_Line.hxx>
25
26 #include <GeomFill_TrihedronLaw.hxx>
27 #include <GeomFill_FunctionDraft.hxx>
28 #include <GeomFill_Tensor.hxx>
29
30 #include <IntCurveSurface_IntersectionPoint.hxx>
31 #include <IntCurveSurface_Intersection.hxx>
32 #include <IntCurveSurface_HInter.hxx>
33
34 #include <math_FunctionSetWithDerivatives.hxx>
35 #include <math_Vector.hxx>
36 #include <math_NewtonFunctionSetRoot.hxx>
37 #include <math_Matrix.hxx>
38 #include <math_Gauss.hxx>
39
40
41 //==================================================================
42 //Function: GeomFill_LocationDraft
43 //Purpose : constructor
44 //==================================================================
45 GeomFill_LocationDraft::GeomFill_LocationDraft
46  (const gp_Dir& Direction,
47   const Standard_Real Angle)
48 {
49   myDir = Direction; // direction de depouille
50  
51   myAngle = Angle; // angle de depouille (teta prime)
52
53   mySurf.Nullify();
54   myLaw = new (GeomFill_DraftTrihedron)(myDir, Angle); // triedre
55   myNbPts = 41; // nb de points utilises pour les calculs
56   myPoles2d = new (TColgp_HArray1OfPnt2d)(1, 2*myNbPts);
57   Intersec = Standard_False; //intersection avec surface d'arret ?
58   WithTrans = Standard_False;
59 }
60
61
62
63 //==================================================================
64 //Function: Copy
65 //Purpose :
66 //==================================================================
67  Handle(GeomFill_LocationLaw) GeomFill_LocationDraft::Copy() const
68 {
69   Handle(GeomFill_TrihedronLaw) law;
70   law = myLaw->Copy();
71   Handle(GeomFill_LocationDraft) copy = 
72     new (GeomFill_LocationDraft) (myDir,myAngle);
73   copy->SetCurve(myCurve);
74   copy->SetStopSurf(mySurf);
75   if (WithTrans) copy->SetTrsf(Trans);
76
77   return copy;
78
79
80 //==================================================================
81 //Function: SetTrsf
82 //Purpose :
83 //==================================================================
84  void GeomFill_LocationDraft::SetTrsf(const gp_Mat& Transfo) 
85 {
86   Trans = Transfo;
87   gp_Mat Aux;
88   Aux.SetIdentity();
89   Aux -= Trans;
90   WithTrans = Standard_False; // Au cas ou Trans = I
91   for (Standard_Integer ii=1; ii<=3 && !WithTrans ; ii++)
92     for (Standard_Integer jj=1; jj<=3 && !WithTrans; jj++)
93       if (Abs(Aux.Value(ii, jj)) > 1.e-14)  WithTrans = Standard_True;
94 }
95
96 //==================================================================
97 //Function: SetCurve
98 //Purpose : Calcul des poles sur la surfaces d'arret (intersection 
99 // entre la generatrice et la surface en myNbPts points de la section)
100 //==================================================================
101  void GeomFill_LocationDraft::SetCurve(const Handle(Adaptor3d_HCurve)& C) 
102 {
103   myCurve = C;
104   myTrimmed = C;
105   myLaw->SetCurve(C);
106
107   Prepare(); 
108 }
109
110 //==================================================================
111 //Function: SetStopSurf
112 //Purpose : 
113 //==================================================================
114  void GeomFill_LocationDraft::SetStopSurf(const Handle(Adaptor3d_HSurface)& Surf) 
115 {
116   mySurf = Surf;
117   Prepare();
118 }
119
120 //==================================================================
121 //Function: SetAngle
122 //Purpose : 
123 //==================================================================
124  void GeomFill_LocationDraft::SetAngle(const Standard_Real Angle) 
125 {
126   myAngle = Angle;
127   myLaw->SetAngle(myAngle);
128   Prepare();
129 }
130
131 //==================================================================
132 //Function: Prepare
133 //Purpose : Poses les jalon de l'intersection : depouille / Surface 
134 //==================================================================
135  void GeomFill_LocationDraft::Prepare() 
136 {
137   if (mySurf.IsNull()) {
138     Intersec = Standard_False;
139     return;
140   }
141
142   Intersec = Standard_True;
143
144   Standard_Integer ii,jj; 
145   Standard_Real f, l, t;
146   gp_Pnt P;
147   gp_Vec D,T,N,B; 
148   Handle(Geom_Line) L;
149   IntCurveSurface_IntersectionPoint P1,P2;
150   f = myCurve->FirstParameter();
151   l = myCurve->LastParameter();
152
153   for (ii=1; ii<=myNbPts; ii++) 
154     {
155       t = Standard_Real(myNbPts - ii)*f + Standard_Real(ii - 1)*l;
156       t /= (myNbPts-1);
157   
158       myCurve->D0(t, P);
159       myLaw->D0(t,T,N,B);
160   
161 // Generatrice
162       D = Cos(myAngle)*B + Sin(myAngle)*N; 
163   
164       L = new (Geom_Line) (P, D);
165    
166       IntCurveSurface_HInter Int; // intersection surface / generatrice
167       Handle(GeomAdaptor_HCurve) AC = new (GeomAdaptor_HCurve) (L);
168       Int.Perform(AC, mySurf); // calcul de l'intersection
169
170       if (Int.NbPoints() > 0) // il y a au moins 1 intersection
171         {
172           P1 = Int.Point(1);  // 1er  point d'intersection          
173
174           for (jj=2 ; jj<=Int.NbPoints() ; jj++) 
175             {
176               P2 = Int.Point(jj);
177               if(P1.W() > P2.W()) P1 = P2; // point le plus proche
178             }//for_jj
179    
180           gp_Pnt2d p (P1.W(), t);        // point de la courbe
181           gp_Pnt2d q (P1.U(),P1.V());    // point sur la surface
182           myPoles2d->SetValue(2*ii-1,p); // point de la courbe (indice impair)
183           myPoles2d->SetValue(2*ii,q);   // point sur la surface (indice pair)
184         }
185       else 
186         {// au moins un point ou il n'y a pas intersection
187           Intersec = Standard_False;
188         }
189
190     }//for_ii
191 }
192
193 //==================================================================
194 //Function: GetCurve
195 //Purpose : return the path
196 //==================================================================
197  const Handle(Adaptor3d_HCurve)& GeomFill_LocationDraft::GetCurve() const
198 {
199   return myCurve;
200 }
201
202
203 //==================================================================
204 //Function: D0
205 //Purpose : 
206 //==================================================================
207  Standard_Boolean GeomFill_LocationDraft::D0(const Standard_Real Param, 
208                                              gp_Mat& M,
209                                              gp_Vec& V)
210 {
211   Standard_Boolean Ok;
212   gp_Vec T,N,B;
213   gp_Pnt P;
214
215   myTrimmed->D0(Param, P);
216   V.SetXYZ(P.XYZ());
217  
218   Ok = myLaw->D0(Param, T, N, B);  
219   if (!Ok) return Ok;
220   M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
221
222   if (WithTrans) {
223     M *= Trans;
224   }
225
226   return Standard_True;
227 }
228
229 //==================================================================
230 //Function: D0
231 //Purpose : calcul de l'intersection (C0) sur la surface
232 //================================================================== 
233  Standard_Boolean GeomFill_LocationDraft::D0(const Standard_Real Param, 
234                                              gp_Mat& M,
235                                              gp_Vec& V,
236                                              TColgp_Array1OfPnt2d& Poles2d)
237
238   Standard_Boolean Ok;
239 //  gp_Vec D,T,N,B,DT,DN,DB;
240   gp_Vec D,T,N,B;
241   gp_Pnt P;
242
243   myCurve->D0(Param, P);
244   V.SetXYZ(P.XYZ());
245   Ok = myLaw->D0(Param, T, N, B);
246   if (!Ok) return Ok;
247   M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
248
249   if (WithTrans) {
250     M *= Trans;
251   }
252
253   if (Intersec == Standard_True) {
254     // la generatrice intersecte la surface d'arret
255     // la generatrice  
256     D = Cos(myAngle)*B + Sin(myAngle)*N; 
257     
258     Handle(Geom_Line) L = new (Geom_Line) (P, D);
259     Handle(GeomAdaptor_HCurve) G = new (GeomAdaptor_HCurve) (L); 
260     
261     Standard_Real t1,t2,Paramt1,t2Param;
262     Standard_Real U0=0,V0=0,W0=0;
263     
264     Standard_Integer ii = 1; 
265     
266     // on recherche l'intervalle auquel appartient Param
267       while (ii<2*myNbPts && myPoles2d->Value(ii).Coord(2) < Param) ii=ii+2;
268     
269     if (ii<2*myNbPts && !IsEqual(myPoles2d->Value(ii).Coord(2),Param)) 
270       {
271         
272         // interpolation lineaire pour initialiser le germe de la recherche
273           t1 = myPoles2d->Value(ii).Coord(2);
274           t2 = myPoles2d->Value(ii-2).Coord(2);
275           
276           Paramt1 = (Param-t1) / (t2-t1);
277           t2Param = (t2-Param) / (t2-t1);
278
279           W0 = myPoles2d->Value(ii-2).Coord(1)*Paramt1 
280                         + myPoles2d->Value(ii).Coord(1)*t2Param;
281           U0 = myPoles2d->Value(ii-1).Coord(1)*Paramt1 
282                         + myPoles2d->Value(ii+1).Coord(1)*t2Param;
283           V0 = myPoles2d->Value(ii-1).Coord(2)*Paramt1 
284                         + myPoles2d->Value(ii+1).Coord(2)*t2Param;
285         }//if
286       // on est sur un param ou les points ont deja ete calcules
287       else if (ii<2*myNbPts && IsEqual(myPoles2d->Value(ii).Coord(2) ,Param)) 
288         {
289           W0 = myPoles2d->Value(ii).Coord(1);
290           U0 = myPoles2d->Value(ii+1).Coord(1);
291           V0 = myPoles2d->Value(ii+1).Coord(2); 
292         }//else if
293
294  // recherche de la solution (pt d'intersection generatrice / surface)
295       // point initial
296       math_Vector X(1,3);
297       X(1) = W0;
298       X(2) = U0;
299       X(3) = V0;
300
301       // tolerance sur X
302       math_Vector XTol(1,3);
303       XTol.Init(0.00001);
304
305       // tolerance sur F
306       Standard_Real FTol = 0.0000001;
307       Standard_Integer Iter = 100;
308
309       // fonction dont il faut trouver la racine : G(W)-S(U,V)=0
310       GeomFill_FunctionDraft E(mySurf , G);
311  
312       // resolution
313       math_NewtonFunctionSetRoot Result(E, XTol, FTol, Iter);
314       Result.Perform(E, X);
315
316       if (Result.IsDone()) 
317       {
318         math_Vector R(1,3); 
319         Result.Root(R);    // solution
320
321         gp_Pnt2d p (R(2), R(3));  // point sur la surface
322         gp_Pnt2d q (R(1), Param); // point de la courbe
323         Poles2d.SetValue(1,p);
324         Poles2d.SetValue(2,q);
325       }
326       else {
327         return Standard_False;
328       }
329   }// if_Intersec
330
331   // la generatrice n'intersecte pas la surface d'arret
332   return Standard_True;
333  }
334
335 //==================================================================
336 //Function: D1
337 //Purpose : calcul de l'intersection (C1) sur la surface
338 //================================================================== 
339  Standard_Boolean GeomFill_LocationDraft::D1(const Standard_Real Param,
340                                              gp_Mat& M,
341                                              gp_Vec& V,
342                                              gp_Mat& DM,
343                                              gp_Vec& DV,
344                                              TColgp_Array1OfPnt2d& Poles2d,
345                                              TColgp_Array1OfVec2d& DPoles2d) 
346 {  
347   Standard_Boolean Ok;
348   gp_Vec D,T,N,B,DT,DN,DB;
349   gp_Pnt P;
350
351   myCurve->D1(Param, P, DV);
352   V.SetXYZ(P.XYZ());
353  
354   Ok = myLaw->D1(Param, T, DT, N, DN, B, DB);
355   if (!Ok) return Standard_False;
356
357   M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
358   DM.SetCols(DN.XYZ(), DB.XYZ(), DT.XYZ());
359
360   if (WithTrans) {
361     M *= Trans;
362     DM *= Trans;
363   }
364
365   if (Intersec == Standard_True) 
366     { // la generatrice intersecte la surface d'arret
367       // la generatrice  
368       D = Cos(myAngle)*B + Sin(myAngle)*N; 
369
370       Handle(Geom_Line) L = new (Geom_Line) (P, D);
371       Handle(GeomAdaptor_HCurve) G = new (GeomAdaptor_HCurve) (L); 
372   
373       Standard_Real t1,t2,Paramt1,t2Param;
374       Standard_Real U0=0,V0=0,W0=0;
375
376       Standard_Integer ii = 1; 
377   
378       // recherche de la solution (pt d'intersection  generatrice / surface)
379
380       // on recherche l'intervalle auquel appartient Param
381       while (ii < 2*myNbPts && myPoles2d->Value(ii).Coord(2) < Param) ii=ii+2;
382
383
384       if (ii < 2*myNbPts && !IsEqual(myPoles2d->Value(ii).Coord(2) ,Param)) 
385         {
386           // interpolation lineaire pour initialiser le germe de la recherche
387           t1 = myPoles2d->Value(ii).Coord(2);
388           t2 = myPoles2d->Value(ii-2).Coord(2);
389
390           Paramt1 = (Param-t1) / (t2-t1);
391           t2Param = (t2-Param) / (t2-t1);
392
393           W0 = myPoles2d->Value(ii-2).Coord(1)*Paramt1 
394                        + myPoles2d->Value(ii).Coord(1)*t2Param;
395           U0 = myPoles2d->Value(ii-1).Coord(1)*Paramt1 
396                        + myPoles2d->Value(ii+1).Coord(1)*t2Param;
397           V0 = myPoles2d->Value(ii-1).Coord(2)*Paramt1 
398                        + myPoles2d->Value(ii+1).Coord(2)*t2Param;
399         }//if
400       else if (ii<2*myNbPts && IsEqual(myPoles2d->Value(ii).Coord(2) ,Param)) 
401         {
402           W0 = myPoles2d->Value(ii).Coord(1);
403           U0 = myPoles2d->Value(ii+1).Coord(1);
404           V0 = myPoles2d->Value(ii+1).Coord(2); 
405         }//else if
406
407       // germe
408       math_Vector X(1,3);
409       X(1) = W0;
410       X(2) = U0;
411       X(3) = V0;
412
413       // tolerance sur X
414       math_Vector XTol(1,3);
415       XTol.Init(0.0001);
416
417       // tolerance sur F
418       Standard_Real FTol = 0.000001;
419       Standard_Integer Iter = 100;
420
421
422       // fonction dont il faut trouver la racine : G(W)-S(U,V)=0
423       GeomFill_FunctionDraft E(mySurf,G);
424
425  
426       // resolution
427       math_NewtonFunctionSetRoot Result(E, XTol, FTol, Iter);
428       Result.Perform(E, X);
429
430       if (Result.IsDone()) 
431       {
432         math_Vector R(1,3); 
433         Result.Root(R);    // solution
434
435         gp_Pnt2d p (R(2), R(3));  // point sur la surface
436         gp_Pnt2d q (R(1), Param); // point de la courbe
437         Poles2d.SetValue(1,p);
438         Poles2d.SetValue(2,q);
439
440         // derivee de la fonction par rapport a Param
441         math_Vector DEDT(1,3,0);
442         E.DerivT(myTrimmed, Param, R(1), DN, myAngle, DEDT); // dE/dt => DEDT
443
444         math_Vector DSDT (1,3,0);
445         math_Matrix DEDX (1,3,1,3,0);
446         E.Derivatives(R, DEDX);  // dE/dx au point R => DEDX
447
448         // resolution du syst. lin. : DEDX*DSDT = -DEDT
449         math_Gauss Ga(DEDX);
450         if (Ga.IsDone()) 
451         {
452           Ga.Solve (DEDT.Opposite(), DSDT); // resolution du syst. lin. 
453           gp_Vec2d dp (DSDT(2), DSDT(3));    // surface
454           gp_Vec2d dq (DSDT(1), 1);          //  courbe
455           DPoles2d.SetValue(1, dp);
456           DPoles2d.SetValue(2, dq);
457         }//if
458
459
460       }//if_Result
461       else {// la generatrice n'intersecte pas la surface d'arret
462         return Standard_False;
463       }    
464   }// if_Intersec
465   return Standard_True;
466 }
467
468 //==================================================================
469 //Function: D2
470 //Purpose : calcul de l'intersection (C2) sur la surface
471 //==================================================================
472  Standard_Boolean GeomFill_LocationDraft::D2(const Standard_Real Param,
473                                              gp_Mat& M,
474                                              gp_Vec& V,
475                                              gp_Mat& DM,
476                                              gp_Vec& DV, 
477                                              gp_Mat& D2M,
478                                              gp_Vec& D2V,
479                                              TColgp_Array1OfPnt2d& Poles2d,
480                                              TColgp_Array1OfVec2d& DPoles2d,
481                                              TColgp_Array1OfVec2d& D2Poles2d) 
482 {
483   Standard_Boolean Ok;
484   gp_Vec D,T,N,B,DT,DN,DB,D2T,D2N,D2B;
485   gp_Pnt P;
486
487   myCurve->D2(Param, P, DV, D2V);
488   V.SetXYZ(P.XYZ());
489  
490   Ok = myLaw->D2(Param, T, DT, D2T, N, DN, D2N, B, DB, D2B);
491   if (!Ok) return Ok;
492
493   M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
494   DM.SetCols(DN.XYZ(), DB.XYZ(), DT.XYZ());
495   D2M.SetCols(D2N.XYZ(), D2B.XYZ(), D2T.XYZ());
496
497   if (WithTrans) {
498     M *= Trans;
499     DM *= Trans;
500     D2M *= Trans;
501   }
502   if (Intersec == Standard_True) 
503     {// la generatrice intersecte la surface d'arret
504
505       // la generatrice  
506       D = Cos(myAngle) * B + Sin(myAngle) * N; 
507
508       Handle(Geom_Line) L = new (Geom_Line) (P, D);
509       Handle(GeomAdaptor_HCurve) G = new (GeomAdaptor_HCurve) (L); 
510   
511       Standard_Real t1,t2,Paramt1,t2Param;
512       Standard_Real U0=0,V0=0,W0=0;
513   
514       Standard_Integer ii = 1; 
515
516       // on recherche l'intervalle auquel appartient Param
517       while (ii<2*myNbPts && myPoles2d->Value(ii).Coord(2) < Param) ii=ii+2;
518
519       if (ii<2*myNbPts && !IsEqual(myPoles2d->Value(ii).Coord(2) ,Param)) 
520         {
521
522           // interpolation lineaire pour initialiser le germe de la recherche
523           t1 = myPoles2d->Value(ii).Coord(2);
524           t2 = myPoles2d->Value(ii-2).Coord(2);
525
526           Paramt1 = (Param-t1) / (t2-t1);
527           t2Param = (t2-Param) / (t2-t1);
528
529           W0 = myPoles2d->Value(ii-2).Coord(1)*Paramt1 + 
530             myPoles2d->Value(ii).Coord(1)*t2Param;
531           U0 = myPoles2d->Value(ii-1).Coord(1)*Paramt1 + 
532             myPoles2d->Value(ii+1).Coord(1)*t2Param;
533           V0 = myPoles2d->Value(ii-1).Coord(2)*Paramt1 + 
534             myPoles2d->Value(ii+1).Coord(2)*t2Param;
535         }//if
536       else if (ii<2*myNbPts  && IsEqual(myPoles2d->Value(ii).Coord(2) ,Param)) 
537         {
538           W0 = myPoles2d->Value(ii).Coord(1);
539           U0 = myPoles2d->Value(ii+1).Coord(1);
540           V0 = myPoles2d->Value(ii+1).Coord(2); 
541         }//else if
542
543 // recherche de la solution (pt d'intersection generatrice / surface)
544       // germe
545       math_Vector X(1,3);
546       X(1) = W0;
547       X(2) = U0;
548       X(3) = V0;
549
550       // tolerance sur X
551       math_Vector XTol(1,3);
552       XTol.Init(0.0001);
553
554       // tolerance sur F
555       Standard_Real FTol = 0.000001;
556       Standard_Integer Iter = 150;
557
558
559       // fonction dont il faut trouver la racine : G(W)-S(U,V)=0
560       GeomFill_FunctionDraft E(mySurf,G);
561
562  
563       // resolution
564       math_NewtonFunctionSetRoot Result (E, XTol, FTol, Iter);
565       Result.Perform(E, X);
566
567       if (Result.IsDone()) 
568         {
569           math_Vector R(1,3); 
570           Result.Root(R);    // solution
571   
572           // solution
573           gp_Pnt2d p (R(2), R(3));  // point sur la surface
574           gp_Pnt2d q (R(1), Param); // point de la courbe
575           Poles2d.SetValue(1,p);
576           Poles2d.SetValue(2,q);
577
578
579      // premiere derivee de la fonction
580           math_Vector DEDT(1,3,0);
581           E.DerivT(myTrimmed, Param, R(1), DN, myAngle, DEDT); // dE/dt => DEDT
582
583           math_Vector DSDT (1,3,0);
584           math_Matrix DEDX (1,3,1,3,0);
585           E.Derivatives(R, DEDX);  // dE/dx => DEDX
586  
587           // resolution du syst. lin.
588           math_Gauss Ga (DEDX);
589           if (Ga.IsDone()) 
590             {
591               Ga.Solve (DEDT.Opposite(), DSDT); 
592               gp_Vec2d dp (DSDT(2), DSDT(3));   // surface
593               gp_Vec2d dq (DSDT(1), 1);         //  courbe
594               DPoles2d.SetValue(1, dp);
595               DPoles2d.SetValue(2, dq);
596             }//if
597
598
599      // deuxieme derivee
600           GeomFill_Tensor D2EDX2(3,3,3);
601           E.Deriv2X(R, D2EDX2); // d2E/dx2
602
603           math_Vector D2EDT2(1,3,0);
604           E.Deriv2T(myTrimmed, Param, R(1), D2N, myAngle ,D2EDT2); // d2E/dt2
605
606           math_Matrix D2EDTDX(1,3,1,3,0);
607           E.DerivTX(DN, myAngle, D2EDTDX); // d2E/dtdx
608
609           math_Vector D2SDT2(1,3,0); // d2s/dt2
610           math_Matrix T(1,3,1,3,0);
611           D2EDX2.Multiply(DSDT,T);
612    
613           // resolution du syst. lin. 
614           math_Gauss Ga1 (DEDX);
615           if (Ga1.IsDone()) 
616             {
617               Ga1.Solve ( -T*DSDT - 2*D2EDTDX*DSDT - D2EDT2 , D2SDT2); 
618               gp_Vec2d d2p (D2SDT2(2), D2SDT2(3));  // surface
619               gp_Vec2d d2q (D2SDT2(1), 0);          // courbe
620               D2Poles2d.SetValue(1, d2p);
621               D2Poles2d.SetValue(2, d2q);
622             }//if
623           else {// la generatrice n'intersecte pas la surface d'arret
624             return Standard_False;
625           }
626         }//if_Result
627     } //if_Intersec
628
629   return Standard_True; 
630 }
631
632 //==================================================================
633 //Function : HasFirstRestriction
634 //Purpose :
635 //==================================================================
636  Standard_Boolean GeomFill_LocationDraft::HasFirstRestriction() const
637 {
638   return Standard_False;
639 }
640
641 //==================================================================
642 //Function : HasLastRestriction
643 //Purpose :
644 //==================================================================
645  Standard_Boolean GeomFill_LocationDraft::HasLastRestriction() const
646 {
647  
648   if (Intersec == Standard_True) return Standard_True;
649   else return Standard_False;
650 }
651
652 //==================================================================
653 //Function : TraceNumber
654 //Purpose :
655 //==================================================================
656  Standard_Integer GeomFill_LocationDraft::TraceNumber() const
657 {
658   if (Intersec == Standard_True) return 1;
659   else return 0;
660 }
661
662 //==================================================================
663 //Function:NbIntervals
664 //Purpose :
665 //==================================================================
666  Standard_Integer GeomFill_LocationDraft::NbIntervals
667  (const GeomAbs_Shape S) const
668 {
669   return myLaw->NbIntervals(S);
670 }
671
672 //==================================================================
673 //Function:Intervals
674 //Purpose :
675 //==================================================================
676  void GeomFill_LocationDraft::Intervals(TColStd_Array1OfReal& T,
677                                         const GeomAbs_Shape S) const
678 {
679   myLaw->Intervals(T, S);
680 }
681
682 //==================================================================
683 //Function:SetInterval
684 //Purpose :
685 //==================================================================
686  void GeomFill_LocationDraft::SetInterval(const Standard_Real First,
687                                           const Standard_Real Last) 
688 {
689   myLaw->SetInterval( First, Last);
690   myTrimmed = myCurve->Trim( First, Last, 0);
691 }
692 //==================================================================
693 //Function: GetInterval
694 //Purpose :
695 //==================================================================
696  void GeomFill_LocationDraft::GetInterval(Standard_Real& First,
697                                           Standard_Real& Last) const
698 {
699   First = myTrimmed->FirstParameter();
700   Last = myTrimmed->LastParameter();
701 }
702
703 //==================================================================
704 //Function: GetDomain
705 //Purpose :
706 //==================================================================
707  void GeomFill_LocationDraft::GetDomain(Standard_Real& First,
708                                         Standard_Real& Last) const
709 {
710   First = myCurve->FirstParameter();
711   Last = myCurve->LastParameter();
712 }
713
714 //==================================================================
715 //function : Resolution
716 //purpose  : 
717 //==================================================================
718 void GeomFill_LocationDraft::Resolution (const Standard_Integer Index,
719                                          const Standard_Real Tol,
720                                          Standard_Real& TolU, 
721                                          Standard_Real& TolV) const
722                                    
723 {
724   if (Index==1) {
725       TolU = mySurf->UResolution(Tol);
726       TolV = mySurf->VResolution(Tol);
727     }
728   else {
729       TolU = Tol;
730       TolV = Tol;
731     }
732 }
733
734 //==================================================================
735 //Function:GetMaximalNorm
736 //Purpose :  On suppose les triedres normes => return 1
737 //==================================================================
738  Standard_Real GeomFill_LocationDraft::GetMaximalNorm() 
739 {
740   return 1.;
741 }
742
743 //==================================================================
744 //Function:GetAverageLaw
745 //Purpose :
746 //==================================================================
747  void GeomFill_LocationDraft::GetAverageLaw(gp_Mat& AM,
748                                             gp_Vec& AV) 
749 {
750   Standard_Integer ii;
751   Standard_Real U, delta;
752   gp_Vec V1,V2,V3, V;
753   
754   myLaw->GetAverageLaw(V1, V2, V3);
755   AM.SetCols(V1.XYZ(), V2.XYZ(), V3.XYZ());
756
757   AV.SetCoord(0., 0., 0.);
758   delta = (myTrimmed->LastParameter() - myTrimmed->FirstParameter())/10;
759   U=  myTrimmed->FirstParameter(); 
760   for (ii=0; ii<=10; ii++, U+=delta) {
761     V.SetXYZ( myTrimmed->Value(U).XYZ() );
762     AV += V;
763   }
764   AV /= 11;   
765 }
766
767 //==================================================================
768 //Function : IsTranslation
769 //Purpose : 
770 //==================================================================
771 // Standard_Boolean GeomFill_LocationDraft::IsTranslation(Standard_Real& Error) const
772  Standard_Boolean GeomFill_LocationDraft::IsTranslation(Standard_Real& ) const
773 {
774   return myLaw->IsConstant();
775 }
776
777 //==================================================================
778 //Function : IsRotation
779 //Purpose : 
780 //==================================================================
781  Standard_Boolean GeomFill_LocationDraft::IsRotation(Standard_Real& Error)  const
782 {
783   GeomAbs_CurveType Type;
784   Error = 0;
785   Type = myCurve->GetType();
786   if (Type == GeomAbs_Circle) {
787     return myLaw->IsOnlyBy3dCurve();
788   }
789   return Standard_False;
790 }
791
792 //==================================================================
793 //Function : Rotation
794 //Purpose : 
795 //==================================================================
796  void GeomFill_LocationDraft::Rotation(gp_Pnt& Centre)  const
797 {
798   Centre =  myCurve->Circle().Location();
799 }
800
801
802 //==================================================================
803 //Function : IsIntersec
804 //Purpose : 
805 //==================================================================
806  Standard_Boolean GeomFill_LocationDraft::IsIntersec()  const
807 {
808  return Intersec;
809 }
810
811
812 //==================================================================
813 //Function : Direction
814 //Purpose : 
815 //==================================================================
816  gp_Dir GeomFill_LocationDraft::Direction()  const
817 {
818  return myDir;
819 }