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