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