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