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