0024428: Implementation of LGPL license
[occt.git] / src / BRepFill / BRepFill_MultiLine.cxx
1 // Created on: 1994-11-14
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <BRepFill_MultiLine.ixx>
18
19 #include <BRepIntCurveSurface_Inter.hxx>
20 #include <gp.hxx>
21 #include <gp_Lin.hxx>
22 #include <gp_Ax3.hxx>
23 #include <gp_Lin2d.hxx>
24 #include <gp_Circ2d.hxx>
25 #include <Precision.hxx>
26 #include <BRep_Tool.hxx>
27 #include <Geom_Line.hxx>
28 #include <Geom_Plane.hxx>
29 #include <Geom_TrimmedCurve.hxx>
30 #include <Geom2d_TrimmedCurve.hxx>
31 #include <Geom_Surface.hxx>
32 #include <Geom_RectangularTrimmedSurface.hxx>
33 #include <Geom2d_Line.hxx>
34 #include <GeomProjLib.hxx>
35 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
36 #include <Geom2dInt_GInter.hxx>
37 #include <IntRes2d_IntersectionPoint.hxx>
38 #include <Standard_ConstructionError.hxx>
39 #include <IntRes2d_IntersectionSegment.hxx>
40 #include <TopExp_Explorer.hxx>
41 #include <TopoDS.hxx>
42 #include <ElCLib.hxx>
43
44
45 #include <GeomAdaptor_Surface.hxx>
46 #include <GeomAbs_SurfaceType.hxx>
47
48 #ifdef DRAW
49 #include <DrawTrSurf.hxx>
50 #endif
51
52 #ifdef DEB
53 static Standard_Boolean AffichCurve = Standard_False;
54 static Standard_Integer NbProj = 1;
55 #endif
56 //POP pour NT
57 #include <stdio.h>
58
59 //=======================================================================
60 //function : isIsoU
61 //purpose  : 
62 //=======================================================================
63
64 static Standard_Boolean isIsoU(const TopoDS_Face& Face,
65                                const TopoDS_Edge& Edge ) 
66 {
67   Handle(Geom2d_Curve) C;
68   Handle(Geom2d_Line) Li;
69   Standard_Real f,l;
70
71   C = BRep_Tool::CurveOnSurface(Edge,Face, f, l);
72   if ( C.IsNull()) {
73     Standard_ConstructionError::Raise ("BRepFill_MultiLine : Edge without PCurve");
74   }
75   
76   gp_Dir2d D = C->DN(f,1);
77
78   if (Abs(D.Dot(gp::DX2d())) < Abs(D.Dot(gp::DY2d()))) 
79     return Standard_True;
80   else            
81     return Standard_False;
82 }
83
84
85
86
87 //=======================================================================
88 //function : BRepFill_MultiLine
89 //purpose  : 
90 //=======================================================================
91
92 BRepFill_MultiLine::BRepFill_MultiLine()
93 {
94 }
95
96
97 //=======================================================================
98 //function : BRepFill_MultiLine
99 //purpose  : 
100 //=======================================================================
101
102 BRepFill_MultiLine::BRepFill_MultiLine(const TopoDS_Face&     Face1, 
103                                        const TopoDS_Face&     Face2,
104                                        const TopoDS_Edge&     Edge1,
105                                        const TopoDS_Edge&     Edge2,
106                                        const Standard_Boolean Inv1,
107                                        const Standard_Boolean Inv2,
108                                        const Handle(Geom2d_Curve)& Bissec) :
109 myFace1(Face1 ),
110 myFace2(Face2 ),
111 myBis  (Bissec),
112 myKPart(0)
113 {
114   // eval if myedges are IsoU or not
115   myIsoU1 = isIsoU(Face1, Edge1);
116   myIsoU2 = isIsoU(Face2, Edge2);
117
118   // eval myU1, myV1, myU2, myV2;
119   Handle(Geom_Plane) RefPlane;
120   Handle(Geom_Plane) BasisPlane = new Geom_Plane(0.,0.,1.,0.);
121   TopLoc_Location L;
122
123   TopExp_Explorer Exp;
124   Standard_Real Umin = 0.,Vmin = 0.,Umax = 0.,Vmax = 0.,U,V;
125   gp_Pnt2d P1,P2;
126   gp_Vec DZ;
127   gp_Pnt P;
128
129   // Result on Face1
130   Standard_Boolean First = Standard_True;
131   for (Exp.Init(myFace1,TopAbs_EDGE);Exp.More(); Exp.Next()) {
132     TopoDS_Edge CurEdge = TopoDS::Edge(Exp.Current());
133     BRep_Tool::UVPoints(CurEdge,myFace1,P1,P2);
134     if ( First) {
135       First = Standard_False;
136       Umin = Min(P1.X(),P2.X());
137       Umax = Max(P1.X(),P2.X());
138  
139       Vmin = Min(P1.Y(),P2.Y());
140       Vmax = Max(P1.Y(),P2.Y());
141     }
142     else {
143       U    = Min(P1.X(),P2.X());
144       Umin = Min(Umin,U);
145       U    = Max(P1.X(),P2.X());
146       Umax = Max(Umax,U);
147
148       V    = Min(P1.Y(),P2.Y());
149       Vmin = Min(Vmin,V);
150       V    = Max(P1.Y(),P2.Y());
151       Vmax = Max(Vmax,V);
152     }
153   }
154   
155
156   // return isos in their domain of restriction.
157   Handle(Geom_Curve) UU1, UU2, VV1, VV2;
158   Handle(Geom_Surface) S;
159   S = BRep_Tool::Surface(myFace1,L);  
160   if (!L.IsIdentity())
161     S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
162
163   if ( myIsoU1) {
164     if (!BRep_Tool::Degenerated(Edge1) && !Inv1) {
165       UU1 = S->UIso(Umin);
166       GeomAdaptor_Curve Dummy(UU1);
167       if (Dummy.GetType() == GeomAbs_Circle && 
168           Dummy.Circle().Radius() < Precision::Confusion()) {
169         UU1 = S->UIso(Umax);
170       }
171     }
172     else {
173       UU1 = S->UIso(Umax);
174       GeomAdaptor_Curve Dummy(UU1);
175       if (Dummy.GetType() == GeomAbs_Circle && 
176           Dummy.Circle().Radius() < Precision::Confusion()) {
177         UU1 = S->UIso(Umin);
178       }
179     }
180     VV1 = S->VIso(Vmin);
181   }
182   else {
183     if (!BRep_Tool::Degenerated(Edge1) && !Inv1) {
184       UU1 = S->VIso(Vmin);    
185       GeomAdaptor_Curve Dummy(UU1);
186       if (Dummy.GetType() == GeomAbs_Circle && 
187           Dummy.Circle().Radius() < Precision::Confusion()) {
188         UU1 = S->VIso(Vmax);
189       }
190     }
191     else {
192       UU1 = S->VIso(Vmax);
193       GeomAdaptor_Curve Dummy(UU1);
194       if (Dummy.GetType() == GeomAbs_Circle && 
195           Dummy.Circle().Radius() < Precision::Confusion()) {
196         UU1 = S->VIso(Vmin);
197       }
198     }
199     VV1 = S->UIso(Umin);
200   }
201
202   if ( myIsoU1) {
203     Standard_Real dummyUmin = Umin, dummyUmax = Umax;
204     Umin = Vmin; 
205     Umax = Vmax;
206     Vmin = dummyUmin;
207     Vmax = dummyUmax;
208   }
209
210   // try duplication
211   GeomAdaptor_Surface GAS1(S);
212   GeomAbs_SurfaceType Type1 = GAS1.GetType();
213
214   if ( UU1->IsPeriodic()) {
215     ElCLib::AdjustPeriodic(UU1->FirstParameter(),
216                            UU1->LastParameter(),
217                            Precision::PConfusion(),
218                            Umin, Umax);
219   }
220   if ( VV1->IsPeriodic()) {
221     ElCLib::AdjustPeriodic(VV1->FirstParameter(),
222                            VV1->LastParameter(),
223                            Precision::PConfusion(),
224                            Vmin, Vmax);
225   }
226   if (GAS1.GetType() == GeomAbs_Sphere) {
227     if (myIsoU1)
228       ElCLib::AdjustPeriodic(-M_PI/2.,M_PI/2.,
229                              Precision::PConfusion(),
230                              Umin, Umax);
231     else
232       ElCLib::AdjustPeriodic(-M_PI/2.,M_PI/2.,
233                              Precision::PConfusion(),
234                              Vmin, Vmax);
235   }
236   // end try duplication
237
238   myU1 = Geom2dAdaptor_Curve(GeomProjLib::Curve2d(UU1, BasisPlane),
239                              Umin, Umax);
240
241   UU1->D1(Umin, P, DZ);
242   RefPlane = new Geom_Plane(gp_Ax3(P,DZ,gp::DZ()));
243
244   myV1 = Geom2dAdaptor_Curve(GeomProjLib::Curve2d(VV1, RefPlane),
245                              Vmin, Vmax);
246
247
248   First = Standard_True;
249   for (Exp.Init(myFace2,TopAbs_EDGE);Exp.More(); Exp.Next()) {
250     TopoDS_Edge CurEdge = TopoDS::Edge(Exp.Current());
251     BRep_Tool::UVPoints(CurEdge,myFace2,P1,P2);
252     if ( First) {
253       First = Standard_False;
254       Umin = Min(P1.X(),P2.X());
255       Umax = Max(P1.X(),P2.X());
256  
257       Vmin = Min(P1.Y(),P2.Y());
258       Vmax = Max(P1.Y(),P2.Y());
259     }
260     else {
261       U    = Min(P1.X(),P2.X());
262       Umin = Min(Umin,U);
263       U    = Max(P1.X(),P2.X());
264       Umax = Max(Umax,U);
265
266       V    = Min(P1.Y(),P2.Y());
267       Vmin = Min(Vmin,V);
268       V    = Max(P1.Y(),P2.Y());
269       Vmax = Max(Vmax,V);
270     }
271   }
272
273   // return isos in their domain of restriction.
274   S = BRep_Tool::Surface(myFace2,L);
275
276   if (!L.IsIdentity())
277     S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
278
279   if ( myIsoU2) {
280     if (!BRep_Tool::Degenerated(Edge2) && !Inv2) {
281       UU2 = S->UIso(Umin);    
282       GeomAdaptor_Curve Dummy(UU2);
283       if (Dummy.GetType() == GeomAbs_Circle && 
284           Dummy.Circle().Radius() < Precision::Confusion()) {
285         UU2 = S->UIso(Umax);
286       }
287     }
288     else {
289       UU2 = S->UIso(Umax);
290       GeomAdaptor_Curve Dummy(UU2);
291       if (Dummy.GetType() == GeomAbs_Circle && 
292           Dummy.Circle().Radius() < Precision::Confusion()) {
293         UU2 = S->UIso(Umin);
294       }
295     }
296     VV2 = S->VIso(Vmin);
297   }
298   else {
299     if (!BRep_Tool::Degenerated(Edge2) && !Inv2) {
300       UU2 = S->VIso(Vmin);
301       GeomAdaptor_Curve Dummy(UU2);
302       if (Dummy.GetType() == GeomAbs_Circle && 
303           Dummy.Circle().Radius() < Precision::Confusion()) {
304         UU2 = S->VIso(Vmax);
305       }
306     }
307     else {
308       UU2 = S->VIso(Vmax);
309       GeomAdaptor_Curve Dummy(UU2);
310       if (Dummy.GetType() == GeomAbs_Circle && 
311           Dummy.Circle().Radius() < Precision::Confusion()) {
312         UU2 = S->VIso(Vmin);
313       }
314     }
315     VV2 = S->UIso(Umin);
316   }
317     
318   if ( myIsoU2) {
319     Standard_Real dummyUmin = Umin, dummyUmax = Umax;
320     Umin = Vmin; 
321     Umax = Vmax;
322     Vmin = dummyUmin;
323     Vmax = dummyUmax;
324   }
325
326   // try duplication
327   GeomAdaptor_Surface GAS2(S);
328   GeomAbs_SurfaceType Type2 = GAS2.GetType();
329
330   if ( UU2->IsPeriodic()) {
331     ElCLib::AdjustPeriodic(UU2->FirstParameter(),
332                            UU2->LastParameter(),
333                            Precision::PConfusion(),
334                            Umin, Umax);
335   }
336   if ( VV2->IsPeriodic()) {
337     ElCLib::AdjustPeriodic(VV2->FirstParameter(),
338                            VV2->LastParameter(),
339                            Precision::PConfusion(),
340                            Vmin, Vmax);
341   }
342   if (GAS2.GetType() == GeomAbs_Sphere) {
343     if (myIsoU2)
344       ElCLib::AdjustPeriodic(-M_PI/2.,M_PI/2.,
345                              Precision::PConfusion(),
346                              Umin, Umax);
347     else
348       ElCLib::AdjustPeriodic(-M_PI/2.,M_PI/2.,
349                              Precision::PConfusion(),
350                              Vmin, Vmax);
351   }
352   // end try duplication
353
354   myU2 = Geom2dAdaptor_Curve(GeomProjLib::Curve2d(UU2, BasisPlane),
355                              Umin, Umax);
356
357   UU2->D1(Umin, P, DZ);
358   RefPlane = new Geom_Plane(gp_Ax3(P,DZ,gp::DZ()));
359   myV2 = Geom2dAdaptor_Curve(GeomProjLib::Curve2d(VV2, RefPlane),
360                              Vmin, Vmax);
361
362   // eval if in a particular case.
363   // Particular case if :
364   //     1) - Straight Bissectrice
365   //        - Bissectrice orthogonal to the base element.
366   //        ==> Iso on 2 faces.
367   //     2) - Straight Bissectrice
368   //        - 2 surfaces are planes.
369   myCont  = GeomAbs_C0;
370
371   if ( myBis.GetType() == GeomAbs_Line) {
372     Standard_Real DeltaU = myBis.LastParameter()  - myBis.FirstParameter();
373     gp_Pnt2d P1 = ValueOnF1(myBis.FirstParameter() + 0.1*DeltaU);
374     gp_Pnt2d P2 = ValueOnF1(myBis.FirstParameter() + 0.9*DeltaU);
375     if ( myIsoU1) {
376       if ( Abs(P1.Y() - P2.Y()) < Precision::Confusion())
377         myKPart = 1;
378     }
379     else {
380       if ( Abs(P1.X() - P2.X()) < Precision::Confusion())
381         myKPart = 1;
382     }
383     
384     if ( myKPart == 1)
385       myCont = GeomAbs_G1;
386
387     if ( (Type1 == GeomAbs_Plane) && (Type2 == GeomAbs_Plane)) {
388       myKPart = 2;
389     }
390   }
391 }
392
393
394 //=======================================================================
395 //function : IsParticularCase
396 //purpose  : 
397 //=======================================================================
398
399 Standard_Boolean BRepFill_MultiLine::IsParticularCase() const 
400 {
401   return ( myKPart != 0);
402 }
403
404
405 //=======================================================================
406 //function : Curves
407 //purpose  : 
408 //=======================================================================
409
410 void BRepFill_MultiLine::Curves(Handle(Geom_Curve)& Curve,
411                                 Handle(Geom2d_Curve)& PCurve1,
412                                 Handle(Geom2d_Curve)& PCurve2) const 
413 {
414   if ( myKPart == 1) {
415     gp_Pnt2d      P1,P2,PMil;
416     Standard_Real f,l;
417
418     P1   = ValueOnF1(myBis.FirstParameter());
419     P2   = ValueOnF1(myBis.LastParameter());
420
421     // find value of the with medium point 
422     // the ends can be degenerated points.
423
424     PMil = ValueOnF1(0.5*(myBis.FirstParameter() + myBis.LastParameter()));
425     
426     TopLoc_Location L;
427     Handle(Geom_Surface) S = BRep_Tool::Surface(myFace1,L);
428     if (!L.IsIdentity())
429       S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
430     
431     Standard_Boolean Sens;
432     if ( !myIsoU1) {
433       Curve   = S->UIso(PMil.X());
434       Sens    = P1.Y() < P2.Y();
435       if ( Sens) 
436         Curve   = new Geom_TrimmedCurve(Curve, P1.Y(), P2.Y(), Sens);
437       else
438         Curve   = new Geom_TrimmedCurve(Curve, P2.Y(), P1.Y(), Sens);
439       
440       f = Curve->FirstParameter();
441       l = Curve->LastParameter();
442       if ( Sens) 
443         PCurve1 = new Geom2d_Line(gp_Pnt2d(PMil.X(),P1.Y() - f), gp::DY2d());
444       else
445         PCurve1 = new Geom2d_Line(gp_Pnt2d(PMil.X(),P1.Y() + f),-gp::DY2d());
446       PCurve1 = new Geom2d_TrimmedCurve( PCurve1 ,f ,l);
447     }
448     else {
449       Curve   = S->VIso(PMil.Y());
450       Sens = P1.X() < P2.X();
451       if (Sens)
452         Curve   = new Geom_TrimmedCurve(Curve, P1.X(), P2.X(), Sens);
453       else
454         Curve   = new Geom_TrimmedCurve(Curve, P2.X(), P1.X(), Sens);
455       
456       f = Curve->FirstParameter();
457       l = Curve->LastParameter();
458       if ( Sens) 
459         PCurve1 = new Geom2d_Line(gp_Pnt2d(P1.X() - f,PMil.Y()), gp::DX2d());
460       else
461         PCurve1 = new Geom2d_Line(gp_Pnt2d(P1.X() + f,PMil.Y()), -gp::DX2d());
462       PCurve1 = new Geom2d_TrimmedCurve( PCurve1 ,f ,l);
463     }
464                      
465     P1   = ValueOnF2(myBis.FirstParameter());
466     P2   = ValueOnF2(myBis.LastParameter());
467     PMil = ValueOnF2(0.5*(myBis.FirstParameter() + myBis.LastParameter()));
468                      
469     if (!myIsoU2) {
470       Sens = P1.Y() < P2.Y();
471       if ( Sens) 
472         PCurve2 = new Geom2d_Line(gp_Pnt2d(PMil.X(),(P1.Y() - f)), gp::DY2d());
473       else
474         PCurve2 = new Geom2d_Line(gp_Pnt2d(PMil.X(),(P1.Y() + f)), -gp::DY2d());
475     }
476     else {
477       Sens = P1.X() < P2.X();
478       if ( Sens) 
479         PCurve2 = new Geom2d_Line(gp_Pnt2d(P1.X() - f ,PMil.Y()), gp::DX2d());
480       else
481         PCurve2 = new Geom2d_Line(gp_Pnt2d(P1.X() + f ,PMil.Y()), -gp::DX2d());
482     }
483     PCurve2 = new Geom2d_TrimmedCurve( PCurve2 ,f ,l);
484   }
485   else if ( myKPart == 2) {
486     TopLoc_Location L;
487     
488     Handle(Geom_Surface) S = BRep_Tool::Surface(myFace1,L);
489     if (!L.IsIdentity())
490       S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
491     
492     if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) 
493       S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
494
495     Handle(Geom_Plane) Plane = Handle(Geom_Plane)::DownCast(S);
496     // eval the 3d curve corresponding to the bissectrice.
497     gp_Pnt2d P = myBis.Line().Location();
498     gp_Dir2d D = myBis.Line().Direction();
499     Handle(Geom_Line) Line = new Geom_Line(gp_Pnt(P.X(),P.Y(),0.),
500                                            gp_Dir(D.X(),D.Y(),0.) );
501     Handle(Geom_TrimmedCurve) TLine = 
502       new Geom_TrimmedCurve(Line, myBis.FirstParameter(),
503                                   myBis.LastParameter());
504     Curve = GeomProjLib::ProjectOnPlane(TLine, Plane, 
505                                         gp::DZ(), Standard_False);
506
507 #ifdef DRAW
508     if ( AffichCurve) {
509 //POP pour NT
510       //      char name[100];
511       char* name = new char[100];
512       sprintf(name,"C2_%d",NbProj);
513       DrawTrSurf::Set(name,TLine);
514       sprintf(name,"C3_%d",NbProj);
515       DrawTrSurf::Set(name,Curve);
516       sprintf(name,"SS_%d",NbProj);
517       DrawTrSurf::Set(name,Plane);
518       NbProj++;
519     }
520 #endif
521
522     // eval PCurve1
523     PCurve1 = GeomProjLib::Curve2d(Curve,Plane);
524     
525     // eval PCurve2
526     S = BRep_Tool::Surface(myFace2,L);
527     if (!L.IsIdentity())
528       S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
529     if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) 
530       S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
531     Plane = Handle(Geom_Plane)::DownCast(S);
532     PCurve2 = GeomProjLib::Curve2d(Curve,Plane);
533   }
534 }
535
536
537 //=======================================================================
538 //function : FirstParameter
539 //purpose  : 
540 //=======================================================================
541
542 Standard_Real BRepFill_MultiLine::FirstParameter() const 
543 {
544   return myBis.FirstParameter();
545 }
546
547
548 //=======================================================================
549 //function : LastParameter
550 //purpose  : 
551 //=======================================================================
552
553 Standard_Real BRepFill_MultiLine::LastParameter() const 
554 {
555   return myBis.LastParameter();
556 }
557
558
559 //=======================================================================
560 //function : Value
561 //purpose  : 
562 //=======================================================================
563
564 gp_Pnt BRepFill_MultiLine::Value(const Standard_Real U) const 
565 {
566   Handle(Geom_Surface) S;
567   TopLoc_Location L;
568
569   S = BRep_Tool::Surface(myFace1,L);  
570
571   gp_Pnt2d P2d = ValueOnF1(U);
572
573   gp_Pnt P3d = S->Value(P2d.X(), P2d.Y());
574   P3d.Transform(L.Transformation());
575
576   return P3d;
577 }
578
579
580 //=======================================================================
581 //function : ValueOnFace
582 //purpose  : 
583 //=======================================================================
584
585 static gp_Pnt2d ValueOnFace(const Standard_Real        U,
586                             const Geom2dAdaptor_Curve& TheBis,
587                             const Geom2dAdaptor_Curve& TheU,
588                             const Geom2dAdaptor_Curve& TheV,
589                             const Standard_Boolean     IsIsoU)
590 {
591   gp_Pnt2d P = TheBis.Value(U);
592
593   Geom2dAPI_ProjectPointOnCurve Ext(P,TheU.Curve(),
594                                     TheU.FirstParameter(),
595                                     TheU.LastParameter());
596 #ifdef DRAW
597   if (AffichCurve) {
598     char* TheUname = "TheU";
599     char* PP1name = "PP1";
600     DrawTrSurf::Set(TheUname,TheU.Curve());
601     DrawTrSurf::Set(PP1name,P);
602 //    DrawTrSurf::Set("TheU",TheU.Curve());
603 //    DrawTrSurf::Set("PP1",P);
604   }
605 #endif
606
607   Standard_Real UU =0., Dist = Precision::Infinite(), D1, D2;
608
609   if ( !Ext.NbPoints() == 0 ) {    
610     UU = Ext.LowerDistanceParameter();
611     Dist = Ext.LowerDistance();
612   }
613   // Control with `ends` 
614   D1 = P.Distance(TheU.Value(TheU.FirstParameter()));
615   D2 = P.Distance(TheU.Value(TheU.LastParameter()));
616
617   if (D1 < Dist || D2 < Dist) {
618     if ( Abs( D1 - D2) < Precision::Confusion()) {
619       if ( TheU.GetType() == GeomAbs_Circle) {
620         gp_Vec2d Axis = TheU.Circle().XAxis().Direction();
621         gp_Vec2d D12d = TheBis.DN(TheBis.FirstParameter(),1);
622         Standard_Real Ang = Axis.Angle(D12d);
623         if ( !TheU.Circle().IsDirect()) Ang = -Ang;
624         UU = ElCLib::InPeriod( Ang, TheU.FirstParameter(), 
625                                     TheU.FirstParameter() + 2*M_PI);
626         Dist = TheU.Circle().Radius();
627       }
628       else {
629 #ifdef DEB
630         cout << "MultiLine : D1 = D2 and the Curve is not a circle" << endl;
631         cout << "  ---> ValueOnFace failed at parameter U = " << U << endl;
632 #endif
633         Standard_ConstructionError::Raise("BRepFill_MultiLine: ValueOnFace");
634       }
635     }
636     else if ( D1 < D2) {
637       Dist = D1;
638       UU   = TheU.FirstParameter();
639     }
640     else {
641       Dist = D2;
642       UU   = TheU.LastParameter();
643     }
644   }
645
646   Standard_Real Tol = Precision::Confusion();
647   Standard_Real VV;
648
649   gp_Pnt2d PF = TheV.Value(TheV.FirstParameter());
650   gp_Pnt2d PL = TheV.Value(TheV.LastParameter());  
651   
652   if (Abs(Dist - Abs(PF.Y())) < Tol) {
653     VV = TheV.FirstParameter();
654   }
655   else if (Abs(Dist - Abs(PL.Y())) < Tol) {
656     VV = TheV.LastParameter();
657   }  
658   else {  
659     // test if the curve is at the side `negative Y`.
660     if ( Min( PF.Y(),PL.Y()) < -Tol)  Dist = -Dist;
661    
662     Handle(Geom2d_Line) Line 
663       = new Geom2d_Line(gp_Pnt2d(0., Dist), gp::DX2d());
664     
665 #ifdef DRAW
666     if (AffichCurve) {
667       static Standard_CString aTheV = "TheV" ;
668       DrawTrSurf::Set(aTheV,TheV.Curve());
669       static Standard_CString aLINF1 = "LINF1" ;
670       DrawTrSurf::Set(aLINF1,Line);
671     }
672 #endif    
673     
674     Geom2dAdaptor_Curve Cu1 = TheV;
675     Geom2dAdaptor_Curve Cu2( Line);
676     
677     Standard_Real TolConf = 0.;
678
679     Geom2dInt_GInter Intersector(Cu1,Cu2,TolConf,Tol);
680
681     if ( !Intersector.IsDone()) {
682 #ifdef DEB
683       cout << "Intersector not done" << endl;
684       cout << "  ---> ValueonFace failed at parameter U = " << U << endl;
685 #endif
686       return gp_Pnt2d(0.,0.);
687     }
688     else {
689       if ( Intersector.NbPoints() > 0) {
690         VV = Intersector.Point(1).ParamOnFirst();
691       }
692       else if ( Intersector.NbSegments() > 0) {
693         IntRes2d_IntersectionSegment Seg = Intersector.Segment(1);
694         Standard_Real VS1 = Seg.FirstPoint().ParamOnFirst();
695         Standard_Real VS2 = Seg.LastPoint().ParamOnFirst();
696         gp_Pnt2d      PS1 = TheV.Value(VS1);
697         gp_Pnt2d      PS2 = TheV.Value(VS2);
698         Standard_Real Alp = (Dist - PS1.Y())/(PS2.Y() - PS1.Y());
699         VV = Alp*(VS2 - VS1) + VS1;
700       }
701       else {
702 #ifdef DEB
703         cout << "Intersector done, but no points found" << endl;
704         cout << "  ---> ValueonFace failed at parameter U = " << U << endl;
705 #endif
706         if (Abs(Dist - PL.Y()) < Abs(Dist - PF.Y()))
707           VV = TheV.LastParameter();
708         else 
709           VV = TheV.FirstParameter();
710       }
711     }
712   }
713
714   if ( IsIsoU) 
715     return gp_Pnt2d(VV,UU);
716   else
717     return gp_Pnt2d(UU,VV);
718 }
719
720 //=======================================================================
721 //function : ValueOnF1
722 //purpose  : 
723 //=======================================================================
724
725 gp_Pnt2d BRepFill_MultiLine::ValueOnF1(const Standard_Real U) const 
726 {
727   return ValueOnFace(U,myBis,myU1,myV1,myIsoU1);
728 }
729
730
731 //=======================================================================
732 //function : ValueOnF2
733 //purpose  : 
734 //=======================================================================
735
736 gp_Pnt2d BRepFill_MultiLine::ValueOnF2(const Standard_Real U) const 
737 {
738   return ValueOnFace(U,myBis,myU2,myV2,myIsoU2);
739 }
740
741 //=======================================================================
742 //function : Value3dOnF1OnF2
743 //purpose  : 
744 //=======================================================================
745
746 void BRepFill_MultiLine::Value3dOnF1OnF2(const Standard_Real U,
747                                                gp_Pnt&       P3d,
748                                                gp_Pnt2d&     PF1,
749                                                gp_Pnt2d&     PF2)
750 const
751 {
752   PF1 = ValueOnFace(U,myBis,myU1,myV1,myIsoU1);
753   PF2 = ValueOnFace(U,myBis,myU2,myV2,myIsoU2);
754
755   Handle(Geom_Surface) S;
756   TopLoc_Location L;
757
758   S = BRep_Tool::Surface(myFace1,L);  
759   P3d = S->Value(PF1.X(), PF1.Y());
760   P3d.Transform(L.Transformation());
761 }
762
763 //=======================================================================
764 //function : Continuity
765 //purpose  : 
766 //=======================================================================
767
768 GeomAbs_Shape BRepFill_MultiLine::Continuity() const
769 {
770   return myCont;
771 }