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.
17 #include <TopOpeBRep_ShapeIntersector.ixx>
20 #include <Bnd_Box.hxx>
21 #include <TopOpeBRepTool_box.hxx>
22 #include <TopOpeBRep_define.hxx>
25 extern Standard_Boolean TopOpeBRep_GettraceSI();
26 extern Standard_Boolean TopOpeBRep_GetcontextFFOR();
27 extern Standard_Integer SAVFFi1; // FacesIntersector
28 extern Standard_Integer SAVFFi2; // FacesIntersector
29 extern void TopOpeBRep_SettraceEEFF(const Standard_Boolean b);
30 extern Standard_Boolean TopOpeBRep_GettraceEEFF(const Standard_Integer e1,const Standard_Integer e2,const Standard_Integer f1,const Standard_Integer f2);
31 void seteeff(const Standard_Boolean b,const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2)
32 {cout<<"b,e1,e2,f1,f2 : "<<b<<" "<<e1<<","<<e2<<","<<f1<<","<<f2<<endl;TopOpeBRep_SettraceEEFF(b);}
33 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);}
34 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);}
37 // modified by NIZHNY-OFV Thu Apr 18 17:15:38 2002 (S)
39 #include <TopoDS_Shape.hxx>
40 #include <TopoDS_Solid.hxx>
41 #include <TopoDS_Shell.hxx>
42 #include <TopoDS_Face.hxx>
43 #include <TopoDS_Wire.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopExp_Explorer.hxx>
46 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
47 #include <TopTools_ListOfShape.hxx>
51 #include <BRepLib_MakeEdge.hxx>
52 #include <BRepLib_MakeWire.hxx>
53 #include <BRepLib_MakeFace.hxx>
54 #include <BRep_Builder.hxx>
55 #include <BRepAdaptor_Surface.hxx>
56 static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2);
57 static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F);
58 // modified by NIZHNY-OFV Thu Apr 18 17:16:45 2002 (F)
60 //=======================================================================
61 //function : TopOpeBRep_ShapeIntersector
63 //=======================================================================
65 TopOpeBRep_ShapeIntersector::TopOpeBRep_ShapeIntersector()
68 myFFIntersector.GetTolerances(myTol1,myTol2);
69 myHBoxTool = FBOX_GetHBoxTool();
70 myFaceScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
71 myEdgeScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
74 //=======================================================================
77 //=======================================================================
79 void TopOpeBRep_ShapeIntersector::Reset()
81 myIntersectionDone = Standard_False;
83 myFFDone = Standard_False;
84 myFFSameDomain = Standard_False;
85 myEEFFDone = Standard_False;
86 myEFDone = Standard_False;
87 myFEDone = Standard_False;
88 myEEDone = Standard_False;
90 myFFInit = Standard_False;
91 myEEFFInit = Standard_False;
92 myEFInit = Standard_False;
93 myFEInit = Standard_False;
94 myEEInit = Standard_False;
97 //=======================================================================
100 //=======================================================================
102 void TopOpeBRep_ShapeIntersector::Init
103 (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
110 //=======================================================================
111 //function : SetIntersectionDone
113 //=======================================================================
115 void TopOpeBRep_ShapeIntersector::SetIntersectionDone()
117 myIntersectionDone = (myFFDone ||
125 //=======================================================================
126 //function : CurrentGeomShape
128 //=======================================================================
130 const TopoDS_Shape& TopOpeBRep_ShapeIntersector::CurrentGeomShape
131 (const Standard_Integer Index) const
133 if ( myIntersectionDone ) {
135 if ( Index == 1 ) return myFaceScanner.Current();
136 else if ( Index == 2 ) return myFaceExplorer.Current();
138 else if (myEEFFDone) {
139 if ( Index == 1 ) return myEdgeScanner.Current();
140 else if ( Index == 2 ) return myEdgeExplorer.Current();
143 if ( Index == 1 ) return myFaceScanner.Current();
144 else if ( Index == 2 ) return myEdgeExplorer.Current();
147 if ( Index == 1 ) return myEdgeScanner.Current();
148 else if ( Index == 2 ) return myFaceExplorer.Current();
151 if ( Index == 1 ) return myEdgeScanner.Current();
152 else if ( Index == 2 ) return myEdgeExplorer.Current();
156 Standard_Failure::Raise("CurrentGeomShape : no intersection");
157 TopoDS_Shape* bid = new TopoDS_Shape();
160 //modified by NIZNHY-PKV Fri Sep 24 11:02:59 1999 from
161 //=======================================================================
162 //function : RejectedFaces
164 //=======================================================================
165 void TopOpeBRep_ShapeIntersector::RejectedFaces (const TopoDS_Shape& anObj,
166 const TopoDS_Shape& aReference,
167 TopTools_ListOfShape& aListOfShape)
170 Standard_Integer isHalfSpace = OneShapeIsHalfSpace( anObj, aReference );
171 if( isHalfSpace != 0 )
173 TopoDS_Face newRejectFace;
174 TopoDS_Solid newSolid;
175 aListOfShape.Clear();
177 if( isHalfSpace == 1 )
179 newSolid = GetNewSolid( anObj, newRejectFace );
180 Init( newSolid, aReference );
182 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
183 TopAbs_ShapeEnum texplo = TopAbs_FACE;
184 myFaceScanner.Clear();
185 myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
186 myFaceExplorer.Init( newSolid, texplo );
188 for(; myFaceExplorer.More(); myFaceExplorer.Next())
190 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
191 if(!aBS.Compare(myFaceExplorer.Current()).More())
193 const TopoDS_Shape& aS=myFaceExplorer.Current();
194 aListOfShape.Append (aS);
198 texplo = TopAbs_EDGE;
199 myFaceScanner.Clear();
200 myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
201 myFaceExplorer.Init( newSolid, texplo );
203 for(; myFaceExplorer.More(); myFaceExplorer.Next())
205 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
206 if(!aBS.Compare(myFaceExplorer.Current()).More())
208 const TopoDS_Shape& aS=myFaceExplorer.Current();
209 aListOfShape.Append (aS);
215 newSolid = GetNewSolid( aReference, newRejectFace );
216 Init( anObj, newSolid );
218 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
219 TopAbs_ShapeEnum texplo = TopAbs_FACE;
220 myFaceScanner.Clear();
221 myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
222 myFaceExplorer.Init( anObj, texplo);
224 for(; myFaceExplorer.More(); myFaceExplorer.Next())
226 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
227 if(!aBS.Compare(myFaceExplorer.Current()).More())
229 const TopoDS_Shape& aS=myFaceExplorer.Current();
230 aListOfShape.Append (aS);
234 texplo = TopAbs_EDGE;
235 myFaceScanner.Clear();
236 myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
237 myFaceExplorer.Init( anObj, texplo );
239 for(; myFaceExplorer.More(); myFaceExplorer.Next())
241 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
242 if(!aBS.Compare(myFaceExplorer.Current()).More())
244 const TopoDS_Shape& aS=myFaceExplorer.Current();
245 aListOfShape.Append (aS);
249 // remove all shapes of < newRejectFace > from list
250 TopExp_Explorer ExpRF(newRejectFace, TopAbs_EDGE);
251 for(; ExpRF.More(); ExpRF.Next() )
253 const TopoDS_Edge& edgef = TopoDS::Edge( ExpRF.Current() );
254 TopTools_ListIteratorOfListOfShape it( aListOfShape );
255 for(; it.More(); it.Next() )
257 const TopoDS_Shape& shape = it.Value();
259 if( shape.ShapeType() != TopAbs_EDGE )
262 const TopoDS_Edge& edgel = TopoDS::Edge( shape );
263 if( edgef.IsSame( edgel ) )
265 aListOfShape.Remove(it);
270 TopTools_ListIteratorOfListOfShape it( aListOfShape );
271 for(; it.More(); it.Next() )
273 const TopoDS_Shape& shape = it.Value();
275 if( shape.ShapeType() != TopAbs_FACE )
278 const TopoDS_Face& facel = TopoDS::Face( shape );
279 if( facel.IsSame( newRejectFace ) )
281 aListOfShape.Remove(it);
286 Init(anObj, aReference);
290 Init(anObj, aReference);
292 aListOfShape.Clear();
293 //find faces to reject
295 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
296 TopAbs_ShapeEnum texplo = TopAbs_FACE;
297 myFaceScanner.Clear();
298 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
299 myFaceExplorer.Init(anObj,texplo);
301 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
302 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
303 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
304 const TopoDS_Shape& aS=myFaceExplorer.Current();
305 aListOfShape.Append (aS);
309 //modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000
310 texplo = TopAbs_EDGE;
311 myFaceScanner.Clear();
312 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
313 myFaceExplorer.Init(anObj,texplo);
315 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
316 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
317 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
318 const TopoDS_Shape& aS=myFaceExplorer.Current();
319 aListOfShape.Append (aS);
323 //modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000
324 /* texplo = TopAbs_VERTEX;
325 myFaceScanner.Clear();
326 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
327 myFaceExplorer.Init(anObj,texplo);
329 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
330 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
331 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
332 const TopoDS_Shape& aS=myFaceExplorer.Current();
333 aListOfShape.Append (aS);
338 //modified by NIZNHY-PKV Fri Sep 24 11:03:02 1999 to
343 //=======================================================================
344 //function : InitIntersection
346 //=======================================================================
348 void TopOpeBRep_ShapeIntersector::InitIntersection (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
352 InitFFIntersection();
353 if ( MoreFFCouple() ) return;
355 InitFEIntersection();
356 if ( MoreFECouple() ) return;
358 InitEFIntersection();
359 if ( MoreEFCouple() ) return;
363 //=======================================================================
364 //function : InitIntersection
366 //=======================================================================
368 void TopOpeBRep_ShapeIntersector::InitIntersection
369 (const TopoDS_Shape& S1, const TopoDS_Shape& S2,
370 const TopoDS_Face& F1, const TopoDS_Face& F2)
377 InitEEIntersection();
381 //=======================================================================
382 //function : MoreIntersection
384 //=======================================================================
386 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreIntersection() const
388 Standard_Boolean res = myIntersectionDone;
391 if (TopOpeBRep_GettraceSI() && res) {
392 if ( myFFDone ) cout<<"FF : ";
393 else if ( myEEFFDone ) cout<<" EE : ";
396 if ( myFFDone && myFFSameDomain ) cout<<"(FF SameDomain)";
397 else if ( myEEFFDone ) cout<<"(EE of FF SameDomain)";
398 else if ( myEEDone ) cout<<"EE : ";
401 Standard_Integer ie1 = myEdgeScanner.Index();
402 Standard_Integer ie2 = myEdgeExplorer.Index();
403 Standard_Integer if1 = myFaceScanner.Index();
404 Standard_Integer if2 = myFaceExplorer.Index();
405 cout<<" trc teeff 1 "<<ie1<<" "<<ie2<<" "<<if1<<" "<<if2<<"; # ie1 ie2 if1 if2"<<endl;
406 Standard_Boolean b = TopOpeBRep_GettraceEEFF(ie1,ie2,if1,if2);
407 if (b) seteefft(ie1,ie2,if1,if2);
408 else seteefff(ie1,ie2,if1,if2);
417 //=======================================================================
418 //function : DumpCurrent
420 //=======================================================================
423 void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer K) const
426 if ( K == 1 ) myFaceScanner.DumpCurrent(cout);
427 else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout);
429 else if ( myEEFFDone ) {
430 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
431 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
433 else if ( myFEDone ) {
434 if ( K == 1 ) myFaceScanner.DumpCurrent(cout);
435 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
437 else if ( myEFDone ) {
438 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
439 else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout);
441 else if ( myEEDone ) {
442 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
443 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
447 void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer) const {}
450 //=======================================================================
453 //=======================================================================
456 Standard_Integer TopOpeBRep_ShapeIntersector::Index
457 (const Standard_Integer K)const
459 Standard_Integer i = 0;
462 if ( K == 1 ) i = myFaceScanner.Index();
463 else if ( K == 2 ) i = myFaceExplorer.Index();
465 else if ( myEEFFDone ) {
466 if ( K == 1 ) i = myEdgeScanner.Index();
467 else if ( K == 2 ) i = myEdgeExplorer.Index();
469 else if ( myFEDone ) {
470 if ( K == 1 ) i = myFaceScanner.Index();
471 else if ( K == 2 ) i = myEdgeExplorer.Index();
473 else if ( myEFDone ) {
474 if ( K == 1 ) i = myEdgeScanner.Index();
475 else if ( K == 2 ) i = myFaceExplorer.Index();
477 else if ( myEEDone ) {
478 if ( K == 1 ) i = myEdgeScanner.Index();
479 else if ( K == 2 ) i = myEdgeExplorer.Index();
484 Standard_Integer TopOpeBRep_ShapeIntersector::Index (const Standard_Integer)const
491 //=======================================================================
492 //function : NextIntersection
494 //=======================================================================
496 void TopOpeBRep_ShapeIntersector::NextIntersection()
498 myIntersectionDone = Standard_False;
500 if (myFFSameDomain) {
501 // precedant etat du More() : 2 faces samedomain
502 myFFDone = Standard_False;
503 myFFSameDomain = Standard_False;
504 InitEEFFIntersection();
505 FindEEFFIntersection();
506 if ( !myIntersectionDone ) {
508 FindFFIntersection();
513 FindFFIntersection();
515 else if ( myEEFFDone ) {
517 FindEEFFIntersection();
518 if ( !myIntersectionDone ) {
520 FindFFIntersection();
523 else if ( myFEDone ) {
525 FindFEIntersection();
527 else if ( myEFDone ) {
529 FindEFIntersection();
531 else if ( myEEDone ) {
533 FindEEIntersection();
536 if ( !myIntersectionDone ) {
537 InitFFIntersection();
540 if ( !myIntersectionDone ) {
541 InitFEIntersection();
544 if ( !myIntersectionDone ) {
545 InitEFIntersection();
548 if ( !myIntersectionDone ) {
549 if ( !myEEFace1.IsNull() && !myEEFace2.IsNull() ) {
550 InitEEIntersection();
562 //=======================================================================
563 //function : InitFFIntersection
565 //=======================================================================
567 void TopOpeBRep_ShapeIntersector::InitFFIntersection()
570 TopAbs_ShapeEnum tscann = TopAbs_FACE;
571 TopAbs_ShapeEnum texplo = TopAbs_FACE;
572 myFaceScanner.Clear();
573 myFaceScanner.AddBoxesMakeCOB(myShape1,tscann);
574 myFaceExplorer.Init(myShape2,texplo);
575 myFaceScanner.Init(myFaceExplorer);
576 FindFFIntersection();
578 myFFInit = Standard_True;
582 //=======================================================================
583 //function : FindFFIntersection
585 //=======================================================================
587 void TopOpeBRep_ShapeIntersector::FindFFIntersection()
589 myFFDone = Standard_False;
590 myFFSameDomain = Standard_False ;
592 while ( MoreFFCouple() ) {
594 // The two candidate intersecting GeomShapes GS1,GS2 and their types t1,t2
595 const TopoDS_Shape& GS1 = myFaceScanner.Current();
596 const TopoDS_Shape& GS2 = myFaceExplorer.Current();
599 SAVFFi1 = myFaceScanner.Index(); SAVFFi2 = myFaceExplorer.Index();
600 if (TopOpeBRep_GettraceSI()) {
602 myFaceScanner.DumpCurrent(cout); myFaceExplorer.DumpCurrent(cout);
607 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
608 const Bnd_Box& B1 = BS.Box(GS1);
609 const Bnd_Box& B2 = BS.Box(GS2);
610 myFFIntersector.Perform(GS1,GS2,B1,B2);
611 Standard_Boolean ok = myFFIntersector.IsDone(); //xpu210998
617 myFFSameDomain = myFFIntersector.SameDomain();
619 if (myFFSameDomain) {
620 myFFDone = Standard_True;
624 myFFDone = ! (myFFIntersector.IsEmpty());
626 // update face/face intersection tolerances
628 Standard_Real tol1,tol2;
629 myFFIntersector.GetTolerances(tol1,tol2);
630 myTol1 = Max(myTol1,tol1); myTol2 = Max(myTol2,tol2);
641 SetIntersectionDone();
645 //=======================================================================
646 //function : MoreFFCouple
648 //=======================================================================
650 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFFCouple() const
652 Standard_Boolean more1 = myFaceScanner.More();
653 Standard_Boolean more2 = myFaceExplorer.More();
654 return (more1 && more2);
658 //=======================================================================
659 //function : NextFFCouple
661 //=======================================================================
663 void TopOpeBRep_ShapeIntersector::NextFFCouple()
665 myFaceScanner.Next();
666 Standard_Boolean b1,b2;
668 b1 = (!myFaceScanner.More());
669 b2 = (myFaceExplorer.More());
671 myFaceExplorer.Next();
672 myFaceScanner.Init(myFaceExplorer);
673 b1 = (!myFaceScanner.More());
674 b2 = (myFaceExplorer.More());
685 //=======================================================================
686 //function : InitEEFFIntersection
688 //=======================================================================
690 void TopOpeBRep_ShapeIntersector::InitEEFFIntersection()
692 // prepare exploration of the edges of the two current SameDomain faces
693 TopoDS_Shape face1 = myFaceScanner.Current(); // -26-08-96
694 TopoDS_Shape face2 = myFaceExplorer.Current(); // -26-08-96
697 if (TopOpeBRep_GetcontextFFOR()) {
698 face1.Orientation(TopAbs_FORWARD); //-05/07
699 face2.Orientation(TopAbs_FORWARD); //-05/07
700 cout<<"ctx : InitEEFFIntersection : faces FORWARD"<<endl;
704 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
705 const Bnd_Box& B1 = BS.Box(face1);
706 const Bnd_Box& B2 = BS.Box(face2);
707 myEEIntersector.SetFaces(face1,face2,B1,B2);
709 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
710 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
711 myEdgeScanner.Clear();
712 myEdgeScanner.AddBoxesMakeCOB(face1,tscann);
713 myEdgeExplorer.Init(face2,texplo);
714 myEdgeScanner.Init(myEdgeExplorer);
716 myEEFFInit = Standard_True;
720 //=======================================================================
721 //function : FindEEFFIntersection
723 //=======================================================================
725 void TopOpeBRep_ShapeIntersector::FindEEFFIntersection()
727 myEEFFDone = Standard_False;
728 while ( MoreEEFFCouple() ) {
729 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
730 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
731 myEEIntersector.Perform(GS1,GS2);
734 if (TopOpeBRep_GettraceSI() && myEEIntersector.IsEmpty()) {
736 myEdgeScanner.DumpCurrent(cout);
737 myEdgeExplorer.DumpCurrent(cout);
738 cout<<"(EE of FF SameDomain)";
739 cout<<" : EMPTY INTERSECTION";
744 myEEFFDone = ! (myEEIntersector.IsEmpty());
745 if (myEEFFDone) break;
746 else NextEEFFCouple();
748 SetIntersectionDone();
752 //=======================================================================
753 //function : MoreEEFFCouple
755 //=======================================================================
757 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEEFFCouple() const
759 Standard_Boolean more1 = myEdgeScanner.More();
760 Standard_Boolean more2 = myEdgeExplorer.More();
761 return (more1 && more2);
765 //=======================================================================
766 //function : NextEEFFCouple
768 //=======================================================================
770 void TopOpeBRep_ShapeIntersector::NextEEFFCouple()
772 myEdgeScanner.Next();
773 while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
774 myEdgeExplorer.Next();
775 myEdgeScanner.Init(myEdgeExplorer);
785 //=======================================================================
786 //function : InitFEIntersection
788 //=======================================================================
790 void TopOpeBRep_ShapeIntersector::InitFEIntersection()
793 TopAbs_ShapeEnum tscann = TopAbs_FACE;
794 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
795 myFaceScanner.Clear();
796 myFaceScanner.AddBoxesMakeCOB(myShape1,tscann);
797 myEdgeExplorer.Init(myShape2,texplo,TopAbs_FACE); // NYI defaut de spec
798 myFaceScanner.Init(myEdgeExplorer);
799 FindFEIntersection();
801 myFEInit = Standard_True;
805 //=======================================================================
806 //function : FindFEIntersection
808 //=======================================================================
810 void TopOpeBRep_ShapeIntersector::FindFEIntersection()
812 myFEDone = Standard_False;
813 while ( MoreFECouple() ) {
814 const TopoDS_Shape& GS1 = myFaceScanner.Current();
815 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
816 myFEIntersector.Perform(GS1,GS2);
817 myFEDone = ! (myFEIntersector.IsEmpty());
821 SetIntersectionDone();
825 //=======================================================================
826 //function : MoreFECouple
828 //=======================================================================
830 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFECouple() const
832 Standard_Boolean more1 = myFaceScanner.More();
833 Standard_Boolean more2 = myEdgeExplorer.More();
834 return (more1 && more2);
838 //=======================================================================
839 //function : NextFECouple
841 //=======================================================================
843 void TopOpeBRep_ShapeIntersector::NextFECouple()
845 myFaceScanner.Next();
846 while ( ! myFaceScanner.More() && myEdgeExplorer.More() ) {
847 myEdgeExplorer.Next();
848 myFaceScanner.Init(myEdgeExplorer);
858 //=======================================================================
859 //function : InitEFIntersection
861 //=======================================================================
863 void TopOpeBRep_ShapeIntersector::InitEFIntersection()
866 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
867 TopAbs_ShapeEnum texplo = TopAbs_FACE;
868 myEdgeScanner.Clear();
869 myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann, TopAbs_FACE); // NYI defaut de spec
870 myFaceExplorer.Init(myShape2,texplo);
871 myEdgeScanner.Init(myFaceExplorer);
872 FindEFIntersection();
874 myEFInit = Standard_True;
877 //=======================================================================
878 //function : FindEFIntersection
880 //=======================================================================
882 void TopOpeBRep_ShapeIntersector::FindEFIntersection()
884 myEFDone = Standard_False;
885 while ( MoreEFCouple() ) {
886 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
887 const TopoDS_Shape& GS2 = myFaceExplorer.Current();
888 myFEIntersector.Perform(GS2,GS1);
889 myEFDone = ! (myFEIntersector.IsEmpty());
893 SetIntersectionDone();
897 //=======================================================================
898 //function : MoreEFCouple
900 //=======================================================================
902 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEFCouple() const
904 Standard_Boolean more1 = myEdgeScanner.More();
905 Standard_Boolean more2 = myFaceExplorer.More();
906 return (more1 && more2);
910 //=======================================================================
911 //function : NextEFCouple
913 //=======================================================================
915 void TopOpeBRep_ShapeIntersector::NextEFCouple()
917 myEdgeScanner.Next();
918 while ( ! myEdgeScanner.More() && myFaceExplorer.More() ) {
919 myFaceExplorer.Next();
920 myEdgeScanner.Init(myFaceExplorer);
928 //=======================================================================
929 //function : InitEEIntersection
931 //=======================================================================
933 void TopOpeBRep_ShapeIntersector::InitEEIntersection()
936 TopoDS_Shape face1 = myEEFace1.Oriented(TopAbs_FORWARD);
937 TopoDS_Shape face2 = myEEFace2.Oriented(TopAbs_FORWARD);
938 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
939 const Bnd_Box& B1 = BS.Box(face1);
940 const Bnd_Box& B2 = BS.Box(face2);
941 myEEIntersector.SetFaces(face1,face2,B1,B2);
943 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
944 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
945 myEdgeScanner.Clear();
946 myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann);
947 myEdgeExplorer.Init(myShape2,texplo);
948 myEdgeScanner.Init(myEdgeExplorer);
949 FindEEIntersection();
951 myEEInit = Standard_True;
955 //=======================================================================
956 //function : FindEEIntersection
958 //=======================================================================
960 void TopOpeBRep_ShapeIntersector::FindEEIntersection()
962 myEEDone = Standard_False;
963 while ( MoreEECouple() ) {
964 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
965 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
966 myEEIntersector.Perform(GS1,GS2);
967 myEEDone = ! (myEEIntersector.IsEmpty());
971 SetIntersectionDone();
975 //=======================================================================
976 //function : MoreEECouple
978 //=======================================================================
980 Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEECouple() const
982 Standard_Boolean more1 = myEdgeScanner.More();
983 Standard_Boolean more2 = myEdgeExplorer.More();
984 return (more1 && more2);
988 //=======================================================================
989 //function : NextEECouple
991 //=======================================================================
993 void TopOpeBRep_ShapeIntersector::NextEECouple()
995 myEdgeScanner.Next();
996 while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
997 myEdgeExplorer.Next();
998 myEdgeScanner.Init(myEdgeExplorer);
1003 //=======================================================================
1006 //=======================================================================
1008 const TopoDS_Shape& TopOpeBRep_ShapeIntersector::Shape
1009 ( const Standard_Integer Index )const
1011 if ( Index == 1 ) return myShape1;
1012 else if ( Index == 2 ) return myShape2;
1014 Standard_Failure::Raise("ShapeIntersector : no shape");
1015 TopoDS_Shape* bid = new TopoDS_Shape();
1020 //=======================================================================
1021 //function : ChangeFacesIntersector
1023 //=======================================================================
1025 TopOpeBRep_FacesIntersector&
1026 TopOpeBRep_ShapeIntersector::ChangeFacesIntersector()
1027 { return myFFIntersector; }
1030 //=======================================================================
1031 //function : ChangeEdgesIntersector
1033 //=======================================================================
1035 TopOpeBRep_EdgesIntersector&
1036 TopOpeBRep_ShapeIntersector::ChangeEdgesIntersector()
1037 { return myEEIntersector; }
1040 //=======================================================================
1041 //function : ChangeFaceEdgeIntersector
1043 //=======================================================================
1045 TopOpeBRep_FaceEdgeIntersector&
1046 TopOpeBRep_ShapeIntersector::ChangeFaceEdgeIntersector()
1047 { return myFEIntersector; }
1050 //=======================================================================
1051 //function : GetTolerances
1053 //=======================================================================
1055 void TopOpeBRep_ShapeIntersector::GetTolerances(Standard_Real& tol1,
1056 Standard_Real& tol2)const
1057 { tol1 = myTol1; tol2 = myTol2; }
1062 //=======================================================================
1063 //function : IsHalfSpaceShape
1064 //purpose : tries to define if one of solids is a half space object
1066 // 0 - no half spaces ( default )
1067 // 1 - half space is S1
1068 // 2 - half space is S2
1069 //=======================================================================
1070 static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
1072 Standard_Integer result = 0;
1074 if( S1.ShapeType() == TopAbs_SOLID && S2.ShapeType() == TopAbs_SOLID )
1076 TopExp_Explorer ExpSol1(S1, TopAbs_FACE);
1077 TopExp_Explorer ExpSol2(S2, TopAbs_FACE);
1078 Standard_Integer NbFacesSol1 = 0;
1079 Standard_Integer NbFacesSol2 = 0;
1081 for(; ExpSol1.More(); ExpSol1.Next() )
1084 for(; ExpSol2.More(); ExpSol2.Next() )
1087 if( NbFacesSol1 == 0 || NbFacesSol2 == 0 ) // strange solids!!!
1089 if( NbFacesSol1 == 1 && NbFacesSol2 == 1 ) // both shapes are half spaces ???
1092 if( (NbFacesSol1 == 1 && NbFacesSol2 >= 2) || (NbFacesSol2 == 1 && NbFacesSol1 >= 2) )
1094 // if one solid has shell consisted of only a face but other one has valid closed
1095 // shell we can detect current boolean operation as operation with half space object.
1096 // if shell of second solid is not valid too we cann't detect what kind of objects
1097 // we try to perform. in this case we do nothing and just return.
1099 // but before we must avoid shperes, toruses and solids with a face biult on spherical surfaces
1100 // of revolution (SSRFS) - solids with shell of one face:
1101 // sphere (U: 0, 2PI) (V: -PI/2, PI/2),
1102 // torus (U: 0, 2PI) (V: 0, 2PI).
1103 // SSRFS (U period = (PI), 2PI) (V period = (PI), 2PI)
1104 // these solids are not halfspaces.
1106 TopExp_Explorer SolidExplorer;
1107 TopoDS_Face testFace;
1109 if( NbFacesSol1 == 1 )
1111 for( SolidExplorer.Init(S1, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
1112 testFace = TopoDS::Face( SolidExplorer.Current() );
1116 for( SolidExplorer.Init(S2, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
1117 testFace = TopoDS::Face( SolidExplorer.Current() );
1120 BRepAdaptor_Surface FSurf( testFace );
1121 Standard_Boolean SolidIsSphereOrTorus = Standard_False;
1123 if( FSurf.GetType() == GeomAbs_Sphere || FSurf.GetType() == GeomAbs_Torus )
1125 Standard_Real minU = FSurf.FirstUParameter();
1126 Standard_Real maxU = FSurf.LastUParameter();
1127 Standard_Real minV = FSurf.FirstVParameter();
1128 Standard_Real maxV = FSurf.LastVParameter();
1129 Standard_Boolean yesU = ( Abs(minU - 0.) < 1.e-9 && Abs(maxU - 2*M_PI) < 1.e-9 );
1130 Standard_Boolean yesV = ( FSurf.GetType() == GeomAbs_Sphere ) ?
1131 ( Abs(minV - (-M_PI/2.)) < 1.e-9 && Abs(maxV - M_PI/2.) < 1.e-9 ) :
1132 ( Abs(minV - 0.) < 1.e-9 && Abs(maxV - 2*M_PI) < 1.e-9 );
1133 SolidIsSphereOrTorus = ( yesU && yesV );
1136 if( FSurf.GetType() == GeomAbs_SurfaceOfRevolution )
1138 Standard_Boolean areBothPeriodic = ( FSurf.IsUPeriodic() && FSurf.IsVPeriodic() );
1139 if( areBothPeriodic )
1141 Standard_Boolean yesU = ( Abs(FSurf.UPeriod() - M_PI) < 1.e-9 || Abs(FSurf.UPeriod() - 2*M_PI) < 1.e-9 );
1142 Standard_Boolean yesV = ( Abs(FSurf.VPeriod() - M_PI) < 1.e-9 || Abs(FSurf.VPeriod() - 2*M_PI) < 1.e-9 );
1143 SolidIsSphereOrTorus = ( yesU && yesV );
1147 if( SolidIsSphereOrTorus )
1150 Standard_Boolean SecondShellOk = Standard_True;
1151 TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1153 Standard_Integer NbEdges = 0, NbFaces = 0, iE = 0;
1155 if( NbFacesSol1 == 1 )
1156 TopExp::MapShapesAndAncestors(S2, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1158 TopExp::MapShapesAndAncestors(S1, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1160 NbEdges = aMapEF.Extent();
1161 for( iE = 1; iE <= NbEdges; iE++)
1163 const TopTools_ListOfShape& listFaces = aMapEF.FindFromIndex( iE );
1164 NbFaces = listFaces.Extent();
1167 SecondShellOk = Standard_False;
1174 result = (NbFacesSol1 == 1) ? 1 : 2;
1178 // ************************** IMPORTANT !!! ************************************
1179 // both shells are of more than 2 faces. if both solids have invalid shells
1180 // we do nothing and just return. on the other hand if only one shell is valid
1181 // currently we should suppose that solid with invalid shell is a half space too,
1182 // but this is not always true.
1184 // so this suggestion must be developed carefully. while we don't classify it!
1185 // *****************************************************************************
1189 cout << "# one of the SOLIDs probably is a HALF SPACE" << endl;
1196 //=======================================================================
1197 //function : GetNewSolid
1198 //purpose : rebuild halfspace solid adding new "face on infinity"
1199 // to build correct bounding box to classify carefully
1200 // "rejected shapes".
1201 //=======================================================================
1202 static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F)
1204 // "new solid" is a new halfspace solid consists of two faces now: the first face is a face
1205 // used to build halfspace solid and the second face is a new "face on infinity" specially
1206 // created to constuct correct bounding box around halfspace solid with bounds more wide than
1209 // the following algorithm is used:
1210 // 1. get face used to build halfspace solid and calculate its normal, Min/Max (U,V) parameters,
1211 // four points lying on the surface of the face inside its restrictions, surface, tolerance
1213 // 2. define the direction into the halfspace solid and project four points along this direction
1214 // on infinite distance. then use those points to create "face on infinity".
1215 // 3. build new shell with two new faces and new "halfspace solid".
1216 // 4. return this solid and "face on infinity" to remove it and all its subshapes from the list
1217 // of rejected shapes.
1219 TopExp_Explorer ShapeExplorer;
1223 for( ShapeExplorer.Init(S, TopAbs_FACE); ShapeExplorer.More(); ShapeExplorer.Next() )
1224 hsFace = TopoDS::Face( ShapeExplorer.Current() );
1226 BRepAdaptor_Surface ASurf( hsFace );
1228 Standard_Real MinU = ASurf.FirstUParameter();
1229 Standard_Real MaxU = ASurf.LastUParameter();
1230 Standard_Real MinV = ASurf.FirstVParameter();
1231 Standard_Real MaxV = ASurf.LastUParameter();
1233 Standard_Real MidU = (MaxU + MinU) * 0.5;
1234 Standard_Real MidV = (MaxV + MinV) * 0.5;
1237 gp_Vec SurfDU, SurfDV;
1238 ASurf.D1( MidU, MidV, MidP, SurfDU, SurfDV );
1240 gp_Vec Normal = SurfDU.Crossed( SurfDV );
1242 if( hsFace.Orientation() == TopAbs_FORWARD )
1247 Standard_Real Pu1 = MinU + Abs( (MaxU - MinU) / 4. );
1248 Standard_Real Pu2 = MinU + Abs( (MaxU - MinU) / 4. * 3. );
1249 Standard_Real Pv1 = MinV + Abs( (MaxV - MinV) / 4. );
1250 Standard_Real Pv2 = MinV + Abs( (MaxV - MinV) / 4. * 3. );
1252 gp_Pnt P1, P2, P3, P4;
1253 ASurf.D0( Pu1, Pv1, P1 );
1254 ASurf.D0( Pu1, Pv2, P2 );
1255 ASurf.D0( Pu2, Pv1, P3 );
1256 ASurf.D0( Pu2, Pv2, P4 );
1258 P1.Translate( Normal );
1259 P2.Translate( Normal );
1260 P3.Translate( Normal );
1261 P4.Translate( Normal );
1263 BRepLib_MakeEdge mke1( P1, P2 );
1264 BRepLib_MakeEdge mke2( P2, P4 );
1265 BRepLib_MakeEdge mke3( P4, P3 );
1266 BRepLib_MakeEdge mke4( P3, P1 );
1268 TopoDS_Edge e1 = mke1.Edge();
1269 TopoDS_Edge e2 = mke2.Edge();
1270 TopoDS_Edge e3 = mke3.Edge();
1271 TopoDS_Edge e4 = mke4.Edge();
1273 BRepLib_MakeWire mkw( e1, e2, e3, e4 );
1274 TopoDS_Wire w = mkw.Wire();
1276 BRepLib_MakeFace mkf( w );
1277 TopoDS_Face infFace = mkf.Face();
1279 TopoDS_Shell newShell;
1280 TopoDS_Solid newSolid;
1282 BRep_Builder newShellBuilder;
1283 newShellBuilder.MakeShell( newShell );
1284 newShellBuilder.Add( newShell, hsFace );
1285 newShellBuilder.Add( newShell, infFace );
1286 newShell.Closed (BRep_Tool::IsClosed (newShell));
1288 BRep_Builder newSolidBuilder;
1289 newSolidBuilder.MakeSolid( newSolid );
1290 newSolidBuilder.Add( newSolid, newShell );