ee39bcc952291b5b24d9c1fe01a8552a18ea15aa
[occt.git] / src / BRepOffset / BRepOffset_Inter2d.cxx
1 // Created on: 1996-09-03
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1996-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 //  Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455
18
19 #include <stdio.h>
20
21 #include <BRepOffset_Inter2d.ixx>
22 #include <BRepAlgo_AsDes.hxx>
23 #include <BRepOffset_Offset.hxx>
24 #include <BRepOffset_Tool.hxx>
25
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <BRepLib_MakeVertex.hxx>
29 #include <BRepAdaptor_Curve.hxx>
30 #include <BRepAdaptor_Surface.hxx>
31 #include <BRepTools_WireExplorer.hxx>
32 #include <TopExp.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <TopoDS_Iterator.hxx>
35
36 #include <TopoDS.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopTools_ListOfShape.hxx>
41 #include <TopTools_ListIteratorOfListOfShape.hxx>
42 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
43 #include <gp_Pnt.hxx>
44 #include <BRep_TEdge.hxx>
45 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
46 #include <BRep_CurveRepresentation.hxx>
47 #include <BRep_GCurve.hxx>
48
49 #include <Geom_Line.hxx>
50 #include <Geom_Plane.hxx>
51 #include <Geom_TrimmedCurve.hxx>
52 #include <Geom_BSplineCurve.hxx>
53 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
54 #include <Precision.hxx>
55 #include <Geom2d_TrimmedCurve.hxx>
56 #include <Geom2d_BezierCurve.hxx>
57 #include <Geom2d_BSplineCurve.hxx>
58 #include <Geom2d_Line.hxx>
59 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
60
61 #include <BRepLib.hxx>
62 #include <BRepAdaptor_Curve2d.hxx>
63 #include <Adaptor3d_HSurface.hxx>
64 #include <Adaptor3d_CurveOnSurface.hxx>
65 #include <Geom_BSplineSurface.hxx>
66 #include <Geom_CylindricalSurface.hxx>
67 #include <Geom_ConicalSurface.hxx>
68 #include <Adaptor2d_HCurve2d.hxx>
69 #include <TColGeom2d_SequenceOfCurve.hxx>
70 #include <Geom2dInt_GInter.hxx>
71 #include <IntRes2d_IntersectionPoint.hxx>
72 #include <IntRes2d_IntersectionSegment.hxx>
73 #include <GeomAPI_ProjectPointOnCurve.hxx>
74 #include <GeomAdaptor_Surface.hxx>
75 #include <Geom2dAdaptor_HCurve.hxx>
76 #include <GeomAdaptor_HSurface.hxx>
77 #include <GeomLib.hxx>
78 #include <GeomProjLib.hxx>
79 #include <TColgp_SequenceOfPnt.hxx>
80 #include <TColgp_Array1OfPnt2d.hxx>
81 #include <Bnd_Box.hxx>
82 #include <BndLib_Add3dCurve.hxx>
83 #include <BRepTools.hxx>
84
85 #ifdef DRAW 
86 #include <DBRep.hxx>
87 #include <Geom2d_BoundedCurve.hxx>
88 #include <Geom_BoundedSurface.hxx>
89 #include <Geom_BoundedCurve.hxx>
90 #include <BRep_CurveOnSurface.hxx>
91 #include <Geom_Surface.hxx>
92 Standard_Boolean Inter2dAffichInt2d;
93 static Standard_Integer NbF2d = 0;
94 static Standard_Integer NbE2d = 0;
95 static Standard_Integer NbNewVertices  = 0;
96 #endif
97
98 //=======================================================================
99 //function : CommonVertex
100 //purpose  : 
101 //=======================================================================
102
103 static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
104                                   TopoDS_Edge& E2)
105 {
106   TopoDS_Vertex V1[2],V2[2],V;
107   //  Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin
108 //  TopExp::Vertices(E1,V1[0],V1[1]);
109 //  TopExp::Vertices(E2,V2[0],V2[1]);
110
111   TopExp::Vertices(E1,V1[0],V1[1], Standard_True);
112   TopExp::Vertices(E2,V2[0],V2[1], Standard_True);
113   // The first edge is the current one, the second edge is the next one.
114   // We check last vertex of the first edge first.
115 //  if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
116 //  if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
117   if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
118   if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
119   //  Modified by skv - Wed Dec 24 18:08:40 2003 OCC4455 End
120   return V;
121 }
122
123 //=======================================================================
124 //function : Store
125 //purpose  : 
126 //=======================================================================
127
128 static void  Store (const TopoDS_Edge&       E1,
129                     const TopoDS_Edge&       E2,
130                     TopTools_ListOfShape&    LV1,
131                     TopTools_ListOfShape&    LV2,
132                     Handle(BRepAlgo_AsDes)   AsDes,
133                     Standard_Real            Tol)
134 {
135   //-------------------------------------------------------------
136   // Test if the points of intersection correspond to existing 
137   // vertices. Otherwise add edges in the descendants.
138   // Note: at this stage only vertices of intersection are in the descendants.
139   //-------------------------------------------------------------
140   const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1);
141   const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2);
142   TopTools_ListOfShape        NewVOnE1;   
143   TopTools_ListOfShape        NewVOnE2; 
144   gp_Pnt                      P,P1,P2;
145   TopoDS_Vertex               V1,V2;
146   TopTools_ListIteratorOfListOfShape it, itLV1, itLV2;
147   BRep_Builder                       B;
148   TopAbs_Orientation                 O1,O2;
149   Standard_Real                      U1,U2;
150   Standard_Boolean                   OnE1,OnE2;
151
152   for (itLV1.Initialize(LV1),itLV2.Initialize(LV2); 
153        itLV1.More(); 
154        itLV1.Next()  ,itLV2.Next()) {
155
156     TopoDS_Vertex V    = TopoDS::Vertex(itLV1.Value());
157
158     U1 = (BRep_Tool::Degenerated(E1))?
159       BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E1) :
160       BRep_Tool::Parameter(V, E1);
161     U2 = (BRep_Tool::Degenerated(E2))?
162       BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E2) :
163       BRep_Tool::Parameter(V, E2);
164     O1 = V.Orientation();
165     O2 = itLV2.Value().Orientation();
166     P  = BRep_Tool::Pnt(V);
167     OnE1 = OnE2 = Standard_False;
168     
169     if (!VOnE1.IsEmpty()) {
170       //-----------------------------------------------------------------
171       // Find if the point of intersection corresponds to a vertex of E1.
172       //-----------------------------------------------------------------
173       for (it.Initialize(VOnE1); it.More(); it.Next()) {
174         P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
175         if (P.IsEqual(P1,Tol)) {
176           V    = TopoDS::Vertex(it.Value());
177           V1   = V;
178           OnE1 = Standard_True;
179           break;
180         }
181       }
182     }
183     if (!VOnE2.IsEmpty()) {
184       if (OnE1) {
185         //-----------------------------------------------------------------
186         // Find if the vertex found on E1 is not already on E2.
187         //-----------------------------------------------------------------
188         for (it.Initialize(VOnE2); it.More(); it.Next()) {
189           if (it.Value().IsSame(V)) {
190             OnE2 = Standard_True;
191             V2   = V;
192             break;
193           }
194         }
195       }
196       for (it.Initialize(VOnE2); it.More(); it.Next()) {
197         //-----------------------------------------------------------------
198         // Find if the point of intersection corresponds to a vertex of E2.
199         //-----------------------------------------------------------------
200         P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
201         if (P.IsEqual(P2,Tol)) {
202           V  = TopoDS::Vertex(it.Value());
203           V2 = V;
204           OnE2 = Standard_True;
205           break;
206         }
207       }      
208     }  
209     if (OnE1 && OnE2) {
210       if (!V1.IsSame(V2)) {
211         //---------------------------------------------------------------
212         // Two vertices are actually the same.
213         // V2 will be replaced by V1. 
214         // update the parameters of vertex on edges.
215         //---------------------------------------------------------------
216         Standard_Real UV2;
217         TopoDS_Edge   EWE2;
218         const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
219
220         for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
221           EWE2  = TopoDS::Edge(it.Value());
222           TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
223           UV2   = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
224 //        UV2   = 
225 //          BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
226           aLocalShape = V1.Oriented(TopAbs_INTERNAL);
227           B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
228 //        B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
229 //                       UV2,EWE2,Tol);
230         }
231         AsDes->Replace(V2,V1);
232       }
233     }
234     if (!OnE1) {
235       if (OnE2) {
236         TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
237         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
238 //      B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
239 //                     U1,E1,Tol);
240       }
241       NewVOnE1.Append(V.Oriented(O1));
242     }
243     if (!OnE2) {
244       if (OnE1) {
245         TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
246         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
247 //      B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
248 //                     U2,E2,Tol);
249       }
250       NewVOnE2.Append(V.Oriented(O2));
251     }
252     
253 #ifdef DRAW
254    if (Inter2dAffichInt2d) {      
255      if (!OnE1 && !OnE2) {
256        char name[256];
257        sprintf(name,"VV_%d",NbNewVertices++);   
258        DBRep::Set(name,V);
259      }
260    }  
261 #endif    
262   }
263   if (!NewVOnE1.IsEmpty()) AsDes->Add(E1,NewVOnE1);
264   if (!NewVOnE2.IsEmpty()) AsDes->Add(E2,NewVOnE2);
265 }
266
267
268 //=======================================================================
269 //function : EdgeInter
270 //purpose  : 
271 //=======================================================================
272
273 static void EdgeInter(const TopoDS_Face&              F,
274                       const TopoDS_Edge&              E1,
275                       const TopoDS_Edge&              E2,
276                       const Handle(BRepAlgo_AsDes)&   AsDes,
277                       Standard_Real                   Tol,
278                       Standard_Boolean                WithOri)
279 {
280 #ifdef DRAW
281   if (Inter2dAffichInt2d) {
282     char name[256];
283     sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
284     DBRep::Set(name,E1);
285     sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
286     DBRep::Set(name,E2);
287   }
288 #endif
289
290   if (E1.IsSame(E2))
291     return;
292
293   Standard_Real f[3],l[3];
294   Standard_Real TolDub = 1.e-7;
295   Standard_Integer i;
296
297   BRep_Tool::Range(E1, f[1], l[1]);
298   BRep_Tool::Range(E2, f[2], l[2]);
299
300   BRepAdaptor_Curve CE1(E1,F);
301   BRepAdaptor_Curve CE2(E2,F);
302
303   TopoDS_Edge                 EI[3]; EI[1] = E1; EI[2] = E2;
304   TopTools_ListOfShape        LV1;   
305   TopTools_ListOfShape        LV2; 
306   BRep_Builder                B;
307
308   TopoDS_Vertex CV;
309   if (!TopExp::CommonVertex( E1, E2, CV ))
310     {
311       BRepLib::BuildCurve3d(E1);
312       BRepLib::BuildCurve3d(E2);
313       
314       Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
315       TolSum = Max( TolSum, 1.e-5 );
316
317       TColgp_SequenceOfPnt   ResPoints;
318       TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
319       gp_Pnt DegPoint;
320       Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
321       
322       if (WithDegen)
323         {
324           Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
325           TopoDS_Iterator iter( EI[ideg] );
326           if (iter.More())
327             {
328               const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
329               DegPoint = BRep_Tool::Pnt(vdeg);
330             }
331           else
332             {
333               BRepAdaptor_Curve CEdeg( EI[ideg], F );
334               DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
335             }
336         }
337       BRepAdaptor_Surface BAsurf(F);
338       Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
339       Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
340       Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
341       Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
342       Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
343       for (i = 1; i <= Inter2d.NbPoints(); i++)
344         {
345           gp_Pnt P3d;
346           if (WithDegen)
347             P3d = DegPoint;
348           else
349             {
350               gp_Pnt2d P2d = Inter2d.Point(i).Value();
351               P3d = BAsurf.Value( P2d.X(), P2d.Y() );
352             }
353           ResPoints.Append( P3d );
354           ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
355           ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
356         }
357
358       for (i = 1; i <= ResPoints.Length(); i++)
359         {
360           Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
361           Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
362           if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
363             {
364 #ifdef OCCT_DEBUG
365               cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
366 #endif
367               continue;
368             }
369           
370           gp_Pnt P = ResPoints(i); //ponc1.Value();
371           TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
372           aNewVertex.Orientation(TopAbs_INTERNAL);
373           B.UpdateVertex( aNewVertex, aT1, E1, Tol );
374           B.UpdateVertex( aNewVertex, aT2, E2, Tol );
375           gp_Pnt P1 = CE1.Value(aT1);
376           gp_Pnt P2 = CE2.Value(aT2);
377           Standard_Real dist1, dist2, dist3;
378           dist1 = P1.Distance(P);
379           dist2 = P2.Distance(P);
380           dist3 = P1.Distance(P2);
381           dist1 = Max( dist1, dist2 );
382           dist1 = Max( dist1, dist3 );
383           B.UpdateVertex( aNewVertex, dist1 );
384           
385 #ifdef OCCT_DEBUG
386           if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
387             {
388               cout << "out of limit"<<endl;
389               cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
390             }
391           if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
392             {
393               cout << "out of limit"<<endl;
394               cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
395             }
396           Standard_Real MilTol2 = 1000*Tol*Tol;
397           if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
398             {
399               cout << "Inter2d : Solution rejected "<<endl;
400               cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
401               cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
402               cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
403               cout<<"MaxDist = "<<dist1<<endl;
404             }
405 #endif
406           //define the orientation of a new vertex
407           TopAbs_Orientation OO1 = TopAbs_REVERSED;
408           TopAbs_Orientation OO2 = TopAbs_REVERSED;
409           if (WithOri)
410             {
411               BRepAdaptor_Curve2d PCE1( E1, F );
412               BRepAdaptor_Curve2d PCE2( E2, F );
413               gp_Pnt2d P2d1, P2d2;
414               gp_Vec2d V1, V2, V1or, V2or;
415               PCE1.D1( aT1, P2d1, V1 );
416               PCE2.D1( aT2, P2d2, V2 );
417               V1or = V1; V2or = V2;
418               if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
419               if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
420               Standard_Real CrossProd = V2or ^ V1;
421 #ifdef OCCT_DEBUG
422               if (Abs(CrossProd) <= gp::Resolution())
423                 cout<<endl<<"CrossProd = "<<CrossProd<<endl;
424 #endif
425               if (CrossProd > 0.)
426                 OO1 = TopAbs_FORWARD;
427               CrossProd = V1or ^ V2;
428               if (CrossProd > 0.)
429                 OO2 = TopAbs_FORWARD;
430             }
431           LV1.Append( aNewVertex.Oriented(OO1) );
432           LV2.Append( aNewVertex.Oriented(OO2) );
433         }
434     }
435   
436   //----------------------------------
437   // Test at end.
438   //---------------------------------
439   Standard_Real U1,U2;
440   Standard_Real TolConf = Tol;
441   TopoDS_Vertex V1[2],V2[2];
442   TopExp::Vertices(E1,V1[0],V1[1]);
443   TopExp::Vertices(E2,V2[0],V2[1]);
444
445   Standard_Integer j;
446   for (j = 0; j < 2; j++) {
447     if (V1[j].IsNull()) continue;
448     for (Standard_Integer k = 0; k < 2; k++) {
449       if (V2[k].IsNull()) continue;
450       gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
451       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
452       Standard_Real Dist = P1.Distance(P2); 
453       if (Dist < TolConf) {
454         TopoDS_Vertex V = BRepLib_MakeVertex(P1);
455         U1 = (j == 0) ? f[1] : l[1];
456         U2 = (k == 0) ? f[2] : l[2];
457         TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
458 //  Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 Begin
459         Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
460
461         if (!V1[j].IsSame(V2[k])) {
462           Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
463
464           aTol = Max(aTol, aTol2);
465         }
466
467         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
468         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
469 //      B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
470 //      B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
471 //      B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
472 //                     U1,E1,Tol);
473 //      B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
474 //                     U2,E2,Tol);
475 //  Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 End
476         LV1.Prepend(V.Oriented(V1[j].Orientation()));
477         LV2.Prepend(V.Oriented(V2[k].Orientation()));
478       }
479     }
480   }
481
482   Standard_Boolean AffichPurge = Standard_False;
483
484   if ( !LV1.IsEmpty()) {
485     //----------------------------------
486     // Remove all vertices.
487     // There can be doubles
488     //----------------------------------
489     TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
490     gp_Pnt P1,P2;
491     Standard_Boolean Purge = Standard_True;
492
493     while (Purge) {
494       i = 1;
495       Purge = Standard_False;
496       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
497            it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
498         j = 1;
499         it2LV1.Initialize(LV1);
500         while (j < i) {      
501           P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
502           P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
503 //  Modified by skv - Thu Jan 22 18:19:04 2004 OCC4455 Begin
504 //        if (P1.IsEqual(P2,10*Tol)) {
505           Standard_Real aTol;
506
507           aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
508                      BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
509           if (P1.IsEqual(P2,aTol)) {
510 //  Modified by skv - Thu Jan 22 18:19:05 2004 OCC4455 End
511             LV1.Remove(it1LV1);
512             LV2.Remove(it1LV2);
513             if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
514             Purge = Standard_True;
515             break;
516           }
517           j++;
518           it2LV1.Next();
519         }
520         if (Purge) break;
521         i++;
522       }
523     }
524     //---------------------------------
525     // Vertex storage in DS.
526     //---------------------------------
527 //  Modified by skv - Tue Jan 13 15:14:30 2004 Begin
528     Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
529
530     TolStore = Max(TolStore, 10.*Tol);
531
532     Store (E1,E2,LV1,LV2,AsDes,TolStore);
533 //    Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
534 //    Store (E1,E2,LV1,LV2,AsDes,Tol);
535 //  Modified by skv - Tue Jan 13 15:14:30 2004 End
536   }
537 }
538 //=======================================================================
539 //function : EdgeInter
540 //purpose  : 
541 //=======================================================================
542
543 static void RefEdgeInter(const TopoDS_Face&              F,
544                          const TopoDS_Edge&              E1,
545                          const TopoDS_Edge&              E2,
546                          const Handle(BRepAlgo_AsDes)&   AsDes,
547                          Standard_Real                   Tol,
548                          Standard_Boolean                WithOri,
549                          gp_Pnt&                         Pref)
550 {
551 #ifdef DRAW
552   if (Inter2dAffichInt2d) {
553     char name[256];
554     sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
555     DBRep::Set(name,E1);
556     sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
557     DBRep::Set(name,E2);
558   }
559 #endif
560
561   if (E1.IsSame(E2))
562     return;
563
564   Standard_Real f[3],l[3];
565   Standard_Real TolDub = 1.e-7;
566   Standard_Integer i;
567
568   //BRep_Tool::Range(E1, f[1], l[1]);
569   //BRep_Tool::Range(E2, f[2], l[2]);
570
571   BRepAdaptor_Curve CE1(E1,F);
572   BRepAdaptor_Curve CE2(E2,F);
573
574   TopoDS_Edge                 EI[3]; EI[1] = E1; EI[2] = E2;
575   TopTools_ListOfShape        LV1;   
576   TopTools_ListOfShape        LV2; 
577   BRep_Builder                B;
578
579   BRepLib::BuildCurve3d(E1);
580   BRepLib::BuildCurve3d(E2);
581
582   Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
583   TolSum = Max( TolSum, 1.e-5 );
584
585   TColgp_SequenceOfPnt   ResPoints;
586   TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
587   gp_Pnt DegPoint;
588   Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
589   
590   if (WithDegen)
591     {
592       Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
593       TopoDS_Iterator iter( EI[ideg] );
594       if (iter.More())
595         {
596           const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
597           DegPoint = BRep_Tool::Pnt(vdeg);
598         }
599       else
600         {
601           BRepAdaptor_Curve CEdeg( EI[ideg], F );
602           DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
603         }
604     }
605   BRepAdaptor_Surface BAsurf(F);
606   Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
607   Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
608   Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
609   Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
610   Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
611   for (i = 1; i <= Inter2d.NbPoints(); i++)
612     {
613       gp_Pnt P3d;
614       if (WithDegen)
615         P3d = DegPoint;
616       else
617         {
618           gp_Pnt2d P2d = Inter2d.Point(i).Value();
619           P3d = BAsurf.Value( P2d.X(), P2d.Y() );
620         }
621       ResPoints.Append( P3d );
622       ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
623       ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
624     }
625   
626   for (i = 1; i <= ResPoints.Length(); i++)
627     {
628       Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
629       Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
630       if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
631         {
632 #ifdef OCCT_DEBUG
633           cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
634 #endif
635           continue;
636         }
637       
638       gp_Pnt P = ResPoints(i); //ponc1.Value();
639       TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
640       aNewVertex.Orientation(TopAbs_INTERNAL);
641       B.UpdateVertex( aNewVertex, aT1, E1, Tol );
642       B.UpdateVertex( aNewVertex, aT2, E2, Tol );
643       gp_Pnt P1 = CE1.Value(aT1);
644       gp_Pnt P2 = CE2.Value(aT2);
645       Standard_Real dist1, dist2, dist3;
646       dist1 = P1.Distance(P);
647       dist2 = P2.Distance(P);
648       dist3 = P1.Distance(P2);
649       dist1 = Max( dist1, dist2 );
650       dist1 = Max( dist1, dist3 );
651       B.UpdateVertex( aNewVertex, dist1 );
652       
653 #ifdef OCCT_DEBUG
654       if (aT1 < f[1]-Tol  || aT1 > l[1]+Tol)
655         {
656           cout << "out of limit"<<endl;
657           cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
658         }
659       if (aT2 < f[2]-Tol  || aT2 > l[2]+Tol)
660         {
661           cout << "out of limit"<<endl;
662           cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
663         }
664       Standard_Real MilTol2 = 1000*Tol*Tol;
665       if (P1.SquareDistance(P) >  MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
666         {
667           cout << "Inter2d : Solution rejected"<<endl;
668           cout<<"P  = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
669           cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
670           cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
671           cout<<"MaxDist = "<<dist1<<endl;
672         }
673 #endif
674       //define the orientation of a new vertex
675       TopAbs_Orientation OO1 = TopAbs_REVERSED;
676       TopAbs_Orientation OO2 = TopAbs_REVERSED;
677       if (WithOri)
678         {
679           BRepAdaptor_Curve2d PCE1( E1, F );
680           BRepAdaptor_Curve2d PCE2( E2, F );
681           gp_Pnt2d P2d1, P2d2;
682           gp_Vec2d V1, V2, V1or, V2or;
683           PCE1.D1( aT1, P2d1, V1 );
684           PCE2.D1( aT2, P2d2, V2 );
685           V1or = V1; V2or = V2;
686           if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
687           if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
688           Standard_Real CrossProd = V2or ^ V1;
689 #ifdef OCCT_DEBUG
690           if (Abs(CrossProd) <= gp::Resolution())
691             cout<<endl<<"CrossProd = "<<CrossProd<<endl;
692 #endif
693           if (CrossProd > 0.)
694             OO1 = TopAbs_FORWARD;
695           CrossProd = V1or ^ V2;
696           if (CrossProd > 0.)
697             OO2 = TopAbs_FORWARD;
698         }
699       LV1.Append( aNewVertex.Oriented(OO1) );
700       LV2.Append( aNewVertex.Oriented(OO2) );
701     }
702   
703   //----------------------------------
704   // Test at end.
705   //---------------------------------
706   Standard_Real U1,U2;
707   Standard_Real TolConf = Tol;
708   TopoDS_Vertex V1[2],V2[2];
709   TopExp::Vertices(E1,V1[0],V1[1]);
710   TopExp::Vertices(E2,V2[0],V2[1]);
711
712   Standard_Integer j;
713   for (j = 0; j < 2; j++) {
714     if (V1[j].IsNull()) continue;
715     for (Standard_Integer k = 0; k < 2; k++) {
716       if (V2[k].IsNull()) continue;
717       gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
718       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
719       Standard_Real Dist = P1.Distance(P2); 
720       if (Dist < TolConf) {
721         TopoDS_Vertex V = BRepLib_MakeVertex(P1);
722         U1 = (j == 0) ? f[1] : l[1];
723         U2 = (k == 0) ? f[2] : l[2];
724         TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
725         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
726         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
727 //      B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
728 //                     U1,E1,Tol);
729 //      B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
730 //                     U2,E2,Tol);
731         LV1.Prepend(V.Oriented(V1[j].Orientation()));
732         LV2.Prepend(V.Oriented(V2[k].Orientation()));
733       }
734     }
735   }
736
737   Standard_Boolean AffichPurge = Standard_False;
738
739   if ( !LV1.IsEmpty()) {
740     //----------------------------------
741     // Remove all vertices.
742     // there can be doubles
743     //----------------------------------
744     TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
745     gp_Pnt P1,P2;
746     Standard_Boolean Purge = Standard_True;
747
748     while (Purge) {
749       i = 1;
750       Purge = Standard_False;
751       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
752            it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
753         j = 1;
754         it2LV1.Initialize(LV1);
755         while (j < i) {      
756           P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
757           P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
758           if (P1.IsEqual(P2,10*Tol)) {
759             LV1.Remove(it1LV1);
760             LV2.Remove(it1LV2);
761             if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
762             Purge = Standard_True;
763             break;
764           }
765           j++;
766           it2LV1.Next();
767         }
768         if (Purge) break;
769         i++;
770       }
771     }
772     //---------------------------------
773     // Vertex storage in SD.
774     //---------------------------------
775 ////-----------------------------------------------------
776     if(LV1.Extent() > 1) {
777       //cout << "IFV - RefEdgeInter: remove vertex" << endl;
778       Standard_Real dmin = RealLast();
779       TopoDS_Vertex Vmin;
780       for (it1LV1.Initialize(LV1); it1LV1.More(); it1LV1.Next()) {
781         gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
782         Standard_Real d = P.SquareDistance(Pref);
783         if(d < dmin) {
784           dmin = d;
785           Vmin = TopoDS::Vertex(it1LV1.Value());
786         }
787       }
788       for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); 
789            it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
790         if(!Vmin.IsSame(it1LV1.Value())) {
791           LV1.Remove(it1LV1);
792           LV2.Remove(it1LV2);
793           if(!it1LV1.More()) break;
794         }
795       }
796     }
797       
798 ////-----------------------------------------------------
799
800 //  Modified by skv - Tue Jan 13 15:14:30 2004 Begin
801     Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
802
803     TolStore = Max(TolStore, 10.*Tol);
804
805     Store (E1,E2,LV1,LV2,AsDes,TolStore);
806 //    Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
807 //    Store (E1,E2,LV1,LV2,AsDes,Tol);
808 //  Modified by skv - Tue Jan 13 15:14:30 2004 End
809   }
810 }
811
812
813 //======================================================================
814 //function : EvaluateMaxSegment
815 //purpose  : return MaxSegment to pass in approximation
816 //======================================================================
817
818 static Standard_Integer evaluateMaxSegment(const Adaptor3d_CurveOnSurface& aCurveOnSurface)
819 {
820   Handle(Adaptor3d_HSurface) aSurf   = aCurveOnSurface.GetSurface();
821   Handle(Adaptor2d_HCurve2d) aCurv2d = aCurveOnSurface.GetCurve();
822
823   Standard_Real aNbSKnots = 0, aNbC2dKnots = 0;
824   
825   if (aSurf->GetType() == GeomAbs_BSplineSurface) {
826     Handle(Geom_BSplineSurface) aBSpline = aSurf->BSpline();
827     aNbSKnots = Max(aBSpline->NbUKnots(), aBSpline->NbVKnots());
828   }
829   if (aCurv2d->GetType() == GeomAbs_BSplineCurve) {
830     aNbC2dKnots = aCurv2d->NbKnots();
831   }
832   Standard_Integer aReturn = (Standard_Integer) (  30 + Max(aNbSKnots, aNbC2dKnots) ) ;
833   return aReturn;
834 }
835
836
837 //=======================================================================
838 //function : ExtendPCurve
839 //purpose  : 
840 //=======================================================================
841
842 static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
843                                      const Standard_Real anEf,
844                                      const Standard_Real anEl,
845                                      const Standard_Real a2Offset,
846                                      Handle(Geom2d_Curve)& NewPCurve)
847 {
848   NewPCurve = aPCurve;
849   if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
850     NewPCurve = (*((Handle(Geom2d_TrimmedCurve)*)&NewPCurve))->BasisCurve();
851   
852   Standard_Real FirstPar = NewPCurve->FirstParameter();
853   Standard_Real LastPar  = NewPCurve->LastParameter();
854
855   if (NewPCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
856       (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
857     {
858       if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
859         {
860           Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve);
861           if (aBezier->NbPoles() == 2)
862             {
863               TColgp_Array1OfPnt2d thePoles(1,2);
864               aBezier->Poles(thePoles);
865               gp_Vec2d aVec(thePoles(1), thePoles(2));
866               NewPCurve = new Geom2d_Line(thePoles(1), aVec);
867               return Standard_True;
868             }
869         }
870       else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
871         {
872           Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve);
873           if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
874             {
875               TColgp_Array1OfPnt2d thePoles(1,2);
876               aBSpline->Poles(thePoles);
877               gp_Vec2d aVec(thePoles(1), thePoles(2));
878               NewPCurve = new Geom2d_Line(thePoles(1), aVec);
879               return Standard_True;
880             }
881         }
882     }
883
884   FirstPar = aPCurve->FirstParameter();
885   LastPar  = aPCurve->LastParameter();
886   Handle(Geom2d_TrimmedCurve) aTrCurve = 
887     new Geom2d_TrimmedCurve(aPCurve, FirstPar, LastPar);
888   
889   // The curve is not prolonged on begin or end.
890   // Trying to prolong it adding a segment to its bound.
891   gp_Pnt2d                              aPBnd;
892   gp_Vec2d                              aVBnd;
893   gp_Pnt2d                              aPBeg;
894   gp_Dir2d                              aDBnd;
895   Handle(Geom2d_Line)                   aLin;
896   Handle(Geom2d_TrimmedCurve)           aSegment;
897   Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
898   Standard_Real                         aTol = Precision::Confusion();
899   Standard_Real                         aDelta = Max(a2Offset, 1.);
900   
901   if (FirstPar > anEf - a2Offset) {
902     aPCurve->D1(FirstPar, aPBnd, aVBnd);
903     aDBnd.SetXY(aVBnd.XY());
904     aPBeg    = aPBnd.Translated(gp_Vec2d(-aDelta*aDBnd.XY()));
905     aLin     = new Geom2d_Line(aPBeg, aDBnd);
906     aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
907     
908     if (!aCompCurve.Add(aSegment, aTol))
909       return Standard_False;
910   }
911   
912   if (LastPar < anEl + a2Offset) {
913     aPCurve->D1(LastPar, aPBeg, aVBnd);
914     aDBnd.SetXY(aVBnd.XY());
915     aLin     = new Geom2d_Line(aPBeg, aDBnd);
916     aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
917     
918     if (!aCompCurve.Add(aSegment, aTol))
919       return Standard_False;
920   }
921   
922   NewPCurve  = aCompCurve.BSplineCurve();
923   return Standard_True;
924 }
925
926 //=======================================================================
927 //function : ExtentEdge
928 //purpose  : 
929 //=======================================================================
930
931 //  Modified by skv - Fri Dec 26 17:00:55 2003 OCC4455 Begin
932 //static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE) 
933 static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real theOffset)
934 {
935   //BRepLib::BuildCurve3d(E);
936
937   TopoDS_Shape  aLocalShape = E.EmptyCopied();
938   Standard_Real anEf;
939   Standard_Real anEl;
940   Standard_Real a2Offset = 2.*Abs(theOffset);
941   BRep_Builder BB;
942   Standard_Integer i, j;
943
944   BRep_Tool::Range(E, anEf, anEl);
945   NE = TopoDS::Edge(aLocalShape); 
946 //  NE = TopoDS::Edge(E.EmptyCopied()); 
947   // Enough for analytic edges, for general case reconstruct the
948   // geometry of the edge recalculating the intersection of surfaces.
949
950   //BRepLib::BuildCurve3d(E);
951
952   Standard_Integer NbPCurves = 0;
953   Standard_Real FirstParOnPC = RealFirst(), LastParOnPC = RealLast();
954   Handle(Geom2d_Curve) MinPC;
955   Handle(Geom_Surface) MinSurf;
956   TopLoc_Location      MinLoc;
957
958   BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves() );
959   for (; itr.More(); itr.Next())
960     {
961       Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
962       Standard_Real FirstPar, LastPar;
963       if (CurveRep->IsCurveOnSurface())
964         {
965           NbPCurves++;
966           Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
967           FirstPar = theCurve->FirstParameter();
968           LastPar  = theCurve->LastParameter();
969
970           if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
971               (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
972             {
973               Handle(Geom2d_Curve) NewPCurve;
974               if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
975                 {
976                   CurveRep->PCurve(NewPCurve);
977                   FirstPar = NewPCurve->FirstParameter();
978                   LastPar  = NewPCurve->LastParameter();
979                   if (CurveRep->IsCurveOnClosedSurface())
980                     {
981                       Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
982                       if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
983                         CurveRep->PCurve2(NewPCurve);
984                     }
985                 }
986             }
987           else if (theCurve->IsPeriodic())
988             {
989               Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
990               delta *= 0.95;
991               FirstPar = anEf - delta;
992               LastPar  = anEl + delta;
993             }
994           else if (theCurve->IsClosed())
995             LastPar -= 0.05*(LastPar - FirstPar);
996
997           //check FirstPar and LastPar: the pcurve should be in its surface
998           theCurve = CurveRep->PCurve();
999           Handle(Geom_Surface) theSurf = CurveRep->Surface();
1000           Standard_Real Umin, Umax, Vmin, Vmax;
1001           theSurf->Bounds(Umin, Umax, Vmin, Vmax);
1002           TColGeom2d_SequenceOfCurve BoundLines;
1003           if (!Precision::IsInfinite(Vmin))
1004             {
1005               Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
1006                                                           gp_Dir2d( 1., 0. ));
1007               BoundLines.Append(aLine);
1008             }
1009           if (!Precision::IsInfinite(Umin))
1010             {
1011               Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
1012                                                           gp_Dir2d( 0., 1. ));
1013               BoundLines.Append(aLine);
1014             }
1015           if (!Precision::IsInfinite(Vmax))
1016             {
1017               Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
1018                                                           gp_Dir2d( 1., 0. ));
1019               BoundLines.Append(aLine);
1020             }
1021           if (!Precision::IsInfinite(Umax))
1022             {
1023               Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
1024                                                           gp_Dir2d( 0., 1. ));
1025               BoundLines.Append(aLine);
1026             }
1027
1028           TColStd_SequenceOfReal params;
1029           Geom2dInt_GInter IntCC;
1030           Geom2dAdaptor_Curve GAcurve(theCurve);
1031           for (i = 1; i <= BoundLines.Length(); i++)
1032             {
1033               Geom2dAdaptor_Curve GAline( BoundLines(i) );
1034               IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
1035               if (IntCC.IsDone())
1036                 {
1037                   for (j = 1; j <= IntCC.NbPoints(); j++)
1038                     {
1039                       const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
1040                       gp_Pnt2d aPoint = ip.Value();
1041                       if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1042                           aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1043                         params.Append( ip.ParamOnFirst() );
1044                     }
1045                   for (j = 1; j <= IntCC.NbSegments(); j++)
1046                     {
1047                       const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
1048                       if (is.HasFirstPoint())
1049                         {
1050                           const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
1051                           gp_Pnt2d aPoint = ip.Value();
1052                           if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1053                               aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1054                             params.Append( ip.ParamOnFirst() );
1055                         }
1056                       if (is.HasLastPoint())
1057                         {
1058                           const IntRes2d_IntersectionPoint& ip = is.LastPoint();
1059                           gp_Pnt2d aPoint = ip.Value();
1060                           if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1061                               aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1062                             params.Append( ip.ParamOnFirst() );
1063                         }
1064                     }
1065                 }
1066             }
1067           if (!params.IsEmpty())
1068             {
1069               if (params.Length() == 1)
1070                 {
1071                   gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
1072                   if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
1073                       PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
1074                     {
1075                       if (LastPar > params(1))
1076                         LastPar = params(1);
1077                     }
1078                   else if (FirstPar < params(1))
1079                     FirstPar = params(1);
1080                 }
1081               else
1082                 {
1083                   Standard_Real fpar = RealLast(), lpar = RealFirst();
1084                   for (i = 1; i <= params.Length(); i++)
1085                     {
1086                       if (params(i) < fpar)
1087                         fpar = params(i);
1088                       if (params(i) > lpar)
1089                         lpar = params(i);
1090                     }
1091                   if (FirstPar < fpar)
1092                     FirstPar = fpar;
1093                   if (LastPar > lpar)
1094                     LastPar = lpar;
1095                 }
1096             }
1097           //// end of check ////
1098           (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
1099           //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
1100           //gp_Pnt2d Plast  = theCurve->Value(LastPar);
1101           //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
1102
1103           //update FirstParOnPC and LastParOnPC
1104           if (FirstPar > FirstParOnPC)
1105             {
1106               FirstParOnPC = FirstPar;
1107               MinPC   = theCurve;
1108               MinSurf = theSurf;
1109               MinLoc  = CurveRep->Location();
1110             }
1111           if (LastPar  < LastParOnPC)
1112             {
1113               LastParOnPC  = LastPar;
1114               MinPC   = theCurve;
1115               MinSurf = theSurf;
1116               MinLoc  = CurveRep->Location();
1117             }
1118         }
1119     }
1120
1121   Standard_Real f, l;
1122   Handle(Geom_Curve) C3d = BRep_Tool::Curve( NE, f, l );
1123   if (NbPCurves)
1124     {
1125       MinLoc = E.Location() * MinLoc;
1126       if (!C3d.IsNull())
1127         {
1128           if (MinPC->IsClosed())
1129             {
1130               f = FirstParOnPC;
1131               l = LastParOnPC;
1132             }
1133           else if (C3d->IsPeriodic())
1134             {
1135               Standard_Real delta = (C3d->Period() - (l - f))*0.5;
1136               delta *= 0.95;
1137               f -= delta;
1138               l += delta;
1139             }
1140           else if (C3d->IsClosed())
1141             l -= 0.05*(l - f);
1142           else
1143             {
1144               f = FirstParOnPC;
1145               l = LastParOnPC;
1146               GeomAPI_ProjectPointOnCurve Projector;
1147               if (!Precision::IsInfinite(FirstParOnPC))
1148                 {
1149                   gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
1150                   gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
1151                   P1.Transform(MinLoc.Transformation());
1152                   Projector.Init( P1, C3d );
1153                   if (Projector.NbPoints() > 0)
1154                     f = Projector.LowerDistanceParameter();
1155 #ifdef OCCT_DEBUG
1156                   else
1157                     cout<<"ProjectPointOnCurve not done"<<endl;
1158 #endif
1159                 }
1160               if (!Precision::IsInfinite(LastParOnPC))
1161                 {
1162                   gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
1163                   gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
1164                   P2.Transform(MinLoc.Transformation());
1165                   Projector.Init( P2, C3d );
1166                   if (Projector.NbPoints() > 0)
1167                     l = Projector.LowerDistanceParameter();
1168 #ifdef OCCT_DEBUG
1169                   else
1170                     cout<<"ProjectPointOnCurve not done"<<endl;
1171 #endif
1172                 }
1173             }
1174           BB.Range( NE, f, l );
1175           if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
1176             BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1177         }
1178       else if (!BRep_Tool::Degenerated(E)) //no 3d curve
1179         {
1180           MinSurf = Handle(Geom_Surface)::DownCast
1181             (MinSurf->Transformed(MinLoc.Transformation()));
1182           Standard_Real max_deviation = 0.;
1183           if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
1184             {
1185               if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1186                 {
1187                   Standard_Boolean IsLine = Standard_False;
1188                   if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1189                     IsLine = Standard_True;
1190                   else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
1191                            MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
1192                     {
1193                       Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC);
1194                       gp_Dir2d LineDir = theLine->Direction();
1195                       if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
1196                         IsLine = Standard_True;
1197                     }
1198                   if (IsLine)
1199                     {
1200                       gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
1201                       gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
1202                       gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
1203                       gp_Vec aVec(P1, P2);
1204                       C3d = new Geom_Line( P1, aVec );
1205                     }
1206                 }
1207             }
1208           else
1209             {
1210               Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
1211               GeomAdaptor_Surface GAsurf( MinSurf );
1212               Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
1213               Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
1214               Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
1215               Standard_Real /*max_deviation,*/ average_deviation;
1216               GeomAbs_Shape Continuity = GeomAbs_C1;
1217               Standard_Integer MaxDegree = 14;
1218               Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
1219               GeomLib::BuildCurve3d(Precision::Confusion(),
1220                                     ConS, FirstParOnPC, LastParOnPC,
1221                                     C3d, max_deviation, average_deviation,
1222                                     Continuity, MaxDegree, MaxSegment);
1223             }
1224           BB.UpdateEdge( NE, C3d, max_deviation );
1225           //BB.Range( NE, FirstParOnPC, LastParOnPC );
1226           Standard_Boolean ProjectionSuccess = Standard_True;
1227           if (NbPCurves > 1)
1228             //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1229             for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
1230                  itr.More();
1231                  itr.Next())
1232               {
1233                 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
1234                 Standard_Real FirstPar, LastPar;
1235                 if (CurveRep->IsCurveOnSurface())
1236                   {
1237                     Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
1238                     Handle(Geom_Surface) theSurf  = CurveRep->Surface();
1239                     TopLoc_Location      theLoc   = CurveRep->Location();
1240                     if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
1241                       continue;
1242                     FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
1243                     LastPar  = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
1244                     if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
1245                         Abs(LastPar  - LastParOnPC)  > Precision::PConfusion())
1246                       {
1247                         theLoc = E.Location() * theLoc;
1248                         theSurf = Handle(Geom_Surface)::DownCast
1249                           (theSurf->Transformed(theLoc.Transformation()));
1250
1251                         if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
1252                             theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
1253                           {
1254                             gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction();
1255                             if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
1256                                 theDir.IsParallel(gp::DY2d(), Precision::Angular()))
1257                               {
1258                                 Standard_Real U1, U2, V1, V2;
1259                                 theSurf->Bounds(U1, U2, V1, V2);
1260                                 gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location();
1261                                 if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
1262                                     Abs(Origin.X()-U2) <= Precision::Confusion() ||
1263                                     Abs(Origin.Y()-V1) <= Precision::Confusion() ||
1264                                     Abs(Origin.Y()-V2) <= Precision::Confusion())
1265                                   {
1266                                     BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1267                                     break;
1268                                   }
1269                               }
1270                           }
1271
1272                         Handle(Geom2d_Curve) ProjPCurve =
1273                           GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
1274                         if (ProjPCurve.IsNull())
1275                           ProjectionSuccess = Standard_False;
1276                         else
1277                           CurveRep->PCurve( ProjPCurve );
1278                       }
1279                   }
1280               }
1281           if (ProjectionSuccess)
1282             BB.Range( NE, FirstParOnPC, LastParOnPC );
1283           else
1284             {
1285               BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
1286               BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1287             }
1288         }
1289     }
1290   else //no pcurves
1291     {
1292       Standard_Real FirstPar = C3d->FirstParameter();
1293       Standard_Real LastPar  = C3d->LastParameter();
1294       
1295       if (C3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) &&
1296           (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
1297         {
1298           Handle(Geom_TrimmedCurve) aTrCurve = 
1299             new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
1300           
1301           // The curve is not prolonged on begin or end.
1302           // Trying to prolong it adding a segment to its bound.
1303           gp_Pnt                              aPBnd;
1304           gp_Vec                              aVBnd;
1305           gp_Pnt                              aPBeg;
1306           gp_Dir                              aDBnd;
1307           Handle(Geom_Line)                   aLin;
1308           Handle(Geom_TrimmedCurve)           aSegment;
1309           GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
1310           Standard_Real                       aTol = Precision::Confusion();
1311           Standard_Real                       aDelta = Max(a2Offset, 1.);
1312           
1313           if (FirstPar > anEf - a2Offset) {
1314             C3d->D1(FirstPar, aPBnd, aVBnd);
1315             aDBnd.SetXYZ(aVBnd.XYZ());
1316             aPBeg    = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
1317             aLin     = new Geom_Line(aPBeg, aDBnd);
1318             aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1319             
1320             if (!aCompCurve.Add(aSegment, aTol))
1321               return;
1322           }
1323           
1324           if (LastPar < anEl + a2Offset) {
1325             C3d->D1(LastPar, aPBeg, aVBnd);
1326             aDBnd.SetXYZ(aVBnd.XYZ());
1327             aLin     = new Geom_Line(aPBeg, aDBnd);
1328             aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1329             
1330             if (!aCompCurve.Add(aSegment, aTol))
1331               return;
1332           }
1333           
1334           C3d = aCompCurve.BSplineCurve();
1335           FirstPar = C3d->FirstParameter();
1336           LastPar  = C3d->LastParameter();
1337           BB.UpdateEdge(NE, C3d, Precision::Confusion());
1338         }
1339       else if (C3d->IsPeriodic())
1340         {
1341           Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
1342           delta *= 0.95;
1343           FirstPar = anEf - delta;
1344           LastPar  = anEl + delta;
1345         }
1346       else if (C3d->IsClosed())
1347         LastPar -= 0.05*(LastPar - FirstPar);
1348       
1349       BB.Range( NE, FirstPar, LastPar );
1350     }
1351 }
1352 //  Modified by skv - Fri Dec 26 17:00:57 2003 OCC4455 End
1353
1354
1355 //=======================================================================
1356 //function : UpdateVertex
1357 //purpose  : 
1358 //=======================================================================
1359
1360 static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
1361                                       TopoDS_Edge&  OE,
1362                                       TopoDS_Edge&  NE,
1363                                       Standard_Real TolConf)
1364 {
1365   BRepAdaptor_Curve OC(OE);
1366   BRepAdaptor_Curve NC(NE);
1367   Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
1368   Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
1369   Standard_Real U = 0.;
1370   Standard_Real ParTol = Precision::PConfusion();
1371   gp_Pnt           P  = BRep_Tool::Pnt(V);
1372   Standard_Boolean OK = Standard_False;
1373
1374   if (P.Distance(OC.Value(Of)) < TolConf) {
1375     if (Of >= Nf + ParTol && Of <= Nl + ParTol  && P.Distance(NC.Value(Of)) < TolConf) {
1376       OK = Standard_True;
1377       U    = Of;
1378     }
1379   }
1380   if (P.Distance(OC.Value(Ol)) < TolConf) {
1381     if (Ol >= Nf + ParTol && Ol <= Nl + ParTol  && P.Distance(NC.Value(Ol)) < TolConf) {
1382       OK = Standard_True;
1383       U    = Ol;
1384     }
1385   }
1386   if (OK) {
1387     BRep_Builder B;
1388     TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
1389     TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
1390 //    TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
1391     aLocalShape = V.Oriented(TopAbs_INTERNAL);
1392     B.UpdateVertex(TopoDS::Vertex(aLocalShape),
1393                    U,NE,BRep_Tool::Tolerance(NE));
1394 //    B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
1395 //                 U,NE,BRep_Tool::Tolerance(NE));
1396   }
1397   return OK;  
1398 }
1399
1400 //=======================================================================
1401 //function : Compute
1402 //purpose  : 
1403 //=======================================================================
1404
1405 void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
1406                                   const TopoDS_Face&                F,
1407                                   const TopTools_IndexedMapOfShape& NewEdges,
1408                                   const Standard_Real               Tol)
1409 {
1410 #ifdef DRAW
1411   NbF2d++;
1412   NbE2d = 0;
1413 #endif 
1414
1415   //Do not intersect the edges of face
1416   TopTools_MapOfShape EdgesOfFace;
1417   TopExp_Explorer Explo( F, TopAbs_EDGE );
1418   for (; Explo.More(); Explo.Next())
1419     EdgesOfFace.Add( Explo.Current() );
1420
1421   //-----------------------------------------------------------
1422   // calculate intersections2d on faces touched by  
1423   // intersection3d
1424   //---------------------------------------------------------
1425   TopTools_ListIteratorOfListOfShape it1LE ;    
1426   TopTools_ListIteratorOfListOfShape it2LE ;  
1427
1428   //-----------------------------------------------
1429   // Intersection of edges 2*2.
1430   //-----------------------------------------------
1431   const TopTools_ListOfShape&        LE = AsDes->Descendant(F);
1432   TopoDS_Vertex                      V1,V2;
1433   Standard_Integer                   j, i = 1;
1434
1435   for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
1436     const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());        
1437     j = 1;
1438     it2LE.Initialize(LE);
1439     
1440     while (j < i && it2LE.More()) {
1441       const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value());
1442       //--------------------------------------------------------------
1443       // Intersections of New edges obtained by intersection
1444       // between them and with edges of restrictions
1445       //------------------------------------------------------
1446       if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
1447            (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
1448         TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
1449         EdgeInter(TopoDS::Face(aLocalShape),E1,E2,AsDes,Tol,Standard_True);
1450 //        EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
1451       }
1452       it2LE.Next();
1453       j++;
1454     }
1455     i++;
1456   }
1457 }
1458
1459 //=======================================================================
1460 //function : ConnexIntByInt
1461 //purpose  : 
1462 //=======================================================================
1463
1464 //  Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin
1465 //  Add another parameter: offset value.
1466 void BRepOffset_Inter2d::ConnexIntByInt
1467 (const TopoDS_Face&            FI,
1468  BRepOffset_Offset&            OFI,
1469  TopTools_DataMapOfShapeShape& MES,
1470  const TopTools_DataMapOfShapeShape& Build,
1471  const Handle(BRepAlgo_AsDes)&     AsDes,
1472  const Standard_Real           Offset,
1473  const Standard_Real           Tol)
1474 //  Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
1475 {  
1476
1477   TopTools_DataMapOfShapeListOfShape MVE;
1478   BRepOffset_Tool::MapVertexEdges(FI,MVE);
1479
1480   //---------------------
1481   // Extension of edges.
1482   //---------------------
1483   TopoDS_Edge  NE;
1484   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(MVE);
1485   for  ( ; it.More(); it.Next()) {
1486     const TopTools_ListOfShape&  L = it.Value();
1487     Standard_Boolean   YaBuild = 0;
1488     TopTools_ListIteratorOfListOfShape itL(L);
1489     for (; itL.More(); itL.Next()) {
1490       YaBuild = Build.IsBound(itL.Value());
1491       if (YaBuild) break;
1492     }
1493     if (YaBuild) {
1494       for (itL.Initialize(L); itL.More(); itL.Next()) {
1495         const TopoDS_Edge& EI = TopoDS::Edge(itL.Value());
1496         TopoDS_Shape aLocalShape = OFI.Generated(EI);
1497         const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape);
1498 //      const TopoDS_Edge& OE = TopoDS::Edge(OFI.Generated(EI));
1499         if (!MES.IsBound(OE) && !Build.IsBound(EI)) {
1500 //  Modified by skv - Fri Dec 26 16:59:52 2003 OCC4455 Begin
1501 //        ExtentEdge(OE,NE);
1502           ExtentEdge(OE,NE, Offset);
1503 //  Modified by skv - Fri Dec 26 16:59:54 2003 OCC4455 End
1504           MES.Bind  (OE,NE);
1505         }
1506       }
1507     } 
1508   }
1509   
1510   TopoDS_Face           FIO = TopoDS::Face(OFI.Face());
1511   if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
1512
1513   TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1514   for (; exp.More(); exp.Next()) {
1515     const TopoDS_Wire&     W = TopoDS::Wire(exp.Current());
1516     BRepTools_WireExplorer wexp;
1517     Standard_Boolean       end = Standard_False ;
1518     TopoDS_Edge            FirstE,CurE,NextE;
1519
1520     TopoDS_Shape aLocalWire = W .Oriented(TopAbs_FORWARD);
1521     TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
1522     wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
1523 //    wexp.Init(TopoDS::Wire(W .Oriented(TopAbs_FORWARD)),
1524 //            TopoDS::Face(FI.Oriented(TopAbs_FORWARD)));
1525     CurE = FirstE  = wexp.Current(); 
1526     while (!end) {
1527       wexp.Next();
1528       if (wexp.More()) {
1529         NextE = wexp.Current();
1530       } 
1531       else {
1532         NextE = FirstE; end = Standard_True;
1533       }
1534       if (CurE.IsSame(NextE)) continue;
1535
1536       //IFV------------
1537       TopoDS_Vertex Vref = CommonVertex(CurE, NextE); 
1538       gp_Pnt Pref = BRep_Tool::Pnt(Vref);
1539       //IFV------------
1540
1541       TopoDS_Shape aLocalShape = OFI.Generated(CurE);
1542       TopoDS_Edge CEO = TopoDS::Edge(aLocalShape);
1543       aLocalShape = OFI.Generated(NextE);
1544       TopoDS_Edge NEO = TopoDS::Edge(aLocalShape);
1545 //      TopoDS_Edge CEO = TopoDS::Edge(OFI.Generated(CurE));
1546 //      TopoDS_Edge NEO = TopoDS::Edge(OFI.Generated(NextE));
1547       //------------------------------------------
1548       // Inter processing of images of CurE NextE.
1549       //------------------------------------------
1550       TopTools_ListOfShape LV1,LV2;
1551       Standard_Boolean     DoInter = 1;
1552       TopoDS_Shape         NE1,NE2;
1553       
1554       if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
1555         NE1 = Build(CurE );
1556         NE2 = Build(NextE);
1557       }
1558       else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
1559         NE1 = Build(CurE);
1560         NE2 = MES  (NEO);
1561       }
1562       else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
1563         NE1 = Build(NextE);
1564         NE2 = MES(CEO);
1565       }
1566       else {
1567         DoInter = 0;
1568       }
1569       if (DoInter) {
1570         //------------------------------------
1571         // NE1,NE2 can be a compound of Edges.
1572         //------------------------------------
1573         TopExp_Explorer Exp1,Exp2;
1574         for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
1575           for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
1576             RefEdgeInter(FIO,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
1577                       AsDes,Tol,Standard_True/*Standard_False*/, Pref);
1578           }
1579         }
1580       }
1581       else {
1582         if (MES.IsBound(CEO)) {
1583           TopoDS_Vertex  V = CommonVertex(CEO,NEO); 
1584           UpdateVertex  (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
1585           AsDes->Add     (MES(CEO),V);
1586         }
1587         else if (MES.IsBound(NEO)) {
1588           TopoDS_Vertex V = CommonVertex(CEO,NEO); 
1589           UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
1590           AsDes->Add    (MES(NEO),V);
1591         }
1592       }
1593       CurE = NextE;
1594     }
1595   }
1596 }
1597
1598
1599