0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / TopOpeBRep / TopOpeBRep_FacesIntersector.cxx
1 // File:      TopOpeBRep_FacesIntersector.cxx
2 // Created:   Thu Nov 18 11:12:07 1993
3 // Author:    Jean Yves LEBEY
4 // Copyright: OPEN CASCADE 1993
5
6 #include <TopOpeBRep_FacesIntersector.ixx>
7
8 #ifdef DRAW
9 #include <TopOpeBRep_DRAW.hxx>
10 #endif
11
12 #include <IntPatch_LineConstructor.hxx>
13 #include <TopOpeBRep_TypeLineCurve.hxx>
14 #include <TopoDS.hxx>
15 #include <TopoDS_Face.hxx>
16 #include <TopoDS_Edge.hxx>
17 #include <BRep_Tool.hxx>
18 #include <TopExp_Explorer.hxx>
19 #include <TopOpeBRepTool_ShapeTool.hxx>
20 #include <Precision.hxx>
21 #include <Geom_Curve.hxx>
22 #include <Standard_ProgramError.hxx>
23 #include <TCollection_AsciiString.hxx>
24 #include <Standard_CString.hxx>
25 #include <BRepTools.hxx>
26 #include <TopOpeBRepTool_tol.hxx>
27
28 Standard_EXPORT Standard_Real GLOBAL_tolFF = 1.e-7;
29
30 #ifdef DEB
31 #include <TopAbs.hxx>
32 Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceFI();
33 Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceFITOL();
34 Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceSAVFF();
35
36 Standard_EXPORT Standard_Integer SAVFFi1 = 0;
37 Standard_EXPORT Standard_Integer SAVFFi2 = 0;
38 static void SAVFF(const TopoDS_Face& F1,const TopoDS_Face& F2)
39 {
40   TCollection_AsciiString an1("SAVA");if (SAVFFi1) an1=an1+SAVFFi1;
41   TCollection_AsciiString an2("SAVB");if (SAVFFi2) an2=an2+SAVFFi2;
42   Standard_CString n1=an1.ToCString();Standard_CString n2=an2.ToCString();
43 #ifdef DRAW
44   cout<<"FaceIntersector :   set "<<n1<<","<<n2<<endl;DBRep::Set(n1,F1);DBRep::Set(n2,F2);
45 #endif
46   cout<<"FaceIntersector : write "<<n1<<","<<n2<<endl;BRepTools::Write(F1,n1);BRepTools::Write(F2,n2); 
47 }
48
49 Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceKRO();
50 #include <TopOpeBRepTool_KRO.hxx>
51 Standard_EXPORT TOPKRO KRO_DSFILLER_INTFF("intersection face/face");
52
53 #endif
54
55 // NYI
56 // NYI : IntPatch_Intersection : TolArc,TolTang exact definition
57 // NYI
58
59
60 // modified by NIZHNY-MKK  Mon Apr  2 12:14:32 2001.BEGIN
61 #include <IntPatch_WLine.hxx>
62 #include <IntPatch_RLine.hxx>
63 #include <IntPatch_Point.hxx>
64 #include <Adaptor3d_HSurface.hxx>
65 #include <Adaptor3d_TopolTool.hxx>
66 #include <Adaptor3d_HVertex.hxx>
67 #include <Adaptor2d_HCurve2d.hxx>
68 #include <Geom2dInt_TheProjPCurOfGInter.hxx>
69
70 static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine,
71                                                   const Standard_Integer                         theRank,
72                                                   const Handle(Adaptor3d_HSurface)&              theSurface,
73                                                   const Handle(Adaptor3d_TopolTool)&             theDomain,
74                                                   const Standard_Real                            theTolArc);
75
76 static 
77 Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
78                                                                const Handle(Adaptor2d_HCurve2d)&              theArc,
79                                                                const Standard_Integer                         theRank);
80
81 static
82 Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine&     theSeqOfWLine,
83                                                    const Standard_Integer             theRank,
84                                                    const Handle(Adaptor3d_HSurface)&  theSurface,
85                                                    const Handle(Adaptor3d_TopolTool)& theDomain,
86                                                    const Standard_Real                theTolArc);
87
88 static void TestWLinesToAnArc(IntPatch_SequenceOfLine&           slin,
89                               const Handle(Adaptor3d_HSurface)&  theSurface1,
90                               const Handle(Adaptor3d_TopolTool)& theDomain1,
91                               const Handle(Adaptor3d_HSurface)&  theSurface2,
92                               const Handle(Adaptor3d_TopolTool)& theDomain2,
93                               const Standard_Real                theTolArc);
94 // modified by NIZHNY-MKK  Mon Apr  2 12:14:38 2001.END
95
96 // modified by NIZHNY-OFV  Fri Mar 29 12:37:21 2002.BEGIN
97 #include <TColgp_SequenceOfPnt.hxx>
98 #include <TopExp.hxx>
99 #include <TColStd_SequenceOfReal.hxx>
100 #include <Extrema_ExtPS.hxx>
101 #include <Extrema_ExtPC.hxx>
102 #include <Extrema_POnSurf.hxx>
103 #include <GeomAdaptor_Curve.hxx>
104 static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine&           theSlin,
105                                                      const Handle(Adaptor3d_HSurface)&  theSurface1,
106                                                      const Handle(Adaptor3d_TopolTool)& theDomain1,
107                                                      const Handle(Adaptor3d_HSurface)&  theSurface2,
108                                                      const Handle(Adaptor3d_TopolTool)& theDomain2,
109                                                      const Standard_Real                theTolArc);
110 //------------------------------------------------------------------------------------------------
111 static Standard_Integer GetArc(IntPatch_SequenceOfLine&           theSlin,
112                                const Standard_Integer&            theRankS,
113                                const Handle(Adaptor3d_HSurface)&  theSurfaceObj,
114                                const Handle(Adaptor3d_TopolTool)& theDomainObj,
115                                const Handle(Adaptor3d_HSurface)&  theSurfaceTool,
116                                const gp_Pnt&                      theTestPoint,
117                                Standard_Real&                     theVrtxTol,
118                                Handle(IntSurf_LineOn2S)&          theLineOn2S,
119                                Standard_Real&                     theFirst,
120                                Standard_Real&                     theLast);
121 //------------------------------------------------------------------------------------------------
122 static Standard_Boolean IsPointOK(const gp_Pnt&            theTestPnt,
123                                   const Adaptor3d_Surface& theTestSurface,
124                                   const Standard_Real&     theTol);
125 //-------------------------------------------------------------------------------------------------
126 static Standard_Boolean GetPointOn2S(const gp_Pnt&            theTestPnt,
127                                      const Adaptor3d_Surface& theTestSurface,
128                                      const Standard_Real&     theTol,
129                                      Extrema_POnSurf&         theResultPoint);
130 //-------------------------------------------------------------------------------------------------------------------------
131 static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine&           theSlin,
132                                                                            const Standard_Real&               theVrtxTol,
133                                                                            const Handle(IntSurf_LineOn2S)&    theLineOn2S);
134 //---------------------------------------------------------------------------------------------------------------------------
135 // modified by NIZHNY-OFV  Fri Mar 29 12:41:02 2002.END
136
137 //=======================================================================
138 //function : TopOpeBRep_FacesIntersector
139 //purpose  : 
140 //=======================================================================
141 TopOpeBRep_FacesIntersector::TopOpeBRep_FacesIntersector ()
142 {
143   ResetIntersection();
144   myTol1 = myTol2 = Precision::Confusion();
145   myForceTolerances = Standard_False;
146   mySurface1 = new BRepAdaptor_HSurface();
147   mySurface2 = new BRepAdaptor_HSurface();
148   myDomain1 = new BRepTopAdaptor_TopolTool();
149   myDomain2 = new BRepTopAdaptor_TopolTool();
150 }
151
152 //=======================================================================
153 //function : Perform
154 //purpose  : 
155 //=======================================================================
156 void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2,
157                                           const Bnd_Box& B1,const Bnd_Box& B2)
158 {
159 #ifdef DEB
160   if (TopOpeBRep_GettraceSAVFF()) SAVFF(TopoDS::Face(F1),TopoDS::Face(F2));
161 #endif
162   
163   ResetIntersection();
164   if (!myForceTolerances) ShapeTolerances(F1,F2);
165   
166   myFace1 = TopoDS::Face(F1); myFace1.Orientation(TopAbs_FORWARD);
167   myFace2 = TopoDS::Face(F2); myFace2.Orientation(TopAbs_FORWARD);
168   BRepAdaptor_Surface& S1 = mySurface1->ChangeSurface(); S1.Initialize(myFace1);
169   BRepAdaptor_Surface& S2 = mySurface2->ChangeSurface(); S2.Initialize(myFace2);
170   mySurfaceType1 = S1.GetType();
171   mySurfaceType2 = S2.GetType();
172   myDomain1->Initialize(mySurface1);
173   myDomain2->Initialize(mySurface2);
174
175 #ifdef DEB
176   if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Start();
177 #endif
178
179   Standard_Real Deflection=0.01,MaxUV=0.01;
180   if (!myForceTolerances) {
181     FTOL_FaceTolerances3d(B1,B2,myFace1,myFace2,S1,S2,
182                                 myTol1,myTol2,Deflection,MaxUV);  
183     myTol1 = (myTol1 > 1.e-4)? 1.e-4: myTol1;
184     myTol2 = (myTol2 > 1.e-4)? 1.e-4: myTol2;
185   }
186   
187   Standard_Real tol1 = myTol1;
188   Standard_Real tol2 = myTol2;
189   GLOBAL_tolFF = Max(tol1,tol2);
190
191 #ifdef DEB
192   if (TopOpeBRep_GettraceFITOL()) {
193     cout<<"FacesIntersector : Perform tol1 = "<<tol1<<endl;
194     cout<<"                           tol2 = "<<tol2<<endl;
195     cout<<"                           defl = "<<Deflection<<"  MaxUV = "<<MaxUV<<endl;
196   }
197 #endif
198
199   myIntersector.SetTolerances(myTol1,myTol2,MaxUV,Deflection); 
200   myIntersector.Perform(mySurface1,myDomain1,mySurface2,myDomain2,myTol1,myTol2);
201
202 #ifdef DEB
203   if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Stop();
204 #endif
205
206   //xpu180998 : cto900Q1
207   Standard_Boolean done = myIntersector.IsDone();
208   if (!done) return;
209
210   PrepareLines();
211   myIntersectionDone = Standard_True;
212
213   // mySurfacesSameOriented : a mettre dans IntPatch NYI
214   if ( SameDomain() ) {
215     mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2);
216   }
217
218   // build the map of edges found as RESTRICTION
219   for (InitLine(); MoreLine(); NextLine()) {
220     TopOpeBRep_LineInter& L = CurrentLine();
221     if (L.TypeLineCurve() == TopOpeBRep_RESTRICTION) {
222       const TopoDS_Shape& E = L.Arc();
223       myEdgeRestrictionMap.Add(E);
224     }
225   }
226   
227 #ifdef DEB
228   if (TopOpeBRep_GettraceFI()) cout<<"Perform : isempty "<<IsEmpty()<<endl;
229 #endif
230 }
231
232 //=======================================================================
233 //function : Perform
234 //purpose  : 
235 //=======================================================================
236
237 void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
238 {
239   Bnd_Box B1,B2;
240   Perform(F1,F2,B1,B2);
241 }
242
243
244 //=======================================================================
245 //function : IsEmpty
246 //purpose  : 
247 //=======================================================================
248
249 Standard_Boolean TopOpeBRep_FacesIntersector::IsEmpty () 
250 {
251   if ( ! myIntersectionDone ) return Standard_False;
252   Standard_Boolean done  = myIntersector.IsDone();
253   Standard_Boolean empty = myIntersector.IsEmpty();
254   if ( !done || empty ) return Standard_True;
255   else {
256     // ElemIntersector is done and is not empty
257     // returns True if at least one VPoint is found
258     empty = Standard_True;
259     for ( InitLine(); MoreLine(); NextLine() ) {
260       empty = (CurrentLine().NbVPoint() == 0);
261       if ( ! empty ) break;
262     }
263     return empty;
264   }
265 }
266
267 //=======================================================================
268 //function : IsDone
269 //purpose  : 
270 //=======================================================================
271
272 Standard_Boolean TopOpeBRep_FacesIntersector::IsDone () const
273 {
274   return myIntersectionDone;
275 }
276
277 //=======================================================================
278 //function : SameDomain
279 //purpose  : 
280 //=======================================================================
281
282 Standard_Boolean TopOpeBRep_FacesIntersector::SameDomain () const 
283 {
284   if (!myIntersectionDone) 
285     Standard_ProgramError::Raise("FacesIntersector : bad SameDomain");
286
287   Standard_Boolean sd = myIntersector.TangentFaces();
288
289   //Standard_Boolean plpl = (mySurfaceType1 == GeomAbs_Plane) && (mySurfaceType2 == GeomAbs_Plane);
290
291 //  if (!plpl) return Standard_False;
292   return sd;
293 }
294
295
296 //=======================================================================
297 //function : Face
298 //purpose  : 
299 //=======================================================================
300
301 const TopoDS_Shape& TopOpeBRep_FacesIntersector::Face
302 (const Standard_Integer Index) const 
303 {
304   if      ( Index == 1 ) return myFace1;
305   else if ( Index == 2 ) return myFace2;
306   else Standard_ProgramError::Raise("TopOpeBRep_FacesIntersector::Face");
307
308   return myNullShape;
309 }
310
311
312 //=======================================================================
313 //function : SurfacesSameOriented
314 //purpose  : 
315 //=======================================================================
316
317 Standard_Boolean TopOpeBRep_FacesIntersector::SurfacesSameOriented () const
318 {
319   if ( SameDomain() ) {
320     return mySurfacesSameOriented;
321   }
322   Standard_ProgramError::Raise("FacesIntersector : bad SurfacesSameOriented");
323   return Standard_False;
324 }
325
326 //=======================================================================
327 //function : IsRestriction
328 //purpose  : 
329 //=======================================================================
330
331 Standard_Boolean TopOpeBRep_FacesIntersector::IsRestriction
332    (const TopoDS_Shape& E) const
333 {
334   Standard_Boolean isrest = myEdgeRestrictionMap.Contains(E);
335   return isrest;
336 }
337
338 //=======================================================================
339 //function : Restrictions
340 //purpose  : 
341 //=======================================================================
342
343 const TopTools_IndexedMapOfShape& TopOpeBRep_FacesIntersector::Restrictions 
344    () const 
345 {
346   return myEdgeRestrictionMap;
347 }
348
349 //=======================================================================
350 //function : PrepareLines
351 //purpose  : 
352 //=======================================================================
353
354 void  TopOpeBRep_FacesIntersector::PrepareLines()
355 {
356   myLineNb = 0;
357   Standard_Integer n = myIntersector.NbLines();
358   myHAL = new TopOpeBRep_HArray1OfLineInter(0,n); 
359   BRepAdaptor_Surface& S1 = *((BRepAdaptor_Surface*)&(mySurface1->Surface()));
360   BRepAdaptor_Surface& S2 = *((BRepAdaptor_Surface*)&(mySurface2->Surface()));
361
362   // modified by NIZHNY-MKK  Mon Apr  2 12:14:58 2001.BEGIN
363   if(n==0)
364     return;
365   // modified by NIZHNY-MKK  Mon Apr  2 12:15:09 2001.END
366
367   Standard_Boolean newV = Standard_True;
368
369   if (!newV) {
370   /*for (  Standard_Integer i=1; i<=n; i++) {
371     TopOpeBRep_LineInter& LI = myHAL->ChangeValue(i);
372     const Handle(IntPatch_Line)& L = myIntersector.Line(i);
373     LI.SetLine(L,S1,S2);
374     LI.Index(i);
375     myLineNb++;;
376   }*/}
377
378   if (newV) {
379     //-- lbr
380
381     // modified by NIZHNY-MKK  Mon Apr  2 12:16:04 2001
382     IntPatch_SequenceOfLine aSeqOfLines, aSeqOfResultLines;
383
384     Standard_Integer i ;
385 //    Standard_Integer nbl=0;
386     IntPatch_LineConstructor **Ptr = 
387       (IntPatch_LineConstructor **)malloc(n*sizeof(IntPatch_LineConstructor *));
388     for( i=1;i<=n;i++) { 
389       Ptr[i-1]=new IntPatch_LineConstructor(2);
390       Ptr[i-1]->Perform(myIntersector.SequenceOfLine(),
391                         myIntersector.Line(i),
392                         mySurface1,myDomain1,
393                         mySurface2,myDomain2,
394                         myTol1);
395       // modified by NIZHNY-MKK  Mon Apr  2 12:16:26 2001.BEGIN
396       aSeqOfLines.Clear();
397       for(Standard_Integer k=1; k<=Ptr[i-1]->NbLines(); k++) {
398         aSeqOfLines.Append(Ptr[i-1]->Line(k));
399       }
400
401       TestWLinesToAnArc(aSeqOfLines, mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
402
403       for(Standard_Integer j=1; j<=aSeqOfLines.Length(); j++) {
404         aSeqOfResultLines.Append(aSeqOfLines.Value(j));
405       }
406       delete Ptr[i-1];      
407       //       nbl+=Ptr[i-1]->NbLines();
408       // modified by NIZHNY-MKK  Mon Apr  2 12:16:31 2001.END
409     }
410
411     // modified by NIZHNY-MKK  Mon Apr  2 12:17:22 2001.BEGIN
412     //     myHAL = new TopOpeBRep_HArray1OfLineInter(0,nbl); 
413     myLineNb = aSeqOfResultLines.Length();
414  
415     //Fun_ConvertWLinesToRLine(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
416     MergeWLinesIfAllSegmentsAlongRestriction(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
417     myLineNb = aSeqOfResultLines.Length();
418
419
420     if(myLineNb > 0) {
421       myHAL = new TopOpeBRep_HArray1OfLineInter(1, myLineNb); 
422       for(Standard_Integer index = 1; index <= myLineNb; index++) {
423         TopOpeBRep_LineInter& LI = myHAL->ChangeValue(index);
424         const Handle(IntPatch_Line)& L = aSeqOfResultLines.Value(index);
425         LI.SetLine(L,S1,S2);
426         LI.Index(index);
427       }
428     }
429     
430     //     nbl=1;
431     //     for(i=1;i<=n;i++) { 
432     //       for(Standard_Integer k=1;k<=Ptr[i-1]->NbLines();k++) {
433     //  TopOpeBRep_LineInter& LI = myHAL->ChangeValue(nbl);
434     //  const Handle(IntPatch_Line)& L = Ptr[i-1]->Line(k);
435     //  LI.SetLine(L,S1,S2);
436     //  LI.Index(nbl);
437     //  myLineNb++;
438     //  nbl++;
439     //       }
440     //       delete Ptr[i-1];
441     //     }
442     // modified by NIZHNY-MKK  Mon Apr  2 12:17:57 2001.END
443     free(Ptr);
444   }
445 }
446
447 //=======================================================================
448 //function : Lines
449 //purpose  : 
450 //=======================================================================
451
452 Handle(TopOpeBRep_HArray1OfLineInter) TopOpeBRep_FacesIntersector::Lines()
453 {
454   return myHAL;
455 }
456
457 //=======================================================================
458 //function : NbLines
459 //purpose  : 
460 //=======================================================================
461
462 Standard_Integer TopOpeBRep_FacesIntersector::NbLines()const
463 {
464   return myLineNb;
465 }
466
467 //=======================================================================
468 //function : InitLine
469 //purpose  : 
470 //=======================================================================
471
472 void  TopOpeBRep_FacesIntersector::InitLine()
473 {
474   myLineIndex = 1;
475   FindLine();
476 }
477
478 //=======================================================================
479 //function : FindLine
480 //purpose  : 
481 //=======================================================================
482
483 void  TopOpeBRep_FacesIntersector::FindLine()
484 {
485   myLineFound = Standard_False;
486   if ( ! myIntersectionDone ) return;
487
488   while (myLineIndex <= myLineNb) {
489     const TopOpeBRep_LineInter& L = myHAL->Value(myLineIndex);
490     myLineFound = L.OK();
491     if (myLineFound) break;
492     else myLineIndex++;
493   }
494 }
495
496 //=======================================================================
497 //function : MoreLine
498 //purpose  : 
499 //=======================================================================
500
501 Standard_Boolean  TopOpeBRep_FacesIntersector::MoreLine()const 
502 {
503   return myLineFound;
504 }
505
506
507 //=======================================================================
508 //function : NextLine
509 //purpose  : 
510 //=======================================================================
511
512 void  TopOpeBRep_FacesIntersector::NextLine()
513 {
514   myLineIndex++;
515   FindLine();
516 }
517
518 //=======================================================================
519 //function : CurrentLine
520 //purpose  : 
521 //=======================================================================
522
523 TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::CurrentLine()
524 {
525   TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(myLineIndex);
526   return TLI;
527 }
528
529
530 //=======================================================================
531 //function : CurrentLineIndex
532 //purpose  : 
533 //=======================================================================
534
535 Standard_Integer TopOpeBRep_FacesIntersector::CurrentLineIndex()const
536 {
537   return myLineIndex;
538 }
539
540 //=======================================================================
541 //function : Line
542 //purpose  : 
543 //=======================================================================
544
545 TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::ChangeLine(const Standard_Integer IL)
546 {
547   TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(IL);
548   return TLI;
549 }
550
551 //=======================================================================
552 //function : ResetIntersection
553 //purpose  : 
554 //=======================================================================
555
556 void TopOpeBRep_FacesIntersector::ResetIntersection() 
557 {
558   myIntersectionDone = Standard_False;
559   myLineIndex = 1;
560   myLineNb = 0;
561   myEdgeRestrictionMap.Clear();
562   myLineFound = Standard_False;
563 }
564
565
566 //=======================================================================
567 //function : ForceTolerances
568 //purpose  : 
569 //=======================================================================
570
571 void TopOpeBRep_FacesIntersector::ForceTolerances(const Standard_Real Tol1,
572                                                   const Standard_Real Tol2)
573 {
574   myTol1 = Tol1;
575   myTol2 = Tol2;  
576   myForceTolerances = Standard_True;
577 #ifdef DEB
578   if (TopOpeBRep_GettraceFITOL())
579     cout<<"ForceTolerances : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl;
580 #endif
581 }
582
583 //=======================================================================
584 //function : GetTolerances
585 //purpose  : 
586 //=======================================================================
587
588 void TopOpeBRep_FacesIntersector::GetTolerances(Standard_Real& Tol1,
589                                                 Standard_Real& Tol2) const
590 {
591   Tol1 = myTol1;
592   Tol2 = myTol2;
593 }
594
595 //=======================================================================
596 //function : ShapeTolerances
597 //purpose  : (private)
598 //=======================================================================
599
600 #ifdef DEB
601 void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& S1,
602                                                   const TopoDS_Shape& S2)
603 #else
604 void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& ,
605                                                   const TopoDS_Shape& )
606 #endif
607 {
608 //  myTol1 = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE));
609   myTol1 = Precision::Confusion();
610   myTol2 = myTol1;  
611   myForceTolerances = Standard_False;
612 #ifdef DEB
613   if (TopOpeBRep_GettraceFITOL()) {
614     cout<<"ShapeTolerances on S1 = ";TopAbs::Print(S1.ShapeType(),cout);
615     cout<<" S2 = ";TopAbs::Print(S2.ShapeType(),cout);
616     cout<<" : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl;
617   }
618 #endif
619 }
620
621 //=======================================================================
622 //function : ToleranceMax
623 //purpose  : (private)
624 //=======================================================================
625
626 Standard_Real TopOpeBRep_FacesIntersector::ToleranceMax
627 (const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const
628 {
629   TopExp_Explorer e(S,T);
630   if ( ! e.More() ) return Precision::Intersection();
631   else {
632     Standard_Real tol = RealFirst();
633     for (; e.More(); e.Next())
634       tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current()));
635     return tol;
636   }
637 }
638
639
640 // modified by NIZHNY-MKK  Mon Apr  2 12:18:30 2001.BEGIN
641 // ================================================================================================
642 // static function: TestWLineAlongRestriction
643 // purpose:
644 // ================================================================================================
645 static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine,
646                                                   const Standard_Integer                         theRank,
647                                                   const Handle(Adaptor3d_HSurface)&              theSurface,
648                                                   const Handle(Adaptor3d_TopolTool)&             theDomain,
649                                                   const Standard_Real                            theTolArc) {
650
651   Standard_Boolean result = Standard_False; 
652   Standard_Integer NbPnts = theWLine->NbPnts();  
653   Standard_Integer along = 0;
654
655   for(Standard_Integer i=1; i<=NbPnts; i++) {
656     const IntSurf_PntOn2S& Pmid = theWLine->Point(i);
657     Standard_Real u=0., v=0.;
658     if(theRank==1) Pmid.ParametersOnS1(u, v);
659     else Pmid.ParametersOnS2(u, v);
660     //------------------------------------------
661     gp_Pnt ap;
662     gp_Vec ad1u, ad1v;
663     //Standard_Real nad1u, nad1v, tolu, tolv;
664     
665     theSurface->D1(u, v, ap, ad1u, ad1v);
666     //nad1u=ad1u.Magnitude();
667     //nad1v=ad1v.Magnitude();
668     //if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1;
669     //if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1;
670     //if(tolu>tolv)  tolu=tolv;
671     //------------------------------------------
672     
673     //if(theDomain->IsThePointOn(gp_Pnt2d(u, v),tolu)) {
674     //  along++;
675     //}
676
677     if(theDomain->IsThePointOn(gp_Pnt2d(u, v),theTolArc)) along++;
678     //if(along!=i) break;
679   }
680   if(along==NbPnts) result = Standard_True;
681   return result;
682 }
683
684
685 // ================================================================================================
686 // static function: BuildRLineBasedOnWLine
687 // purpose: 
688 // ================================================================================================
689 static 
690 Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
691                                                                const Handle(Adaptor2d_HCurve2d)&              theArc,
692                                                                const Standard_Integer                         theRank) {
693   Handle(IntPatch_RLine) anRLine;
694
695   if((theRank != 1) && (theRank != 2))
696     return anRLine;
697
698   gp_Pnt2d aPOnLine;
699   Standard_Real u=0., v=0.;
700   Standard_Integer nbvtx = theWLine->NbVertex();
701   const IntPatch_Point& Vtx1 = theWLine->Vertex(1);
702   const IntPatch_Point& Vtx2 = theWLine->Vertex(nbvtx);
703   
704   if(theRank == 1) {
705     Vtx1.ParametersOnS1(u, v);
706   }
707   else {
708     Vtx1.ParametersOnS2(u, v);
709   }
710   
711   aPOnLine = gp_Pnt2d(u, v);
712   Standard_Real par1 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
713   
714   if(theRank == 1) {
715     Vtx2.ParametersOnS1(u, v);
716   }
717   else {
718     Vtx2.ParametersOnS2(u, v);
719   }
720   aPOnLine = gp_Pnt2d(u, v);
721   Standard_Real par2 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
722
723   Standard_Real tol = (Vtx1.Tolerance() > Vtx2.Tolerance()) ? Vtx1.Tolerance() : Vtx2.Tolerance();
724
725   if(Abs(par1 - par2) < theArc->Resolution(tol))
726     return anRLine;
727
728   Standard_Boolean IsOnFirst = (theRank == 1);
729
730   Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
731   const Handle(IntSurf_LineOn2S)& Lori = theWLine->Curve();
732   IntSurf_Transition TransitionUndecided;
733   
734   anRLine = new IntPatch_RLine(Standard_False, theWLine->TransitionOnS1(), theWLine->TransitionOnS2());
735
736   if(IsOnFirst) {
737     anRLine->SetArcOnS1(theArc);
738   }
739   else {
740     anRLine->SetArcOnS2(theArc);
741   }
742   
743   Standard_Integer k = 0;
744   if(par1 < par2) {
745
746     for(k = 1; k <= Lori->NbPoints(); k++) { 
747       aLineOn2S->Add(Lori->Value(k));
748     }
749     anRLine->Add(aLineOn2S);
750     IntPatch_Point VtxFirst = Vtx1;
751     
752     VtxFirst.SetArc(IsOnFirst, //-- On First
753                     theArc,
754                     par1,
755                     TransitionUndecided,
756                     TransitionUndecided);
757     VtxFirst.SetParameter(par1);
758     anRLine->AddVertex(VtxFirst);
759     
760     for(k = 2; k < nbvtx; k++) { 
761       IntPatch_Point Vtx = theWLine->Vertex(k);
762       if(theRank == 1) {
763         Vtx.ParametersOnS1(u, v);
764       }
765       else {
766         Vtx.ParametersOnS2(u, v);
767       }
768       gp_Pnt2d atmpPoint(u, v);
769       Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7);
770       Vtx.SetParameter(apar);
771       anRLine->AddVertex(Vtx);
772     }
773     
774     IntPatch_Point VtxLast = Vtx2;
775     VtxLast.SetArc(IsOnFirst, //-- On First
776                    theArc,
777                    par2,
778                    TransitionUndecided,
779                    TransitionUndecided);
780     VtxLast.SetParameter(par2);
781     anRLine->AddVertex(VtxLast);
782     anRLine->SetFirstPoint(1);
783     anRLine->SetLastPoint(nbvtx);
784     anRLine->ComputeVertexParameters(Precision::Confusion());
785   }
786   else {
787
788     for(k = Lori->NbPoints(); k >= 1; k--) { 
789       aLineOn2S->Add(Lori->Value(k));
790     }
791     anRLine->Add(aLineOn2S);
792
793     IntPatch_Point VtxFirst = Vtx2;
794     VtxFirst.SetArc(IsOnFirst, //-- On First
795                     theArc,
796                     par2,
797                     TransitionUndecided,
798                     TransitionUndecided);
799     VtxFirst.SetParameter(par2);
800     anRLine->AddVertex(VtxFirst);
801
802     for(k = nbvtx - 1; k >= 2; k--) { 
803       IntPatch_Point Vtx = theWLine->Vertex(k);
804       Vtx.ReverseTransition();
805       if(theRank == 1) {
806         Vtx.ParametersOnS1(u, v);
807       }
808       else {
809         Vtx.ParametersOnS2(u, v);
810       }
811       gp_Pnt2d atmpPoint(u, v);
812       Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7);
813       Vtx.SetParameter(apar);
814       anRLine->AddVertex(Vtx);
815     }
816     IntPatch_Point VtxLast = Vtx1;
817     VtxLast.SetArc(IsOnFirst, //-- On First
818                    theArc,
819                    par1,
820                    TransitionUndecided,
821                    TransitionUndecided);
822     VtxLast.SetParameter(par1);
823     anRLine->AddVertex(VtxLast);
824     anRLine->SetFirstPoint(1);
825     anRLine->SetLastPoint(nbvtx);
826     anRLine->ComputeVertexParameters(Precision::Confusion());
827   }
828
829   return anRLine;
830 }
831
832 // ================================================================================================
833 // static function: BuildRLine
834 // purpose: build rline based on group of wlines
835 //          return null handle if it is not possible to build rline
836 // ================================================================================================
837 static
838 Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine&     theSeqOfWLine, 
839                                                    const Standard_Integer             theRank,
840                                                    const Handle(Adaptor3d_HSurface)&  theSurface,
841                                                    const Handle(Adaptor3d_TopolTool)& theDomain,
842                                                    const Standard_Real                theTolArc) {
843   Handle(IntPatch_RLine) anRLine;
844   const Handle(IntPatch_WLine)& aWLine1 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(1)));
845   const Handle(IntPatch_WLine)& aWLine2 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(theSeqOfWLine.Length())));
846   const IntPatch_Point& P1 = aWLine1->Vertex(1);
847   const IntPatch_Point& P2 = aWLine2->Vertex(aWLine2->NbVertex());
848   const Handle(Adaptor3d_HVertex)& aV1 = (theRank==1) ? P1.VertexOnS1() : P1.VertexOnS2();
849   const Handle(Adaptor3d_HVertex)& aV2 = (theRank==1) ? P2.VertexOnS1() : P2.VertexOnS2();
850
851   // avoid closed and degenerated edges
852   if(aV1->IsSame(aV2))
853     return anRLine;
854
855   for(theDomain->Init(); theDomain->More(); theDomain->Next()) {
856     theDomain->Initialize(theDomain->Value());
857     Standard_Boolean foundVertex1 = Standard_False;
858     Standard_Boolean foundVertex2 = Standard_False;
859
860     for(theDomain->InitVertexIterator(); (!foundVertex1 || !foundVertex2) && theDomain->MoreVertex(); theDomain->NextVertex()) {
861
862       if(!foundVertex1 && aV1->IsSame(theDomain->Vertex()))
863         foundVertex1 = Standard_True;
864       if(!foundVertex2 && aV2->IsSame(theDomain->Vertex()))
865           foundVertex2 = Standard_True;
866     }
867
868     if(foundVertex1 && foundVertex2) {
869       Standard_Boolean buildrline = (theSeqOfWLine.Length() > 0);
870
871       for(Standard_Integer i = 1; buildrline && i<=theSeqOfWLine.Length(); i++) {
872         const Handle(IntPatch_WLine)& aWLine = 
873           *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(i)));
874
875         Standard_Integer indexpnt = aWLine->NbPnts()/2;
876         if(indexpnt < 1)
877           buildrline = Standard_False;
878         else {    
879           Standard_Real u = RealLast(), v = RealLast();
880           const IntSurf_PntOn2S& POn2S = aWLine->Point(indexpnt);
881           if(theRank==1) {
882             POn2S.ParametersOnS1(u, v);
883           }
884           else {
885             POn2S.ParametersOnS2(u, v);
886           }
887           gp_Pnt2d aPOnArc, aPOnLine(u, v);
888           Standard_Real par = Geom2dInt_TheProjPCurOfGInter::FindParameter(theDomain->Value()->Curve2d(), aPOnLine, 1e-7);
889           aPOnArc = theDomain->Value()->Value(par);
890           gp_Pnt ap;
891           gp_Vec ad1u, ad1v;
892           Standard_Real nad1u, nad1v, tolu, tolv;         
893
894           theSurface->D1(u, v, ap, ad1u, ad1v);
895           nad1u=ad1u.Magnitude();
896           nad1v=ad1v.Magnitude();
897           if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1;
898           if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1;
899           Standard_Real aTolerance  = (tolu > tolv) ? tolv : tolu;
900           
901           if(aPOnArc.Distance(aPOnLine) > aTolerance) {
902             buildrline = Standard_False;
903           }
904         }
905       } //end for
906       
907       if(buildrline) {
908         IntSurf_TypeTrans trans1 = IntSurf_Undecided, trans2 = IntSurf_Undecided;
909
910         Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
911
912         for(Standard_Integer j = 1; j<=theSeqOfWLine.Length(); j++) {
913           const Handle(IntPatch_WLine)& atmpWLine = 
914             *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(j)));
915
916           const Handle(IntSurf_LineOn2S)& Lori = atmpWLine->Curve();
917           
918           if(atmpWLine->TransitionOnS1()!=IntSurf_Undecided && atmpWLine->TransitionOnS1()!=IntSurf_Touch) {
919             trans1 = atmpWLine->TransitionOnS1();
920           }
921           if(atmpWLine->TransitionOnS2()!=IntSurf_Undecided && atmpWLine->TransitionOnS2()!=IntSurf_Touch) {
922             trans2 = atmpWLine->TransitionOnS2();
923           }
924
925           Standard_Integer ParamMinOnLine = (Standard_Integer) atmpWLine->Vertex(1).ParameterOnLine();
926           Standard_Integer ParamMaxOnLine = (Standard_Integer) atmpWLine->Vertex(atmpWLine->NbVertex()).ParameterOnLine();
927
928           for(Standard_Integer k = ParamMinOnLine; k <= ParamMaxOnLine; k++) { 
929             aLineOn2S->Add(Lori->Value(k));
930           }
931         }
932
933         Handle(IntPatch_WLine) emulatedWLine = 
934           new IntPatch_WLine(aLineOn2S, Standard_False, trans1, trans2);
935
936         IntPatch_Point aFirstVertex = P1;
937         IntPatch_Point aLastVertex  = P2;
938         aFirstVertex.SetParameter(1);
939         aLastVertex.SetParameter(aLineOn2S->NbPoints());
940
941         emulatedWLine->AddVertex(aFirstVertex);
942         Standard_Integer apointindex = 0;
943
944         for(apointindex = 2; apointindex <= aWLine1->NbVertex(); apointindex++) {
945           IntPatch_Point aPoint = aWLine1->Vertex(apointindex);
946           Standard_Real aTolerance = (aPoint.Tolerance() > P1.Tolerance()) ? aPoint.Tolerance() : P1.Tolerance();
947           if(aPoint.Value().IsEqual(P1.Value(), aTolerance)) {
948             aPoint.SetParameter(1);
949             emulatedWLine->AddVertex(aPoint);
950           }
951         }
952         
953         for(apointindex = 1; apointindex < aWLine2->NbVertex(); apointindex++) {
954           IntPatch_Point aPoint = aWLine2->Vertex(apointindex);
955           Standard_Real aTolerance = (aPoint.Tolerance() > P2.Tolerance()) ? aPoint.Tolerance() : P2.Tolerance();
956           if(aPoint.Value().IsEqual(P2.Value(), aTolerance)) {
957             aPoint.SetParameter(aLineOn2S->NbPoints());
958             emulatedWLine->AddVertex(aPoint);
959           }
960         }
961
962         emulatedWLine->AddVertex(aLastVertex);
963
964         anRLine = BuildRLineBasedOnWLine(emulatedWLine, theDomain->Value(), theRank);
965         
966         break;
967       }
968     }
969   } //end for
970   
971   return anRLine;
972 }
973
974 // ================================================================================================
975 // static function: TestWLinesToAnArc
976 // purpose: test if possible to replace group of wlines by rline and replace in the sequence slin
977 // ================================================================================================
978 static void TestWLinesToAnArc(IntPatch_SequenceOfLine&           slin,
979                               const Handle(Adaptor3d_HSurface)&  theSurface1,
980                               const Handle(Adaptor3d_TopolTool)& theDomain1,
981                               const Handle(Adaptor3d_HSurface)&  theSurface2,
982                               const Handle(Adaptor3d_TopolTool)& theDomain2,
983                               const Standard_Real                theTolArc) { 
984
985   IntPatch_SequenceOfLine aSeqOfWLine;
986   IntPatch_SequenceOfLine aSeqOfRLine;
987   for(Standard_Integer rank = 1; rank <= 2; rank++) {
988     for(Standard_Integer i=1; i<=slin.Length(); i++) {
989       if(slin.Value(i)->ArcType()!=IntPatch_Walking)
990         continue;
991       const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (slin.Value(i)));
992       Standard_Integer nbvtx = aWLine->NbVertex();
993       const IntPatch_Point& Vtx1 = aWLine->Vertex(1);
994       const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx);
995       Standard_Boolean isvertex = Standard_False, wlineWasAppended = Standard_False;
996
997
998       if(rank==1)
999         isvertex = Vtx1.IsVertexOnS1();
1000       else
1001         isvertex = Vtx1.IsVertexOnS2();
1002
1003       if(isvertex) {
1004         Standard_Boolean appendwline = Standard_True;
1005         if(rank==1) {
1006           if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {       
1007             appendwline = Standard_False;
1008           }
1009         }
1010         if(rank==2) {
1011           if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
1012             appendwline = Standard_False;
1013           }
1014         }
1015         wlineWasAppended = appendwline;
1016         if(appendwline)
1017           aSeqOfWLine.Append(aWLine);
1018       }
1019       else {
1020         if(aSeqOfWLine.Length()==0)
1021           continue;
1022         const Handle(IntPatch_WLine)& aLastWLine = 
1023           *((Handle(IntPatch_WLine) *)& (aSeqOfWLine.Value(aSeqOfWLine.Length())));
1024         const IntPatch_Point& aLastPoint = aLastWLine->Vertex(aLastWLine->NbVertex());
1025         Standard_Real aTolerance = (aLastPoint.Tolerance() > Vtx1.Tolerance()) ? aLastPoint.Tolerance() : Vtx1.Tolerance();
1026         if(aLastPoint.Value().IsEqual(Vtx1.Value(), aTolerance)) {
1027           Standard_Boolean appendwline = Standard_True;
1028           if(rank==1) {
1029             if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {     
1030               appendwline = Standard_False;
1031             }
1032           }
1033           if(rank==2) {
1034             if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
1035               appendwline = Standard_False;
1036             }
1037           }
1038           wlineWasAppended = appendwline;
1039           if(appendwline)
1040             aSeqOfWLine.Append(aWLine);   
1041         }
1042         else {
1043           aSeqOfWLine.Clear();
1044         }
1045       }
1046
1047       isvertex = Standard_False;
1048       if(rank==1)
1049         isvertex = Vtx2.IsVertexOnS1();
1050       else
1051         isvertex = Vtx2.IsVertexOnS2();
1052
1053       if(wlineWasAppended && isvertex) {
1054         // build rline based on sequence of wlines.
1055         Handle(IntPatch_RLine) anRLine;
1056         if(rank==1) {
1057           anRLine = BuildRLine(aSeqOfWLine, rank, theSurface1, theDomain1, theTolArc);
1058         }
1059         else {
1060           anRLine = BuildRLine(aSeqOfWLine, rank, theSurface2, theDomain2, theTolArc);
1061         }
1062         
1063         if(!anRLine.IsNull()) {
1064           aSeqOfRLine.Append(anRLine);
1065           for(Standard_Integer k=1; k<=aSeqOfWLine.Length(); k++) {
1066             for(Standard_Integer j=1; j<=slin.Length(); j++) {
1067               if(aSeqOfWLine(k)==slin(j)) {
1068                 slin.Remove(j);
1069                 break;
1070               }
1071             }
1072           }
1073         }
1074         aSeqOfWLine.Clear();
1075       }
1076     }
1077   }
1078   
1079   for(Standard_Integer i=1; i<=aSeqOfRLine.Length(); i++) {
1080     slin.Append(aSeqOfRLine.Value(i));
1081   }  
1082 }
1083 // modified by NIZHNY-MKK  Mon Apr  2 12:18:34 2001.END
1084
1085 //====================================================================================
1086 // function: MergeWLinesIfAllSegmentsAlongRestriction
1087 //
1088 //  purpose: If the result of LineConstructor is a set of WLines segments which are
1089 //           placed along RESTRICTION, we can suppose that this result is not correct:
1090 //           here we should have a RLine. If it is not possible to construct RLine
1091 //           we should merge segments of WLines into single WLine equals to the same
1092 //           RLine.
1093 //====================================================================================
1094 static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine&           theSlin,
1095                                                      const Handle(Adaptor3d_HSurface)&  theSurface1,
1096                                                      const Handle(Adaptor3d_TopolTool)& theDomain1,
1097                                                      const Handle(Adaptor3d_HSurface)&  theSurface2,
1098                                                      const Handle(Adaptor3d_TopolTool)& theDomain2,
1099                                                      const Standard_Real                theTolArc)
1100 {
1101   Standard_Integer i = 0, rank = 0;
1102   Standard_Real tol = 1.e-9;
1103
1104   // here we check that all segments of WLines placed along restriction
1105   Standard_Integer WLOnRS1 = 0;
1106   Standard_Integer WLOnRS2 = 0;
1107   Standard_Integer NbWLines = 0;
1108   TColgp_SequenceOfPnt sqVertexPoints;
1109
1110   for(rank = 1; rank <= 2; rank++)
1111     {
1112       NbWLines = 0;
1113       for(i = 1; i <= theSlin.Length(); i++)
1114         {
1115           if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1116             continue;
1117           NbWLines++;
1118           const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1119           Standard_Integer nbvtx = aWLine->NbVertex();
1120           const IntPatch_Point& Vtx1 = aWLine->Vertex(1);
1121           const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx);
1122           if( rank==1 )
1123             {
1124               sqVertexPoints.Append(Vtx1.Value());
1125               sqVertexPoints.Append(Vtx2.Value());
1126               if( TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc) )
1127                 WLOnRS1++;
1128             }
1129           else
1130             {
1131               if( TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc) )
1132                 WLOnRS2++;
1133             }
1134         }
1135       if( NbWLines == WLOnRS1 || NbWLines == WLOnRS2 ) break;
1136     }
1137
1138   Standard_Integer WLineRank = 0;   // not possible to merge WLines
1139
1140   if( WLOnRS1 == NbWLines )
1141     WLineRank = 1;                  // create merged WLine based on arc of S1
1142   else if( WLOnRS2 == NbWLines )
1143     WLineRank = 2;                  // create merged WLine based on arc of S2
1144   else
1145     return;
1146
1147   // avoid closed (degenerated) edges
1148   if( sqVertexPoints.Length() <= 2 )
1149     return;
1150   if( sqVertexPoints.Value(1).IsEqual(sqVertexPoints.Value(sqVertexPoints.Length()),tol) )
1151     return;
1152
1153   Standard_Real TolVrtx = 1.e-5;
1154   Standard_Integer testPointIndex = ( sqVertexPoints.Length() > 3 ) ? ((Standard_Integer) sqVertexPoints.Length() / 2) : 2;
1155   gp_Pnt testPoint = sqVertexPoints.Value( testPointIndex );
1156   Standard_Real Fp = 0., Lp = 0.;
1157
1158
1159   if( WLineRank == 1 )
1160     {
1161       Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1162       Standard_Integer arcnumber = GetArc(theSlin,WLineRank,theSurface1,theDomain1,theSurface2,testPoint,TolVrtx,aLineOn2S,Fp,Lp);
1163
1164       if( arcnumber == 0 )
1165         return;
1166      
1167       Handle(IntPatch_WLine) anWLine = NULL;
1168       anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S);
1169 #ifdef DEB
1170           cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction S1 to WLine ***" << endl;
1171 #endif
1172       theSlin.Clear();
1173       theSlin.Append(anWLine);
1174     }
1175   else
1176     {
1177       Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1178       Standard_Integer arcnumber = GetArc(theSlin,WLineRank,theSurface2,theDomain2,theSurface1,testPoint,TolVrtx,aLineOn2S,Fp,Lp);
1179       
1180       if( arcnumber == 0 )
1181         return;
1182
1183       Handle(IntPatch_WLine) anWLine = NULL;
1184       anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S);
1185 #ifdef DEB
1186           cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction S2 to WLine***" << endl;
1187 #endif
1188       theSlin.Clear();
1189       theSlin.Append(anWLine);
1190     }
1191 }
1192
1193 //=========================================================================================
1194 // function: GetArc
1195 //
1196 //  purpose: Define arc on (OBJ) surface which all WLine segments are placed along.
1197 //           Check states of points in the gaps between segments on (TOOL). If those states
1198 //           are IN or ON return the LineOn2S based on points3D were given from detected arc.
1199 //           Returns 0 if it is not possible to create merged WLine.
1200 //========================================================================================
1201 static Standard_Integer GetArc(IntPatch_SequenceOfLine&           theSlin,
1202                                const Standard_Integer&            theRankS,
1203                                const Handle(Adaptor3d_HSurface)&  theSurfaceObj,
1204                                const Handle(Adaptor3d_TopolTool)& theDomainObj,
1205                                const Handle(Adaptor3d_HSurface)&  theSurfaceTool,
1206                                const gp_Pnt&                      theTestPoint,
1207                                Standard_Real&                     theVrtxTol,
1208                                Handle(IntSurf_LineOn2S)&          theLineOn2S,
1209                                Standard_Real&                     theFirst,
1210                                Standard_Real&                     theLast)
1211 {
1212   // 1. find number of arc (edge) on which the WLine segments are placed.
1213
1214   Standard_Real MinDistance2 = 1.e+200, firstES1 = 0., lastES1 = 0.;
1215   Standard_Integer ArcNumber = 0, CurArc = 0, i = 0, j = 0;
1216   theFirst = 0.;
1217   theLast = 0.;
1218
1219   for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
1220     {
1221       CurArc++;
1222       Standard_Address anEAddress = theDomainObj->Edge();
1223
1224       if( anEAddress == NULL )
1225         continue;
1226       
1227       TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
1228       Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1);
1229       if ( aCEdge.IsNull() ) // e.g. degenerated edge, see OCC21770
1230         continue;
1231       GeomAdaptor_Curve CE;
1232       CE.Load(aCEdge);
1233       Extrema_ExtPC epc(theTestPoint, CE, 1.e-7);
1234
1235       if( epc.IsDone() )
1236         {
1237           for( i = 1; i <= epc.NbExt(); i++ )
1238             {
1239               if( epc.SquareDistance( i ) < MinDistance2 )
1240                 {
1241                   MinDistance2 = epc.SquareDistance( i );
1242                   ArcNumber = CurArc;
1243                 }
1244             }
1245         }
1246     }
1247
1248   if( ArcNumber == 0 )
1249     return 0;
1250
1251   // 2. load parameters of founded edge and its arc.
1252   CurArc = 0;
1253   TColgp_SequenceOfPnt PointsFromArc;
1254   Handle(Adaptor2d_HCurve2d) arc = NULL;
1255   Standard_Real tol = 1.e-7;
1256   TColStd_SequenceOfReal WLVertexParameters;
1257   Standard_Boolean classifyOK = Standard_True;
1258   Standard_Real CheckTol = 1.e-5;
1259
1260   for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
1261     {
1262       CurArc++;
1263       if( CurArc != ArcNumber )
1264         continue;
1265
1266       arc = theDomainObj->Value();
1267
1268       for(i = 1; i <= theSlin.Length(); i++)
1269         {
1270           if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1271             continue;
1272
1273           const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1274
1275           Standard_Integer nbpnts = aWLine->NbPnts();
1276           const IntSurf_PntOn2S& POn2S_F = aWLine->Point(1);
1277           const IntSurf_PntOn2S& POn2S_L = aWLine->Point(nbpnts);
1278
1279           Standard_Real Upf = 0., Vpf = 0., Upl = 0., Vpl = 0.;
1280
1281           if(theRankS == 1)
1282             {
1283               POn2S_F.ParametersOnS1(Upf, Vpf);
1284               POn2S_L.ParametersOnS1(Upl, Vpl);
1285             }
1286           else
1287             {
1288               POn2S_F.ParametersOnS2(Upf, Vpf);
1289               POn2S_L.ParametersOnS2(Upl, Vpl);
1290             }
1291
1292           gp_Pnt2d aPOnLine_F(Upf, Vpf);
1293           gp_Pnt2d aPOnLine_L(Upl, Vpl);
1294
1295           Standard_Real par_F = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_F, tol);
1296           Standard_Real par_L = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_L, tol);
1297
1298           WLVertexParameters.Append(par_F);
1299           WLVertexParameters.Append(par_L);
1300         }
1301       
1302       for(i = 1; i <= WLVertexParameters.Length(); i++)
1303         {
1304           for(j = i; j <= WLVertexParameters.Length(); j++)
1305             {
1306               if(j == i)
1307                 continue;
1308           
1309               if(WLVertexParameters.Value(i) > WLVertexParameters.Value(j))
1310                 {
1311                   Standard_Real pol = WLVertexParameters.Value(i);
1312                   WLVertexParameters.SetValue(i, WLVertexParameters.Value(j));
1313                   WLVertexParameters.SetValue(j, pol);
1314                 }
1315             }
1316         }
1317
1318       Standard_Address anEAddress = theDomainObj->Edge();
1319       TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
1320       TopoDS_Vertex V1, V2;
1321       TopExp::Vertices(*anE,V1,V2);
1322       Standard_Real MaxVertexTol = Max(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2));
1323       theVrtxTol = MaxVertexTol;
1324       Standard_Real EdgeTol = BRep_Tool::Tolerance(*anE);
1325       CheckTol = Max(MaxVertexTol, EdgeTol);
1326       Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1);
1327       // classification gaps
1328       //  a. min - first
1329       if(Abs(firstES1 - WLVertexParameters.Value(1)) > arc->Resolution(MaxVertexTol))
1330         {
1331           Standard_Real param = (firstES1 + WLVertexParameters.Value(1)) / 2.;
1332           gp_Pnt point;
1333           aCEdge->D0(param, point);
1334           if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1335             {
1336               classifyOK = Standard_False;
1337               break;
1338             }
1339         }
1340       //  b. max - last
1341       if(Abs(lastES1 - WLVertexParameters.Value(WLVertexParameters.Length())) > arc->Resolution(MaxVertexTol))
1342         {
1343           Standard_Real param = (lastES1 + WLVertexParameters.Value(WLVertexParameters.Length())) / 2.;
1344           gp_Pnt point;
1345           aCEdge->D0(param, point);
1346           if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1347             {
1348               classifyOK = Standard_False;
1349               break;
1350             }
1351         }
1352       //  c. all middle gaps
1353       Standard_Integer NbChkPnts = theSlin.Length() - 1;
1354       for(i = 1; i <= NbChkPnts; i++)
1355         {
1356           if( Abs(WLVertexParameters.Value(i*2+1) - WLVertexParameters.Value(i*2)) > arc->Resolution(MaxVertexTol))
1357             {
1358               Standard_Real param = (WLVertexParameters.Value(i*2) + WLVertexParameters.Value(i*2+1)) / 2.;
1359               gp_Pnt point;
1360               aCEdge->D0(param, point);
1361               if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1362                 {
1363                   classifyOK = Standard_False;
1364                   break;
1365                 }
1366             }
1367         }
1368       
1369       if( !classifyOK )
1370         break;
1371
1372       // if classification gaps OK, fill sequence by the points from arc (edge)
1373       Standard_Real ParamFirst = WLVertexParameters.Value(1);
1374       Standard_Real ParamLast  = WLVertexParameters.Value(WLVertexParameters.Length());
1375       Standard_Real dParam     = Abs(ParamLast - ParamFirst) / 100.;
1376       Standard_Real cParam = ParamFirst;
1377       for( i = 0; i < 100; i++ )
1378         {
1379           if( i == 99 )
1380             cParam = ParamLast;
1381
1382           gp_Pnt cPnt;
1383           aCEdge->D0(cParam, cPnt);
1384           PointsFromArc.Append(cPnt);
1385           cParam += dParam;
1386         }
1387       theFirst = ParamFirst;
1388       theLast  = ParamLast;
1389
1390     }
1391
1392   if( !classifyOK )
1393     return 0;
1394
1395   // create IntSurf_LineOn2S from points < PointsFromArc >
1396   for( i = 1; i <= PointsFromArc.Length(); i++ )
1397     {
1398       Extrema_POnSurf pOnS1;
1399       Extrema_POnSurf pOnS2;
1400       gp_Pnt arcpoint = PointsFromArc.Value( i );
1401       Standard_Boolean isOnS1 = GetPointOn2S( arcpoint, theSurfaceObj->Surface(), CheckTol, pOnS1 );
1402       Standard_Boolean isOnS2 = GetPointOn2S( arcpoint, theSurfaceTool->Surface(), CheckTol, pOnS2 );
1403       if( isOnS1 && isOnS2 )
1404         {
1405           Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1406           pOnS1.Parameter(u1, v1);
1407           pOnS2.Parameter(u2, v2);
1408           IntSurf_PntOn2S pOn2S;
1409           pOn2S.SetValue(arcpoint, u1, v1, u2, v2 );
1410           theLineOn2S->Add( pOn2S );
1411         }
1412     }
1413
1414   return ArcNumber;
1415 }
1416
1417 //=========================================================================================
1418 // function: IsPointOK
1419 //
1420 //  purpose: returns the state of testPoint on OTHER face.
1421 //========================================================================================
1422 static Standard_Boolean IsPointOK(const gp_Pnt&            theTestPnt,
1423                                   const Adaptor3d_Surface& theTestSurface,
1424                                   const Standard_Real&     theTol)
1425 {
1426   Standard_Boolean result = Standard_False;
1427   Standard_Real ExtTol = theTol;//1.e-7;
1428   Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol);
1429   if( extPS.IsDone() && extPS.NbExt() > 0 )
1430     {
1431       Standard_Integer i = 0, minext = 1;
1432       Standard_Real MinDist2 = 1.e+200;
1433       for(i = 1; i <= extPS.NbExt(); i++)
1434         {
1435           if( extPS.SquareDistance(i) < MinDist2 )
1436             {
1437               minext = i;
1438               MinDist2 = extPS.SquareDistance(i);
1439             }
1440         }
1441       if( MinDist2 <= theTol * theTol )
1442           result = Standard_True;
1443     }
1444   return result;
1445 }
1446
1447 //=========================================================================================
1448 // function: GetPointOn2S
1449 //
1450 //  purpose: check state of testPoint and returns result point if state is OK.
1451 //========================================================================================
1452 static Standard_Boolean GetPointOn2S(const gp_Pnt&            theTestPnt,
1453                                      const Adaptor3d_Surface& theTestSurface,
1454                                      const Standard_Real&     theTol,
1455                                      Extrema_POnSurf&         theResultPoint)
1456 {
1457   Standard_Boolean result = Standard_False;
1458   Standard_Real ExtTol = theTol;//1.e-7;
1459   Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol);
1460   if( extPS.IsDone() && extPS.NbExt() > 0 )
1461     {
1462       Standard_Integer i = 0, minext = 1;
1463       Standard_Real MinDist2 = 1.e+200;
1464       for(i = 1; i <= extPS.NbExt(); i++)
1465         {
1466           if( extPS.SquareDistance(i) < MinDist2 )
1467             {
1468               minext = i;
1469               MinDist2 = extPS.SquareDistance(i);
1470             }
1471         }
1472       if( MinDist2 <= theTol * theTol )
1473         {
1474           result = Standard_True;
1475           theResultPoint = extPS.Point(minext);
1476         }
1477     }
1478   return result;
1479 }
1480
1481 //=========================================================================================
1482 // function: GetMergedWLineOnRestriction
1483 //
1484 //  purpose: merge sequence of WLines all placed along restriction if the conditions of
1485 //           merging are OK.
1486 //========================================================================================
1487 static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine&           theSlin,
1488                                                                            const Standard_Real&               theVrtxTol,
1489                                                                            const Handle(IntSurf_LineOn2S)&    theLineOn2S)
1490 {
1491   IntSurf_TypeTrans trans1 = IntSurf_Undecided;
1492   IntSurf_TypeTrans trans2 = IntSurf_Undecided;
1493   Standard_Integer i = 0;
1494
1495   for(i = 1; i <= theSlin.Length(); i++)
1496     {
1497       if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1498         continue;
1499
1500       const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1501
1502       if( aWLine->TransitionOnS1() != IntSurf_Undecided  &&  aWLine->TransitionOnS1() != IntSurf_Touch )
1503         trans1 = aWLine->TransitionOnS1();
1504       if( aWLine->TransitionOnS2() != IntSurf_Undecided  &&  aWLine->TransitionOnS2() != IntSurf_Touch )
1505         trans2 = aWLine->TransitionOnS2();
1506     }
1507
1508   Handle(IntPatch_WLine) mWLine = new IntPatch_WLine(theLineOn2S, Standard_False, trans1, trans2);
1509
1510   Standard_Integer NbPnts = mWLine->NbPnts();
1511   IntPatch_Point aFirstVertex, aLastVertex;
1512
1513   aFirstVertex.SetValue(mWLine->Point(1).Value(),theVrtxTol,Standard_False);
1514   aLastVertex.SetValue(mWLine->Point(NbPnts).Value(),theVrtxTol,Standard_False);
1515
1516   Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1517
1518   mWLine->Point(1).Parameters(u1, v1, u2, v2);
1519   aFirstVertex.SetParameters(u1, v1, u2, v2);
1520
1521   mWLine->Point(NbPnts).Parameters(u1, v1, u2, v2);
1522   aLastVertex.SetParameters(u1, v1, u2, v2);
1523
1524   aFirstVertex.SetParameter(1);
1525   aLastVertex.SetParameter(theLineOn2S->NbPoints());
1526
1527   mWLine->AddVertex(aFirstVertex);
1528   mWLine->AddVertex(aLastVertex);
1529
1530   mWLine->ComputeVertexParameters(theVrtxTol);
1531
1532   return mWLine;
1533 }