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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #define No_Standard_OutOfRange
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>
34 //=======================================================================
35 //function : HLRBRep_Hider
37 //=======================================================================
39 HLRBRep_Hider (const Handle(HLRBRep_Data)& DS) :
43 //=======================================================================
44 //function : OwnHiding
46 //=======================================================================
48 void HLRBRep_Hider::OwnHiding(const Standard_Integer)
52 //=======================================================================
55 //=======================================================================
57 void HLRBRep_Hider::Hide(const Standard_Integer FI,
58 BRepTopAdaptor_MapOfShapeTool& MST)
60 // *****************************************************************
62 // This algorithm hides a set of edges stored in the data structure <myDS>
63 // with the hiding face number FI in <myDS>.
65 // Outline of the algorithm
67 // 1. Loop on the Edges (not hidden and not rejected by the face minmax)
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
74 // Compute interferences with the not rejected edges of the face.
75 // Store IN and ON interferences in two sorted lists
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.
87 // If ILHidden is not empty
88 // Resolve ComplexTransitions in ILHidden
89 // Build Hidden parts of the edge
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
101 // *****************************************************************
103 myDS->InitEdge(FI,MST);
104 if (!myDS->MoreEdge()) // there is nothing to do
105 return; // **********************
106 if (myDS->IsBadFace())
108 HLRBRep_EdgeInterferenceTool EIT(myDS); // List of Intersections
109 HLRBRep_Array1OfEData& myEData = myDS->EDataArray();
111 for (; myDS->MoreEdge(); myDS->NextEdge()) { // loop on the Edges
112 Standard_Integer E = myDS->Edge(); // *****************
116 Standard_Boolean hasOut = Standard_False;
117 HLRAlgo_InterferenceList ILHidden;
118 HLRAlgo_InterferenceList ILOn;
121 for (myDS->InitInterference(); // intersections with face-edges
122 myDS->MoreInterference(); // *****************************
123 myDS->NextInterference()) {
124 if (myDS->RejectedInterference()) {
125 if (myDS->AboveInterference() &&
126 myDS->SimpleHidingFace ()) {
127 hasOut = Standard_True;
131 HLRAlgo_Interference& Int = myDS->Interference();
132 switch (Int.Intersection().State()) {
134 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT); break;
136 HLRBRep_EdgeIList::AddInterference(ILOn ,Int,EIT); break;
138 case TopAbs_UNKNOWN : break;
143 //-- ============================================================
144 Standard_Boolean Modif;
146 Modif = Standard_False;
147 HLRAlgo_ListIteratorOfInterferenceList ItSegHidden1(ILHidden);
148 while(ItSegHidden1.More() && Modif==Standard_False) {
149 HLRAlgo_Interference& Int1 = ItSegHidden1.Value();
150 Standard_Integer numseg1=Int1.Intersection().SegIndex();
152 HLRAlgo_ListIteratorOfInterferenceList ItSegHidden2(ILHidden);
153 while(ItSegHidden2.More() && Modif==Standard_False) {
154 HLRAlgo_Interference& Int2 = ItSegHidden2.Value();
155 Standard_Integer numseg2=Int2.Intersection().SegIndex();
156 if(numseg1+numseg2 == 0) {
157 //--printf("\nHidden Traitement du segment %d %d\n",numseg1,numseg2); fflush(stdout);
158 TopAbs_State stbef1,staft1,stbef2,staft2;
159 Int1.Boundary().State3D(stbef1,staft1);
160 Int2.Boundary().State3D(stbef2,staft2);
161 if(Int1.Orientation() == Int2.Orientation()) {
162 if(Int1.Transition() == Int2.Transition()) {
163 if(stbef1==stbef2 && staft1==staft2 && stbef1!=TopAbs_ON && staft1!=TopAbs_ON ) {
164 //-- printf("\n Index1 = %d Index2 = %d\n",Int1.Intersection().Index(),Int2.Intersection().Index());
165 Standard_Integer nind=-1;
166 if(Int1.Intersection().Index()!=0) {
167 nind=Int1.Intersection().Index();
169 if(Int2.Intersection().Index()!=0) {
171 if(Int1.Intersection().Index() != Int2.Intersection().Index()) {
176 nind=Int2.Intersection().Index();
179 if(Int1.Intersection().Index()==0 && Int2.Intersection().Index()==0) nind=0;
182 //-- printf("\n Segment Supprime\n"); fflush(stdout);
183 HLRAlgo_Intersection& inter = Int1.ChangeIntersection();
184 inter.SegIndex(nind);
185 Standard_Real p1 = Int1.Intersection().Parameter();
186 Standard_Real p2 = Int2.Intersection().Parameter();
187 inter.Parameter((p1+p2)*0.5);
188 Int1.BoundaryTransition(TopAbs_EXTERNAL);
190 ILHidden.Remove(ItSegHidden2);
197 if(Modif==Standard_False) {
202 if(Modif==Standard_False) {
210 //-- ============================================================
213 if (!ILOn.IsEmpty()) { // process the interferences on ILOn
214 // *********************************
216 HLRBRep_EdgeIList::ProcessComplex // complex transition on ILOn
217 (ILOn,EIT); // **************************
219 HLRAlgo_ListIteratorOfInterferenceList It(ILOn);
221 while(It.More()) { // process Intersections on the Face
222 // *********************************
224 HLRAlgo_Interference& Int = It.Value();
225 TopAbs_State stbef, staft; // read the 3d states
226 Int.Boundary().State3D(stbef,staft); // ******************
228 switch (Int.Transition()) {
229 case TopAbs_FORWARD :
232 ILOn.Remove(It); break;
234 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
235 ILOn.Remove(It); break;
236 case TopAbs_UNKNOWN :
238 cout << "UNKNOWN state staft" << endl;
243 case TopAbs_REVERSED :
246 ILOn.Remove(It); break;
248 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
249 ILOn.Remove(It); break;
250 case TopAbs_UNKNOWN :
252 cout << "UNKNOWN state stbef" << endl;
257 case TopAbs_EXTERNAL :
258 ILOn.Remove(It); break;
259 case TopAbs_INTERNAL :
264 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
265 ILOn.Remove(It); break;
267 Int.Transition(TopAbs_FORWARD ); // FORWARD in ILOn,
268 HLRBRep_EdgeIList::AddInterference // REVERSED in ILHidden
269 (ILHidden,HLRAlgo_Interference
274 Int.BoundaryTransition()),EIT);
277 Int.Transition(TopAbs_REVERSED); // set REVERSED
278 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
279 ILOn.Remove(It); break;
280 case TopAbs_UNKNOWN :
282 cout << "UNKNOWN state after" << endl;
289 Int.Transition(TopAbs_REVERSED); // REVERSED in ILOn,
290 HLRBRep_EdgeIList::AddInterference // REVERSED in ILHidden
291 (ILHidden,HLRAlgo_Interference
296 Int.BoundaryTransition()),EIT); break;
297 case TopAbs_ON : break;
299 Int.Transition(TopAbs_REVERSED); break;
300 case TopAbs_UNKNOWN :
302 cout << "UNKNOWN state after" << endl;
310 Int.Transition(TopAbs_FORWARD); // set FORWARD
311 HLRBRep_EdgeIList::AddInterference(ILHidden,Int,EIT);
312 ILOn.Remove(It); break;
314 Int.Transition(TopAbs_FORWARD ); // FORWARD in ILOn
317 ILOn.Remove(It); break;
318 case TopAbs_UNKNOWN :
320 cout << "UNKNOWN state after" << endl;
324 case TopAbs_UNKNOWN :
326 cout << "UNKNOWN state stbef" << endl;
334 if (ILHidden.IsEmpty() && ILOn.IsEmpty() && !hasOut) {
335 HLRBRep_EdgeData& ed = myEData(E);
336 TopAbs_State st = myDS->Compare(E,ed); // Classification
337 if (st == TopAbs_IN || st == TopAbs_ON) // **************
338 ed.Status().HideAll();
341 Standard_Real p1 = 0.,p2 = 0.;
342 Standard_ShortReal tol1 = 0., tol2 = 0.;
344 HLRBRep_EdgeData& ed = myEData(E);
345 HLRAlgo_EdgeStatus& ES = ed.Status();
347 Standard_Boolean foundHidden = Standard_False;
349 if (!ILHidden.IsEmpty()) {
351 HLRBRep_EdgeIList::ProcessComplex // complex transition on ILHidden
352 (ILHidden,EIT); // ******************************
353 Standard_Integer level = 0;
354 if (!myDS->SimpleHidingFace()) // Level at Start
355 level = myDS->HidingStartLevel(E,ed,ILHidden); // **************
357 HLRAlgo_ListIteratorOfInterferenceList It(ILHidden);
358 if (myDS->SimpleHidingFace()) //remove excess interferences
360 TColStd_SequenceOfReal ToRemove;
361 TopAbs_Orientation PrevTrans = TopAbs_EXTERNAL;
362 Standard_Real PrevParam = 0.;
363 for (; It.More(); It.Next())
365 const HLRAlgo_Interference& Int = It.Value();
366 TopAbs_Orientation aTrans = Int.Transition();
367 if (aTrans == PrevTrans)
369 if (aTrans == TopAbs_FORWARD)
371 ToRemove.Append(Int.Intersection().Parameter());
373 cout<<"Two adjacent interferences with transition FORWARD"<<endl;
376 else if (aTrans == TopAbs_REVERSED)
378 ToRemove.Append(PrevParam);
380 cout<<"Two adjacent interferences with transition REVERSED"<<endl;
385 PrevParam = Int.Intersection().Parameter();
387 It.Initialize(ILHidden);
390 Standard_Real aParam = It.Value().Intersection().Parameter();
391 Standard_Boolean found = Standard_False;
392 for (Standard_Integer i = 1; i <= ToRemove.Length(); i++)
393 if (aParam == ToRemove(i))
395 found = Standard_True;
403 } //remove excess interferences
405 It.Initialize(ILHidden);
406 while(It.More()) { // suppress multi-inside Intersections
407 // ***********************************
409 HLRAlgo_Interference& Int = It.Value();
410 switch (Int.Transition()) {
412 case TopAbs_FORWARD :
414 Standard_Integer decal = Int.Intersection().Level();
419 level = level + decal;
422 case TopAbs_REVERSED :
424 level = level - Int.Intersection().Level();
431 case TopAbs_EXTERNAL :
434 case TopAbs_INTERNAL :
442 if (ILHidden.IsEmpty()) // Edge hidden
443 ES.HideAll(); // ***********
445 foundHidden = Standard_True;
449 if (!ILHidden.IsEmpty()) {
452 TopAbs_State aBuildIN = TopAbs_IN;
453 Standard_Boolean IsSuspicion = Standard_True;
455 Standard_Real pmax, pmin;
456 Standard_Boolean allInt = Standard_False;
457 Standard_Boolean allFor = Standard_False;
458 Standard_Boolean allRev = Standard_False;
462 if(ILHidden.Extent() > 1 ) {
463 allInt = Standard_True;
464 allFor = Standard_True;
465 allRev = Standard_True;
466 HLRAlgo_ListIteratorOfInterferenceList It(ILHidden);
467 for(;It.More(); It.Next()) {
468 Standard_Real p = It.Value().Intersection().Parameter();
469 allFor = allFor && ( It.Value().Transition() == TopAbs_FORWARD);
470 allRev = allRev && ( It.Value().Transition() == TopAbs_REVERSED);
471 allInt = allInt && ( It.Value().Transition() == TopAbs_INTERNAL);
472 if(p < pmin) pmin = p;
473 if(p > pmax) pmax = p;
478 HLRAlgo_ListIteratorOfInterferenceList Itl(ILHidden);
479 HLRBRep_VertexList IL(EIT,Itl);
482 HLRBRep_EdgeBuilder EB(IL);
484 EB.Builds(aBuildIN); // build hidden parts
485 // ******************
486 while (EB.MoreEdges()) {
488 Standard_Integer aMaskP1P2 = 0;
489 while (EB.MoreVertices()) {
490 switch (EB.Orientation()) {
491 case TopAbs_FORWARD :
492 p1 = EB.Current().Parameter();
493 tol1 = EB.Current().Tolerance();
496 case TopAbs_REVERSED :
497 p2 = EB.Current().Parameter();
498 tol2 = EB.Current().Tolerance();
501 case TopAbs_INTERNAL :
502 case TopAbs_EXTERNAL :
508 if(aMaskP1P2 != 3 || p2 - p1 <= 1.e-7) {
514 if(p1 < pmin) p1 = pmin;
515 if(p2 > pmax) p2 = pmax;
516 //HLRBRep_EdgeData& ed = myEData(E);
517 //TopAbs_State st = myDS->Compare(E,ed); // Classification
520 TopAbs_State aTestState = TopAbs_IN;
522 //Standard_Integer aNbp = 1;
523 //aTestState = myDS->SimplClassify(E, ed, aNbp, p1, p2);
524 Standard_Integer tmplevel = 0;
525 aTestState = myDS->Classify(E,ed,Standard_True,tmplevel,(p1+p2)/2.);
528 if(aTestState != TopAbs_OUT) {
529 ES.Hide(p1,tol1,p2,tol2,
530 Standard_False, // under the Face
531 Standard_False); // inside the Face
537 EB.Builds(TopAbs_ON); // build parts under the boundary
538 // ******************************
539 while (EB.MoreEdges()) {
541 Standard_Integer aMaskP1P2 = 0;
542 while (EB.MoreVertices()) {
543 switch (EB.Orientation()) {
544 case TopAbs_FORWARD :
545 p1 = EB.Current().Parameter();
546 tol1 = EB.Current().Tolerance();
549 case TopAbs_REVERSED :
550 p2 = EB.Current().Parameter();
551 tol2 = EB.Current().Tolerance();
554 case TopAbs_INTERNAL :
555 case TopAbs_EXTERNAL :
561 if(aMaskP1P2 != 3 || p2 - p1 <= 1.e-7) {
566 TopAbs_State aTestState = TopAbs_IN;
568 //Standard_Integer aNbp = 1;
569 //aTestState = myDS->SimplClassify(E, ed, aNbp, p1, p2);
570 Standard_Integer tmplevel = 0;
571 aTestState = myDS->Classify(E,ed,Standard_True,tmplevel,(p1+p2)/2.);
574 if(aTestState != TopAbs_OUT)
575 ES.Hide(p1,tol1,p2,tol2,
576 Standard_False, // under the Face
577 Standard_True); // on the boundary
583 if (!ILOn.IsEmpty()) {
584 Standard_Integer level = 0;
585 if (!myDS->SimpleHidingFace()) // Level at Start
586 level = myDS->HidingStartLevel(E,ed,ILOn); // **************
588 HLRAlgo_ListIteratorOfInterferenceList It(ILOn);
590 while(It.More()) { // suppress multi-inside Intersections
591 // ***********************************
593 HLRAlgo_Interference& Int = It.Value();
594 switch (Int.Transition()) {
596 case TopAbs_FORWARD :
598 Standard_Integer decal = Int.Intersection().Level();
599 if (level > 0) ILOn.Remove(It);
601 level = level + decal;
604 case TopAbs_REVERSED :
605 level = level - Int.Intersection().Level();
606 if (level > 0) ILOn.Remove(It);
609 case TopAbs_EXTERNAL :
610 case TopAbs_INTERNAL :
616 if (ILOn.IsEmpty() && !foundHidden) // Edge hidden
617 ES.HideAll(); // ***********
621 if (!ILOn.IsEmpty()) {
622 HLRBRep_VertexList IL(EIT,ILOn);
623 HLRBRep_EdgeBuilder EB(IL);
625 EB.Builds (TopAbs_IN); // build parts on the Face
626 // ***********************
627 while (EB.MoreEdges()) {
629 Standard_Integer aMaskP1P2 = 0;
630 while (EB.MoreVertices()) {
631 switch (EB.Orientation()) {
632 case TopAbs_FORWARD :
633 p1 = EB.Current().Parameter();
634 tol1 = EB.Current().Tolerance();
637 case TopAbs_REVERSED :
638 p2 = EB.Current().Parameter();
639 tol2 = EB.Current().Tolerance();
642 case TopAbs_INTERNAL :
643 case TopAbs_EXTERNAL :
649 if(aMaskP1P2 != 3 || p2 - p1 <= 1.e-7) {
654 ES.Hide(p1,tol1,p2,tol2,
655 Standard_True, // on the Face
656 Standard_False); // inside the Face
660 EB.Builds(TopAbs_ON); // build hidden parts under the boundary
661 // *************************************
662 while (EB.MoreEdges()) {
664 Standard_Integer aMaskP1P2 = 0;
665 while (EB.MoreVertices()) {
666 switch (EB.Orientation()) {
667 case TopAbs_FORWARD :
668 p1 = EB.Current().Parameter();
669 tol1 = EB.Current().Tolerance();
672 case TopAbs_REVERSED :
673 p2 = EB.Current().Parameter();
674 tol2 = EB.Current().Tolerance();
677 case TopAbs_INTERNAL :
678 case TopAbs_EXTERNAL :
684 if(aMaskP1P2 != 3 || p2 - p1 <= 1.e-7) {
689 ES.Hide(p1,tol1,p2,tol2,
690 Standard_True, // on the Face
691 Standard_True); // on the boundary
699 catch(Standard_Failure const& anException) {
701 cout << "An exception was catched when hiding edge " << E;
702 cout << " by the face " << FI << endl;
703 cout << anException << endl;