0024255: Regressions in test cases on OCCT vc9 win64 Release
[occt.git] / src / BRepFill / BRepFill_TrimEdgeTool.cxx
1 // Created on: 1995-04-24
2 // Created by: Bruno DUMORTIER
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 #include <BRepFill_TrimEdgeTool.ixx>
18 #include <BRep_Tool.hxx>
19 #include <Bisector_BisecAna.hxx>
20 #include <Geom2d_Curve.hxx>
21 #include <Geom2d_TrimmedCurve.hxx>
22 #include <Geom2d_CartesianPoint.hxx>
23 #include <Geom_Curve.hxx>
24 #include <GeomProjLib.hxx>
25 #include <Geom_TrimmedCurve.hxx>
26 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
27 #include <Geom2dInt_GInter.hxx>
28 #include <gp_Pnt.hxx>
29 #include <TopLoc_Location.hxx>
30 #include <TopoDS.hxx>
31 #include <Precision.hxx>
32 #include <IntRes2d_IntersectionPoint.hxx>
33 #include <IntRes2d_IntersectionSegment.hxx>
34 #include <ElCLib.hxx>
35 #include <StdFail_NotDone.hxx>
36 #ifdef OCCT_DEBUG
37 //#define DRAW
38 #ifdef DRAW
39 #include <DrawTrSurf.hxx>
40 #include <DBRep.hxx>
41 static Standard_Boolean Affich       = Standard_False;
42 static Standard_Boolean AffichInt    = Standard_False;
43 static Standard_Integer intind       = 0;
44 #endif
45 #endif
46
47
48 //=======================================================================
49 //function : SimpleExpression
50 //purpose  : 
51 //=======================================================================
52
53 static void SimpleExpression (const Bisector_Bisec&        B, 
54   Handle(Geom2d_Curve)&  Bis)
55 {
56   Bis = B.Value();
57
58   Handle(Standard_Type) BT = Bis->DynamicType();
59   if (BT == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
60     Handle(Geom2d_TrimmedCurve) TrBis 
61       = Handle(Geom2d_TrimmedCurve)::DownCast(Bis);
62     Handle(Geom2d_Curve) BasBis = TrBis->BasisCurve();
63     BT = BasBis->DynamicType();
64     if (BT == STANDARD_TYPE(Bisector_BisecAna)) {
65       Bis = Handle(Bisector_BisecAna)::DownCast(BasBis)->Geom2dCurve();
66       Bis = new Geom2d_TrimmedCurve (Bis,
67         TrBis->FirstParameter(),
68         TrBis->LastParameter());
69     }
70   }
71 }
72
73
74 //=======================================================================
75 //function : BRepFill_TrimEdgeTool
76 //purpose  : 
77 //=======================================================================
78
79 BRepFill_TrimEdgeTool::BRepFill_TrimEdgeTool()
80 {
81 }
82
83
84 //=======================================================================
85 //function : BRepFill_TrimEdgeTool
86 //purpose  : 
87 //=======================================================================
88
89 BRepFill_TrimEdgeTool::BRepFill_TrimEdgeTool
90   (const Bisector_Bisec& Bisec,
91   const Handle(Geom2d_Geometry)& S1,
92   const Handle(Geom2d_Geometry)& S2,
93   const Standard_Real   Offset) :
94 myOffset(Offset),
95   myBisec(Bisec)
96 {
97   isPoint1 = (S1->DynamicType() == STANDARD_TYPE(Geom2d_CartesianPoint));
98   isPoint2 = (S2->DynamicType() == STANDARD_TYPE(Geom2d_CartesianPoint));
99
100   // return geometries of shapes.
101   //  Standard_Real f,l;
102   if (isPoint1) {
103     myP1 = Handle(Geom2d_Point)::DownCast(S1)->Pnt2d();
104   }
105   else {
106     myC1 = Handle(Geom2d_Curve)::DownCast(S1);
107 #ifdef DRAW
108     if ( Affich) {
109       //POP pour NT
110       char* myC1name = "myC1";
111       DrawTrSurf::Set(myC1name,myC1);
112       //      DrawTrSurf::Set("myC1",myC1);
113     }
114 #endif
115   }
116   if (isPoint2) {
117     myP2 = Handle(Geom2d_Point)::DownCast(S2)->Pnt2d();
118   }
119   else {
120     myC2 = Handle(Geom2d_Curve)::DownCast(S2);
121 #ifdef DRAW
122     if ( Affich) {
123       char* myC2name = "myC2";
124       DrawTrSurf::Set(myC2name,myC2);
125       //      DrawTrSurf::Set("myC2",myC2);
126     }
127 #endif
128   }
129   // return the simple expression of the bissectrice
130   Handle(Geom2d_Curve) Bis;
131   SimpleExpression(myBisec, Bis);
132   myBis = Geom2dAdaptor_Curve(Bis);
133 #ifdef DRAW
134   if ( Affich) {
135     char* myBisname = "myBis";
136     DrawTrSurf::Set(myBisname,Bis);
137   }
138 #endif
139
140 }
141
142 //=======================================================================
143 //function : Bubble
144 //purpose  : Order the sequence of points by increasing x. 
145 //=======================================================================
146
147 static void Bubble(TColgp_SequenceOfPnt& Seq) 
148 {
149   Standard_Boolean Invert = Standard_True;
150   Standard_Integer NbPoints = Seq.Length();
151   while (Invert) {
152     Invert = Standard_False;
153     for ( Standard_Integer i = 1; i < NbPoints; i++) {
154       gp_Pnt P1 = Seq.Value(i);
155       gp_Pnt P2 = Seq.Value(i+1);
156       if (P2.X()<P1.X())  {
157         Seq.Exchange(i,i+1);
158         Invert = Standard_True;
159       }
160     }
161   }
162 }
163
164
165 //=======================================================================
166 //function : EvalParameters  
167 //purpose  : 
168 //=======================================================================
169
170 static void EvalParameters(const Geom2dAdaptor_Curve& Bis,
171   const Geom2dAdaptor_Curve& AC,
172   TColgp_SequenceOfPnt& Params)
173 {
174   Geom2dInt_GInter Intersector;
175   Standard_Real Tol = Precision::Confusion();
176   //  Standard_Real TolC = 1.e-9;
177
178   Geom2dAdaptor_Curve CBis(Bis);
179   Geom2dAdaptor_Curve CAC (AC);
180
181   //Intersector = Geom2dInt_GInter(CBis, CAC, TolC, Tol);
182   Intersector = Geom2dInt_GInter(CAC, CBis, Tol, Tol);
183
184   Standard_Integer NbPoints, NbSegments;
185   Standard_Real U1, U2;
186   gp_Pnt P;
187
188   if ( !Intersector.IsDone()) {
189     StdFail_NotDone::Raise("BRepFill_TrimSurfaceTool::IntersectWith");
190   }
191
192   NbPoints = Intersector.NbPoints();
193
194   if (NbPoints > 0) {
195     for ( Standard_Integer i = 1; i <= NbPoints; i++) {
196       U1 = Intersector.Point(i).ParamOnSecond();
197       U2 = Intersector.Point(i).ParamOnFirst();
198       P = gp_Pnt(U1,U2,0.);
199       Params.Append(P);
200     }
201
202   }
203
204   NbSegments = Intersector.NbSegments();
205
206   if (NbSegments > 0) {
207     IntRes2d_IntersectionSegment Seg;
208     for ( Standard_Integer i = 1; i <= NbSegments; i++) {
209       Seg = Intersector.Segment(i);
210       U1  = Seg.FirstPoint().ParamOnSecond();
211       Standard_Real Ulast = Seg.LastPoint().ParamOnSecond();
212       if ( Abs(U1    - CBis.FirstParameter()) <= Tol &&
213         Abs(Ulast - CBis.LastParameter())  <= Tol    ) {
214           P = gp_Pnt(U1,Seg.FirstPoint().ParamOnFirst(),0.);
215           Params.Append(P);
216           P = gp_Pnt(Ulast,Seg.LastPoint().ParamOnFirst(),0.);
217           Params.Append(P);
218       }
219       else {
220         U1 += Seg.LastPoint().ParamOnSecond();
221         U1 /= 2.;
222         U2  = Seg.FirstPoint().ParamOnFirst();
223         U2 += Seg.LastPoint().ParamOnFirst();
224         U2 /= 2.;
225         P = gp_Pnt(U1,U2,0.);
226         Params.Append(P);
227       }
228     }
229   }
230
231   // Order the sequence by growing parameter on the bissectrice.
232   Bubble( Params);
233 }
234
235 static void EvalParametersBis(const Geom2dAdaptor_Curve& Bis,
236   const Geom2dAdaptor_Curve& AC,
237   TColgp_SequenceOfPnt& Params,
238   const Standard_Real Tol)
239 {
240   Geom2dInt_GInter Intersector;
241   Standard_Real TolC = Tol;
242
243   Geom2dAdaptor_Curve CBis(Bis);
244   Geom2dAdaptor_Curve CAC (AC);
245
246   Intersector = Geom2dInt_GInter(CAC, CBis, TolC, Tol);
247
248   Standard_Integer NbPoints, NbSegments;
249   Standard_Real U1, U2;
250   gp_Pnt P;
251
252   if ( !Intersector.IsDone()) {
253     StdFail_NotDone::Raise("BRepFill_TrimSurfaceTool::IntersectWith");
254   }
255
256   NbPoints = Intersector.NbPoints();
257
258   if (NbPoints > 0) {
259     for ( Standard_Integer i = 1; i <= NbPoints; i++) {
260       U1 = Intersector.Point(i).ParamOnSecond();
261       U2 = Intersector.Point(i).ParamOnFirst();
262       P = gp_Pnt(U1,U2,0.);
263       Params.Append(P);
264     }
265
266   }
267
268   NbSegments = Intersector.NbSegments();
269
270   if (NbSegments > 0) {
271     IntRes2d_IntersectionSegment Seg;
272     for ( Standard_Integer i = 1; i <= NbSegments; i++) {
273       Seg = Intersector.Segment(i);
274       U1  = Seg.FirstPoint().ParamOnSecond();
275       Standard_Real Ulast = Seg.LastPoint().ParamOnSecond();
276       if ( Abs(U1    - CBis.FirstParameter()) <= Tol &&
277         Abs(Ulast - CBis.LastParameter())  <= Tol    ) {
278           P = gp_Pnt(U1,Seg.FirstPoint().ParamOnFirst(),0.);
279           Params.Append(P);
280           P = gp_Pnt(Ulast,Seg.LastPoint().ParamOnFirst(),0.);
281           Params.Append(P);
282       }
283       else {
284         U1 += Seg.LastPoint().ParamOnSecond();
285         U1 /= 2.;
286         U2  = Seg.FirstPoint().ParamOnFirst();
287         U2 += Seg.LastPoint().ParamOnFirst();
288         U2 /= 2.;
289         P = gp_Pnt(U1,U2,0.);
290         Params.Append(P);
291       }
292     }
293   }
294
295   // Order the sequence by parameter growing on the bissectrice.
296   Bubble( Params);
297 }
298
299
300 //=======================================================================
301 //function : IntersectWith
302 //purpose  : 
303 //=======================================================================
304
305 void BRepFill_TrimEdgeTool::IntersectWith(const TopoDS_Edge& Edge1,
306   const TopoDS_Edge& Edge2,
307   TColgp_SequenceOfPnt& Params)
308 {
309   Params.Clear();
310
311   // return curves associated to edges.
312   TopLoc_Location L;
313   Standard_Real   f,l;
314   Handle(Geom_Surface) Surf;
315
316   Handle(Geom2d_Curve) C1;
317   BRep_Tool::CurveOnSurface(Edge1,C1,Surf,L,f,l);
318   Geom2dAdaptor_Curve AC1(C1,f,l);
319
320   Handle(Geom2d_Curve) C2;
321   BRep_Tool::CurveOnSurface(Edge2,C2,Surf,L,f,l);
322   Geom2dAdaptor_Curve AC2(C2,f,l);
323
324 #ifdef DRAW
325   if ( AffichInt) {
326     f = AC1.FirstParameter();
327     l = AC1.LastParameter();
328     char name[32];
329     sprintf(name,"C1_%d", ++intind);
330     DrawTrSurf::Set(name, new Geom2d_TrimmedCurve(C1,f,l));
331     f = AC2.FirstParameter();
332     l = AC2.LastParameter();
333     sprintf(name,"C2_%d", intind);
334     DrawTrSurf::Set(name, new Geom2d_TrimmedCurve(C2,f,l));
335     f = myBis.FirstParameter();
336     l = myBis.LastParameter();
337     sprintf(name,"BIS%d", intind);
338     DrawTrSurf::Set(name, new Geom2d_TrimmedCurve(myBis.Curve(),f,l));
339     sprintf(name,"E1_%d", intind);
340     DBRep::Set(name, Edge1);
341     sprintf(name,"E2_%d", intind);
342     DBRep::Set(name, Edge2);
343
344   }
345 #endif
346
347   // Calculate intersection
348   TColgp_SequenceOfPnt Points2;
349   gp_Pnt PSeq;
350
351   EvalParameters (myBis,AC1,Params);
352   EvalParameters (myBis,AC2,Points2);
353
354
355
356   Standard_Integer SeanceDeRattrapage=0;
357   Standard_Real TolInit= 1.e-9;
358   Standard_Integer nn = 7;
359
360   if((AC1.GetType() != GeomAbs_Circle && AC1.GetType() != GeomAbs_Line) ||
361     (AC2.GetType() != GeomAbs_Circle && AC2.GetType() != GeomAbs_Line)) {
362
363       TolInit = 1.e-8;
364       nn = 6;
365   }
366
367   if(Params.IsEmpty() && Points2.IsEmpty())
368   {
369     //Check, may be there are no intersections at all
370     // for case myBis == Line
371     if(myBis.GetType() == GeomAbs_Line)
372     {
373       Standard_Real dmax = TolInit;
374       Standard_Integer n = 0;
375       while(n < nn)
376       {
377         dmax *= 10.0;
378         ++n;
379       }
380       dmax *= dmax;
381       //
382       gp_Lin2d anL = myBis.Line();
383       Standard_Boolean isFar1 = Standard_True;
384       Standard_Boolean isFar2 = Standard_True;
385       gp_Pnt2d aP;
386       //
387       Standard_Real d = RealLast();
388       AC1.D0(AC1.FirstParameter(), aP);
389       Standard_Real par = ElCLib::Parameter(anL, aP);
390       if(par >= myBis.FirstParameter() && par <= myBis.LastParameter())
391       {
392         d = anL.SquareDistance(aP);
393       }
394       AC1.D0(AC1.LastParameter(), aP);
395       par = ElCLib::Parameter(anL, aP);
396       if(par >= myBis.FirstParameter() && par <= myBis.LastParameter())
397       {
398         d = Min(anL.SquareDistance(aP), d);
399       }
400       isFar1 = d > dmax;
401       //
402       d = RealLast();
403       AC2.D0(AC2.FirstParameter(), aP);
404       par = ElCLib::Parameter(anL, aP);
405       if(par >= myBis.FirstParameter() && par <= myBis.LastParameter())
406       {
407         d = anL.SquareDistance(aP);
408       }
409       AC2.D0(AC2.LastParameter(), aP);
410       par = ElCLib::Parameter(anL, aP);
411       if(par >= myBis.FirstParameter() && par <= myBis.LastParameter())
412       {
413         d = Min(anL.SquareDistance(aP), d);
414       }
415       isFar2 = d > dmax;
416       //
417       if(isFar1 && isFar2)
418       {
419         return;
420       }
421     }
422   }
423
424   while (     SeanceDeRattrapage < nn // TolInit <= 0.01
425     && ( Points2.Length() != Params.Length() || 
426     (Points2.Length() == 0 && Params.Length() == 0) ) ) {
427
428 #ifdef OCCT_DEBUG
429       cout << "BRepFill_TrimEdgeTool: incoherent intersection. Try with a greater tolerance" << endl;
430 #endif
431
432       Params.Clear();
433       Points2.Clear();
434
435       TolInit*=10.0;
436
437       EvalParametersBis(myBis,AC1,Params,TolInit);
438       EvalParametersBis(myBis,AC2,Points2,TolInit); 
439       SeanceDeRattrapage++;
440   }
441
442 #ifdef OCCT_DEBUG
443   if(SeanceDeRattrapage != 0) cout << "SeanceDeRattrapage = " << SeanceDeRattrapage << endl;
444   if(SeanceDeRattrapage == nn) { 
445     cout << "BRepFill_TrimEdgeTool: incoherent intersection" << endl;
446   }
447 #endif
448
449
450   if(Params.Length() == 0 && Points2.Length() == 1) {
451
452     //cout << "Params.Length() == 0 && Points2.Length() == 1" << endl;
453     Standard_Real dmin, dmax = 0.25*myOffset*myOffset;
454     Standard_Real tBis = Points2(1).X();
455     gp_Pnt2d PBis = myBis.Value(tBis);
456
457     Standard_Real t = AC1.FirstParameter();
458     gp_Pnt2d PC = AC1.Value(t);
459     dmin = PC.SquareDistance(PBis);
460     gp_Pnt P(tBis, t, 0.);
461     if(dmin < dmax)
462     {
463       Params.Append(P);
464     }
465
466     t = AC1.LastParameter();
467     PC = AC1.Value(t);
468     Standard_Real dmin1 = PC.SquareDistance(PBis);
469     if(dmin > dmin1 && dmin1 < dmax ) {
470       P.SetY(t);
471       if(Params.IsEmpty())
472         Params.Append(P);
473       else
474         Params.SetValue(1,P);
475     }
476   }
477   else if(Params.Length() == 1 && Points2.Length() == 0) {
478
479     //cout << "Params.Length() == 1 && Points2.Length() == 0" << endl;
480     Standard_Real dmin, dmax = 0.25*myOffset*myOffset;
481     Standard_Real tBis = Params(1).X();
482     gp_Pnt2d PBis = myBis.Value(tBis);
483
484     Standard_Real t = AC2.FirstParameter();
485     gp_Pnt2d PC = AC2.Value(t);
486     dmin = PC.SquareDistance(PBis);
487     gp_Pnt P(tBis, t, 0.);
488     if(dmin < dmax)
489     {
490       Points2.Append(P);
491     }
492
493     t = AC2.LastParameter();
494     PC = AC2.Value(t);
495     Standard_Real dmin1 = PC.SquareDistance(PBis);
496     if(dmin > dmin1 && dmin1 < dmax ) {
497       P.SetY(t);
498       if(Points2.IsEmpty())
499         Points2.Append(P);
500       else
501         Points2.SetValue(1,P);
502     }
503   }
504
505   // small manipulation to remove incorrect intersections:
506   // return only common intersections (same parameter
507   // on the bissectrice.).
508   // The tolerance can be eventually changed.
509
510   gp_Pnt P1,P2;
511   Standard_Real Tol = 4 * 100 * Precision::PConfusion();
512   Standard_Integer i = 1;
513   Standard_Integer NbPoints = Params.Length();
514
515   if(NbPoints == 1 && Points2.Length() == 1) {
516     //cout << "NbPoints == 1 && Points2.Length() == 1" << endl;
517     for ( i = 1; i <= NbPoints; i++) {
518       PSeq = Params(i);
519       PSeq.SetZ((Points2.Value(i)).Y());
520       Params.SetValue(i,PSeq);
521     }
522     return;
523   }    
524
525   i = 1;
526   while ( i <= Min( Params.Length(), Points2.Length())) {
527     P1 = Params(i);
528     P2 = Points2(i);
529     Standard_Real P1xP2x=Abs( P1.X() - P2.X());
530
531     if ( P1xP2x > Tol ) {
532 #ifdef OCCT_DEBUG
533       cout << "BRepFill_TrimEdgeTool: no same parameter on the bissectrice" << endl;
534 #endif
535       if(P1xP2x>TolInit) { 
536 #ifdef OCCT_DEBUG
537         cout << "BRepFill_TrimEdgeTool: Continue somehow" << endl;
538 #endif  
539         i++;
540       }
541       else { 
542         if ( P1.X() < P2.X()) Params.Remove(i);
543         else                  Points2.Remove(i);
544       }
545     }
546     else i++;
547   }
548
549   if ( Params.Length() > Points2.Length()) {
550     Params.Remove(Points2.Length()+1, Params.Length());
551   }
552   else if ( Params.Length() < Points2.Length()) {
553     Points2.Remove(Params.Length()+1, Points2.Length());
554   }
555
556   NbPoints = Params.Length();
557   for ( i = 1; i <= NbPoints; i++) {
558     PSeq = Params(i);
559     PSeq.SetZ((Points2.Value(i)).Y());
560     Params.SetValue(i,PSeq);
561   }
562 }
563
564 //=======================================================================
565 //function : AddOrConfuse
566 //purpose  : the first or the last point of the bissectrice is on the 
567 //           parallel if it was not found in the intersections, 
568 //           it is projected on parallel lines and added in the parameters 
569 //=======================================================================
570
571 void BRepFill_TrimEdgeTool::AddOrConfuse(const Standard_Boolean  Start,
572   const TopoDS_Edge&      Edge1,
573   const TopoDS_Edge&      Edge2,
574   TColgp_SequenceOfPnt&   Params) 
575   const 
576 {
577   Standard_Boolean  ToProj = Standard_True;
578   gp_Pnt2d          PBis;
579   Standard_Real     Tol = 10*Precision::Confusion(); 
580
581   // return curves associated to edges.
582   TopLoc_Location L;
583   Standard_Real   f,l;
584   Handle(Geom_Surface) Surf;
585
586   Handle(Geom2d_Curve) C1;
587   BRep_Tool::CurveOnSurface(Edge1,C1,Surf,L,f,l);
588   Geom2dAdaptor_Curve AC1(C1,f,l);
589
590
591   if (Start) PBis = myBis.Value(myBis.FirstParameter());
592   else       PBis = myBis.Value(myBis.LastParameter ()); 
593
594   // Test if the end of the bissectrice is in the set of intersection points.
595   if (!Params.IsEmpty()) {
596     gp_Pnt2d P;
597     if (Start) P = AC1.Value(Params.First().Y());
598     else       P = AC1.Value(Params.Last ().Y()); 
599     ToProj     = !PBis.IsEqual(P,Tol);
600   }
601
602   if (ToProj) {
603 #ifdef OCCT_DEBUG
604     cout << " project extremity bissectrice on parallel."<<endl;
605 #endif
606
607     // Project point on parallels and add in Params
608
609     Standard_Real f2,l2;
610     Handle(Geom2d_Curve) C2;
611     BRep_Tool::CurveOnSurface(Edge2,C2,Surf,L,f2,l2);
612
613     Geom2dAPI_ProjectPointOnCurve Projector1(PBis,C1,f,l);    
614     Geom2dAPI_ProjectPointOnCurve Projector2(PBis,C2,f2,l2);
615
616     if (Projector1.NbPoints() == 0) {
617 #ifdef OCCT_DEBUG
618       cout << "Failed projection in BRepFill_TrimEdgeTool::AddOrConfuse"<<endl;
619 #endif
620       return;
621     }
622     if (!Projector1.NearestPoint().IsEqual(PBis,Tol)) {
623 #ifdef OCCT_DEBUG
624       cout <<"Incorrect solution in BRepFill_TrimEdgeTool::AddOrConfuse"<<endl;
625 #endif
626       return;
627     }
628     if (Projector2.NbPoints() == 0) {
629 #ifdef OCCT_DEBUG
630       cout << "Failed projection in BRepFill_TrimEdgeTool::AddOrConfuse"<<endl;
631 #endif
632       return;
633     }
634     if (!Projector2.NearestPoint().IsEqual(PBis,Tol)) {
635 #ifdef OCCT_DEBUG
636       cout <<" Mauvaisesolution dans BRepFill_TrimEdgeTool::AddOrConfuse"<<endl;
637 #endif
638       return;
639     }
640     gp_Pnt PInt (0,
641       Projector1.LowerDistanceParameter(),
642       Projector2.LowerDistanceParameter());
643     if (Start) {
644       PInt.SetX (myBis.FirstParameter());
645       Params.Prepend(PInt);
646     }
647     else {
648       PInt.SetX (myBis.LastParameter());
649       Params.Append(PInt);
650     }
651   }
652 }
653
654 //=======================================================================
655 //function : IsInside
656 //purpose  : 
657 //=======================================================================
658
659 Standard_Boolean BRepFill_TrimEdgeTool::IsInside(const gp_Pnt2d& P) const 
660 {
661   //  Modified by Sergey KHROMOV - Fri Sep 27 11:43:12 2002 Begin
662   //   Standard_Real Dist;
663   Standard_Real Dist = RealLast();
664   //  Modified by Sergey KHROMOV - Fri Sep 27 11:43:12 2002 End
665   if (isPoint1) 
666     Dist = P.Distance(myP1);
667   else if (isPoint2) 
668     Dist = P.Distance(myP2);
669   else {
670     Geom2dAPI_ProjectPointOnCurve Projector(P,myC1);
671     if (Projector.NbPoints() > 0) {
672       Dist = Projector.LowerDistance();
673     }
674     //  Modified by Sergey KHROMOV - Fri Sep 27 11:43:43 2002 Begin
675     //     else {
676     //       gp_Pnt2d PF = myC1->Value(myC1->FirstParameter());
677     //       gp_Pnt2d PL = myC1->Value(myC1->LastParameter());
678     //       Dist = Min (P.Distance(PF),P.Distance(PL));
679     //     }
680
681     // Check of distances between P and first and last point of the first curve
682     // should be performed in any case, despite of the results of projection.
683     gp_Pnt2d      PF       = myC1->Value(myC1->FirstParameter());
684     gp_Pnt2d      PL       = myC1->Value(myC1->LastParameter());
685     Standard_Real aDistMin = Min (P.Distance(PF),P.Distance(PL));
686
687     if (Dist > aDistMin)
688       Dist = aDistMin;
689     //  Modified by Sergey KHROMOV - Fri Sep 27 11:43:44 2002 End
690   }
691
692   //  return (Dist < Abs(myOffset);
693   // return (Dist < Abs(myOffset) + Precision::Confusion());
694   return (Dist < Abs(myOffset) - Precision::Confusion());
695 }
696