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