e50176204f954817c027d003bd1d548d0dbf5985
[occt.git] / src / ChFi3d / ChFi3d_ChBuilder.cxx
1 // Created on: 1995-04-26
2 // Created by: Flore Lantheaume
3 // Copyright (c) 1995-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
18 #include <Adaptor3d_TopolTool.hxx>
19 #include <Blend_Point.hxx>
20 #include <BlendFunc_SectionShape.hxx>
21 #include <BRepAdaptor_Curve2d.hxx>
22 #include <BRepAdaptor_HCurve2d.hxx>
23 #include <BRepAdaptor_HSurface.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25 #include <BRepBlend_Chamfer.hxx>
26 #include <BRepBlend_ChamfInv.hxx>
27 #include <BRepBlend_ChAsym.hxx>
28 #include <BRepBlend_ChAsymInv.hxx>
29 #include <BRepBlend_Line.hxx>
30 #include <BRepBlend_Walking.hxx>
31 #include <BRepTools.hxx>
32 #include <ChFi3d.hxx>
33 #include <ChFi3d_Builder_0.hxx>
34 #include <ChFi3d_ChBuilder.hxx>
35 #include <ChFiDS_ChamfSpine.hxx>
36 #include <ChFiDS_CircSection.hxx>
37 #include <ChFiDS_HData.hxx>
38 #include <ChFiDS_HElSpine.hxx>
39 #include <ChFiDS_ListIteratorOfListOfStripe.hxx>
40 #include <ChFiDS_ListIteratorOfRegularities.hxx>
41 #include <ChFiDS_ListOfStripe.hxx>
42 #include <ChFiDS_Regul.hxx>
43 #include <ChFiDS_SecHArray1.hxx>
44 #include <ChFiDS_Spine.hxx>
45 #include <ChFiDS_Stripe.hxx>
46 #include <ChFiDS_SurfData.hxx>
47 #include <ElSLib.hxx>
48 #include <Extrema_GenLocateExtPS.hxx>
49 #include <GeomAdaptor_HCurve.hxx>
50 #include <Standard_ConstructionError.hxx>
51 #include <Standard_DomainError.hxx>
52 #include <Standard_NotImplemented.hxx>
53 #include <TopAbs.hxx>
54 #include <TopoDS_Edge.hxx>
55 #include <TopoDS_Face.hxx>
56 #include <TopoDS_Shape.hxx>
57 #include <TopoDS_Vertex.hxx>
58 #include <TopOpeBRepBuild_HBuilder.hxx>
59 #include <TopOpeBRepDS_HDataStructure.hxx>
60 #include <TopTools_ListIteratorOfListOfShape.hxx>
61
62 #ifdef OCCT_DEBUG
63 extern Standard_Boolean ChFi3d_GettraceCHRON();
64 #endif
65
66 //=======================================================================
67 //function : SearchCommonFaces
68 //purpose  : search the 2 common faces <F1> and <F2> of the edge <E>
69 //           uses the EFMap and take the 2 first good faces 
70 //=======================================================================
71
72 void SearchCommonFaces(const ChFiDS_Map& EFMap, 
73                        const TopoDS_Edge& E,
74                        TopoDS_Face& F1,
75                        TopoDS_Face& F2)
76 {
77   TopoDS_Face Fc;
78   TopTools_ListIteratorOfListOfShape It;
79   
80   F1.Nullify();
81   F2.Nullify();
82   for ( It.Initialize(EFMap(E)); It.More(); It.Next() ) {
83     Fc = TopoDS::Face(It.Value());
84     if ( F1.IsNull() )
85       F1 = Fc;
86     else if ( !Fc.IsSame(F1) ) {
87       F2 = Fc;
88       break;
89     }
90   }
91
92   if (!F1.IsNull() && F2.IsNull() && BRepTools::IsReallyClosed( E, F1 ))
93     F2 = F1;
94 }
95
96 //=======================================================================
97 //function : ExtentSpinesOnCommonFace
98 //purpose  : Extend spines of two chamfers by distance dis1,dis2
99 //           on their common face
100 //           Two guide lines Spine1 and Spine2 cross in V
101 //           isfirst(i) = False if Spine(i) is oriented to V (i = 1,2)
102 //=======================================================================
103
104 void ExtentSpineOnCommonFace(Handle(ChFiDS_Spine)&  Spine1,
105                              Handle(ChFiDS_Spine)&  Spine2,
106                              const TopoDS_Vertex&   V,
107                              const Standard_Real    dis1,
108                              const Standard_Real    dis2,
109                              const Standard_Boolean isfirst1,
110                              const Standard_Boolean isfirst2)
111 {                 
112   Standard_Real tolesp = 1.e-7;
113
114     // alpha, the opening angle between two 
115     // tangents of two guidelines in V is found
116     Standard_Real tga1,tga2;
117     Standard_Real d1plus = 0., d2plus = 0.;
118
119     gp_Pnt tmp;
120     gp_Vec tg1, tg2;
121     Spine1->D1(Spine1->Absc(V),tmp,tg1);
122     Spine2->D1(Spine2->Absc(V),tmp,tg2);
123     tg1.Normalize();
124     tg2.Normalize();
125     if (isfirst1)  
126       tg1.Reverse();
127     if (isfirst2)  
128       tg2.Reverse();
129
130     Standard_Real cosalpha,sinalpha;   
131     cosalpha = tg1.Dot(tg2);
132     sinalpha = sqrt(1-cosalpha*cosalpha);
133     
134     //a1+a2 = alpha
135     Standard_Real temp;
136     temp = cosalpha+dis2/dis1;
137     if( Abs(temp) > tolesp ){
138       tga1 = sinalpha/temp;
139       d1plus = dis1/tga1;
140     }
141     temp = cosalpha+dis1/dis2;
142     if( Abs(temp) > tolesp ){
143       tga2 = sinalpha/temp;
144       d2plus = dis2/tga2;
145     }
146
147     //extension by the calculated distance
148     if (d1plus > 0.) {
149       d1plus *= 3.;
150       if (isfirst1){
151         Spine1->SetFirstParameter(-d1plus);
152         Spine1->SetFirstTgt(0.);
153       }
154       else{
155         Standard_Real param = Spine1->LastParameter(Spine1->NbEdges());
156         Spine1->SetLastParameter(d1plus+param);
157         Spine1->SetLastTgt(param);
158       }
159     }
160     if (d2plus > 0.) {
161       d2plus *= 1.5;
162       if (isfirst2){
163         Spine2->SetFirstParameter(-d2plus);
164         Spine2->SetFirstTgt(0.);
165       }
166       else{
167         Standard_Real param = Spine2->LastParameter(Spine2->NbEdges());
168         Spine2->SetLastParameter(d2plus+param);
169         Spine2->SetLastTgt(param);
170       }
171     }
172 }
173
174 //=======================================================================
175 //function : ChFi3d_ChBuilder
176 //purpose  : 
177 //=======================================================================
178
179 ChFi3d_ChBuilder::ChFi3d_ChBuilder(const TopoDS_Shape& S,
180                                    const Standard_Real Ta) : 
181                                           ChFi3d_Builder(S, Ta)
182 {
183 }
184
185
186 //=======================================================================
187 //function : Add
188 //purpose  : create a new stripe with a spine containing the edge <E>
189 //           add on the spine the tangential edges to <E>
190 //=======================================================================
191
192 void  ChFi3d_ChBuilder::Add(const TopoDS_Edge& E)
193 {
194
195   if(!Contains(E) && myEFMap.Contains(E)){
196     Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe();
197     Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine();
198     Sp = new ChFiDS_ChamfSpine(tolesp);
199     Handle(ChFiDS_ChamfSpine) Spine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp);
200
201     TopoDS_Edge E_wnt = E;
202     E_wnt.Orientation(TopAbs_FORWARD);
203     Spine->SetEdges(E_wnt);
204     if(PerformElement(Spine)){
205       PerformExtremity(Spine);
206       Spine->Load();
207       myListStripe.Append(Stripe);
208     }
209   }
210 }
211
212
213 //=======================================================================
214 //function : Add
215 //purpose  : create a new stripe with a ChamfSpine containing the edge <E>
216 //           with the distance <Dis>   on the face <F> 
217 //           . Add the tangential edges continuous to E in the spine
218 //           
219 //=======================================================================
220
221 void  ChFi3d_ChBuilder::Add(const Standard_Real Dis,
222                             const TopoDS_Edge& E,
223                             const TopoDS_Face& F)
224 {
225   if (!Contains(E)  && myEFMap.Contains(E)) {
226      
227     // Take the 2 common faces of the egde <E>
228     TopoDS_Face F1,F2;
229     SearchCommonFaces(myEFMap,E,F1,F2);
230
231     if (! F1.IsSame(F) && F2.IsSame(F) ) {
232       F2 = F1;
233       F1 = F;
234     }
235
236     if ( F1.IsSame(F)) {
237       TopoDS_Edge E_wnt = E;
238       E_wnt.Orientation(TopAbs_FORWARD);
239       BRepAdaptor_Surface Sb1,Sb2;
240       Sb1.Initialize(F1);
241       Sb2.Initialize(F2);
242       TopAbs_Orientation Or1,Or2;
243       ChFi3d::ConcaveSide(Sb1,Sb2,E_wnt,Or1,Or2); 
244       Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe();
245       Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine();
246       Sp = new ChFiDS_ChamfSpine(tolesp);
247       Handle(ChFiDS_ChamfSpine) 
248         Spine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp);
249
250       Spine->SetEdges(E_wnt);
251       if(PerformElement(Spine)){
252         Spine->Load();
253         myListStripe.Append(Stripe);
254         
255         Spine->SetDist(Dis);
256
257         PerformExtremity(Spine);
258       }
259     }
260   }
261 }
262
263
264 //=======================================================================
265 //function : SetDist
266 //purpose  : set the distances <Dis>of the contour of 
267 //           index IC
268 //=======================================================================
269
270 void  ChFi3d_ChBuilder::SetDist(const Standard_Real    Dis,
271                                 const Standard_Integer IC,
272                                 const TopoDS_Face&     F)
273 {
274
275   if(IC <= NbElements()) {
276     Handle(ChFiDS_ChamfSpine) csp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC));
277
278     // Search the first edge which has a common face equal to F
279     TopoDS_Face F1,F2,FirstF1,FirstF2;
280     //TopAbs_Orientation Or1,Or2;
281     //Standard_Integer Choix, ChoixConge;
282     BRepAdaptor_Surface Sb1,Sb2;
283     Standard_Integer i = 1;
284     Standard_Boolean Found = Standard_False;
285     while ( (i <= csp->NbEdges()) && (!Found) ) {
286       SearchCommonFaces(myEFMap,csp->Edges(i),F1,F2);
287       if ( i == 1) {
288         FirstF1 = F1;
289         FirstF2 = F2;
290       }
291       Found = ( F1.IsSame(F) || F2.IsSame(F) );
292       i++;
293     }
294
295     if (Found) {
296       if ( F2.IsSame(F) ) {
297         F2 = F1;
298         F1 = F;
299       }
300       csp->SetDist(Dis);
301
302     }
303     else
304       Standard_DomainError::Raise("the face is not common to any of edges of the contour");
305
306   }
307 }
308
309
310 //=======================================================================
311 //function : GetDist
312 //purpose  : 
313 //=======================================================================
314
315 void ChFi3d_ChBuilder::GetDist(const Standard_Integer  IC,
316                                Standard_Real&          Dis) const
317 {
318     Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC));
319     chsp->GetDist(Dis);
320
321 }
322
323
324 //=======================================================================
325 //function : Add
326 //purpose  : create a new stripe with a ChAsymSpine containing the edge <E>
327 //           with the distance <Dis> and the angle Angle  on the face <F> 
328 //           . Add the tangential edges continuous to E in the spine
329 //           
330 //=======================================================================
331
332 void  ChFi3d_ChBuilder::Add(const Standard_Real Dis1,
333                             const Standard_Real Dis2,
334                             const TopoDS_Edge& E,
335                             const TopoDS_Face& F)
336 {
337   if (!Contains(E)  && myEFMap.Contains(E)) {
338      
339     // Take the 2 common faces of the egde <E>
340     TopoDS_Face F1,F2;
341     SearchCommonFaces(myEFMap,E,F1,F2);
342
343     if (! F1.IsSame(F) && F2.IsSame(F) ) {
344       F2 = F1;
345       F1 = F;
346     }
347
348     if ( F1.IsSame(F)) {
349       TopoDS_Edge E_wnt = E;
350       E_wnt.Orientation(TopAbs_FORWARD);
351       BRepAdaptor_Surface Sb1,Sb2;
352       Sb1.Initialize(F1);
353       Sb2.Initialize(F2);
354       TopAbs_Orientation Or1,Or2;
355       Standard_Integer Choix = ChFi3d::ConcaveSide(Sb1,Sb2,E_wnt,Or1,Or2); 
356
357       Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe();
358       Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine();
359       Sp = new ChFiDS_ChamfSpine(tolesp);
360       Handle(ChFiDS_ChamfSpine) 
361         Spine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp);
362
363       Spine->SetEdges(E_wnt);
364       if(PerformElement(Spine)){
365         Spine->Load();
366         myListStripe.Append(Stripe);
367         
368         Standard_Integer ChoixConge;
369         SearchCommonFaces(myEFMap,Spine->Edges(1),F1,F2);
370         Sb1.Initialize(F1);
371         Sb2.Initialize(F2);
372         ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2,
373                                          Spine->Edges(1),
374                                          Or1,Or2);
375
376
377         // compare the 2 computed choices to know how to set the 
378         // distances of the Spine according to the choice done 
379         // on the added edge <e>
380         if ( ChoixConge%2 != Choix%2 )
381           Spine->SetDists(Dis2, Dis1);
382         else Spine->SetDists(Dis1, Dis2);
383
384         PerformExtremity(Spine);
385       }
386     }
387   }
388 }
389
390
391 //=======================================================================
392 //function : SetDists
393 //purpose  : set the distances <Dis1> and <Dis2> of the contour of 
394 //           index IC
395 //=======================================================================
396
397 void  ChFi3d_ChBuilder::SetDists(const Standard_Real    Dis1,
398                                  const Standard_Real    Dis2,
399                                  const Standard_Integer IC,
400                                  const TopoDS_Face&     F)
401 {
402
403   if(IC <= NbElements()) {
404     Handle(ChFiDS_ChamfSpine) csp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC));
405
406     // Search the first edge which has a common face equal to F
407     TopoDS_Face F1,F2,FirstF1,FirstF2;
408     TopAbs_Orientation Or1,Or2;
409     Standard_Integer Choix, ChoixConge;
410     BRepAdaptor_Surface Sb1,Sb2;
411     Standard_Integer i = 1;
412     Standard_Boolean Found = Standard_False;
413     while ( (i <= csp->NbEdges()) && (!Found) ) {
414       SearchCommonFaces(myEFMap,csp->Edges(i),F1,F2);
415       if ( i == 1) {
416         FirstF1 = F1;
417         FirstF2 = F2;
418       }
419       Found = ( F1.IsSame(F) || F2.IsSame(F) );
420       i++;
421     }
422
423     if (Found) {
424       if ( F2.IsSame(F) ) {
425         F2 = F1;
426         F1 = F;
427       }
428       Sb1.Initialize(F1);
429       Sb2.Initialize(F2);
430       Choix = ChFi3d::ConcaveSide(Sb1,Sb2,
431                                   csp->Edges(i-1),
432                                   Or1,Or2);
433       Sb1.Initialize(FirstF1);
434       Sb2.Initialize(FirstF2);
435       ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2,
436                                        csp->Edges(1),
437                                        Or1,Or2);
438       if ( ChoixConge%2 != Choix%2 )
439         csp->SetDists(Dis2,Dis1);
440       else csp->SetDists(Dis1,Dis2);
441     }
442     else
443       Standard_DomainError::Raise("the face is not common to any of edges of the contour");
444
445   }
446 }
447
448
449 //=======================================================================
450 //function : Dists
451 //purpose  : 
452 //=======================================================================
453
454 void ChFi3d_ChBuilder::Dists(const Standard_Integer  IC,
455                              Standard_Real&          dis1,
456                              Standard_Real&          dis2) const
457 {
458     Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC));
459     Standard_Real temp1, temp2;
460     chsp->Dists(temp1,temp2);
461     dis1 = temp1;
462     dis2 = temp2;
463 }
464
465
466 //=======================================================================
467 //function : Add
468 //purpose  : create a new stripe with a ChAsymSpine containing the edge <E>
469 //           with the distance <Dis> and the angle Angle  on the face <F> 
470 //           . Add the tangential edges continuous to E in the spine
471 //           
472 //=======================================================================
473
474 void  ChFi3d_ChBuilder::AddDA(const Standard_Real Dis1,
475                               const Standard_Real Angle,
476                               const TopoDS_Edge& E,
477                               const TopoDS_Face& F)
478 {
479   if (!Contains(E)  && myEFMap.Contains(E)) {
480      
481     // Take the 2 common faces of the egde <E>
482     TopoDS_Face F1,F2;
483     SearchCommonFaces(myEFMap,E,F1,F2);
484  
485     if (! F1.IsSame(F) && F2.IsSame(F) ) {
486       F2 = F1;
487       F1 = F;
488     }
489
490     if ( F1.IsSame(F)) {
491       TopoDS_Edge E_wnt = E;
492       E_wnt.Orientation(TopAbs_FORWARD);
493       BRepAdaptor_Surface Sb1,Sb2;
494       Sb1.Initialize(F1);
495       Sb2.Initialize(F2);
496       TopAbs_Orientation Or1,Or2;
497       Standard_Integer Choix = ChFi3d::ConcaveSide(Sb1,Sb2,E_wnt,Or1,Or2); 
498
499       Handle(ChFiDS_Stripe) Stripe = new ChFiDS_Stripe();
500       Handle(ChFiDS_Spine)& Sp = Stripe->ChangeSpine();
501       Sp = new ChFiDS_ChamfSpine(tolesp);
502       Handle(ChFiDS_ChamfSpine) 
503         Spine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp);
504
505       Spine->SetEdges(E_wnt);
506       if(PerformElement(Spine)){
507         Spine->Load();
508         myListStripe.Append(Stripe);
509         
510         Standard_Integer ChoixConge;
511         SearchCommonFaces(myEFMap,Spine->Edges(1),F1,F2);
512         Sb1.Initialize(F1);
513         Sb2.Initialize(F2);
514         ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2,
515                                          Spine->Edges(1),
516                                          Or1,Or2);
517
518         // compare the 2 computed choices to know how to set the 
519         // distances of the Spine according to the choice done 
520         // on the added edge <e>
521         if ( ChoixConge%2 != Choix%2 ) {
522           Spine->SetDistAngle(Dis1, Angle, Standard_False);
523         }
524         else { 
525           Spine->SetDistAngle(Dis1, Angle, Standard_True);
526         }
527         
528         PerformExtremity(Spine);
529       }
530     }
531   }
532 }
533
534
535 //=======================================================================
536 //function : SetDistAngle
537 //purpose  : set the distances <Dis> and <Angle> of the contour of 
538 //           index IC
539 //=======================================================================
540
541 void  ChFi3d_ChBuilder::SetDistAngle(const Standard_Real    Dis,
542                                      const Standard_Real    Angle,
543                                      const Standard_Integer IC,
544                                      const TopoDS_Face&     F)
545 {
546
547   if(IC <= NbElements()) {
548     Handle(ChFiDS_ChamfSpine) csp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC));
549
550     // Search the first edge which has a common face equal to F
551     TopoDS_Face F1,F2,FirstF1,FirstF2;
552     TopAbs_Orientation Or1,Or2;
553     Standard_Integer Choix, ChoixConge;
554     BRepAdaptor_Surface Sb1,Sb2;
555     Standard_Integer i = 1;
556     Standard_Boolean Found = Standard_False;
557 //    Standard_Boolean DisOnF1 = Standard_True;
558
559     while ( (i <= csp->NbEdges()) && (!Found) ) {
560       SearchCommonFaces(myEFMap,csp->Edges(i),F1,F2);
561       if ( i == 1) {
562         FirstF1 = F1;
563         FirstF2 = F2;
564       }
565       Found = ( F1.IsSame(F) || F2.IsSame(F) );
566       i++;
567     }
568
569     if (Found) {
570       if ( F2.IsSame(F) ) {
571         F2 = F1;
572         F1 = F;
573       }
574       Sb1.Initialize(F1);
575       Sb2.Initialize(F2);
576       Choix = ChFi3d::ConcaveSide(Sb1,Sb2,
577                                   csp->Edges(i-1),
578                                   Or1,Or2);
579       Sb1.Initialize(FirstF1);
580       Sb2.Initialize(FirstF2);
581       ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2,
582                                        csp->Edges(1),
583                                        Or1,Or2);
584       if ( ChoixConge%2 != Choix%2 ) {
585         csp->SetDistAngle(Dis, Angle, Standard_False);
586       }
587       else {
588         csp->SetDistAngle(Dis, Angle, Standard_True);
589       }
590     }
591     else
592       Standard_DomainError::Raise("the face is not common to any edges of the contour");
593
594   }
595 }
596
597
598 //=======================================================================
599 //function : GetDistAngle
600 //purpose  : 
601 //=======================================================================
602
603 void ChFi3d_ChBuilder::GetDistAngle(const Standard_Integer  IC,
604                                     Standard_Real&          Dis,
605                                     Standard_Real&          Angle,
606                                     Standard_Boolean&       DisOnFace1) const
607 {
608     Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC));
609
610     chsp->GetDistAngle(Dis, Angle, DisOnFace1);
611 }
612
613 //=======================================================================
614 //function : IsChamfer
615 //purpose  : 
616 //=======================================================================
617 ChFiDS_ChamfMethod ChFi3d_ChBuilder::IsChamfer(const Standard_Integer  IC) const
618 {
619   Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC));
620     
621   ChFiDS_ChamfMethod ret = chsp->IsChamfer();
622
623   return ret;
624
625 }
626
627 //=======================================================================
628 //function : ResetContour
629 //purpose  : 
630 //=======================================================================
631
632 void  ChFi3d_ChBuilder::ResetContour(const Standard_Integer IC)
633 {
634   if(IC <= NbElements()) {
635     Handle(ChFiDS_ChamfSpine) chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Value(IC));
636     chsp->Reset(Standard_True);
637   }
638 }
639
640 //--------------------------------AJOUT----------------------------------
641 //=======================================================================
642 //function : Simulate
643 //purpose  : 
644 //=======================================================================
645
646 void ChFi3d_ChBuilder::Simulate (const Standard_Integer IC)
647 {
648 #ifdef OCCT_DEBUG
649   if(ChFi3d_GettraceCHRON()){
650     simul.Reset();elspine.Reset();chemine.Reset();
651     simul.Start();
652   }
653 #endif
654   ChFiDS_ListIteratorOfListOfStripe itel;
655   Standard_Integer i = 1;
656   for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) {
657     if(i == IC){
658       PerformSetOfSurf(itel.Value(), Standard_True);
659       break;
660     }
661   }
662 #ifdef OCCT_DEBUG
663   if(ChFi3d_GettraceCHRON()){
664     simul.Stop();
665     cout<<"Total simulation time : ";
666     simul.Show();
667     cout<<"Spine construction time : ";
668     elspine.Show();
669     cout<<"and progression time : ";
670     chemine.Show();
671   }
672 #endif
673 }
674
675 //---------------------------AJOUT---------------------------------------
676 //=======================================================================
677 //function : NbSurf
678 //purpose  : 
679 //=======================================================================
680
681 Standard_Integer ChFi3d_ChBuilder::NbSurf (const Standard_Integer IC) const 
682 {
683   ChFiDS_ListIteratorOfListOfStripe itel;
684   Standard_Integer i = 1;
685   for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) {
686     if(i == IC){
687       return itel.Value()->SetOfSurfData()->Length();
688     }
689   }
690   return 0;
691 }
692
693
694 //--------------------------AJOUT---------------------------------------
695 //=======================================================================
696 //function : Sect
697 //purpose  : 
698 //=======================================================================
699
700 Handle(ChFiDS_SecHArray1) ChFi3d_ChBuilder::Sect (const Standard_Integer IC,
701                                                   const Standard_Integer IS) const 
702 {
703   ChFiDS_ListIteratorOfListOfStripe itel;
704   Standard_Integer i = 1;
705   Handle(ChFiDS_SecHArray1) res;
706   for (itel.Initialize(myListStripe);itel.More(); itel.Next(), i++) {
707     if(i == IC){
708       Handle(MMgt_TShared) bid = itel.Value()->SetOfSurfData()->Value(IS)->Simul();
709       res = Handle(ChFiDS_SecHArray1)::DownCast(bid);
710       return res;
711     }
712   }
713   return Handle(ChFiDS_SecHArray1)();
714 }
715
716
717 //-------------------MODIFS---------------------------------------------
718 //=======================================================================
719 //function : SimulKPart
720 //purpose  : Stores simulating sections in simul
721 //=======================================================================
722
723 void  ChFi3d_ChBuilder::SimulKPart(const Handle(ChFiDS_SurfData)& SD ) const 
724 {
725   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
726   Handle(Geom_Surface) S = DStr.Surface(SD->Surf()).Surface();
727   gp_Pnt2d p1f = SD->InterferenceOnS1().PCurveOnSurf()->
728     Value(SD->InterferenceOnS1().FirstParameter());
729   gp_Pnt2d p1l = SD->InterferenceOnS1().PCurveOnSurf()->
730     Value(SD->InterferenceOnS1().LastParameter());
731   gp_Pnt2d p2f = SD->InterferenceOnS2().PCurveOnSurf()->
732     Value(SD->InterferenceOnS2().FirstParameter());
733   gp_Pnt2d p2l = SD->InterferenceOnS2().PCurveOnSurf()->
734     Value(SD->InterferenceOnS2().LastParameter());
735   GeomAdaptor_Surface AS(S);
736   Handle(ChFiDS_SecHArray1) sec;
737   Standard_Real u1,v1,u2,v2;
738   GeomAbs_SurfaceType typ = AS.GetType();
739   switch (typ){
740   case GeomAbs_Plane:
741     {
742       v1 = p1f.Y();
743       v2 = p2f.Y();
744       u1 = Max(p1f.X(),p2f.X());
745       u2 = Min(p1l.X(),p2l.X());
746       sec = new ChFiDS_SecHArray1(1,2); 
747       gp_Pln Pl = AS.Plane();
748       ChFiDS_CircSection& sec1 = sec->ChangeValue(1);
749       ChFiDS_CircSection& sec2 = sec->ChangeValue(2);
750       sec1.Set(ElSLib::PlaneUIso(Pl.Position(),u1),v1,v2);
751       sec2.Set(ElSLib::PlaneUIso(Pl.Position(),u2),v1,v2);
752     }
753     break;
754   case GeomAbs_Cone:
755     {
756       v1 = p1f.Y();
757       v2 = p2f.Y();
758       u1 = Max(p1f.X(),p2f.X());
759       u2 = Min(p1l.X(),p2l.X());
760       Standard_Real ang = (u2-u1);
761       gp_Cone Co = AS.Cone();
762       Standard_Real rad = Co.RefRadius(), sang = Co.SemiAngle();
763       Standard_Integer n = (Standard_Integer) (36.*ang/M_PI + 1);
764       if(n<2) n = 2;
765       sec = new ChFiDS_SecHArray1(1, n);
766       for (Standard_Integer i = 1; i <= n; i++) {
767         ChFiDS_CircSection& isec = sec->ChangeValue(i);
768         Standard_Real u = u1 + (i - 1)*(u2 - u1)/(n-1);
769         isec.Set(ElSLib::ConeUIso(Co.Position(), rad, sang, u), v1, v2);  
770       }
771     }
772     break;
773   default:
774     break;
775   }
776   SD->SetSimul(sec);
777 }
778
779 //------------------------MODIFS---------------------------------------
780 //=======================================================================
781 //function : SimulSurf
782 //purpose  : 
783 //=======================================================================
784
785 Standard_Boolean
786 ChFi3d_ChBuilder::SimulSurf(Handle(ChFiDS_SurfData)&            Data,
787                             const Handle(ChFiDS_HElSpine)&      HGuide,
788                             const Handle(ChFiDS_Spine)&         Spine,
789                             const Standard_Integer              Choix,
790                             const Handle(BRepAdaptor_HSurface)& S1,
791                             const Handle(Adaptor3d_TopolTool)&    I1,
792                             const Handle(BRepAdaptor_HSurface)& S2,
793                             const Handle(Adaptor3d_TopolTool)&    I2,
794                             const Standard_Real                 TolGuide,
795                             Standard_Real&                      First,
796                             Standard_Real&                      Last,
797                             const Standard_Boolean              Inside,
798                             const Standard_Boolean              Appro,
799                             const Standard_Boolean              Forward,
800                             const Standard_Boolean              RecOnS1,
801                             const Standard_Boolean              RecOnS2,
802                             const math_Vector&                  Soldep,
803                             Standard_Boolean&                   intf,
804                             Standard_Boolean&                   intl)
805      
806 {
807   Handle(ChFiDS_ChamfSpine) 
808     chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Spine);
809   
810   if (chsp.IsNull()) 
811     Standard_ConstructionError::Raise
812       ("SimulSurf : this is not the spine of a chamfer");
813
814
815   Standard_Real radius;
816   // Flexible parameters!
817   Standard_Real la = HGuide->LastParameter(), fi = HGuide->FirstParameter();
818   Standard_Real longueur = la - fi;
819   Standard_Real MaxStep = longueur * 0.05;
820   Standard_Real radiusspine = 0, locfleche, w;
821   gp_Pnt Pbid;
822   gp_Vec d1,d2;
823   // As ElSpine is parameterized by a curvilinear quasi-abscissa,
824   // the min radius is estimated as 1/D2 max;
825   //for(Standard_Integer i = 0; i <= 20; i++){
826   Standard_Integer i;
827   for( i = 0; i <= 20; i++){ 
828     w = fi + i*MaxStep;
829     HGuide->D2(w,Pbid,d1,d2);
830     Standard_Real temp = d2.SquareMagnitude();
831     if(temp>radiusspine) radiusspine = temp;
832   }
833
834   Handle(BRepBlend_Line) lin;
835   Standard_Real PFirst = First;
836   if(intf) First = chsp->FirstParameter(1);
837   if(intl) Last = chsp->LastParameter(chsp->NbEdges());
838
839
840
841   if (chsp->IsChamfer() == ChFiDS_Sym) {
842     Standard_Real dis;
843     chsp->GetDist(dis);
844     radius = Max(dis, radiusspine);
845     locfleche = radius*1.e-2; //graphic criterion
846
847     BRepBlend_Chamfer Func(S1,S2,HGuide);
848     BRepBlend_ChamfInv FInv(S1,S2,HGuide); 
849     Func.Set(dis, dis, Choix);
850     FInv.Set(dis, dis, Choix);
851     
852     done = SimulData(Data,HGuide,lin,S1,I1,S2,I2,
853                      Func,FInv,PFirst,MaxStep,locfleche,
854                      TolGuide,First,Last,Inside,Appro,Forward,
855                      Soldep,4,RecOnS1,RecOnS2);
856
857     if ( !done ) return Standard_False;
858     Handle(ChFiDS_SecHArray1) sec;
859     gp_Pnt2d pf1,pl1,pf2,pl2;  
860     
861     Standard_Integer nbp = lin->NbPoints();
862     sec = new ChFiDS_SecHArray1(1,nbp);
863     for( i = 1; i <= nbp; i++ ){
864       ChFiDS_CircSection& isec = sec->ChangeValue(i);
865       Standard_Real u1,v1,u2,v2,ww,p1,p2;
866       gp_Lin line;
867       const Blend_Point& p = lin->Point(i);
868       p.ParametersOnS1(u1,v1);
869       p.ParametersOnS2(u2,v2);
870       ww = p.Parameter();
871       Func.Section(ww,u1,v1,u2,v2,p1,p2,line); 
872       isec.Set(line,p1,p2);
873       if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} 
874       if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} 
875     }
876
877     Data->SetSimul(sec);
878     Data->Set2dPoints(pf1,pl1,pf2,pl2);
879     ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
880                           Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
881     ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
882                           Standard_False,Data->ChangeVertexLastOnS1(),tolesp);
883     ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
884                           Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
885     ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
886                           Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
887     
888     Standard_Boolean reverse = (!Forward || Inside);
889     if(intf && reverse){
890       Standard_Boolean ok = 0;
891       const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1();
892       if(cp1.IsOnArc()){
893         TopoDS_Face F1 = S1->ChangeSurface().Face();
894         TopoDS_Face bid;
895         ok = intf = !SearchFace(Spine,cp1,F1,bid);
896       }
897       const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2();
898       if(cp2.IsOnArc() && !ok){
899         TopoDS_Face F2 = S2->ChangeSurface().Face();
900         TopoDS_Face bid;
901         intf = !SearchFace(Spine,cp2,F2,bid);
902       }
903     }
904     if(intl){
905       Standard_Boolean ok = 0;
906       const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1();
907       if(cp1.IsOnArc()){
908         TopoDS_Face F1 = S1->ChangeSurface().Face();
909         TopoDS_Face bid;
910         ok = intl = !SearchFace(Spine,cp1,F1,bid);
911       }
912       const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2();
913       if(cp2.IsOnArc() && !ok){
914         TopoDS_Face F2 = S2->ChangeSurface().Face();
915         TopoDS_Face bid;
916         intl = !SearchFace(Spine,cp2,F2,bid);
917       }
918     }
919   }
920   else if (chsp->IsChamfer() == ChFiDS_TwoDist) {
921     Standard_Real dis1, dis2;
922     chsp->Dists(dis1, dis2);
923     radius = Max(dis1, dis2);
924     radius = Max(radius, radiusspine);
925     locfleche = radius*1.e-2; //graphic criterion
926
927     BRepBlend_Chamfer Func(S1,S2,HGuide);
928     BRepBlend_ChamfInv FInv(S1,S2,HGuide); 
929     Func.Set(dis1,dis2,Choix);
930     FInv.Set(dis1,dis2,Choix);
931     
932     done = SimulData(Data,HGuide,lin,S1,I1,S2,I2,
933                      Func,FInv,PFirst,MaxStep,locfleche,
934                      TolGuide,First,Last,Inside,Appro,Forward,
935                      Soldep,4,RecOnS1,RecOnS2);
936
937     if ( !done ) return Standard_False;
938     Handle(ChFiDS_SecHArray1) sec;
939     gp_Pnt2d pf1,pl1,pf2,pl2;  
940     
941     Standard_Integer nbp = lin->NbPoints();
942     sec = new ChFiDS_SecHArray1(1,nbp);
943     for( i = 1; i <= nbp; i++ ){
944       ChFiDS_CircSection& isec = sec->ChangeValue(i);
945       Standard_Real u1,v1,u2,v2,ww,p1,p2;
946       gp_Lin line;
947       const Blend_Point& p = lin->Point(i);
948       p.ParametersOnS1(u1,v1);
949       p.ParametersOnS2(u2,v2);
950       ww = p.Parameter();
951       Func.Section(ww,u1,v1,u2,v2,p1,p2,line); 
952       isec.Set(line,p1,p2);
953       if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} 
954       if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} 
955     }
956     
957     Data->SetSimul(sec);
958     Data->Set2dPoints(pf1,pl1,pf2,pl2);
959     ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
960                         Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
961     ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
962                           Standard_False,Data->ChangeVertexLastOnS1(),tolesp);
963     ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
964                           Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
965     ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
966                           Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
967     
968     Standard_Boolean reverse = (!Forward || Inside);
969     if(intf && reverse){
970       Standard_Boolean ok = 0;
971       const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1();
972       if(cp1.IsOnArc()){
973         TopoDS_Face F1 = S1->ChangeSurface().Face();
974         TopoDS_Face bid;
975         ok = intf = !SearchFace(Spine,cp1,F1,bid);
976       }
977       const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2();
978       if(cp2.IsOnArc() && !ok){
979         TopoDS_Face F2 = S2->ChangeSurface().Face();
980         TopoDS_Face bid;
981         intf = !SearchFace(Spine,cp2,F2,bid);
982       }
983     }
984     if(intl){
985       Standard_Boolean ok = 0;
986       const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1();
987       if(cp1.IsOnArc()){
988         TopoDS_Face F1 = S1->ChangeSurface().Face();
989         TopoDS_Face bid;
990         ok = intl = !SearchFace(Spine,cp1,F1,bid);
991       }
992       const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2();
993       if(cp2.IsOnArc() && !ok){
994         TopoDS_Face F2 = S2->ChangeSurface().Face();
995         TopoDS_Face bid;
996         intl = !SearchFace(Spine,cp2,F2,bid);
997       }
998     }
999   }
1000   else  {
1001     Standard_Real dis, angle;
1002     Standard_Boolean disonF1;  
1003     chsp->GetDistAngle(dis, angle, disonF1);
1004     radius = Max(dis, dis * tan(angle));
1005     radius = Max(radius, radiusspine);
1006     locfleche = radius*1.e-2; //graphic criterion
1007
1008     Standard_Integer Ch = FindChoiceDistAngle(Choix, disonF1);
1009
1010     if (disonF1)  {
1011       BRepBlend_ChAsym    Func(S1,S2,HGuide);
1012       BRepBlend_ChAsymInv FInv(S1,S2,HGuide); 
1013
1014       Func.Set(dis, angle, Ch);
1015       FInv.Set(dis, angle, Ch);
1016
1017       done = SimulData(Data,HGuide,lin,S1,I1,S2,I2,
1018                        Func,FInv,PFirst,MaxStep,locfleche,
1019                        TolGuide,First,Last,Inside,Appro,Forward,
1020                        Soldep,4,RecOnS1,RecOnS2);
1021     
1022       if ( !done ) return Standard_False;
1023       Handle(ChFiDS_SecHArray1) sec;
1024       gp_Pnt2d pf1,pl1,pf2,pl2;  
1025       
1026       Standard_Integer nbp = lin->NbPoints();
1027       sec = new ChFiDS_SecHArray1(1,nbp);
1028       for( i = 1; i <= nbp; i++ ){
1029         ChFiDS_CircSection& isec = sec->ChangeValue(i);
1030         Standard_Real u1,v1,u2,v2,ww,p1,p2;
1031         gp_Lin line;
1032         const Blend_Point& p = lin->Point(i);
1033         p.ParametersOnS1(u1,v1);
1034         p.ParametersOnS2(u2,v2);
1035         ww = p.Parameter();
1036         Func.Section(ww,u1,v1,u2,v2,p1,p2,line); 
1037         isec.Set(line,p1,p2);
1038         if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} 
1039         if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} 
1040       }
1041     
1042       Data->SetSimul(sec);
1043       Data->Set2dPoints(pf1,pl1,pf2,pl2);
1044       ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
1045                             Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1046       ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
1047                             Standard_False,Data->ChangeVertexLastOnS1(),tolesp);
1048       ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
1049                             Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1050       ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
1051                             Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1052
1053       Standard_Boolean reverse = (!Forward || Inside);
1054       if(intf && reverse){
1055         Standard_Boolean ok = 0;
1056         const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1();
1057         if(cp1.IsOnArc()){
1058           TopoDS_Face F1 = S1->ChangeSurface().Face();
1059           TopoDS_Face bid;
1060           ok = intf = !SearchFace(Spine,cp1,F1,bid);
1061         }
1062         const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2();
1063         if(cp2.IsOnArc() && !ok){
1064           TopoDS_Face F2 = S2->ChangeSurface().Face();
1065           TopoDS_Face bid;
1066           intf = !SearchFace(Spine,cp2,F2,bid);
1067         }
1068       }
1069       
1070       if(intl){
1071         Standard_Boolean ok = 0;
1072         const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1();
1073         if(cp1.IsOnArc()){
1074           TopoDS_Face F1 = S1->ChangeSurface().Face();
1075           TopoDS_Face bid;
1076           ok = intl = !SearchFace(Spine,cp1,F1,bid);
1077         }
1078         const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2();
1079         if(cp2.IsOnArc() && !ok){
1080           TopoDS_Face F2 = S2->ChangeSurface().Face();
1081           TopoDS_Face bid;
1082           intl = !SearchFace(Spine,cp2,F2,bid);
1083         }
1084       }
1085     }
1086     else {
1087       BRepBlend_ChAsym    Func(S2,S1,HGuide);
1088       BRepBlend_ChAsymInv FInv(S2,S1,HGuide); 
1089
1090       Func.Set(dis, angle, Ch);
1091       FInv.Set(dis, angle, Ch);
1092
1093       Standard_Real Rtemp;
1094       Rtemp     = Soldep(1);
1095       Soldep(1) = Soldep(3);
1096       Soldep(3) = Rtemp;
1097       Rtemp     = Soldep(2);
1098       Soldep(2) = Soldep(4);
1099       Soldep(4) = Rtemp;
1100
1101       done = SimulData(Data,HGuide,lin,S2,I2,S1,I1,
1102                        Func,FInv,PFirst,MaxStep,locfleche,
1103                        TolGuide,First,Last,Inside,Appro,Forward,
1104                        Soldep,4,RecOnS2,RecOnS1);
1105     
1106       if ( !done ) return Standard_False;
1107       Handle(ChFiDS_SecHArray1) sec;
1108       gp_Pnt2d pf1,pl1,pf2,pl2;  
1109       
1110       Standard_Integer nbp = lin->NbPoints();
1111       sec = new ChFiDS_SecHArray1(1,nbp);
1112       for( i = 1; i <= nbp; i++ ){
1113         ChFiDS_CircSection& isec = sec->ChangeValue(i);
1114         Standard_Real u1,v1,u2,v2,ww,p1,p2;
1115         gp_Lin line;
1116         const Blend_Point& p = lin->Point(i);
1117         p.ParametersOnS1(u1,v1);
1118         p.ParametersOnS2(u2,v2);
1119         ww = p.Parameter();
1120         Func.Section(ww,u1,v1,u2,v2,p1,p2,line); 
1121         isec.Set(line,p1,p2);
1122         if(i == 1) {pf1.SetCoord(u1,v1); pf2.SetCoord(u2,v2);} 
1123         if(i == nbp) {pl1.SetCoord(u1,v1); pl2.SetCoord(u2,v2);} 
1124       }
1125     
1126       Data->SetSimul(sec);
1127       Data->Set2dPoints(pf1,pl1,pf2,pl2);
1128       ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
1129                             Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1130       ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
1131                             Standard_False,Data->ChangeVertexLastOnS1(),tolesp);
1132       ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
1133                             Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1134       ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
1135                             Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1136
1137       Standard_Boolean reverse = (!Forward || Inside);
1138       if(intf && reverse){
1139         Standard_Boolean ok = 0;
1140         const ChFiDS_CommonPoint& cp1 = Data->VertexFirstOnS1();
1141         if(cp1.IsOnArc()){
1142           TopoDS_Face F1 = S1->ChangeSurface().Face();
1143           TopoDS_Face bid;
1144           ok = intf = !SearchFace(Spine,cp1,F1,bid);
1145         }
1146         const ChFiDS_CommonPoint& cp2 = Data->VertexFirstOnS2();
1147         if(cp2.IsOnArc() && !ok){
1148           TopoDS_Face F2 = S2->ChangeSurface().Face();
1149           TopoDS_Face bid;
1150           intf = !SearchFace(Spine,cp2,F2,bid);
1151         }
1152       }
1153       
1154       if(intl){
1155         Standard_Boolean ok = 0;
1156         const ChFiDS_CommonPoint& cp1 = Data->VertexLastOnS1();
1157         if(cp1.IsOnArc()){
1158           TopoDS_Face F1 = S1->ChangeSurface().Face();
1159           TopoDS_Face bid;
1160           ok = intl = !SearchFace(Spine,cp1,F1,bid);
1161         }
1162         const ChFiDS_CommonPoint& cp2 = Data->VertexLastOnS2();
1163         if(cp2.IsOnArc() && !ok){
1164           TopoDS_Face F2 = S2->ChangeSurface().Face();
1165           TopoDS_Face bid;
1166           intl = !SearchFace(Spine,cp2,F2,bid);
1167         }
1168       }
1169     }
1170   }
1171   return Standard_True;
1172 }
1173
1174 void  ChFi3d_ChBuilder::SimulSurf(Handle(ChFiDS_SurfData)&            ,
1175                                 const Handle(ChFiDS_HElSpine)&      , 
1176                                 const Handle(ChFiDS_Spine)&         , 
1177                                 const Standard_Integer              ,
1178                                 const Handle(BRepAdaptor_HSurface)& ,
1179                                 const Handle(Adaptor3d_TopolTool)&    ,
1180                                 const Handle(BRepAdaptor_HCurve2d)& ,
1181                                 const Handle(BRepAdaptor_HSurface)& ,
1182                                 const Handle(BRepAdaptor_HCurve2d)& ,
1183                                 Standard_Boolean&                   ,
1184                                 const Handle(BRepAdaptor_HSurface)& ,
1185                                 const Handle(Adaptor3d_TopolTool)&    ,
1186                                 const TopAbs_Orientation            ,
1187                                 const Standard_Real                 ,
1188                                 const Standard_Real                 ,
1189                                 Standard_Real&                      ,
1190                                 Standard_Real&                      ,
1191                                 const Standard_Boolean              ,
1192                                 const Standard_Boolean              ,
1193                                 const Standard_Boolean              ,
1194                                 const Standard_Boolean              ,
1195                                 const Standard_Boolean              ,
1196                                 const Standard_Boolean              ,
1197                                 const math_Vector&                  )
1198 {
1199   Standard_Failure::Raise("SimulSurf Not Implemented");
1200 }
1201 void  ChFi3d_ChBuilder::SimulSurf(Handle(ChFiDS_SurfData)&            ,
1202                                 const Handle(ChFiDS_HElSpine)&      , 
1203                                 const Handle(ChFiDS_Spine)&         , 
1204                                 const Standard_Integer              ,
1205                                 const Handle(BRepAdaptor_HSurface)& ,
1206                                 const Handle(Adaptor3d_TopolTool)&    ,
1207                                 const TopAbs_Orientation            ,
1208                                 const Handle(BRepAdaptor_HSurface)& ,
1209                                 const Handle(Adaptor3d_TopolTool)&    ,
1210                                 const Handle(BRepAdaptor_HCurve2d)& ,
1211                                 const Handle(BRepAdaptor_HSurface)& ,
1212                                 const Handle(BRepAdaptor_HCurve2d)& ,
1213                                 Standard_Boolean&                   ,
1214                                 const Standard_Real                 ,
1215                                 const Standard_Real                 ,
1216                                 Standard_Real&                      ,
1217                                 Standard_Real&                      ,
1218                                 const Standard_Boolean              ,
1219                                 const Standard_Boolean              ,
1220                                 const Standard_Boolean              ,
1221                                 const Standard_Boolean              ,
1222                                 const Standard_Boolean              ,
1223                                 const Standard_Boolean              ,
1224                                 const math_Vector&                  )
1225 {
1226   Standard_Failure::Raise("SimulSurf Not Implemented");
1227 }
1228 void  ChFi3d_ChBuilder::SimulSurf(Handle(ChFiDS_SurfData)&            ,
1229                                 const Handle(ChFiDS_HElSpine)&      ,
1230                                 const Handle(ChFiDS_Spine)&         ,
1231                                 const Standard_Integer              ,
1232                                 const Handle(BRepAdaptor_HSurface)& ,
1233                                 const Handle(Adaptor3d_TopolTool)&    ,
1234                                 const Handle(BRepAdaptor_HCurve2d)& ,
1235                                 const Handle(BRepAdaptor_HSurface)& ,
1236                                 const Handle(BRepAdaptor_HCurve2d)& ,
1237                                 Standard_Boolean&                   ,
1238                                 const TopAbs_Orientation            ,
1239                                 const Handle(BRepAdaptor_HSurface)& ,
1240                                 const Handle(Adaptor3d_TopolTool)&    ,
1241                                 const Handle(BRepAdaptor_HCurve2d)& ,
1242                                 const Handle(BRepAdaptor_HSurface)& ,
1243                                 const Handle(BRepAdaptor_HCurve2d)& ,
1244                                 Standard_Boolean&                   ,
1245                                 const TopAbs_Orientation            ,
1246                                 const Standard_Real                 ,
1247                                 const Standard_Real                 ,
1248                                 Standard_Real&                      ,
1249                                 Standard_Real&                      ,
1250                                 const Standard_Boolean              ,
1251                                 const Standard_Boolean              ,
1252                                 const Standard_Boolean              ,
1253                                 const Standard_Boolean              ,
1254                                 const Standard_Boolean              ,
1255                                 const Standard_Boolean              ,
1256                                 const Standard_Boolean              ,
1257                                 const math_Vector&                  )
1258 {
1259   Standard_Failure::Raise("SimulSurf Not Implemented");
1260 }
1261 //------------------------MODIFS---------------------------------------
1262 //=======================================================================
1263 //function : PerformFirstSection
1264 //purpose  : to implement the first section if there is no KPart
1265 //=======================================================================
1266
1267 Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection
1268 (const Handle(ChFiDS_Spine)&         Spine,
1269  const Handle(ChFiDS_HElSpine)&      HGuide,
1270  const Standard_Integer              Choix,
1271  Handle(BRepAdaptor_HSurface)&       S1,
1272  Handle(BRepAdaptor_HSurface)&       S2,
1273  const Handle(Adaptor3d_TopolTool)&    I1,
1274  const Handle(Adaptor3d_TopolTool)&    I2,
1275  const Standard_Real                 Par,
1276  math_Vector&                        SolDep,
1277  TopAbs_State&                       Pos1,
1278  TopAbs_State&                       Pos2) const 
1279 {
1280   Handle(ChFiDS_ChamfSpine) 
1281     chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Spine);
1282   
1283   if (chsp.IsNull()) 
1284     Standard_ConstructionError::Raise
1285       ("PerformSurf : this is not the spine of a chamfer");
1286
1287   Standard_Real TolGuide = HGuide->Resolution(tolesp) ;
1288
1289
1290   if (chsp->IsChamfer() == ChFiDS_Sym) {
1291     Standard_Real dis;
1292     chsp->GetDist(dis);
1293     
1294     BRepBlend_Chamfer Func(S1,S2,HGuide);
1295     Func.Set(dis,dis,Choix);
1296     BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
1297     
1298     //calculate an approximate starting solution
1299     gp_Vec TgF, TgL, tmp1, tmp2, d1gui;
1300     gp_Pnt pt1, pt2, ptgui;
1301     gp_XYZ temp;
1302     
1303     ( HGuide->Curve() ).D1(Par,ptgui,d1gui);
1304     //  ptgui = (S1->Surface()).Value(SolDep(1),SolDep(2));
1305     
1306     Func.Set(Par);
1307     Func.Tangent(SolDep(1),SolDep(2),SolDep(3),SolDep(4),TgF,TgL,tmp1,tmp2);
1308     
1309     Standard_Boolean rev1 = Standard_False;
1310     Standard_Boolean rev2 = Standard_False;
1311     Standard_Real    sign = (TgF.Crossed(d1gui)).Dot(TgL);
1312   
1313     if( Choix%2 == 1 )
1314       rev1 = Standard_True;
1315     else
1316       rev2 = Standard_True;
1317     
1318     if( sign < 0. ){
1319       rev1 = !rev1;
1320       rev2 = !rev2;
1321     }
1322     
1323     if( rev1 )
1324       TgF.Reverse();
1325     if( rev2 )
1326       TgL.Reverse();
1327     
1328     temp = (TgF.XYZ()).Multiplied(dis);
1329     pt1.SetXYZ( (ptgui.XYZ()).Added(temp) );
1330     temp = (TgL.XYZ()).Multiplied(dis);
1331     pt2.SetXYZ( (ptgui.XYZ()).Added(temp) );
1332     
1333     Standard_Real tol = tolesp*1.e2;
1334 //    Standard_Real u,v;
1335     Extrema_GenLocateExtPS proj1(S1->Surface(), tol, tol);
1336     proj1.Perform(pt1, SolDep(1), SolDep(2));
1337     Extrema_GenLocateExtPS proj2(S2->Surface(), tol, tol);
1338     proj2.Perform(pt2, SolDep(3), SolDep(4));
1339
1340     if( proj1.IsDone() ){
1341       (proj1.Point()).Parameter(SolDep(1),SolDep(2)); 
1342     }
1343     if( proj2.IsDone() ){
1344       (proj2.Point()).Parameter(SolDep(3),SolDep(4)); 
1345     }
1346     
1347     return TheWalk.PerformFirstSection(Func,Par,SolDep,
1348                                        tolesp,TolGuide,Pos1,Pos2);
1349   }
1350   else if (chsp->IsChamfer() == ChFiDS_TwoDist)  {
1351     Standard_Real dis1, dis2;
1352     chsp->Dists(dis1, dis2);
1353     
1354     BRepBlend_Chamfer Func(S1,S2,HGuide);
1355     Func.Set(dis1,dis2,Choix);
1356     BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
1357     
1358     //calculate an approximate starting solution
1359     gp_Vec TgF, TgL, tmp1, tmp2, d1gui;
1360     gp_Pnt pt1, pt2, ptgui;
1361     gp_XYZ temp;
1362     
1363     ( HGuide->Curve() ).D1(Par,ptgui,d1gui);
1364     //  ptgui = (S1->Surface()).Value(SolDep(1),SolDep(2));
1365     
1366     Func.Set(Par);
1367     Func.Tangent(SolDep(1),SolDep(2),SolDep(3),SolDep(4),TgF,TgL,tmp1,tmp2);
1368     
1369     Standard_Boolean rev1 = Standard_False;
1370     Standard_Boolean rev2 = Standard_False;
1371     Standard_Real    sign = (TgF.Crossed(d1gui)).Dot(TgL);
1372   
1373     if( Choix%2 == 1 )
1374       rev1 = Standard_True;
1375     else
1376       rev2 = Standard_True;
1377     
1378     if( sign < 0. ){
1379       rev1 = !rev1;
1380       rev2 = !rev2;
1381     }
1382     
1383     if( rev1 )
1384       TgF.Reverse();
1385     if( rev2 )
1386       TgL.Reverse();
1387     
1388     temp = (TgF.XYZ()).Multiplied(dis1);
1389     pt1.SetXYZ( (ptgui.XYZ()).Added(temp) );
1390     temp = (TgL.XYZ()).Multiplied(dis2);
1391     pt2.SetXYZ( (ptgui.XYZ()).Added(temp) );
1392     
1393     Standard_Real tol = tolesp*1.e2;
1394 //    Standard_Real u,v;
1395
1396     Extrema_GenLocateExtPS proj1(S1->Surface(), tol, tol);
1397     proj1.Perform(pt1, SolDep(1), SolDep(2));
1398     Extrema_GenLocateExtPS proj2(S2->Surface(), tol, tol);
1399     proj2.Perform(pt2, SolDep(3), SolDep(4));
1400
1401     if( proj1.IsDone() ){
1402       (proj1.Point()).Parameter(SolDep(1),SolDep(2)); 
1403     }
1404     if( proj2.IsDone() ){
1405       (proj2.Point()).Parameter(SolDep(3),SolDep(4)); 
1406     }
1407     
1408     return TheWalk.PerformFirstSection(Func,Par,SolDep,
1409                                        tolesp,TolGuide,Pos1,Pos2);
1410   }
1411   else {
1412     Standard_Real dis1, angle;
1413     Standard_Boolean disonF1; 
1414     chsp->GetDistAngle(dis1, angle, disonF1);
1415     
1416     Standard_Integer Ch = FindChoiceDistAngle(Choix, disonF1);
1417     
1418     if (disonF1)  {
1419       BRepBlend_ChAsym Func(S1,S2,HGuide);
1420       Func.Set(dis1, angle, Ch);
1421       BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
1422     
1423     //calculate an approximate starting solution
1424       gp_Vec TgF, TgL, tmp1, tmp2, d1gui;
1425       gp_Pnt pt1, pt2, ptgui;
1426       gp_XYZ temp;
1427       
1428       ( HGuide->Curve() ).D1(Par,ptgui,d1gui);
1429       //  ptgui = (S1->Surface()).Value(SolDep(1),SolDep(2));
1430       
1431       Func.Set(Par);
1432       Func.Tangent(SolDep(1),SolDep(2),SolDep(3),SolDep(4),TgF,TgL,tmp1,tmp2);
1433       
1434       Standard_Boolean rev1 = Standard_False;
1435       Standard_Boolean rev2 = Standard_False;
1436       Standard_Real    sign = (TgF.Crossed(d1gui)).Dot(TgL);
1437       
1438       if( Ch%2 == 1 )
1439         rev1 = Standard_True;
1440       else
1441         rev2 = Standard_True;
1442       
1443       if( sign < 0. ){
1444         rev1 = !rev1;
1445         rev2 = !rev2;
1446       }
1447       
1448       if( rev1 )
1449         TgF.Reverse();
1450       if( rev2 )
1451         TgL.Reverse();
1452   
1453       temp = (TgF.XYZ()).Multiplied(dis1);
1454       pt1.SetXYZ( (ptgui.XYZ()).Added(temp) );
1455       
1456       Standard_Real dis2, tmpcos, tmpsin;
1457       tmpcos = TgF.Dot(TgL);
1458       tmpsin = sqrt(1. - tmpcos * tmpcos);  
1459       
1460       dis2   = dis1 / (tmpcos + tmpsin / tan(angle)); 
1461       
1462       temp = (TgL.XYZ()).Multiplied(dis2);
1463       pt2.SetXYZ( (ptgui.XYZ()).Added(temp) );
1464       
1465       Standard_Real tol = tolesp*1.e2;
1466 //      Standard_Real u,v;
1467       Extrema_GenLocateExtPS proj1(S1->Surface(), tol, tol);
1468       proj1.Perform(pt1, SolDep(1), SolDep(2));
1469       Extrema_GenLocateExtPS proj2(S2->Surface(), tol, tol);
1470       proj2.Perform(pt2, SolDep(3), SolDep(4));
1471       if( proj1.IsDone() ){
1472         (proj1.Point()).Parameter(SolDep(1),SolDep(2)); 
1473       }
1474       if( proj2.IsDone() ){
1475         (proj2.Point()).Parameter(SolDep(3),SolDep(4)); 
1476       }
1477       
1478       return TheWalk.PerformFirstSection(Func,Par,SolDep,
1479                                          tolesp,TolGuide,Pos1,Pos2);
1480     }
1481     else {
1482       Standard_Real Rtemp;
1483       BRepBlend_ChAsym Func(S2,S1,HGuide);
1484       Func.Set(dis1, angle, Ch);
1485       BRepBlend_Walking TheWalk(S2,S1,I2,I1,HGuide);
1486     
1487     //calculate an approximate starting solution
1488       gp_Vec TgF, TgL, tmp1, tmp2, d1gui;
1489       gp_Pnt pt1, pt2, ptgui;
1490       gp_XYZ temp;
1491       
1492       ( HGuide->Curve() ).D1(Par,ptgui,d1gui);
1493       //  ptgui = (S1->Surface()).Value(SolDep(1),SolDep(2));
1494       Rtemp     = SolDep(1);
1495       SolDep(1) = SolDep(3);
1496       SolDep(3) = Rtemp;
1497       Rtemp     = SolDep(2);
1498       SolDep(2) = SolDep(4);
1499       SolDep(4) = Rtemp;      
1500       Func.Set(Par);
1501
1502       Func.Tangent(SolDep(1),SolDep(2),SolDep(3),SolDep(4),TgF,TgL,tmp1,tmp2);
1503       
1504       Standard_Boolean rev1 = Standard_False;
1505       Standard_Boolean rev2 = Standard_False;
1506       Standard_Real    sign = (TgF.Crossed(d1gui)).Dot(TgL);
1507       
1508       if( Ch%2 == 1 )
1509         rev1 = Standard_True;
1510       else
1511         rev2 = Standard_True;
1512       
1513       if( sign < 0. ){
1514         rev1 = !rev1;
1515         rev2 = !rev2;
1516       }
1517       
1518       if( rev1 )
1519         TgF.Reverse();
1520       if( rev2 )
1521         TgL.Reverse();
1522   
1523       temp = (TgF.XYZ()).Multiplied(dis1);
1524       pt1.SetXYZ( (ptgui.XYZ()).Added(temp) );
1525       
1526       Standard_Real dis2, tmpcos, tmpsin;
1527       tmpcos = TgF.Dot(TgL);
1528       tmpsin = sqrt(1. - tmpcos * tmpcos);  
1529       
1530       dis2   = dis1 / (tmpcos + tmpsin / tan(angle)); 
1531       
1532       temp = (TgL.XYZ()).Multiplied(dis2);
1533       pt2.SetXYZ( (ptgui.XYZ()).Added(temp) );
1534       
1535       Standard_Real tol = tolesp*1.e2;
1536 //      Standard_Real u,v;
1537       Extrema_GenLocateExtPS proj1(S2->Surface(), tol, tol);
1538       proj1.Perform(pt1, SolDep(1), SolDep(2));
1539       Extrema_GenLocateExtPS proj2(S1->Surface(), tol, tol);
1540       proj2.Perform(pt2, SolDep(3), SolDep(4));
1541       if( proj1.IsDone() ) {
1542         (proj1.Point()).Parameter(SolDep(1),SolDep(2)); 
1543       }
1544       if( proj2.IsDone() ){
1545         (proj2.Point()).Parameter(SolDep(3),SolDep(4)); 
1546       }
1547       
1548       Standard_Boolean RetWalk =  TheWalk.PerformFirstSection(Func,Par,SolDep,
1549                                                               tolesp,TolGuide,Pos2,Pos1);
1550       Rtemp     = SolDep(1);
1551       SolDep(1) = SolDep(3);
1552       SolDep(3) = Rtemp;
1553       Rtemp     = SolDep(2);
1554       SolDep(2) = SolDep(4);
1555       SolDep(4) = Rtemp;
1556
1557       return RetWalk;
1558     }
1559   }
1560 }
1561
1562
1563 //=======================================================================
1564 //function : PerformSurf
1565 //purpose  : 
1566 //=======================================================================
1567
1568 Standard_Boolean  
1569 ChFi3d_ChBuilder::PerformSurf(ChFiDS_SequenceOfSurfData&          SeqData,
1570                               const Handle(ChFiDS_HElSpine)&      HGuide,
1571                               const Handle(ChFiDS_Spine)&         Spine,
1572                               const Standard_Integer              Choix,
1573                               const Handle(BRepAdaptor_HSurface)& S1,
1574                               const Handle(Adaptor3d_TopolTool)&    I1,
1575                               const Handle(BRepAdaptor_HSurface)& S2,
1576                               const Handle(Adaptor3d_TopolTool)&    I2,
1577                               const Standard_Real                 MaxStep,
1578                               const Standard_Real                 Fleche,
1579                               const Standard_Real                 TolGuide,
1580                               Standard_Real&                      First,
1581                               Standard_Real&                      Last,
1582                               const Standard_Boolean              Inside,
1583                               const Standard_Boolean              Appro,
1584                               const Standard_Boolean              Forward,
1585                               const Standard_Boolean              RecOnS1,
1586                               const Standard_Boolean              RecOnS2,
1587                               const math_Vector&                  Soldep,
1588                               Standard_Boolean&                   intf,
1589                               Standard_Boolean&                   intl)
1590      
1591 {
1592   Handle(ChFiDS_SurfData) Data = SeqData(1);
1593   Handle(ChFiDS_ChamfSpine) 
1594     chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Spine);
1595   
1596   if (chsp.IsNull()) 
1597     Standard_ConstructionError::Raise
1598       ("PerformSurf : this is not the spine of a chamfer");
1599   
1600   Standard_Boolean gd1,gd2,gf1,gf2;
1601   Handle(BRepBlend_Line) lin;
1602   TopAbs_Orientation Or = S1->ChangeSurface().Face().Orientation();
1603   Standard_Real PFirst = First;
1604   if(intf) First = chsp->FirstParameter(1);
1605   if(intl) Last = chsp->LastParameter(chsp->NbEdges());
1606
1607   if (chsp->IsChamfer() == ChFiDS_Sym) {
1608     BRepBlend_Chamfer  Func(S1,S2,HGuide);
1609     BRepBlend_ChamfInv FInv(S1,S2,HGuide);
1610     Standard_Real dis;
1611     chsp->GetDist(dis);
1612     Func.Set(dis, dis, Choix);
1613     FInv.Set(dis, dis, Choix);
1614       
1615     done = ComputeData(Data,HGuide,Spine,lin,S1,I1,S2,I2,Func,FInv,
1616                        PFirst,MaxStep,Fleche,TolGuide,First,Last,
1617                        Inside,Appro,Forward,Soldep,intf,intl,
1618                        gd1,gd2,gf1,gf2,RecOnS1,RecOnS2);
1619     if(!done) return Standard_False; // ratrappage possible PMN 14/05/1998
1620     done = CompleteData(Data,Func,lin,S1,S2,Or,gd1,gd2,gf1,gf2);
1621     if(!done) Standard_Failure::Raise("PerformSurf : Fail of approximation!");
1622   }
1623   else if (chsp->IsChamfer() == ChFiDS_TwoDist) {
1624     BRepBlend_Chamfer  Func(S1,S2,HGuide);
1625     BRepBlend_ChamfInv FInv(S1,S2,HGuide);
1626     Standard_Real d1, d2;
1627     chsp->Dists(d1,d2);
1628     Func.Set(d1,d2,Choix);
1629     FInv.Set(d1,d2,Choix);
1630     
1631     done = ComputeData(Data,HGuide,Spine,lin,S1,I1,S2,I2,Func,FInv,
1632                        PFirst,MaxStep,Fleche,TolGuide,First,Last,
1633                        Inside,Appro,Forward,Soldep,intf,intl,
1634                        gd1,gd2,gf1,gf2,RecOnS1,RecOnS2);
1635     if(!done) return Standard_False; // ratrappage possible PMN 14/05/1998
1636     done = CompleteData(Data,Func,lin,S1,S2,Or,gd1,gd2,gf1,gf2);
1637     if(!done) Standard_Failure::Raise("PerformSurf : Fail of approximation!");
1638   }
1639   else {
1640     Standard_Real d1, angle;
1641     Standard_Boolean disonF1;
1642     chsp->GetDistAngle(d1, angle, disonF1);
1643     
1644     Standard_Integer Ch = FindChoiceDistAngle(Choix, disonF1);
1645
1646     if (disonF1) {
1647       BRepBlend_ChAsym  Func(S1,S2,HGuide);
1648       BRepBlend_ChAsymInv FInv(S1,S2,HGuide);
1649       Func.Set(d1, angle, Ch);
1650       FInv.Set(d1, angle, Ch);
1651     
1652       done = ComputeData(Data,HGuide,Spine,lin,S1,I1,S2,I2,Func,FInv,
1653                          PFirst,MaxStep,Fleche,TolGuide,First,Last,
1654                          Inside,Appro,Forward,Soldep,intf,intl,
1655                          gd1,gd2,gf1,gf2,RecOnS1,RecOnS2);
1656
1657       if(!done) return Standard_False; // ratrappage possible PMN 14/05/1998
1658       done = CompleteData(Data,Func,lin,S1,S2,Or,gd1,gd2,gf1,gf2);
1659       if(!done) Standard_Failure::Raise("PerformSurf : Fail of approximation!");
1660     }
1661     else {
1662       Standard_Real Rtemp;
1663       BRepBlend_ChAsym  Func(S2, S1, HGuide);
1664       BRepBlend_ChAsymInv FInv(S2, S1,HGuide);
1665       Func.Set(d1, angle, Ch);
1666       FInv.Set(d1, angle, Ch);
1667
1668       Rtemp     = Soldep(1);
1669       Soldep(1) = Soldep(3);
1670       Soldep(3) = Rtemp;
1671       Rtemp     = Soldep(2);
1672       Soldep(2) = Soldep(4);
1673       Soldep(4) = Rtemp;
1674
1675       TopAbs_Orientation Or2 = S2->ChangeSurface().Face().Orientation();
1676
1677       done = ComputeData(Data,HGuide,Spine,lin,S2,I2,S1,I1,Func,FInv,
1678                          PFirst,MaxStep,Fleche,TolGuide,First,Last,
1679                          Inside,Appro,Forward,Soldep,intf,intl,
1680                          gd2,gd1,gf2,gf1,RecOnS2,RecOnS1);
1681
1682       ChFiDS_CommonPoint tmp = Data->VertexFirstOnS1();
1683       Data->ChangeVertexFirstOnS1() = Data->VertexFirstOnS2();
1684       Data->ChangeVertexFirstOnS2() = tmp;
1685       tmp = Data->VertexLastOnS1();
1686       Data->ChangeVertexLastOnS1() = Data->VertexLastOnS2();
1687       Data->ChangeVertexLastOnS2() = tmp;
1688       if(!done) return Standard_False; // ratrappage possible PMN 14/05/1998
1689       done = CompleteData(Data,Func,lin,S1,S2,Or2,gd1,gd2,gf1,gf2, Standard_True);
1690       if(!done) Standard_Failure::Raise("PerformSurf : Fail of approximation!");
1691     }      
1692
1693   }
1694   return Standard_True;
1695 }
1696 void  ChFi3d_ChBuilder::PerformSurf(ChFiDS_SequenceOfSurfData&          ,
1697                                   const Handle(ChFiDS_HElSpine)&      , 
1698                                   const Handle(ChFiDS_Spine)&         , 
1699                                   const Standard_Integer              ,
1700                                   const Handle(BRepAdaptor_HSurface)& ,
1701                                   const Handle(Adaptor3d_TopolTool)&    ,
1702                                   const Handle(BRepAdaptor_HCurve2d)& ,
1703                                   const Handle(BRepAdaptor_HSurface)& ,
1704                                   const Handle(BRepAdaptor_HCurve2d)& ,
1705                                   Standard_Boolean&                   ,
1706                                   const Handle(BRepAdaptor_HSurface)& ,
1707                                   const Handle(Adaptor3d_TopolTool)&    ,
1708                                   const TopAbs_Orientation            ,
1709                                   const Standard_Real                 ,
1710                                   const Standard_Real                 ,
1711                                   const Standard_Real                 ,
1712                                   Standard_Real&                      ,
1713                                   Standard_Real&                      ,
1714                                   const Standard_Boolean              ,
1715                                   const Standard_Boolean              ,
1716                                   const Standard_Boolean              ,
1717                                   const Standard_Boolean              ,
1718                                   const Standard_Boolean              ,
1719                                   const Standard_Boolean              ,
1720                                   const math_Vector&                  )
1721 {
1722   Standard_Failure::Raise("PerformSurf Not Implemented");
1723 }
1724 void  ChFi3d_ChBuilder::PerformSurf(ChFiDS_SequenceOfSurfData&          ,
1725                                   const Handle(ChFiDS_HElSpine)&      , 
1726                                   const Handle(ChFiDS_Spine)&         , 
1727                                   const Standard_Integer              ,
1728                                   const Handle(BRepAdaptor_HSurface)& ,
1729                                   const Handle(Adaptor3d_TopolTool)&    ,
1730                                   const TopAbs_Orientation            ,
1731                                   const Handle(BRepAdaptor_HSurface)& ,
1732                                   const Handle(Adaptor3d_TopolTool)&    ,
1733                                   const Handle(BRepAdaptor_HCurve2d)& ,
1734                                   const Handle(BRepAdaptor_HSurface)& ,
1735                                   const Handle(BRepAdaptor_HCurve2d)& ,
1736                                   Standard_Boolean&                   ,
1737                                   const Standard_Real                 ,
1738                                   const Standard_Real                 ,
1739                                   const Standard_Real                 ,
1740                                   Standard_Real&                      ,
1741                                   Standard_Real&                      ,
1742                                   const Standard_Boolean              ,
1743                                   const Standard_Boolean              ,
1744                                   const Standard_Boolean              ,
1745                                   const Standard_Boolean              ,
1746                                   const Standard_Boolean              ,
1747                                   const Standard_Boolean              ,
1748                                   const math_Vector&                  )
1749 {
1750   Standard_Failure::Raise("PerformSurf Not Implemented");
1751
1752 }
1753 void  ChFi3d_ChBuilder::PerformSurf(ChFiDS_SequenceOfSurfData&          ,
1754                                   const Handle(ChFiDS_HElSpine)&      ,
1755                                   const Handle(ChFiDS_Spine)&         ,
1756                                   const Standard_Integer              ,
1757                                   const Handle(BRepAdaptor_HSurface)& ,
1758                                   const Handle(Adaptor3d_TopolTool)&    ,
1759                                   const Handle(BRepAdaptor_HCurve2d)& ,
1760                                   const Handle(BRepAdaptor_HSurface)& ,
1761                                   const Handle(BRepAdaptor_HCurve2d)& ,
1762                                   Standard_Boolean&                   ,
1763                                   const TopAbs_Orientation            ,
1764                                   const Handle(BRepAdaptor_HSurface)& ,
1765                                   const Handle(Adaptor3d_TopolTool)&    ,
1766                                   const Handle(BRepAdaptor_HCurve2d)& ,
1767                                   const Handle(BRepAdaptor_HSurface)& ,
1768                                   const Handle(BRepAdaptor_HCurve2d)& ,
1769                                   Standard_Boolean&                   ,
1770                                   const TopAbs_Orientation            ,
1771                                   const Standard_Real                 ,
1772                                   const Standard_Real                 ,
1773                                   const Standard_Real                 ,
1774                                   Standard_Real&                      ,
1775                                   Standard_Real&                      ,
1776                                   const Standard_Boolean              ,
1777                                   const Standard_Boolean              ,
1778                                   const Standard_Boolean              ,
1779                                   const Standard_Boolean              ,
1780                                   const Standard_Boolean              ,
1781                                   const Standard_Boolean              ,
1782                                   const Standard_Boolean              ,
1783                                   const math_Vector&                  )
1784 {
1785   Standard_Failure::Raise("PerformSurf Not Implemented");
1786
1787 }
1788 //=======================================================================
1789 //function : ExtentOneCorner
1790 //purpose  : extends the spine of the stripe S on the side of the vertex V
1791 // PMN : 28/11/97 : Reproduces the code of fillets, and it seems to work better...
1792 //=======================================================================
1793
1794 void ChFi3d_ChBuilder::ExtentOneCorner(const TopoDS_Vertex&          V,
1795                                        const Handle(ChFiDS_Stripe)&  S)
1796 {
1797   Standard_Integer      Sens = 0;
1798   Standard_Real         Coeff = 0.5;
1799   Handle(ChFiDS_Spine)  Spine = S->Spine();
1800   ChFi3d_IndexOfSurfData(V,S,Sens);
1801   if (Spine->IsTangencyExtremity((Sens == 1))) return; //No extension on queue
1802   Standard_Real dU = Spine->LastParameter(Spine->NbEdges());
1803   if (Sens == 1) {
1804     Spine->SetFirstParameter(-dU*Coeff);
1805     Spine->SetFirstTgt(0.);
1806   }
1807   else {
1808     Spine->SetLastParameter(dU*(1.+Coeff));
1809     Spine->SetLastTgt(dU);
1810   }
1811 /*
1812   Standard_Integer Sens;
1813   Standard_Boolean isfirst;
1814   Standard_Integer Iedge = 1;
1815   Standard_Real d1, d2;
1816
1817   Handle(ChFiDS_Spine) Spine = S->Spine();
1818   Handle(ChFiDS_ChamfSpine)
1819       chsp = Handle(ChFiDS_ChamfSpine)::DownCast(Spine);
1820   chsp->Dists(d1,d2); 
1821   Standard_Integer IE = ChFi3d_IndexOfSurfData(V,S,Sens);
1822   isfirst = (Sens == 1);
1823   if (!isfirst)  
1824     Iedge = Spine->NbEdges();
1825  
1826   TopTools_ListIteratorOfListOfShape It, Jt;
1827   TopoDS_Edge E1, E2, Ec;
1828   TopoDS_Face F1, F2, Fc;
1829   TopoDS_Edge EdgeSp = Spine->Edges(Iedge);
1830
1831   ConexFaces(Spine,Iedge,F1,F2);
1832
1833   for (Jt.Initialize(myVEMap(V));Jt.More();Jt.Next()) {
1834     Ec = TopoDS::Edge(Jt.Value());
1835     if (!Ec.IsSame(EdgeSp)){
1836       for (It.Initialize(myEFMap(Ec));It.More();It.Next()) {
1837         Fc = TopoDS::Face(It.Value());
1838         if (Fc.IsSame(F1))
1839           E1 = Ec;
1840         else if (Fc.IsSame(F2))
1841           E2 = Ec;
1842       } 
1843     }
1844   }
1845
1846   gp_Vec tg1, tg2, tgsp;
1847   gp_Pnt tmp, ptgui;
1848   Spine->D1(Spine->Absc(V),ptgui,tgsp);
1849   if (isfirst)
1850     tgsp.Reverse();
1851
1852   // tg1
1853   BRepAdaptor_Curve curv;
1854   curv.Initialize(E1);
1855   curv.D1(curv.FirstParameter(),tmp,tg1); //pour eviter les projections
1856   tg1.Reverse();
1857     // pbm d'erreurs d'approx : baisser la tolerance
1858   if( !tmp.IsEqual(ptgui,tolesp*1.e2) )
1859     curv.D1(curv.LastParameter(),tmp,tg1);
1860
1861   // tg2
1862   curv.Initialize(E2);
1863   curv.D1(curv.FirstParameter(),tmp,tg2);
1864   tg2.Reverse();
1865   if( !tmp.IsEqual(ptgui,tolesp*1.e2) )
1866     curv.D1(curv.LastParameter(),tmp,tg2);
1867
1868   // calcul de dspine
1869   Standard_Real dspine;
1870   Standard_Real d1plus = 0.;
1871   Standard_Real d2plus = 0.;
1872
1873   Standard_Real sinalpha = tg1.Dot(tgsp);
1874   if (sinalpha < 0.){
1875     Standard_Real cosalpha = Sqrt(1 - sinalpha*sinalpha);
1876     d1plus = -d1*sinalpha/cosalpha;
1877   }
1878   sinalpha = tg2.Dot(tgsp);
1879   if (sinalpha < 0.){
1880     Standard_Real cosalpha = Sqrt(1 - sinalpha*sinalpha);
1881     d2plus = -d2*sinalpha/cosalpha;
1882   }
1883   dspine = d1plus;
1884   if (d2plus > d1plus)
1885     dspine = d2plus;
1886
1887   dspine *=1.5;
1888
1889   // ExtentOneCorner
1890   if (isfirst) {
1891     Spine->SetFirstParameter(-dspine);
1892     Spine->SetFirstTgt(0.);
1893   }
1894   else{
1895     Standard_Real param = Spine->LastParameter(Spine->NbEdges());
1896     Spine->SetLastParameter(param+dspine);
1897     Spine->SetLastTgt(param);
1898   } */
1899 }
1900
1901
1902
1903 //=======================================================================
1904 //function : ExtentTwoCorner
1905 //purpose  : extends the spines of the stripes contained in the list LS,
1906 //           on the side of the vertex V
1907 //=======================================================================
1908
1909
1910 void ChFi3d_ChBuilder::ExtentTwoCorner(const TopoDS_Vertex&        V,
1911                                        const ChFiDS_ListOfStripe&  LS)
1912 {
1913   Standard_Integer Sens = 0;
1914   ChFiDS_ListIteratorOfListOfStripe itel(LS);
1915   Standard_Boolean FF = Standard_True;
1916   Standard_Boolean isfirst[2];
1917   Standard_Integer Iedge[2];
1918   Iedge[0] = 1;
1919   Iedge[1] = 1;
1920   Handle(ChFiDS_Stripe) Stripe[2];
1921   Handle(ChFiDS_Spine) Spine[2];
1922
1923   Standard_Integer i = 0;
1924   for (; itel.More(); itel.Next(),i++) {    
1925   ChFi3d_IndexOfSurfData(V,itel.Value(),Sens);
1926     if (!FF)
1927       if ( Stripe[1] == itel.Value())
1928         Sens = -Sens; 
1929     
1930     Stripe[i] = itel.Value();
1931     isfirst[i] = (Sens == 1);
1932     Spine[i] = Stripe[i]->Spine();
1933     if( !isfirst[i] )
1934       Iedge[i] = Spine[i]->NbEdges();
1935     FF = Standard_False;
1936   }
1937
1938
1939   Handle(ChFiDS_ChamfSpine) chsp[2];
1940   Standard_Real d[4], dis[2] = { 0.0, 0.0 };
1941   Standard_Integer j;
1942   TopoDS_Face F[4];
1943   Standard_Real tmpang, tmd;
1944   Standard_Boolean disonF1;
1945
1946
1947   for (i=0, j=0; i<2; i++, j += 2) {
1948     chsp[i] = Handle(ChFiDS_ChamfSpine)::DownCast(Spine[i]);
1949     ConexFaces(Spine[i],Iedge[i],F[j],F[j+1]);
1950
1951     if (chsp[i]->IsChamfer() == ChFiDS_Sym) {
1952       chsp[i]->GetDist(d[j]);
1953       d[j+1] = d[j]; 
1954     }
1955     else if (chsp[i]->IsChamfer() == ChFiDS_TwoDist) {
1956       chsp[i]->Dists(d[j],d[j+1]); 
1957     }
1958     else {
1959       chsp[i]->GetDistAngle(tmd, tmpang, disonF1);
1960       // an approximate calculation of distance 2 is done
1961       if (disonF1) {
1962         d[j]   = tmd;
1963         d[j+1] = tmd * tan(tmpang); 
1964       }
1965       else
1966       {
1967         d[j]   = tmd * tan(tmpang);
1968         d[j+1] = tmd;
1969       }
1970     }
1971
1972   }
1973
1974   Standard_Boolean notfound = Standard_True;
1975   i = 0; 
1976   while (notfound && (i<2)) {
1977     j = 0;
1978     while (notfound && (j<2)) {
1979       if (F[i].IsSame(F[j+2])) {
1980         dis[0] = d[i];
1981 //      dOnArc[0] = d[(i+1)%2];
1982
1983         dis[1] = d[j + 2];
1984 //      dOnArc[1] = d[(j+1)%2 + 2];
1985         notfound = Standard_False;
1986       }
1987       j++;
1988     }
1989     i++;
1990   }
1991   // ExtentTwoCorner
1992
1993   ChFiDS_State State[2];
1994
1995   for (i=0; i<2; i++) {
1996     if (isfirst[i])
1997       State[i] = Spine[i]->FirstStatus();
1998     else
1999       State[i] = Spine[i]->LastStatus();
2000  }
2001   
2002   if (State[0] == ChFiDS_AllSame ){
2003 /*      
2004    // The greatest intersection of the chamfer is found (on the incident edge)
2005     // with the face at end
2006     i = 0;
2007     j = 1;
2008     if(dOnArc[j] > dOnArc[i]) {
2009       Standard_Integer temp = i;
2010       i = j;
2011       j = temp;
2012     }
2013     ExtentOneCorner( V, Stripe[i] ); */
2014
2015     // it is necessary that two chamfers touch the face at end 
2016     for (j=0; j<2; j++)
2017       ExtentOneCorner( V, Stripe[j] ); 
2018   }
2019   else if ((State[0] == ChFiDS_OnSame) && (State[1] == ChFiDS_OnSame)) {
2020
2021     ExtentSpineOnCommonFace(Spine[0],Spine[1],V,dis[0],dis[1],
2022                             isfirst[0],isfirst[1]);
2023   }
2024
2025 }
2026
2027 //=======================================================================
2028 //function : ExtentThreeCorner
2029 //purpose  : 
2030 //=======================================================================
2031
2032 void ChFi3d_ChBuilder::ExtentThreeCorner(const TopoDS_Vertex& V,
2033                                          const ChFiDS_ListOfStripe& LS)
2034 {
2035   Standard_Integer Sens = 0;
2036   ChFiDS_ListOfStripe check;
2037   Standard_Boolean isfirst[3];
2038   Standard_Integer Iedge[3];
2039   Iedge[0] = 1;
2040   Iedge[1] = 1;
2041   Iedge[2] = 1;  
2042   Handle(ChFiDS_Spine) Spine[3];
2043
2044   Standard_Integer i = 0;
2045   for(ChFiDS_ListIteratorOfListOfStripe itel(LS); itel.More(); itel.Next(), i++) {    
2046     Handle(ChFiDS_Stripe) Stripe = itel.Value(); 
2047     ChFi3d_IndexOfSurfData(V,Stripe,Sens);
2048     for(ChFiDS_ListIteratorOfListOfStripe ich(check); ich.More(); ich.Next()){
2049       if(Stripe == ich.Value()){
2050         Sens = -Sens;
2051         break;
2052       }
2053     }
2054
2055     isfirst[i] = (Sens == 1);
2056     Spine[i] = Stripe->Spine();
2057     if( !isfirst[i] )
2058       Iedge[i] = Spine[i]->NbEdges();
2059
2060     check.Append(Stripe);
2061   }
2062   
2063   Standard_Real d[3][2], tmd, tmpangle;
2064   Standard_Boolean disonF1;
2065   Standard_Integer j;
2066   TopoDS_Face F[3][2];
2067
2068   Handle(ChFiDS_ChamfSpine) chsp[3];
2069
2070   for (i=0; i<3; i++) {
2071     chsp[i] = Handle(ChFiDS_ChamfSpine)::DownCast(Spine[i]);
2072     ConexFaces(Spine[i],Iedge[i],F[i][0],F[i][1]);
2073
2074     if (chsp[i]->IsChamfer() == ChFiDS_Sym) {
2075       chsp[i]->GetDist(d[i][0]); 
2076       d[i][1] = d[i][0];
2077     }
2078     else if (chsp[i]->IsChamfer() == ChFiDS_TwoDist) {
2079        chsp[i]->Dists(d[i][0],d[i][1]); 
2080     }
2081     else {
2082       chsp[i]->GetDistAngle(tmd, tmpangle, disonF1);
2083       // an approximate calculation of distance 2 is done
2084
2085       if (disonF1) {
2086         d[i][0] = tmd;
2087         d[i][1] = tmd * tan(tmpangle); 
2088       }
2089       else {
2090         d[i][0] = tmd * tan(tmpangle);
2091         d[i][1] = tmd;
2092       }     
2093     }
2094   }
2095
2096
2097   // dis[i][j] distance from chamfer i on the common face with 
2098   // chamfer j
2099   Standard_Real dis[3][3];
2100
2101   for (i=0; i<3; i++) {
2102 //    for (Standard_Integer ii=0; ii<3; ii++) {
2103 //      j = (i+ii)%3;
2104       j = (i+1)%3;
2105       Standard_Boolean notfound = Standard_True;
2106       Standard_Integer k, l;
2107       k = 0;
2108       while (notfound && (k<2)) {
2109         l = 0;
2110         while (notfound && (l<2)) {
2111           if (F[i][k].IsSame(F[j][l])) {
2112             dis[i][j] = d[i][k];
2113             dis[j][i] = d[j][l];
2114             notfound = Standard_False;
2115           }
2116           l++;
2117         }
2118         k++;
2119       } 
2120 //    }
2121   }
2122    
2123   //ExtentThreeCorner
2124   for (i=0; i<3; i++) {
2125     j = (i+1)%3;
2126     ExtentSpineOnCommonFace(Spine[i],Spine[j],V,dis[i][j],dis[j][i],
2127                             isfirst[i],isfirst[j]);
2128   }
2129
2130 }
2131
2132 //=======================================================================
2133 //function : SetRegul
2134 //purpose  : 
2135 //=======================================================================
2136
2137 void ChFi3d_ChBuilder::SetRegul()
2138
2139 {
2140   ChFiDS_ListIteratorOfRegularities it;
2141   TopTools_ListIteratorOfListOfShape itc;
2142   TopTools_ListIteratorOfListOfShape its1;
2143   TopTools_ListIteratorOfListOfShape its2;
2144   BRepAdaptor_Surface S;
2145   BRepAdaptor_Curve2d PC;
2146   Standard_Real u,v,t;
2147   gp_Pnt p;
2148   gp_Vec n1,n2,du,dv;
2149   BRep_Builder B;
2150   Standard_Real Seuil = M_PI/360.;
2151   Standard_Real Seuil2 = Seuil * Seuil;
2152   for (it.Initialize(myRegul); it.More(); it.Next()){
2153     const ChFiDS_Regul& reg = it.Value();
2154     itc.Initialize(myCoup->NewEdges(reg.Curve()));
2155     if(itc.More()){
2156       TopoDS_Edge E = TopoDS::Edge(itc.Value());
2157       if(reg.IsSurface1() && reg.IsSurface2()){
2158         its1.Initialize(myCoup->NewFaces(reg.S1()));
2159         its2.Initialize(myCoup->NewFaces(reg.S2()));
2160         if(its1.More() && its2.More()){
2161           TopoDS_Face F1 = TopoDS::Face(its1.Value());
2162           TopoDS_Face F2 = TopoDS::Face(its2.Value());
2163           S.Initialize(F1,Standard_False);
2164           PC.Initialize(E,F1);
2165           t = 0.5*(PC.FirstParameter() + PC.LastParameter());
2166           PC.Value(t).Coord(u,v);
2167           S.D1(u,v,p,du,dv);
2168           n1 = du.Crossed(dv);
2169
2170           S.Initialize(F2,Standard_False);
2171           PC.Initialize(E,F2);
2172           PC.Value(t).Coord(u,v);
2173           S.D1(u,v,p,du,dv);
2174           n2 = du.Crossed(dv);
2175           
2176           if(n1.SquareMagnitude() > 1.e-14 && n2.SquareMagnitude() > 1.e-14){
2177             n1.Normalize();
2178             n2.Normalize();
2179             Standard_Real sina2 = n1.Crossed(n2).SquareMagnitude();
2180             if(sina2 < Seuil2) {
2181               GeomAbs_Shape cont = ChFi3d_evalconti(E,F1,F2);
2182               B.Continuity(E,F1,F2,cont);
2183             }
2184           }
2185         }
2186       }
2187     }
2188   }
2189 }
2190
2191 //=======================================================================
2192 //function : ConexFaces
2193 //purpose  : F1, F2 are connected to edge so that F1 corresponds to distance
2194 //=======================================================================
2195
2196 void ChFi3d_ChBuilder::ConexFaces (const Handle(ChFiDS_Spine)&  Spine,
2197                                    const Standard_Integer       IEdge,
2198                                    TopoDS_Face&                 F1,
2199                                    TopoDS_Face&                 F2) const
2200 {
2201   BRepAdaptor_Surface Sb1,Sb2;
2202   TopAbs_Orientation tmp1,tmp2;
2203   Standard_Integer RC,Choix;
2204   TopoDS_Face f1,f2,ff1,ff2;
2205
2206   //calculate the reference orientation
2207   // ChFi3d_Builder::StripeOrientations is private
2208   SearchCommonFaces(myEFMap,Spine->Edges(1),ff1,ff2);
2209   ff1.Orientation(TopAbs_FORWARD);
2210   Sb1.Initialize(ff1);
2211   ff2.Orientation(TopAbs_FORWARD);
2212   Sb2.Initialize(ff2);
2213   RC = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(1),tmp1,tmp2);
2214                                   
2215   //calculate the connected faces
2216   SearchCommonFaces(myEFMap,Spine->Edges(IEdge),f1,f2);
2217   Sb1.Initialize(f1);
2218   Sb2.Initialize(f2);
2219   Choix = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(IEdge),tmp1,tmp2);
2220
2221   if (RC%2 != Choix%2) {
2222     F1 = f2;
2223     F2 = f1;
2224   }
2225   else {
2226     F1 = f1;
2227     F2 = f2;
2228   }
2229 }
2230
2231
2232 //=======================================================================
2233 //function : FindChoiceDistAngle
2234 //purpose  : F1, F2 connected to the edge so that F1 corresponds to distance
2235 //=======================================================================
2236
2237 Standard_Integer ChFi3d_ChBuilder::FindChoiceDistAngle(const Standard_Integer Choice,
2238                                                        const Standard_Boolean DisOnF1) const
2239 {
2240   Standard_Integer ch = 0;  
2241   if (!DisOnF1) {
2242
2243     switch (Choice) {
2244       case 1 : ch = 2;
2245                break;
2246       case 2 : ch = 1;
2247                break;
2248       case 3 : ch = 8;
2249                break;
2250       case 4 : ch = 7;
2251                break;
2252       case 5 : ch = 6;
2253                break;
2254       case 6 : ch = 5;
2255                break;
2256       case 7 : ch = 4;
2257                break;
2258       case 8 : ch = 3;
2259                break;
2260     }
2261
2262   }
2263   else
2264     ch = Choice;
2265  
2266   return ch;
2267 }