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