0027341: Incorrect exact HLR results
[occt.git] / src / HLRBRep / HLRBRep_Hider.cxx
1 // Created on: 1997-04-17
2 // Created by: Christophe MARION
3 // Copyright (c) 1997-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 #define No_Standard_OutOfRange
18
19
20 #include <HLRAlgo_Coincidence.hxx>
21 #include <HLRAlgo_Interference.hxx>
22 #include <HLRAlgo_InterferenceList.hxx>
23 #include <HLRAlgo_Intersection.hxx>
24 #include <HLRAlgo_ListIteratorOfInterferenceList.hxx>
25 #include <HLRBRep_Data.hxx>
26 #include <HLRBRep_EdgeBuilder.hxx>
27 #include <HLRBRep_EdgeIList.hxx>
28 #include <HLRBRep_EdgeInterferenceTool.hxx>
29 #include <HLRBRep_Hider.hxx>
30 #include <HLRBRep_VertexList.hxx>
31 #include <TColStd_SequenceOfReal.hxx>
32 #include <Standard_ErrorHandler.hxx>
33
34 //=======================================================================
35 //function : HLRBRep_Hider
36 //purpose  : 
37 //=======================================================================
38 HLRBRep_Hider::
39 HLRBRep_Hider (const Handle(HLRBRep_Data)& DS) :
40   myDS(DS) 
41 {}
42
43 //=======================================================================
44 //function : OwnHiding
45 //purpose  : 
46 //=======================================================================
47
48 void HLRBRep_Hider::OwnHiding(const Standard_Integer)
49 {
50 }
51
52 //=======================================================================
53 //function : Hide
54 //purpose  : 
55 //=======================================================================
56
57 void HLRBRep_Hider::Hide(const Standard_Integer FI,
58                          BRepTopAdaptor_MapOfShapeTool& MST)
59 {
60   // *****************************************************************
61   //
62   // This algorithm hides a set of edges stored in the data structure <myDS>
63   // with the hiding face number FI in <myDS>.
64   //
65   // Outline of the algorithm
66   //
67   //   1. Loop on the Edges (not hidden and not rejected by the face minmax)
68   //   
69   //       The rejections depending of the face are 
70   //          - Edge above the face
71   //          - Edge belonging to the face
72   //          - Edge rejected by a wire minmax
73   //
74   //       Compute interferences with the not rejected edges of the face.
75   //           Store IN and ON interferences in two sorted lists
76   //               ILHidden and ILOn
77   //       If ILOn is not empty
78   //           Resolve ComplexTransitions in ILOn
79   //           Resolve ON Intersections in ILOn
80   //             An On interference may become
81   //               IN  : Move it from ILOn to ILHidden
82   //               OUT : Remove it from ILOn
83   //       If ILHidden and ILOn are empty
84   //           intersect the edge with the face and classify the Edge.
85   //               - if inside and under the face hide it.
86   //       Else
87   //         If ILHidden is not empty
88   //           Resolve ComplexTransitions in ILHidden
89   //           Build Hidden parts of the edge
90   //               - Hide them
91   //           Build visible parts of the edge
92   //           Build Parts of the edge under the boundary of the face
93   //               - Hide them as Boundary
94   //         If ILOn is not empty
95   //           Build ON parts of the edge
96   //               - Hide them as ON parts
97   //           Build Parts of the edge on the boundary of the face
98   //               - Hide them as ON parts on Boundary
99   // 
100   //
101   // *****************************************************************
102
103   myDS->InitEdge(FI,MST);
104   if (!myDS->MoreEdge())                        // there is nothing to do
105      return;                                    // **********************
106   HLRBRep_EdgeInterferenceTool EIT(myDS); // List of Intersections
107   HLRBRep_Array1OfEData& myEData = myDS->EDataArray();
108
109   for (; myDS->MoreEdge(); myDS->NextEdge()) {       // loop on the Edges
110     Standard_Integer E = myDS->Edge();               // *****************
111
112     try {
113       OCC_CATCH_SIGNALS
114       Standard_Boolean hasOut = Standard_False;
115       HLRAlgo_InterferenceList ILHidden;
116       HLRAlgo_InterferenceList ILOn;
117       EIT.LoadEdge();
118       
119       for (myDS->InitInterference();     // intersections with face-edges
120            myDS->MoreInterference();     // *****************************
121            myDS->NextInterference()) {
122         if (myDS->RejectedInterference()) {
123           if (myDS->AboveInterference() &&
124               myDS->SimpleHidingFace ()) { 
125             hasOut = Standard_True;
126           }
127         }
128         else {
129           HLRAlgo_Interference& Int = myDS->Interference();
130           switch (Int.Intersection().State()) {
131           case TopAbs_IN      :
132             HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT); break;
133           case TopAbs_ON      :
134             HLRBRep_EdgeIList::AddInterference(ILOn    ,Int,EIT); break;
135           case TopAbs_OUT     : 
136           case TopAbs_UNKNOWN :                                   break;
137           }
138         }
139       }
140       
141       //-- ============================================================
142       Standard_Boolean Modif;
143       do { 
144         Modif = Standard_False; 
145         HLRAlgo_ListIteratorOfInterferenceList ItSegHidden1(ILHidden);
146         while(ItSegHidden1.More() && Modif==Standard_False) { 
147           HLRAlgo_Interference& Int1 = ItSegHidden1.Value();
148           Standard_Integer numseg1=Int1.Intersection().SegIndex();
149           if(numseg1!=0) { 
150             HLRAlgo_ListIteratorOfInterferenceList ItSegHidden2(ILHidden);
151             while(ItSegHidden2.More()  && Modif==Standard_False) {
152               HLRAlgo_Interference& Int2 = ItSegHidden2.Value();
153               Standard_Integer numseg2=Int2.Intersection().SegIndex();
154               if(numseg1+numseg2 == 0) { 
155                 //--printf("\nHidden Traitement du segment %d  %d\n",numseg1,numseg2); fflush(stdout);
156                 TopAbs_State stbef1,staft1,stbef2,staft2;
157                 Int1.Boundary().State3D(stbef1,staft1);  
158                 Int2.Boundary().State3D(stbef2,staft2);
159                 if(Int1.Orientation() == Int2.Orientation()) {
160                   if(Int1.Transition() == Int2.Transition()) {
161                     if(stbef1==stbef2 && staft1==staft2 && stbef1!=TopAbs_ON && staft1!=TopAbs_ON ) { 
162                       //-- printf("\n Index1 = %d  Index2 = %d\n",Int1.Intersection().Index(),Int2.Intersection().Index());
163                       Standard_Integer nind=-1;
164                       if(Int1.Intersection().Index()!=0) { 
165                         nind=Int1.Intersection().Index();
166                       }
167                       if(Int2.Intersection().Index()!=0) {
168                         if(nind!=-1) {
169                           if(Int1.Intersection().Index() != Int2.Intersection().Index()) { 
170                             nind=-1;
171                           }
172                         }
173                         else { 
174                           nind=Int2.Intersection().Index();
175                         }
176                       }
177                       if(Int1.Intersection().Index()==0 && Int2.Intersection().Index()==0) nind=0;
178                      
179                       if(nind!=-1) { 
180                         //-- printf("\n Segment Supprime\n"); fflush(stdout);
181                         HLRAlgo_Intersection& inter = Int1.ChangeIntersection();
182                         inter.SegIndex(nind);
183                         Standard_Real p1 = Int1.Intersection().Parameter();
184                         Standard_Real p2 = Int2.Intersection().Parameter();
185                         inter.Parameter((p1+p2)*0.5);
186                         Int1.BoundaryTransition(TopAbs_EXTERNAL);
187
188                         ILHidden.Remove(ItSegHidden2);
189                         Modif=Standard_True;
190                       }
191                     }
192                   }
193                 }
194               }
195               if(Modif==Standard_False) { 
196                 ItSegHidden2.Next();
197               }
198             }
199           }
200           if(Modif==Standard_False) { 
201             ItSegHidden1.Next();
202           }
203         }
204       }
205       while(Modif);
206         
207
208       //-- ============================================================
209
210
211       if (!ILOn.IsEmpty()) {         // process the interferences on ILOn
212                                      // *********************************
213       
214         HLRBRep_EdgeIList::ProcessComplex   // complex transition on ILOn
215           (ILOn,EIT);                       // **************************
216
217         HLRAlgo_ListIteratorOfInterferenceList It(ILOn); 
218         
219         while(It.More()) {           // process Intersections on the Face
220                                      // *********************************
221           
222           HLRAlgo_Interference& Int = It.Value();
223           TopAbs_State stbef, staft;                // read the 3d states
224           Int.Boundary().State3D(stbef,staft);      // ******************
225
226           switch (Int.Transition()) {
227           case TopAbs_FORWARD  :
228             switch (staft) {
229             case TopAbs_OUT     :
230               ILOn.Remove(It);                            break;
231             case TopAbs_IN      :
232               HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
233               ILOn.Remove(It);                            break;
234             case TopAbs_UNKNOWN : 
235 #ifdef OCCT_DEBUG
236               cout << "UNKNOWN state staft" << endl;
237 #endif
238             case TopAbs_ON      :
239               It.Next();                                  break;
240             }                                             break;
241           case TopAbs_REVERSED :
242             switch (stbef) {
243             case TopAbs_OUT     :
244               ILOn.Remove(It);                            break;
245             case TopAbs_IN      :
246               HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
247               ILOn.Remove(It);                            break;
248             case TopAbs_UNKNOWN :
249 #ifdef OCCT_DEBUG
250               cout << "UNKNOWN state stbef" << endl;
251 #endif
252             case TopAbs_ON      :
253               It.Next();                                  break;
254             }                                             break;
255           case TopAbs_EXTERNAL :
256             ILOn.Remove(It);                              break;
257           case TopAbs_INTERNAL :
258             switch (stbef) {
259             case TopAbs_IN        :
260               switch (staft) {
261               case TopAbs_IN      :
262                 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
263                 ILOn.Remove(It);                          break;
264               case TopAbs_ON      :
265                 Int.Transition(TopAbs_FORWARD );      // FORWARD  in ILOn,
266                 HLRBRep_EdgeIList::AddInterference    // REVERSED in ILHidden
267                   (ILHidden,HLRAlgo_Interference   
268                    (Int.Intersection(),
269                     Int.Boundary(),
270                     Int.Orientation(),
271                     TopAbs_REVERSED,
272                     Int.BoundaryTransition()),EIT);
273                 It.Next();                                break;
274               case TopAbs_OUT     :
275                 Int.Transition(TopAbs_REVERSED);      // set REVERSED
276                 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
277                 ILOn.Remove(It);                          break;
278               case TopAbs_UNKNOWN :
279 #ifdef OCCT_DEBUG
280                 cout << "UNKNOWN state after" << endl;
281 #endif
282                 It.Next();                                break;
283               }                                           break;
284             case TopAbs_ON :
285               switch (staft) {
286               case TopAbs_IN      :
287                 Int.Transition(TopAbs_REVERSED);      // REVERSED in ILOn,
288                 HLRBRep_EdgeIList::AddInterference    // REVERSED in ILHidden
289                   (ILHidden,HLRAlgo_Interference   
290                    (Int.Intersection(),
291                     Int.Boundary(),
292                     Int.Orientation(),
293                     TopAbs_FORWARD,
294                     Int.BoundaryTransition()),EIT);       break;
295               case TopAbs_ON      :                       break;
296               case TopAbs_OUT     :
297                 Int.Transition(TopAbs_REVERSED);          break;
298               case TopAbs_UNKNOWN :
299 #ifdef OCCT_DEBUG
300                 cout << "UNKNOWN state after" << endl;
301 #endif
302                 break;
303               }     
304               It.Next();                                  break;
305             case TopAbs_OUT :
306               switch (staft) {
307               case TopAbs_IN      :
308                 Int.Transition(TopAbs_FORWARD);       // set FORWARD
309                 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
310                 ILOn.Remove(It);                          break;
311               case TopAbs_ON      :
312                 Int.Transition(TopAbs_FORWARD );      // FORWARD  in ILOn
313                 It.Next();                                break;
314               case TopAbs_OUT     :
315                 ILOn.Remove(It);                          break;
316               case TopAbs_UNKNOWN :
317 #ifdef OCCT_DEBUG
318                 cout << "UNKNOWN state after" << endl;
319 #endif
320                 It.Next();                                break;
321               }                                           break;
322             case TopAbs_UNKNOWN :
323 #ifdef OCCT_DEBUG
324               cout << "UNKNOWN state stbef" << endl;
325 #endif
326               break;
327             }
328           }
329         }
330       }
331       
332       if (ILHidden.IsEmpty() && ILOn.IsEmpty() && !hasOut) {
333         HLRBRep_EdgeData& ed = myEData(E);
334         TopAbs_State st = myDS->Compare(E,ed);              // Classification
335         if (st == TopAbs_IN || st == TopAbs_ON)             // **************
336           ed.Status().HideAll();
337       }
338       else {
339         Standard_Real p1 = 0.,p2 = 0.;
340         Standard_ShortReal tol1 = 0., tol2 = 0.;
341
342         HLRBRep_EdgeData& ed = myEData(E);
343         HLRAlgo_EdgeStatus& ES = ed.Status();
344
345         Standard_Boolean foundHidden = Standard_False;
346         
347         if (!ILHidden.IsEmpty()) {    
348
349           HLRBRep_EdgeIList::ProcessComplex // complex transition on ILHidden
350             (ILHidden,EIT);                 // ******************************
351           Standard_Integer level = 0;
352           if (!myDS->SimpleHidingFace())                    // Level at Start
353             level = myDS->HidingStartLevel(E,ed,ILHidden);  // **************
354
355           HLRAlgo_ListIteratorOfInterferenceList It(ILHidden);
356           if (myDS->SimpleHidingFace()) //remove excess interferences
357           {
358             TColStd_SequenceOfReal ToRemove;
359             TopAbs_Orientation PrevTrans = TopAbs_EXTERNAL;
360             Standard_Real PrevParam = 0.;
361             for (; It.More(); It.Next())
362             {
363               const HLRAlgo_Interference& Int = It.Value();
364               TopAbs_Orientation aTrans = Int.Transition();
365               if (aTrans == PrevTrans)
366               {
367                 if (aTrans == TopAbs_FORWARD)
368                 {
369                   ToRemove.Append(Int.Intersection().Parameter());
370 #ifdef OCCT_DEBUG
371                   cout<<"Two adjacent interferences with transition FORWARD"<<endl;
372 #endif
373                 }
374                 else if (aTrans == TopAbs_REVERSED)
375                 {
376                   ToRemove.Append(PrevParam);
377 #ifdef OCCT_DEBUG
378                   cout<<"Two adjacent interferences with transition REVERSED"<<endl;
379 #endif
380                 }
381               }
382               PrevTrans = aTrans;
383               PrevParam = Int.Intersection().Parameter();
384             }
385             It.Initialize(ILHidden);
386             while (It.More())
387             {
388               Standard_Real aParam = It.Value().Intersection().Parameter();
389               Standard_Boolean found = Standard_False;
390               for (Standard_Integer i = 1; i <= ToRemove.Length(); i++)
391                 if (aParam == ToRemove(i))
392                 {
393                   found = Standard_True;
394                   ILHidden.Remove(It);
395                   ToRemove.Remove(i);
396                   break;
397                 }
398               if (!found)
399                 It.Next();
400             }
401           } //remove excess interferences
402           
403           It.Initialize(ILHidden);
404           while(It.More()) {           // suppress multi-inside Intersections
405                                        // ***********************************
406           
407             HLRAlgo_Interference& Int = It.Value();
408             switch (Int.Transition()) {
409               
410             case TopAbs_FORWARD  :
411               {
412                 Standard_Integer decal = Int.Intersection().Level();
413                 if (level > 0)
414                   ILHidden.Remove(It);
415                 else
416                   It.Next();
417                 level = level + decal;
418               }
419               break;
420             case TopAbs_REVERSED : 
421               { 
422                 level = level - Int.Intersection().Level();
423                 if (level > 0)
424                   ILHidden.Remove(It);
425                 else
426                   It.Next();
427               }
428               break;
429             case TopAbs_EXTERNAL :
430               It.Next();
431               break;
432             case TopAbs_INTERNAL :
433               It.Next();
434               break;
435             default :
436               It.Next();
437               break;
438             }
439           }
440           if (ILHidden.IsEmpty())                             // Edge hidden
441             ES.HideAll();                                     // ***********
442           else
443             foundHidden = Standard_True;
444         }
445
446
447         if (!ILHidden.IsEmpty()) {
448           //IFV
449
450           TopAbs_State aBuildIN = TopAbs_IN;
451           Standard_Boolean IsSuspicion = Standard_True;
452           
453           Standard_Real pmax, pmin;
454           Standard_Boolean allInt = Standard_False;
455           Standard_Boolean allFor = Standard_False;
456           Standard_Boolean allRev = Standard_False;
457           pmin = RealLast();
458           pmax = -pmin;
459
460           if(ILHidden.Extent() > 1 ) {
461             allInt = Standard_True;
462             allFor = Standard_True;
463             allRev = Standard_True;
464             HLRAlgo_ListIteratorOfInterferenceList It(ILHidden);
465             for(;It.More(); It.Next()) {
466               Standard_Real p = It.Value().Intersection().Parameter();
467               allFor = allFor && ( It.Value().Transition() == TopAbs_FORWARD);
468               allRev = allRev && ( It.Value().Transition() == TopAbs_REVERSED);
469               allInt = allInt && ( It.Value().Transition() == TopAbs_INTERNAL);
470               if(p < pmin) pmin = p;
471               if(p > pmax) pmax = p;
472             }
473
474           }
475           
476           HLRAlgo_ListIteratorOfInterferenceList Itl(ILHidden);
477           HLRBRep_VertexList IL(EIT,Itl);
478
479
480           HLRBRep_EdgeBuilder EB(IL);
481           
482           EB.Builds(aBuildIN);                         // build hidden parts
483                                                        // ******************
484           while (EB.MoreEdges()) {
485             p1 = 0.; p2 = 0.;
486             Standard_Integer aMaskP1P2 = 0;
487             while (EB.MoreVertices()) {
488               switch (EB.Orientation()) {
489               case TopAbs_FORWARD  : 
490                 p1   =  EB.Current().Parameter(); 
491                 tol1 =  EB.Current().Tolerance();
492                 aMaskP1P2 |= 1;
493                 break;
494               case TopAbs_REVERSED :
495                 p2   =  EB.Current().Parameter(); 
496                 tol2 =  EB.Current().Tolerance();
497                 aMaskP1P2 |= 2;
498                 break;
499               case TopAbs_INTERNAL :
500               case TopAbs_EXTERNAL :
501                 break;
502               }
503               EB.NextVertex();
504             }
505
506             if(aMaskP1P2 != 3 || p2 - p1 <= 1.e-7) {
507               EB.NextEdge();
508               continue;
509             }
510
511             if(allInt) {
512               if(p1 < pmin) p1 = pmin;
513               if(p2 > pmax) p2 = pmax;
514               //HLRBRep_EdgeData& ed = myEData(E);
515               //TopAbs_State st = myDS->Compare(E,ed);              // Classification
516             }
517             
518             TopAbs_State aTestState = TopAbs_IN;
519             if(IsSuspicion) {
520               //Standard_Integer aNbp = 1;
521               //aTestState = myDS->SimplClassify(E, ed, aNbp, p1, p2);
522               Standard_Integer tmplevel = 0;
523               aTestState = myDS->Classify(E,ed,Standard_True,tmplevel,(p1+p2)/2.);
524             }
525
526             if(aTestState != TopAbs_OUT) {
527               ES.Hide(p1,tol1,p2,tol2,
528                       Standard_False,   // under  the Face
529                       Standard_False);  // inside the Face
530             }
531             
532             EB.NextEdge();
533           }
534           
535           EB.Builds(TopAbs_ON);             // build parts under the boundary
536                                             // ******************************
537           while (EB.MoreEdges()) {
538             p1 = 0.; p2 = 0.;
539             Standard_Integer aMaskP1P2 = 0;
540             while (EB.MoreVertices()) {
541               switch (EB.Orientation()) {
542               case TopAbs_FORWARD  :
543                 p1   = EB.Current().Parameter(); 
544                 tol1 = EB.Current().Tolerance();
545                 aMaskP1P2 |= 1;
546                 break;
547               case TopAbs_REVERSED :
548                 p2   = EB.Current().Parameter(); 
549                 tol2 = EB.Current().Tolerance();
550                 aMaskP1P2 |= 2;
551                 break;
552               case TopAbs_INTERNAL :
553               case TopAbs_EXTERNAL :
554                 break;
555               }
556               EB.NextVertex();
557             }
558
559             if(aMaskP1P2 != 3 || p2 - p1 <= 1.e-7) {
560               EB.NextEdge();
561               continue;
562             }
563
564             TopAbs_State aTestState = TopAbs_IN;
565             if(IsSuspicion) {
566               //Standard_Integer aNbp = 1;
567               //aTestState = myDS->SimplClassify(E, ed, aNbp, p1, p2);
568               Standard_Integer tmplevel = 0;
569               aTestState = myDS->Classify(E,ed,Standard_True,tmplevel,(p1+p2)/2.);
570             }
571
572             if(aTestState != TopAbs_OUT)
573               ES.Hide(p1,tol1,p2,tol2,
574                       Standard_False,   // under the Face
575                       Standard_True);   // on the boundary
576             
577             EB.NextEdge();
578           }
579         }      
580         
581         if (!ILOn.IsEmpty()) {
582           Standard_Integer level = 0;
583           if (!myDS->SimpleHidingFace())                    // Level at Start
584             level = myDS->HidingStartLevel(E,ed,ILOn);      // **************
585           if (level > 0) {
586             HLRAlgo_ListIteratorOfInterferenceList It(ILOn); 
587             
588             while(It.More()) {         // suppress multi-inside Intersections
589                                        // ***********************************
590               
591               HLRAlgo_Interference& Int = It.Value();
592               switch (Int.Transition()) {
593                 
594               case TopAbs_FORWARD  :
595                 {
596                   Standard_Integer decal = Int.Intersection().Level();
597                   if (level > 0) ILOn.Remove(It);
598                   else           It.Next();
599                   level = level + decal;
600                 }
601                 break;
602               case TopAbs_REVERSED :
603                 level = level - Int.Intersection().Level();
604                 if (level > 0) ILOn.Remove(It);
605                 else           It.Next();
606                 break;
607               case TopAbs_EXTERNAL :
608               case TopAbs_INTERNAL :
609                 default :
610                 It.Next();
611                 break;
612               }
613             }
614             if (ILOn.IsEmpty() && !foundHidden)               // Edge hidden
615               ES.HideAll();                                   // ***********
616           }
617         }
618         
619         if (!ILOn.IsEmpty()) {
620           HLRBRep_VertexList IL(EIT,ILOn);
621           HLRBRep_EdgeBuilder EB(IL);
622           
623           EB.Builds (TopAbs_IN);                   // build parts on the Face
624                                                    // ***********************
625           while (EB.MoreEdges()) {
626             p1 = 0.; p2 = 0.;
627             Standard_Integer aMaskP1P2 = 0;
628             while (EB.MoreVertices()) {
629               switch (EB.Orientation()) {
630               case TopAbs_FORWARD  : 
631                 p1   = EB.Current().Parameter(); 
632                 tol1 = EB.Current().Tolerance();
633                 aMaskP1P2 |= 1;
634                 break;
635               case TopAbs_REVERSED :
636                 p2   = EB.Current().Parameter(); 
637                 tol2 = EB.Current().Tolerance();
638                 aMaskP1P2 |= 2;
639                 break;
640               case TopAbs_INTERNAL :
641               case TopAbs_EXTERNAL :   
642                 break;
643               }
644               EB.NextVertex();
645             }
646
647             if(aMaskP1P2 != 3 || p2 - p1 <= 1.e-7) {
648               EB.NextEdge();
649               continue;
650             }
651
652             ES.Hide(p1,tol1,p2,tol2,
653                     Standard_True,    // on     the Face
654                     Standard_False);  // inside the Face
655             EB.NextEdge();
656           }
657           
658           EB.Builds(TopAbs_ON);      // build hidden parts under the boundary
659                                      // *************************************
660           while (EB.MoreEdges()) {
661             p1 = 0.; p2 = 0.;
662             Standard_Integer aMaskP1P2 = 0;
663             while (EB.MoreVertices()) {
664               switch (EB.Orientation()) {
665               case TopAbs_FORWARD  :
666                 p1   = EB.Current().Parameter(); 
667                 tol1 = EB.Current().Tolerance();
668                 aMaskP1P2 |= 1;
669                 break;
670               case TopAbs_REVERSED :
671                 p2   = EB.Current().Parameter(); 
672                 tol2 = EB.Current().Tolerance();
673                 aMaskP1P2 |= 2;
674                 break;
675               case TopAbs_INTERNAL :
676               case TopAbs_EXTERNAL :
677                 break;
678               }
679               EB.NextVertex();
680             }
681
682             if(aMaskP1P2 != 3 || p2 - p1 <= 1.e-7) {
683               EB.NextEdge();
684               continue;
685             }
686
687             ES.Hide(p1,tol1,p2,tol2,
688                     Standard_True,    // on the Face
689                     Standard_True);   // on the boundary
690             EB.NextEdge();
691           }
692         }
693       }
694
695     }
696
697     catch(Standard_Failure) {
698 #ifdef OCCT_DEBUG
699       cout << "An exception was catched when hiding edge " << E;
700       cout << " by the face " << FI << endl;
701       Handle(Standard_Failure) fail = Standard_Failure::Caught();
702       cout << fail << endl;
703 #endif
704     }
705   }
706 }