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