1 // Created on: 1993-05-07
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-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.
18 #include <Bnd_Box.hxx>
20 #include <TopoDS_Face.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopOpeBRep_define.hxx>
23 #include <TopOpeBRep_EdgesIntersector.hxx>
24 #include <TopOpeBRep_FaceEdgeIntersector.hxx>
25 #include <TopOpeBRep_FacesIntersector.hxx>
26 #include <TopOpeBRep_ShapeIntersector.hxx>
27 #include <TopOpeBRepTool_box.hxx>
28 #include <TopOpeBRepTool_HBoxTool.hxx>
31 extern Standard_Boolean TopOpeBRep_GettraceSI();
32 extern Standard_Boolean TopOpeBRep_GetcontextFFOR();
33 extern Standard_Integer SAVFFi1; // FacesIntersector
34 extern Standard_Integer SAVFFi2; // FacesIntersector
35 extern void TopOpeBRep_SettraceEEFF(const Standard_Boolean b);
36 extern Standard_Boolean TopOpeBRep_GettraceEEFF(const Standard_Integer e1,const Standard_Integer e2,const Standard_Integer f1,const Standard_Integer f2);
37 void seteeff(const Standard_Boolean b,const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2)
38 {std::cout<<"b,e1,e2,f1,f2 : "<<b<<" "<<e1<<","<<e2<<","<<f1<<","<<f2<<std::endl;TopOpeBRep_SettraceEEFF(b);}
39 void seteefft(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_True,e1,e2,f1,f2);}
40 void seteefff(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_False,e1,e2,f1,f2);}
43 // modified by NIZHNY-OFV Thu Apr 18 17:15:38 2002 (S)
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Solid.hxx>
47 #include <TopoDS_Shell.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Wire.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopExp_Explorer.hxx>
52 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
53 #include <TopTools_ListOfShape.hxx>
57 #include <BRepLib_MakeEdge.hxx>
58 #include <BRepLib_MakeWire.hxx>
59 #include <BRepLib_MakeFace.hxx>
60 #include <BRep_Builder.hxx>
61 #include <BRepAdaptor_Surface.hxx>
62 static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2);
63 static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F);
64 // modified by NIZHNY-OFV Thu Apr 18 17:16:45 2002 (F)
66 //=======================================================================
67 //function : TopOpeBRep_ShapeIntersector
69 //=======================================================================
71 TopOpeBRep_ShapeIntersector::TopOpeBRep_ShapeIntersector()
74 myFFIntersector.GetTolerances(myTol1,myTol2);
75 myHBoxTool = FBOX_GetHBoxTool();
76 myFaceScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
77 myEdgeScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
80 //=======================================================================
83 //=======================================================================
85 void TopOpeBRep_ShapeIntersector::Reset()
87 myIntersectionDone = Standard_False;
89 myFFDone = Standard_False;
90 myFFSameDomain = Standard_False;
91 myEEFFDone = Standard_False;
92 myEFDone = Standard_False;
93 myFEDone = Standard_False;
94 myEEDone = Standard_False;
96 myFFInit = Standard_False;
97 myEEFFInit = Standard_False;
98 myEFInit = Standard_False;
99 myFEInit = Standard_False;
100 myEEInit = Standard_False;
103 //=======================================================================
106 //=======================================================================
108 void TopOpeBRep_ShapeIntersector::Init
109 (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
116 //=======================================================================
117 //function : SetIntersectionDone
119 //=======================================================================
121 void TopOpeBRep_ShapeIntersector::SetIntersectionDone()
123 myIntersectionDone = (myFFDone ||
131 //=======================================================================
132 //function : CurrentGeomShape
134 //=======================================================================
136 const TopoDS_Shape& TopOpeBRep_ShapeIntersector::CurrentGeomShape
137 (const Standard_Integer Index) const
139 if ( myIntersectionDone ) {
141 if ( Index == 1 ) return myFaceScanner.Current();
142 else if ( Index == 2 ) return myFaceExplorer.Current();
144 else if (myEEFFDone) {
145 if ( Index == 1 ) return myEdgeScanner.Current();
146 else if ( Index == 2 ) return myEdgeExplorer.Current();
149 if ( Index == 1 ) return myFaceScanner.Current();
150 else if ( Index == 2 ) return myEdgeExplorer.Current();
153 if ( Index == 1 ) return myEdgeScanner.Current();
154 else if ( Index == 2 ) return myFaceExplorer.Current();
157 if ( Index == 1 ) return myEdgeScanner.Current();
158 else if ( Index == 2 ) return myEdgeExplorer.Current();
162 throw Standard_Failure("CurrentGeomShape : no intersection");
164 //modified by NIZNHY-PKV Fri Sep 24 11:02:59 1999 from
165 //=======================================================================
166 //function : RejectedFaces
168 //=======================================================================
169 void TopOpeBRep_ShapeIntersector::RejectedFaces (const TopoDS_Shape& anObj,
170 const TopoDS_Shape& aReference,
171 TopTools_ListOfShape& aListOfShape)
174 Standard_Integer isHalfSpace = OneShapeIsHalfSpace( anObj, aReference );
175 if( isHalfSpace != 0 )
177 TopoDS_Face newRejectFace;
178 TopoDS_Solid newSolid;
179 aListOfShape.Clear();
181 if( isHalfSpace == 1 )
183 newSolid = GetNewSolid( anObj, newRejectFace );
184 Init( newSolid, aReference );
186 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
187 TopAbs_ShapeEnum texplo = TopAbs_FACE;
188 myFaceScanner.Clear();
189 myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
190 myFaceExplorer.Init( newSolid, texplo );
192 for(; myFaceExplorer.More(); myFaceExplorer.Next())
194 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
195 if(!aBS.Compare(myFaceExplorer.Current()).More())
197 const TopoDS_Shape& aS=myFaceExplorer.Current();
198 aListOfShape.Append (aS);
202 texplo = TopAbs_EDGE;
203 myFaceScanner.Clear();
204 myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
205 myFaceExplorer.Init( newSolid, texplo );
207 for(; myFaceExplorer.More(); myFaceExplorer.Next())
209 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
210 if(!aBS.Compare(myFaceExplorer.Current()).More())
212 const TopoDS_Shape& aS=myFaceExplorer.Current();
213 aListOfShape.Append (aS);
219 newSolid = GetNewSolid( aReference, newRejectFace );
220 Init( anObj, newSolid );
222 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
223 TopAbs_ShapeEnum texplo = TopAbs_FACE;
224 myFaceScanner.Clear();
225 myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
226 myFaceExplorer.Init( anObj, texplo);
228 for(; myFaceExplorer.More(); myFaceExplorer.Next())
230 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
231 if(!aBS.Compare(myFaceExplorer.Current()).More())
233 const TopoDS_Shape& aS=myFaceExplorer.Current();
234 aListOfShape.Append (aS);
238 texplo = TopAbs_EDGE;
239 myFaceScanner.Clear();
240 myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
241 myFaceExplorer.Init( anObj, texplo );
243 for(; myFaceExplorer.More(); myFaceExplorer.Next())
245 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
246 if(!aBS.Compare(myFaceExplorer.Current()).More())
248 const TopoDS_Shape& aS=myFaceExplorer.Current();
249 aListOfShape.Append (aS);
253 // remove all shapes of < newRejectFace > from list
254 TopExp_Explorer ExpRF(newRejectFace, TopAbs_EDGE);
255 for(; ExpRF.More(); ExpRF.Next() )
257 const TopoDS_Edge& edgef = TopoDS::Edge( ExpRF.Current() );
258 TopTools_ListIteratorOfListOfShape it( aListOfShape );
259 for(; it.More(); it.Next() )
261 const TopoDS_Shape& shape = it.Value();
263 if( shape.ShapeType() != TopAbs_EDGE )
266 const TopoDS_Edge& edgel = TopoDS::Edge( shape );
267 if( edgef.IsSame( edgel ) )
269 aListOfShape.Remove(it);
274 TopTools_ListIteratorOfListOfShape it( aListOfShape );
275 for(; it.More(); it.Next() )
277 const TopoDS_Shape& shape = it.Value();
279 if( shape.ShapeType() != TopAbs_FACE )
282 const TopoDS_Face& facel = TopoDS::Face( shape );
283 if( facel.IsSame( newRejectFace ) )
285 aListOfShape.Remove(it);
290 Init(anObj, aReference);
294 Init(anObj, aReference);
296 aListOfShape.Clear();
297 //find faces to reject
299 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
300 TopAbs_ShapeEnum texplo = TopAbs_FACE;
301 myFaceScanner.Clear();
302 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
303 myFaceExplorer.Init(anObj,texplo);
305 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
306 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
307 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
308 const TopoDS_Shape& aS=myFaceExplorer.Current();
309 aListOfShape.Append (aS);
313 //modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000
314 texplo = TopAbs_EDGE;
315 myFaceScanner.Clear();
316 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
317 myFaceExplorer.Init(anObj,texplo);
319 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
320 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
321 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
322 const TopoDS_Shape& aS=myFaceExplorer.Current();
323 aListOfShape.Append (aS);
327 //modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000
328 /* texplo = TopAbs_VERTEX;
329 myFaceScanner.Clear();
330 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
331 myFaceExplorer.Init(anObj,texplo);
333 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
334 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
335 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
336 const TopoDS_Shape& aS=myFaceExplorer.Current();
337 aListOfShape.Append (aS);
342 //modified by NIZNHY-PKV Fri Sep 24 11:03:02 1999 to
347 //=======================================================================
348 //function : InitIntersection
350 //=======================================================================
352 void TopOpeBRep_ShapeIntersector::InitIntersection (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
356 InitFFIntersection();
357 if ( MoreFFCouple() ) return;
359 InitFEIntersection();
360 if ( MoreFECouple() ) return;
362 InitEFIntersection();
363 if ( MoreEFCouple() ) return;
367 //=======================================================================
368 //function : InitIntersection
370 //=======================================================================
372 void TopOpeBRep_ShapeIntersector::InitIntersection
373 (const TopoDS_Shape& S1, const TopoDS_Shape& S2,
374 const TopoDS_Face& F1, const TopoDS_Face& F2)
381 InitEEIntersection();
385 //=======================================================================
386 //function : MoreIntersection
388 //=======================================================================
390 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreIntersection() const
392 Standard_Boolean res = myIntersectionDone;
395 if (TopOpeBRep_GettraceSI() && res) {
396 if ( myFFDone ) std::cout<<"FF : ";
397 else if ( myEEFFDone ) std::cout<<" EE : ";
400 if ( myFFDone && myFFSameDomain ) std::cout<<"(FF SameDomain)";
401 else if ( myEEFFDone ) std::cout<<"(EE of FF SameDomain)";
402 else if ( myEEDone ) std::cout<<"EE : ";
403 std::cout<<std::endl;
405 Standard_Integer ie1 = myEdgeScanner.Index();
406 Standard_Integer ie2 = myEdgeExplorer.Index();
407 Standard_Integer if1 = myFaceScanner.Index();
408 Standard_Integer if2 = myFaceExplorer.Index();
409 std::cout<<" trc teeff 1 "<<ie1<<" "<<ie2<<" "<<if1<<" "<<if2<<"; # ie1 ie2 if1 if2"<<std::endl;
410 Standard_Boolean b = TopOpeBRep_GettraceEEFF(ie1,ie2,if1,if2);
411 if (b) seteefft(ie1,ie2,if1,if2);
412 else seteefff(ie1,ie2,if1,if2);
421 //=======================================================================
422 //function : DumpCurrent
424 //=======================================================================
427 void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer K) const
430 if ( K == 1 ) myFaceScanner.DumpCurrent(std::cout);
431 else if ( K == 2 ) myFaceExplorer.DumpCurrent(std::cout);
433 else if ( myEEFFDone ) {
434 if ( K == 1 ) myEdgeScanner.DumpCurrent(std::cout);
435 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(std::cout);
437 else if ( myFEDone ) {
438 if ( K == 1 ) myFaceScanner.DumpCurrent(std::cout);
439 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(std::cout);
441 else if ( myEFDone ) {
442 if ( K == 1 ) myEdgeScanner.DumpCurrent(std::cout);
443 else if ( K == 2 ) myFaceExplorer.DumpCurrent(std::cout);
445 else if ( myEEDone ) {
446 if ( K == 1 ) myEdgeScanner.DumpCurrent(std::cout);
447 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(std::cout);
451 void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer) const {}
454 //=======================================================================
457 //=======================================================================
460 Standard_Integer TopOpeBRep_ShapeIntersector::Index
461 (const Standard_Integer K)const
463 Standard_Integer i = 0;
466 if ( K == 1 ) i = myFaceScanner.Index();
467 else if ( K == 2 ) i = myFaceExplorer.Index();
469 else if ( myEEFFDone ) {
470 if ( K == 1 ) i = myEdgeScanner.Index();
471 else if ( K == 2 ) i = myEdgeExplorer.Index();
473 else if ( myFEDone ) {
474 if ( K == 1 ) i = myFaceScanner.Index();
475 else if ( K == 2 ) i = myEdgeExplorer.Index();
477 else if ( myEFDone ) {
478 if ( K == 1 ) i = myEdgeScanner.Index();
479 else if ( K == 2 ) i = myFaceExplorer.Index();
481 else if ( myEEDone ) {
482 if ( K == 1 ) i = myEdgeScanner.Index();
483 else if ( K == 2 ) i = myEdgeExplorer.Index();
488 Standard_Integer TopOpeBRep_ShapeIntersector::Index (const Standard_Integer)const
495 //=======================================================================
496 //function : NextIntersection
498 //=======================================================================
500 void TopOpeBRep_ShapeIntersector::NextIntersection()
502 myIntersectionDone = Standard_False;
504 if (myFFSameDomain) {
505 // precedant etat du More() : 2 faces samedomain
506 myFFDone = Standard_False;
507 myFFSameDomain = Standard_False;
508 InitEEFFIntersection();
509 FindEEFFIntersection();
510 if ( !myIntersectionDone ) {
512 FindFFIntersection();
517 FindFFIntersection();
519 else if ( myEEFFDone ) {
521 FindEEFFIntersection();
522 if ( !myIntersectionDone ) {
524 FindFFIntersection();
527 else if ( myFEDone ) {
529 FindFEIntersection();
531 else if ( myEFDone ) {
533 FindEFIntersection();
535 else if ( myEEDone ) {
537 FindEEIntersection();
540 if ( !myIntersectionDone ) {
541 InitFFIntersection();
544 if ( !myIntersectionDone ) {
545 InitFEIntersection();
548 if ( !myIntersectionDone ) {
549 InitEFIntersection();
552 if ( !myIntersectionDone ) {
553 if ( !myEEFace1.IsNull() && !myEEFace2.IsNull() ) {
554 InitEEIntersection();
566 //=======================================================================
567 //function : InitFFIntersection
569 //=======================================================================
571 void TopOpeBRep_ShapeIntersector::InitFFIntersection()
574 TopAbs_ShapeEnum tscann = TopAbs_FACE;
575 TopAbs_ShapeEnum texplo = TopAbs_FACE;
576 myFaceScanner.Clear();
577 myFaceScanner.AddBoxesMakeCOB(myShape1,tscann);
578 myFaceExplorer.Init(myShape2,texplo);
579 myFaceScanner.Init(myFaceExplorer);
580 FindFFIntersection();
582 myFFInit = Standard_True;
586 //=======================================================================
587 //function : FindFFIntersection
589 //=======================================================================
591 void TopOpeBRep_ShapeIntersector::FindFFIntersection()
593 myFFDone = Standard_False;
594 myFFSameDomain = Standard_False ;
596 while ( MoreFFCouple() ) {
598 // The two candidate intersecting GeomShapes GS1,GS2 and their types t1,t2
599 const TopoDS_Shape& GS1 = myFaceScanner.Current();
600 const TopoDS_Shape& GS2 = myFaceExplorer.Current();
603 SAVFFi1 = myFaceScanner.Index(); SAVFFi2 = myFaceExplorer.Index();
604 if (TopOpeBRep_GettraceSI()) {
605 std::cout<<"?? FF : ";
606 myFaceScanner.DumpCurrent(std::cout); myFaceExplorer.DumpCurrent(std::cout);
607 std::cout<<std::endl;
611 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
612 const Bnd_Box& B1 = BS.Box(GS1);
613 const Bnd_Box& B2 = BS.Box(GS2);
614 myFFIntersector.Perform(GS1,GS2,B1,B2);
615 Standard_Boolean ok = myFFIntersector.IsDone(); //xpu210998
621 myFFSameDomain = myFFIntersector.SameDomain();
623 if (myFFSameDomain) {
624 myFFDone = Standard_True;
628 myFFDone = ! (myFFIntersector.IsEmpty());
630 // update face/face intersection tolerances
632 Standard_Real tol1,tol2;
633 myFFIntersector.GetTolerances(tol1,tol2);
634 myTol1 = Max(myTol1,tol1); myTol2 = Max(myTol2,tol2);
645 SetIntersectionDone();
649 //=======================================================================
650 //function : MoreFFCouple
652 //=======================================================================
654 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFFCouple() const
656 Standard_Boolean more1 = myFaceScanner.More();
657 Standard_Boolean more2 = myFaceExplorer.More();
658 return (more1 && more2);
662 //=======================================================================
663 //function : NextFFCouple
665 //=======================================================================
667 void TopOpeBRep_ShapeIntersector::NextFFCouple()
669 myFaceScanner.Next();
670 Standard_Boolean b1,b2;
672 b1 = (!myFaceScanner.More());
673 b2 = (myFaceExplorer.More());
675 myFaceExplorer.Next();
676 myFaceScanner.Init(myFaceExplorer);
677 b1 = (!myFaceScanner.More());
678 b2 = (myFaceExplorer.More());
689 //=======================================================================
690 //function : InitEEFFIntersection
692 //=======================================================================
694 void TopOpeBRep_ShapeIntersector::InitEEFFIntersection()
696 // prepare exploration of the edges of the two current SameDomain faces
697 TopoDS_Shape face1 = myFaceScanner.Current(); // -26-08-96
698 TopoDS_Shape face2 = myFaceExplorer.Current(); // -26-08-96
701 if (TopOpeBRep_GetcontextFFOR()) {
702 face1.Orientation(TopAbs_FORWARD); //-05/07
703 face2.Orientation(TopAbs_FORWARD); //-05/07
704 std::cout<<"ctx : InitEEFFIntersection : faces FORWARD"<<std::endl;
708 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
709 const Bnd_Box& B1 = BS.Box(face1);
710 const Bnd_Box& B2 = BS.Box(face2);
711 myEEIntersector.SetFaces(face1,face2,B1,B2);
713 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
714 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
715 myEdgeScanner.Clear();
716 myEdgeScanner.AddBoxesMakeCOB(face1,tscann);
717 myEdgeExplorer.Init(face2,texplo);
718 myEdgeScanner.Init(myEdgeExplorer);
720 myEEFFInit = Standard_True;
724 //=======================================================================
725 //function : FindEEFFIntersection
727 //=======================================================================
729 void TopOpeBRep_ShapeIntersector::FindEEFFIntersection()
731 myEEFFDone = Standard_False;
732 while ( MoreEEFFCouple() ) {
733 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
734 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
735 myEEIntersector.Perform(GS1,GS2);
738 if (TopOpeBRep_GettraceSI() && myEEIntersector.IsEmpty()) {
740 myEdgeScanner.DumpCurrent(std::cout);
741 myEdgeExplorer.DumpCurrent(std::cout);
742 std::cout<<"(EE of FF SameDomain)";
743 std::cout<<" : EMPTY INTERSECTION";
744 std::cout<<std::endl;
748 myEEFFDone = ! (myEEIntersector.IsEmpty());
749 if (myEEFFDone) break;
750 else NextEEFFCouple();
752 SetIntersectionDone();
756 //=======================================================================
757 //function : MoreEEFFCouple
759 //=======================================================================
761 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEEFFCouple() const
763 Standard_Boolean more1 = myEdgeScanner.More();
764 Standard_Boolean more2 = myEdgeExplorer.More();
765 return (more1 && more2);
769 //=======================================================================
770 //function : NextEEFFCouple
772 //=======================================================================
774 void TopOpeBRep_ShapeIntersector::NextEEFFCouple()
776 myEdgeScanner.Next();
777 while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
778 myEdgeExplorer.Next();
779 myEdgeScanner.Init(myEdgeExplorer);
789 //=======================================================================
790 //function : InitFEIntersection
792 //=======================================================================
794 void TopOpeBRep_ShapeIntersector::InitFEIntersection()
797 TopAbs_ShapeEnum tscann = TopAbs_FACE;
798 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
799 myFaceScanner.Clear();
800 myFaceScanner.AddBoxesMakeCOB(myShape1,tscann);
801 myEdgeExplorer.Init(myShape2,texplo,TopAbs_FACE); // NYI defaut de spec
802 myFaceScanner.Init(myEdgeExplorer);
803 FindFEIntersection();
805 myFEInit = Standard_True;
809 //=======================================================================
810 //function : FindFEIntersection
812 //=======================================================================
814 void TopOpeBRep_ShapeIntersector::FindFEIntersection()
816 myFEDone = Standard_False;
817 while ( MoreFECouple() ) {
818 const TopoDS_Shape& GS1 = myFaceScanner.Current();
819 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
820 myFEIntersector.Perform(GS1,GS2);
821 myFEDone = ! (myFEIntersector.IsEmpty());
825 SetIntersectionDone();
829 //=======================================================================
830 //function : MoreFECouple
832 //=======================================================================
834 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFECouple() const
836 Standard_Boolean more1 = myFaceScanner.More();
837 Standard_Boolean more2 = myEdgeExplorer.More();
838 return (more1 && more2);
842 //=======================================================================
843 //function : NextFECouple
845 //=======================================================================
847 void TopOpeBRep_ShapeIntersector::NextFECouple()
849 myFaceScanner.Next();
850 while ( ! myFaceScanner.More() && myEdgeExplorer.More() ) {
851 myEdgeExplorer.Next();
852 myFaceScanner.Init(myEdgeExplorer);
862 //=======================================================================
863 //function : InitEFIntersection
865 //=======================================================================
867 void TopOpeBRep_ShapeIntersector::InitEFIntersection()
870 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
871 TopAbs_ShapeEnum texplo = TopAbs_FACE;
872 myEdgeScanner.Clear();
873 myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann, TopAbs_FACE); // NYI defaut de spec
874 myFaceExplorer.Init(myShape2,texplo);
875 myEdgeScanner.Init(myFaceExplorer);
876 FindEFIntersection();
878 myEFInit = Standard_True;
881 //=======================================================================
882 //function : FindEFIntersection
884 //=======================================================================
886 void TopOpeBRep_ShapeIntersector::FindEFIntersection()
888 myEFDone = Standard_False;
889 while ( MoreEFCouple() ) {
890 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
891 const TopoDS_Shape& GS2 = myFaceExplorer.Current();
892 myFEIntersector.Perform(GS2,GS1);
893 myEFDone = ! (myFEIntersector.IsEmpty());
897 SetIntersectionDone();
901 //=======================================================================
902 //function : MoreEFCouple
904 //=======================================================================
906 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEFCouple() const
908 Standard_Boolean more1 = myEdgeScanner.More();
909 Standard_Boolean more2 = myFaceExplorer.More();
910 return (more1 && more2);
914 //=======================================================================
915 //function : NextEFCouple
917 //=======================================================================
919 void TopOpeBRep_ShapeIntersector::NextEFCouple()
921 myEdgeScanner.Next();
922 while ( ! myEdgeScanner.More() && myFaceExplorer.More() ) {
923 myFaceExplorer.Next();
924 myEdgeScanner.Init(myFaceExplorer);
932 //=======================================================================
933 //function : InitEEIntersection
935 //=======================================================================
937 void TopOpeBRep_ShapeIntersector::InitEEIntersection()
940 TopoDS_Shape face1 = myEEFace1.Oriented(TopAbs_FORWARD);
941 TopoDS_Shape face2 = myEEFace2.Oriented(TopAbs_FORWARD);
942 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
943 const Bnd_Box& B1 = BS.Box(face1);
944 const Bnd_Box& B2 = BS.Box(face2);
945 myEEIntersector.SetFaces(face1,face2,B1,B2);
947 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
948 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
949 myEdgeScanner.Clear();
950 myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann);
951 myEdgeExplorer.Init(myShape2,texplo);
952 myEdgeScanner.Init(myEdgeExplorer);
953 FindEEIntersection();
955 myEEInit = Standard_True;
959 //=======================================================================
960 //function : FindEEIntersection
962 //=======================================================================
964 void TopOpeBRep_ShapeIntersector::FindEEIntersection()
966 myEEDone = Standard_False;
967 while ( MoreEECouple() ) {
968 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
969 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
970 myEEIntersector.Perform(GS1,GS2);
971 myEEDone = ! (myEEIntersector.IsEmpty());
975 SetIntersectionDone();
979 //=======================================================================
980 //function : MoreEECouple
982 //=======================================================================
984 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEECouple() const
986 Standard_Boolean more1 = myEdgeScanner.More();
987 Standard_Boolean more2 = myEdgeExplorer.More();
988 return (more1 && more2);
992 //=======================================================================
993 //function : NextEECouple
995 //=======================================================================
997 void TopOpeBRep_ShapeIntersector::NextEECouple()
999 myEdgeScanner.Next();
1000 while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
1001 myEdgeExplorer.Next();
1002 myEdgeScanner.Init(myEdgeExplorer);
1007 //=======================================================================
1010 //=======================================================================
1012 const TopoDS_Shape& TopOpeBRep_ShapeIntersector::Shape
1013 ( const Standard_Integer Index )const
1015 if ( Index == 1 ) return myShape1;
1016 else if ( Index == 2 ) return myShape2;
1018 throw Standard_Failure("ShapeIntersector : no shape");
1022 //=======================================================================
1023 //function : ChangeFacesIntersector
1025 //=======================================================================
1027 TopOpeBRep_FacesIntersector&
1028 TopOpeBRep_ShapeIntersector::ChangeFacesIntersector()
1029 { return myFFIntersector; }
1032 //=======================================================================
1033 //function : ChangeEdgesIntersector
1035 //=======================================================================
1037 TopOpeBRep_EdgesIntersector&
1038 TopOpeBRep_ShapeIntersector::ChangeEdgesIntersector()
1039 { return myEEIntersector; }
1042 //=======================================================================
1043 //function : ChangeFaceEdgeIntersector
1045 //=======================================================================
1047 TopOpeBRep_FaceEdgeIntersector&
1048 TopOpeBRep_ShapeIntersector::ChangeFaceEdgeIntersector()
1049 { return myFEIntersector; }
1052 //=======================================================================
1053 //function : GetTolerances
1055 //=======================================================================
1057 void TopOpeBRep_ShapeIntersector::GetTolerances(Standard_Real& tol1,
1058 Standard_Real& tol2)const
1059 { tol1 = myTol1; tol2 = myTol2; }
1064 //=======================================================================
1065 //function : IsHalfSpaceShape
1066 //purpose : tries to define if one of solids is a half space object
1068 // 0 - no half spaces ( default )
1069 // 1 - half space is S1
1070 // 2 - half space is S2
1071 //=======================================================================
1072 static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
1074 Standard_Integer result = 0;
1076 if( S1.ShapeType() == TopAbs_SOLID && S2.ShapeType() == TopAbs_SOLID )
1078 TopExp_Explorer ExpSol1(S1, TopAbs_FACE);
1079 TopExp_Explorer ExpSol2(S2, TopAbs_FACE);
1080 Standard_Integer NbFacesSol1 = 0;
1081 Standard_Integer NbFacesSol2 = 0;
1083 for(; ExpSol1.More(); ExpSol1.Next() )
1086 for(; ExpSol2.More(); ExpSol2.Next() )
1089 if( NbFacesSol1 == 0 || NbFacesSol2 == 0 ) // strange solids!!!
1091 if( NbFacesSol1 == 1 && NbFacesSol2 == 1 ) // both shapes are half spaces ???
1094 if( (NbFacesSol1 == 1 && NbFacesSol2 >= 2) || (NbFacesSol2 == 1 && NbFacesSol1 >= 2) )
1096 // if one solid has shell consisted of only a face but other one has valid closed
1097 // shell we can detect current boolean operation as operation with half space object.
1098 // if shell of second solid is not valid too we cann't detect what kind of objects
1099 // we try to perform. in this case we do nothing and just return.
1101 // but before we must avoid shperes, toruses and solids with a face biult on spherical surfaces
1102 // of revolution (SSRFS) - solids with shell of one face:
1103 // sphere (U: 0, 2PI) (V: -PI/2, PI/2),
1104 // torus (U: 0, 2PI) (V: 0, 2PI).
1105 // SSRFS (U period = (PI), 2PI) (V period = (PI), 2PI)
1106 // these solids are not halfspaces.
1108 TopExp_Explorer SolidExplorer;
1109 TopoDS_Face testFace;
1111 if( NbFacesSol1 == 1 )
1113 for( SolidExplorer.Init(S1, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
1114 testFace = TopoDS::Face( SolidExplorer.Current() );
1118 for( SolidExplorer.Init(S2, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
1119 testFace = TopoDS::Face( SolidExplorer.Current() );
1122 BRepAdaptor_Surface FSurf( testFace );
1123 Standard_Boolean SolidIsSphereOrTorus = Standard_False;
1125 if( FSurf.GetType() == GeomAbs_Sphere || FSurf.GetType() == GeomAbs_Torus )
1127 Standard_Real minU = FSurf.FirstUParameter();
1128 Standard_Real maxU = FSurf.LastUParameter();
1129 Standard_Real minV = FSurf.FirstVParameter();
1130 Standard_Real maxV = FSurf.LastVParameter();
1131 Standard_Boolean yesU = ( Abs(minU - 0.) < 1.e-9 && Abs(maxU - 2*M_PI) < 1.e-9 );
1132 Standard_Boolean yesV = ( FSurf.GetType() == GeomAbs_Sphere ) ?
1133 ( Abs(minV - (-M_PI/2.)) < 1.e-9 && Abs(maxV - M_PI/2.) < 1.e-9 ) :
1134 ( Abs(minV - 0.) < 1.e-9 && Abs(maxV - 2*M_PI) < 1.e-9 );
1135 SolidIsSphereOrTorus = ( yesU && yesV );
1138 if( FSurf.GetType() == GeomAbs_SurfaceOfRevolution )
1140 Standard_Boolean areBothPeriodic = ( FSurf.IsUPeriodic() && FSurf.IsVPeriodic() );
1141 if( areBothPeriodic )
1143 Standard_Boolean yesU = ( Abs(FSurf.UPeriod() - M_PI) < 1.e-9 || Abs(FSurf.UPeriod() - 2*M_PI) < 1.e-9 );
1144 Standard_Boolean yesV = ( Abs(FSurf.VPeriod() - M_PI) < 1.e-9 || Abs(FSurf.VPeriod() - 2*M_PI) < 1.e-9 );
1145 SolidIsSphereOrTorus = ( yesU && yesV );
1149 if( SolidIsSphereOrTorus )
1152 Standard_Boolean SecondShellOk = Standard_True;
1153 TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1155 Standard_Integer NbEdges = 0, NbFaces = 0, iE = 0;
1157 if( NbFacesSol1 == 1 )
1158 TopExp::MapShapesAndAncestors(S2, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1160 TopExp::MapShapesAndAncestors(S1, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1162 NbEdges = aMapEF.Extent();
1163 for( iE = 1; iE <= NbEdges; iE++)
1165 const TopTools_ListOfShape& listFaces = aMapEF.FindFromIndex( iE );
1166 NbFaces = listFaces.Extent();
1169 SecondShellOk = Standard_False;
1176 result = (NbFacesSol1 == 1) ? 1 : 2;
1180 // ************************** IMPORTANT !!! ************************************
1181 // both shells are of more than 2 faces. if both solids have invalid shells
1182 // we do nothing and just return. on the other hand if only one shell is valid
1183 // currently we should suppose that solid with invalid shell is a half space too,
1184 // but this is not always true.
1186 // so this suggestion must be developed carefully. while we don't classify it!
1187 // *****************************************************************************
1191 std::cout << "# one of the SOLIDs probably is a HALF SPACE" << std::endl;
1198 //=======================================================================
1199 //function : GetNewSolid
1200 //purpose : rebuild halfspace solid adding new "face on infinity"
1201 // to build correct bounding box to classify carefully
1202 // "rejected shapes".
1203 //=======================================================================
1204 static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F)
1206 // "new solid" is a new halfspace solid consists of two faces now: the first face is a face
1207 // used to build halfspace solid and the second face is a new "face on infinity" specially
1208 // created to constuct correct bounding box around halfspace solid with bounds more wide than
1211 // the following algorithm is used:
1212 // 1. get face used to build halfspace solid and calculate its normal, Min/Max (U,V) parameters,
1213 // four points lying on the surface of the face inside its restrictions, surface, tolerance
1215 // 2. define the direction into the halfspace solid and project four points along this direction
1216 // on infinite distance. then use those points to create "face on infinity".
1217 // 3. build new shell with two new faces and new "halfspace solid".
1218 // 4. return this solid and "face on infinity" to remove it and all its subshapes from the list
1219 // of rejected shapes.
1221 TopExp_Explorer ShapeExplorer;
1225 for( ShapeExplorer.Init(S, TopAbs_FACE); ShapeExplorer.More(); ShapeExplorer.Next() )
1226 hsFace = TopoDS::Face( ShapeExplorer.Current() );
1228 BRepAdaptor_Surface ASurf( hsFace );
1230 Standard_Real MinU = ASurf.FirstUParameter();
1231 Standard_Real MaxU = ASurf.LastUParameter();
1232 Standard_Real MinV = ASurf.FirstVParameter();
1233 Standard_Real MaxV = ASurf.LastUParameter();
1235 Standard_Real MidU = (MaxU + MinU) * 0.5;
1236 Standard_Real MidV = (MaxV + MinV) * 0.5;
1239 gp_Vec SurfDU, SurfDV;
1240 ASurf.D1( MidU, MidV, MidP, SurfDU, SurfDV );
1242 gp_Vec Normal = SurfDU.Crossed( SurfDV );
1244 if( hsFace.Orientation() == TopAbs_FORWARD )
1249 Standard_Real Pu1 = MinU + Abs( (MaxU - MinU) / 4. );
1250 Standard_Real Pu2 = MinU + Abs( (MaxU - MinU) / 4. * 3. );
1251 Standard_Real Pv1 = MinV + Abs( (MaxV - MinV) / 4. );
1252 Standard_Real Pv2 = MinV + Abs( (MaxV - MinV) / 4. * 3. );
1254 gp_Pnt P1, P2, P3, P4;
1255 ASurf.D0( Pu1, Pv1, P1 );
1256 ASurf.D0( Pu1, Pv2, P2 );
1257 ASurf.D0( Pu2, Pv1, P3 );
1258 ASurf.D0( Pu2, Pv2, P4 );
1260 P1.Translate( Normal );
1261 P2.Translate( Normal );
1262 P3.Translate( Normal );
1263 P4.Translate( Normal );
1265 BRepLib_MakeEdge mke1( P1, P2 );
1266 BRepLib_MakeEdge mke2( P2, P4 );
1267 BRepLib_MakeEdge mke3( P4, P3 );
1268 BRepLib_MakeEdge mke4( P3, P1 );
1270 TopoDS_Edge e1 = mke1.Edge();
1271 TopoDS_Edge e2 = mke2.Edge();
1272 TopoDS_Edge e3 = mke3.Edge();
1273 TopoDS_Edge e4 = mke4.Edge();
1275 BRepLib_MakeWire mkw( e1, e2, e3, e4 );
1276 TopoDS_Wire w = mkw.Wire();
1278 BRepLib_MakeFace mkf( w );
1279 TopoDS_Face infFace = mkf.Face();
1281 TopoDS_Shell newShell;
1282 TopoDS_Solid newSolid;
1284 BRep_Builder newShellBuilder;
1285 newShellBuilder.MakeShell( newShell );
1286 newShellBuilder.Add( newShell, hsFace );
1287 newShellBuilder.Add( newShell, infFace );
1288 newShell.Closed (BRep_Tool::IsClosed (newShell));
1290 BRep_Builder newSolidBuilder;
1291 newSolidBuilder.MakeSolid( newSolid );
1292 newSolidBuilder.Add( newSolid, newShell );