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