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