0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / TopOpeBRep / TopOpeBRep_ShapeIntersector.cxx
CommitLineData
b311480e 1// Created on: 1993-05-07
2// Created by: Jean Yves LEBEY
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <TopOpeBRep_ShapeIntersector.ixx>
18
19#include <TopAbs.hxx>
20#include <Bnd_Box.hxx>
21#include <TopOpeBRepTool_box.hxx>
22#include <TopOpeBRep_define.hxx>
23
24#ifdef DEB
1d0a9d4d 25extern Standard_Boolean TopOpeBRep_GettraceSI();
26extern Standard_Boolean TopOpeBRep_GetcontextFFOR();
27extern Standard_Integer SAVFFi1; // FacesIntersector
28extern Standard_Integer SAVFFi2; // FacesIntersector
29extern void TopOpeBRep_SettraceEEFF(const Standard_Boolean b);
30extern Standard_Boolean TopOpeBRep_GettraceEEFF(const Standard_Integer e1,const Standard_Integer e2,const Standard_Integer f1,const Standard_Integer f2);
7fd59977 31void 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);}
33void seteefft(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_True,e1,e2,f1,f2);}
34void seteefff(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_False,e1,e2,f1,f2);}
35#endif
36
37// modified by NIZHNY-OFV Thu Apr 18 17:15:38 2002 (S)
38#include <TopoDS.hxx>
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>
48#include <TopExp.hxx>
49#include <gp_Pnt.hxx>
50#include <gp_Vec.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>
56static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2);
57static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F);
58// modified by NIZHNY-OFV Thu Apr 18 17:16:45 2002 (F)
59
60//=======================================================================
61//function : TopOpeBRep_ShapeIntersector
62//purpose :
63//=======================================================================
64
65TopOpeBRep_ShapeIntersector::TopOpeBRep_ShapeIntersector()
66{
67 Reset();
68 myFFIntersector.GetTolerances(myTol1,myTol2);
69 myHBoxTool = FBOX_GetHBoxTool();
70 myFaceScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
71 myEdgeScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
72}
73
74//=======================================================================
75//function : Reset
76//purpose :
77//=======================================================================
78
79void TopOpeBRep_ShapeIntersector::Reset()
80{
81 myIntersectionDone = Standard_False;
82
83 myFFDone = Standard_False;
84 myFFSameDomain = Standard_False;
85 myEEFFDone = Standard_False;
86 myEFDone = Standard_False;
87 myFEDone = Standard_False;
88 myEEDone = Standard_False;
89
90 myFFInit = Standard_False;
91 myEEFFInit = Standard_False;
92 myEFInit = Standard_False;
93 myFEInit = Standard_False;
94 myEEInit = Standard_False;
95}
96
97//=======================================================================
98//function : Init
99//purpose :
100//=======================================================================
101
102void TopOpeBRep_ShapeIntersector::Init
103(const TopoDS_Shape& S1, const TopoDS_Shape& S2)
104{
105 Reset();
106 myShape1 = S1;
107 myShape2 = S2;
108}
109
110//=======================================================================
111//function : SetIntersectionDone
112//purpose :
113//=======================================================================
114
115void TopOpeBRep_ShapeIntersector::SetIntersectionDone()
116{
117 myIntersectionDone = (myFFDone ||
118 myEEFFDone ||
119 myFEDone ||
120 myEFDone ||
121 myEEDone);
122}
123
124
125//=======================================================================
126//function : CurrentGeomShape
127//purpose :
128//=======================================================================
129
130const TopoDS_Shape& TopOpeBRep_ShapeIntersector::CurrentGeomShape
131 (const Standard_Integer Index) const
132{
133 if ( myIntersectionDone ) {
134 if (myFFDone) {
135 if ( Index == 1 ) return myFaceScanner.Current();
136 else if ( Index == 2 ) return myFaceExplorer.Current();
137 }
138 else if (myEEFFDone) {
139 if ( Index == 1 ) return myEdgeScanner.Current();
140 else if ( Index == 2 ) return myEdgeExplorer.Current();
141 }
142 else if (myFEDone) {
143 if ( Index == 1 ) return myFaceScanner.Current();
144 else if ( Index == 2 ) return myEdgeExplorer.Current();
145 }
146 else if (myEFDone) {
147 if ( Index == 1 ) return myEdgeScanner.Current();
148 else if ( Index == 2 ) return myFaceExplorer.Current();
149 }
150 else if (myEEDone) {
151 if ( Index == 1 ) return myEdgeScanner.Current();
152 else if ( Index == 2 ) return myEdgeExplorer.Current();
153 }
154 }
155
156 Standard_Failure::Raise("CurrentGeomShape : no intersection");
157 TopoDS_Shape* bid = new TopoDS_Shape();
158 return *bid;
159}
160//modified by NIZNHY-PKV Fri Sep 24 11:02:59 1999 from
161//=======================================================================
162//function : RejectedFaces
163//purpose :
164//=======================================================================
165void TopOpeBRep_ShapeIntersector::RejectedFaces (const TopoDS_Shape& anObj,
166 const TopoDS_Shape& aReference,
167 TopTools_ListOfShape& aListOfShape)
168{
169
170 Standard_Integer isHalfSpace = OneShapeIsHalfSpace( anObj, aReference );
171 if( isHalfSpace != 0 )
172 {
173 TopoDS_Face newRejectFace;
174 TopoDS_Solid newSolid;
175 aListOfShape.Clear();
176
177 if( isHalfSpace == 1 )
178 {
179 newSolid = GetNewSolid( anObj, newRejectFace );
180 Init( newSolid, aReference );
181
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 );
187
188 for(; myFaceExplorer.More(); myFaceExplorer.Next())
189 {
190 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
191 if(!aBS.Compare(myFaceExplorer.Current()).More())
192 {
193 const TopoDS_Shape& aS=myFaceExplorer.Current();
194 aListOfShape.Append (aS);
195 }
196 }
197
198 texplo = TopAbs_EDGE;
199 myFaceScanner.Clear();
200 myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
201 myFaceExplorer.Init( newSolid, texplo );
202
203 for(; myFaceExplorer.More(); myFaceExplorer.Next())
204 {
205 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
206 if(!aBS.Compare(myFaceExplorer.Current()).More())
207 {
208 const TopoDS_Shape& aS=myFaceExplorer.Current();
209 aListOfShape.Append (aS);
210 }
211 }
212 }
213 else
214 {
215 newSolid = GetNewSolid( aReference, newRejectFace );
216 Init( anObj, newSolid );
217
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);
223
224 for(; myFaceExplorer.More(); myFaceExplorer.Next())
225 {
226 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
227 if(!aBS.Compare(myFaceExplorer.Current()).More())
228 {
229 const TopoDS_Shape& aS=myFaceExplorer.Current();
230 aListOfShape.Append (aS);
231 }
232 }
233
234 texplo = TopAbs_EDGE;
235 myFaceScanner.Clear();
236 myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
237 myFaceExplorer.Init( anObj, texplo );
238
239 for(; myFaceExplorer.More(); myFaceExplorer.Next())
240 {
241 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
242 if(!aBS.Compare(myFaceExplorer.Current()).More())
243 {
244 const TopoDS_Shape& aS=myFaceExplorer.Current();
245 aListOfShape.Append (aS);
246 }
247 }
248 }
249 // remove all shapes of < newRejectFace > from list
250 TopExp_Explorer ExpRF(newRejectFace, TopAbs_EDGE);
251 for(; ExpRF.More(); ExpRF.Next() )
252 {
253 const TopoDS_Edge& edgef = TopoDS::Edge( ExpRF.Current() );
254 TopTools_ListIteratorOfListOfShape it( aListOfShape );
255 for(; it.More(); it.Next() )
256 {
257 const TopoDS_Shape& shape = it.Value();
258
259 if( shape.ShapeType() != TopAbs_EDGE )
260 continue;
261
262 const TopoDS_Edge& edgel = TopoDS::Edge( shape );
263 if( edgef.IsSame( edgel ) )
264 {
265 aListOfShape.Remove(it);
266 break;
267 }
268 }
269 }
270 TopTools_ListIteratorOfListOfShape it( aListOfShape );
271 for(; it.More(); it.Next() )
272 {
273 const TopoDS_Shape& shape = it.Value();
274
275 if( shape.ShapeType() != TopAbs_FACE )
276 continue;
277
278 const TopoDS_Face& facel = TopoDS::Face( shape );
279 if( facel.IsSame( newRejectFace ) )
280 {
281 aListOfShape.Remove(it);
282 break;
283 }
284 }
285
286 Init(anObj, aReference);
287 return;
288 }
289
290 Init(anObj, aReference);
291
292 aListOfShape.Clear();
293 //find faces to reject
294
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);
300
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);
306 }
307 }
308
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);
314
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);
320 }
321 }
322
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);
328
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);
334 }
335 }
336*/
337}
338//modified by NIZNHY-PKV Fri Sep 24 11:03:02 1999 to
339
340
341
342
343//=======================================================================
344//function : InitIntersection
345//purpose :
346//=======================================================================
347
348 void TopOpeBRep_ShapeIntersector::InitIntersection (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
349{
350 Init(S1,S2);
351
352 InitFFIntersection();
353 if ( MoreFFCouple() ) return;
354
355 InitFEIntersection();
356 if ( MoreFECouple() ) return;
357
358 InitEFIntersection();
359 if ( MoreEFCouple() ) return;
360}
361
362
363//=======================================================================
364//function : InitIntersection
365//purpose :
366//=======================================================================
367
368void TopOpeBRep_ShapeIntersector::InitIntersection
369 (const TopoDS_Shape& S1, const TopoDS_Shape& S2,
370 const TopoDS_Face& F1, const TopoDS_Face& F2)
371{
372 Init(S1,S2);
373
374 myEEFace1 = F1;
375 myEEFace2 = F2;
376
377 InitEEIntersection();
378}
379
380
381//=======================================================================
382//function : MoreIntersection
383//purpose :
384//=======================================================================
385
386Standard_Boolean TopOpeBRep_ShapeIntersector::MoreIntersection() const
387{
388 Standard_Boolean res = myIntersectionDone;
389
390#ifdef DEB
7fd59977 391 if (TopOpeBRep_GettraceSI() && res) {
392 if ( myFFDone ) cout<<"FF : ";
393 else if ( myEEFFDone ) cout<<" EE : ";
394 DumpCurrent(1);
395 DumpCurrent(2);
396 if ( myFFDone && myFFSameDomain ) cout<<"(FF SameDomain)";
397 else if ( myEEFFDone ) cout<<"(EE of FF SameDomain)";
398 else if ( myEEDone ) cout<<"EE : ";
399 cout<<endl;
400 if (myEEFFDone) {
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);
409 }
410 }
411#endif
412
413 return res;
414}
415
416
417//=======================================================================
418//function : DumpCurrent
419//purpose :
420//=======================================================================
421
498ce76b 422#ifdef DEB
7fd59977 423void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer K) const
424{
7fd59977 425 if ( myFFDone ) {
426 if ( K == 1 ) myFaceScanner.DumpCurrent(cout);
427 else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout);
428 }
429 else if ( myEEFFDone ) {
430 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
431 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
432 }
433 else if ( myFEDone ) {
434 if ( K == 1 ) myFaceScanner.DumpCurrent(cout);
435 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
436 }
437 else if ( myEFDone ) {
438 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
439 else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout);
440 }
441 else if ( myEEDone ) {
442 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
443 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
444 }
7fd59977 445}
498ce76b 446#else
447void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer) const {}
448#endif
7fd59977 449
450//=======================================================================
451//function : Index
452//purpose :
453//=======================================================================
454
498ce76b 455#ifdef DEB
7fd59977 456Standard_Integer TopOpeBRep_ShapeIntersector::Index
457(const Standard_Integer K)const
458{
459 Standard_Integer i = 0;
498ce76b 460
7fd59977 461 if ( myFFDone ) {
462 if ( K == 1 ) i = myFaceScanner.Index();
463 else if ( K == 2 ) i = myFaceExplorer.Index();
464 }
465 else if ( myEEFFDone ) {
466 if ( K == 1 ) i = myEdgeScanner.Index();
467 else if ( K == 2 ) i = myEdgeExplorer.Index();
468 }
469 else if ( myFEDone ) {
470 if ( K == 1 ) i = myFaceScanner.Index();
471 else if ( K == 2 ) i = myEdgeExplorer.Index();
472 }
473 else if ( myEFDone ) {
474 if ( K == 1 ) i = myEdgeScanner.Index();
475 else if ( K == 2 ) i = myFaceExplorer.Index();
476 }
477 else if ( myEEDone ) {
478 if ( K == 1 ) i = myEdgeScanner.Index();
479 else if ( K == 2 ) i = myEdgeExplorer.Index();
480 }
7fd59977 481 return i;
482}
498ce76b 483#else
484Standard_Integer TopOpeBRep_ShapeIntersector::Index (const Standard_Integer)const
485{
486 return 0;
487}
488#endif
7fd59977 489
490
491//=======================================================================
492//function : NextIntersection
493//purpose :
494//=======================================================================
495
496void TopOpeBRep_ShapeIntersector::NextIntersection()
497{
498 myIntersectionDone = Standard_False;
499
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 ) {
507 NextFFCouple();
508 FindFFIntersection();
509 }
510 }
511 else if (myFFDone) {
512 NextFFCouple();
513 FindFFIntersection();
514 }
515 else if ( myEEFFDone ) {
516 NextEEFFCouple();
517 FindEEFFIntersection();
518 if ( !myIntersectionDone ) {
519 NextFFCouple();
520 FindFFIntersection();
521 }
522 }
523 else if ( myFEDone ) {
524 NextFECouple();
525 FindFEIntersection();
526 }
527 else if ( myEFDone ) {
528 NextEFCouple();
529 FindEFIntersection();
530 }
531 else if ( myEEDone ) {
532 NextEECouple();
533 FindEEIntersection();
534 }
535
536 if ( !myIntersectionDone ) {
537 InitFFIntersection();
538 }
539
540 if ( !myIntersectionDone ) {
541 InitFEIntersection();
542 }
543
544 if ( !myIntersectionDone ) {
545 InitEFIntersection();
546 }
547
548 if ( !myIntersectionDone ) {
549 if ( !myEEFace1.IsNull() && !myEEFace2.IsNull() ) {
550 InitEEIntersection();
551 }
552 }
553
554}
555
556
557// ========
558// FFFFFFFF
559// ========
560
561
562//=======================================================================
563//function : InitFFIntersection
564//purpose :
565//=======================================================================
566
567void TopOpeBRep_ShapeIntersector::InitFFIntersection()
568{
569 if ( !myFFInit) {
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();
577 }
578 myFFInit = Standard_True;
579}
580
581
582//=======================================================================
583//function : FindFFIntersection
584//purpose :
585//=======================================================================
586
587void TopOpeBRep_ShapeIntersector::FindFFIntersection()
588{
589 myFFDone = Standard_False;
590 myFFSameDomain = Standard_False ;
591
592 while ( MoreFFCouple() ) {
593
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();
597
598#ifdef DEB
599 SAVFFi1 = myFaceScanner.Index(); SAVFFi2 = myFaceExplorer.Index();
600 if (TopOpeBRep_GettraceSI()) {
7fd59977 601 cout<<"?? FF : ";
602 myFaceScanner.DumpCurrent(cout); myFaceExplorer.DumpCurrent(cout);
603 cout<<endl;
604 }
605#endif
606
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
612 if (!ok) {
613 NextFFCouple();
614 continue;
615 }
616
617 myFFSameDomain = myFFIntersector.SameDomain();
618
619 if (myFFSameDomain) {
620 myFFDone = Standard_True;
621 break;
622 }
623 else {
624 myFFDone = ! (myFFIntersector.IsEmpty());
625
626 // update face/face intersection tolerances
627 if (myFFDone) {
628 Standard_Real tol1,tol2;
629 myFFIntersector.GetTolerances(tol1,tol2);
630 myTol1 = Max(myTol1,tol1); myTol2 = Max(myTol2,tol2);
631 }
632
633 if ( myFFDone ) {
634 break;
635 }
636 }
637
638 NextFFCouple();
639 }
640
641 SetIntersectionDone();
642}
643
644
645//=======================================================================
646//function : MoreFFCouple
647//purpose :
648//=======================================================================
649
650Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFFCouple() const
651{
652 Standard_Boolean more1 = myFaceScanner.More();
653 Standard_Boolean more2 = myFaceExplorer.More();
654 return (more1 && more2);
655}
656
657
658//=======================================================================
659//function : NextFFCouple
660//purpose :
661//=======================================================================
662
663void TopOpeBRep_ShapeIntersector::NextFFCouple()
664{
665 myFaceScanner.Next();
666 Standard_Boolean b1,b2;
667
668 b1 = (!myFaceScanner.More());
669 b2 = (myFaceExplorer.More());
670 while ( b1 && b2 ) {
671 myFaceExplorer.Next();
672 myFaceScanner.Init(myFaceExplorer);
673 b1 = (!myFaceScanner.More());
674 b2 = (myFaceExplorer.More());
675 }
676
677}
678
679
680// ========
681// EEFFEEFF
682// ========
683
684
685//=======================================================================
686//function : InitEEFFIntersection
687//purpose :
688//=======================================================================
689
690void TopOpeBRep_ShapeIntersector::InitEEFFIntersection()
691{
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
695
696#ifdef DEB
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;
701 }
702#endif
703
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);
708
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);
715
716 myEEFFInit = Standard_True;
717}
718
719
720//=======================================================================
721//function : FindEEFFIntersection
722//purpose :
723//=======================================================================
724
725void TopOpeBRep_ShapeIntersector::FindEEFFIntersection()
726{
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);
732
733#ifdef DEB
7fd59977 734 if (TopOpeBRep_GettraceSI() && myEEIntersector.IsEmpty()) {
735 cout<<" EE : ";
736 myEdgeScanner.DumpCurrent(cout);
737 myEdgeExplorer.DumpCurrent(cout);
738 cout<<"(EE of FF SameDomain)";
739 cout<<" : EMPTY INTERSECTION";
740 cout<<endl;
741 }
742#endif
743
744 myEEFFDone = ! (myEEIntersector.IsEmpty());
745 if (myEEFFDone) break;
746 else NextEEFFCouple();
747 }
748 SetIntersectionDone();
749}
750
751
752//=======================================================================
753//function : MoreEEFFCouple
754//purpose :
755//=======================================================================
756
757Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEEFFCouple() const
758{
759 Standard_Boolean more1 = myEdgeScanner.More();
760 Standard_Boolean more2 = myEdgeExplorer.More();
761 return (more1 && more2);
762}
763
764
765//=======================================================================
766//function : NextEEFFCouple
767//purpose :
768//=======================================================================
769
770void TopOpeBRep_ShapeIntersector::NextEEFFCouple()
771{
772 myEdgeScanner.Next();
773 while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
774 myEdgeExplorer.Next();
775 myEdgeScanner.Init(myEdgeExplorer);
776 }
777}
778
779
780// ========
781// FEFEFEFE
782// ========
783
784
785//=======================================================================
786//function : InitFEIntersection
787//purpose :
788//=======================================================================
789
790void TopOpeBRep_ShapeIntersector::InitFEIntersection()
791{
792 if ( !myFEInit) {
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();
800 }
801 myFEInit = Standard_True;
802}
803
804
805//=======================================================================
806//function : FindFEIntersection
807//purpose :
808//=======================================================================
809
810void TopOpeBRep_ShapeIntersector::FindFEIntersection()
811{
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());
818 if (myFEDone) break;
819 else NextFECouple();
820 }
821 SetIntersectionDone();
822}
823
824
825//=======================================================================
826//function : MoreFECouple
827//purpose :
828//=======================================================================
829
830Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFECouple() const
831{
832 Standard_Boolean more1 = myFaceScanner.More();
833 Standard_Boolean more2 = myEdgeExplorer.More();
834 return (more1 && more2);
835}
836
837
838//=======================================================================
839//function : NextFECouple
840//purpose :
841//=======================================================================
842
843void TopOpeBRep_ShapeIntersector::NextFECouple()
844{
845 myFaceScanner.Next();
846 while ( ! myFaceScanner.More() && myEdgeExplorer.More() ) {
847 myEdgeExplorer.Next();
848 myFaceScanner.Init(myEdgeExplorer);
849 }
850}
851
852
853// ========
854// EFEFEFEF
855// ========
856
857
858//=======================================================================
859//function : InitEFIntersection
860//purpose :
861//=======================================================================
862
863void TopOpeBRep_ShapeIntersector::InitEFIntersection()
864{
865 if ( !myEFInit) {
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();
873 }
874 myEFInit = Standard_True;
875}
876
877//=======================================================================
878//function : FindEFIntersection
879//purpose :
880//=======================================================================
881
882void TopOpeBRep_ShapeIntersector::FindEFIntersection()
883{
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());
890 if (myEFDone) break;
891 else NextEFCouple();
892 }
893 SetIntersectionDone();
894}
895
896
897//=======================================================================
898//function : MoreEFCouple
899//purpose :
900//=======================================================================
901
902Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEFCouple() const
903{
904 Standard_Boolean more1 = myEdgeScanner.More();
905 Standard_Boolean more2 = myFaceExplorer.More();
906 return (more1 && more2);
907}
908
909
910//=======================================================================
911//function : NextEFCouple
912//purpose :
913//=======================================================================
914
915void TopOpeBRep_ShapeIntersector::NextEFCouple()
916{
917 myEdgeScanner.Next();
918 while ( ! myEdgeScanner.More() && myFaceExplorer.More() ) {
919 myFaceExplorer.Next();
920 myEdgeScanner.Init(myFaceExplorer);
921 }
922}
923
924// ========
925// EEEEEEEE
926// ========
927
928//=======================================================================
929//function : InitEEIntersection
930//purpose :
931//=======================================================================
932
933void TopOpeBRep_ShapeIntersector::InitEEIntersection()
934{
935 if ( ! myEEInit ) {
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);
942
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();
950 }
951 myEEInit = Standard_True;
952}
953
954
955//=======================================================================
956//function : FindEEIntersection
957//purpose :
958//=======================================================================
959
960void TopOpeBRep_ShapeIntersector::FindEEIntersection()
961{
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());
968 if (myEEDone) break;
969 else NextEECouple();
970 }
971 SetIntersectionDone();
972}
973
974
975//=======================================================================
976//function : MoreEECouple
977//purpose :
978//=======================================================================
979
980Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEECouple() const
981{
982 Standard_Boolean more1 = myEdgeScanner.More();
983 Standard_Boolean more2 = myEdgeExplorer.More();
984 return (more1 && more2);
985}
986
987
988//=======================================================================
989//function : NextEECouple
990//purpose :
991//=======================================================================
992
993void TopOpeBRep_ShapeIntersector::NextEECouple()
994{
995 myEdgeScanner.Next();
996 while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
997 myEdgeExplorer.Next();
998 myEdgeScanner.Init(myEdgeExplorer);
999 }
1000}
1001
1002
1003//=======================================================================
1004//function : Shape
1005//purpose :
1006//=======================================================================
1007
1008const TopoDS_Shape& TopOpeBRep_ShapeIntersector::Shape
1009 ( const Standard_Integer Index )const
1010{
1011 if ( Index == 1 ) return myShape1;
1012 else if ( Index == 2 ) return myShape2;
1013
1014 Standard_Failure::Raise("ShapeIntersector : no shape");
1015 TopoDS_Shape* bid = new TopoDS_Shape();
1016 return *bid;
1017}
1018
1019
1020//=======================================================================
1021//function : ChangeFacesIntersector
1022//purpose :
1023//=======================================================================
1024
1025TopOpeBRep_FacesIntersector&
1026TopOpeBRep_ShapeIntersector::ChangeFacesIntersector()
1027{ return myFFIntersector; }
1028
1029
1030//=======================================================================
1031//function : ChangeEdgesIntersector
1032//purpose :
1033//=======================================================================
1034
1035TopOpeBRep_EdgesIntersector&
1036TopOpeBRep_ShapeIntersector::ChangeEdgesIntersector()
1037{ return myEEIntersector; }
1038
1039
1040//=======================================================================
1041//function : ChangeFaceEdgeIntersector
1042//purpose :
1043//=======================================================================
1044
1045TopOpeBRep_FaceEdgeIntersector&
1046TopOpeBRep_ShapeIntersector::ChangeFaceEdgeIntersector()
1047{ return myFEIntersector; }
1048
1049
1050//=======================================================================
1051//function : GetTolerances
1052//purpose :
1053//=======================================================================
1054
1055void TopOpeBRep_ShapeIntersector::GetTolerances(Standard_Real& tol1,
1056 Standard_Real& tol2)const
1057{ tol1 = myTol1; tol2 = myTol2; }
1058
1059
1060
1061
1062//=======================================================================
1063//function : IsHalfSpaceShape
1064//purpose : tries to define if one of solids is a half space object
1065// returns:
1066// 0 - no half spaces ( default )
1067// 1 - half space is S1
1068// 2 - half space is S2
1069//=======================================================================
1070static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
1071{
1072 Standard_Integer result = 0;
1073
1074 if( S1.ShapeType() == TopAbs_SOLID && S2.ShapeType() == TopAbs_SOLID )
1075 {
1076 TopExp_Explorer ExpSol1(S1, TopAbs_FACE);
1077 TopExp_Explorer ExpSol2(S2, TopAbs_FACE);
1078 Standard_Integer NbFacesSol1 = 0;
1079 Standard_Integer NbFacesSol2 = 0;
1080
1081 for(; ExpSol1.More(); ExpSol1.Next() )
1082 NbFacesSol1++;
1083
1084 for(; ExpSol2.More(); ExpSol2.Next() )
1085 NbFacesSol2++;
1086
1087 if( NbFacesSol1 == 0 || NbFacesSol2 == 0 ) // strange solids!!!
1088 return result;
1089 if( NbFacesSol1 == 1 && NbFacesSol2 == 1 ) // both shapes are half spaces ???
1090 return result;
1091
1092 if( (NbFacesSol1 == 1 && NbFacesSol2 >= 2) || (NbFacesSol2 == 1 && NbFacesSol1 >= 2) )
1093 {
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.
1098
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.
1105
1106 TopExp_Explorer SolidExplorer;
1107 TopoDS_Face testFace;
1108
1109 if( NbFacesSol1 == 1 )
1110 {
1111 for( SolidExplorer.Init(S1, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
1112 testFace = TopoDS::Face( SolidExplorer.Current() );
1113 }
1114 else
1115 {
1116 for( SolidExplorer.Init(S2, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
1117 testFace = TopoDS::Face( SolidExplorer.Current() );
1118 }
1119
1120 BRepAdaptor_Surface FSurf( testFace );
1121 Standard_Boolean SolidIsSphereOrTorus = Standard_False;
1122
1123 if( FSurf.GetType() == GeomAbs_Sphere || FSurf.GetType() == GeomAbs_Torus )
1124 {
1125 Standard_Real minU = FSurf.FirstUParameter();
1126 Standard_Real maxU = FSurf.LastUParameter();
1127 Standard_Real minV = FSurf.FirstVParameter();
1128 Standard_Real maxV = FSurf.LastVParameter();
c6541a0c 1129 Standard_Boolean yesU = ( Abs(minU - 0.) < 1.e-9 && Abs(maxU - 2*M_PI) < 1.e-9 );
7fd59977 1130 Standard_Boolean yesV = ( FSurf.GetType() == GeomAbs_Sphere ) ?
c6541a0c
D
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 );
7fd59977 1133 SolidIsSphereOrTorus = ( yesU && yesV );
1134 }
1135
1136 if( FSurf.GetType() == GeomAbs_SurfaceOfRevolution )
1137 {
1138 Standard_Boolean areBothPeriodic = ( FSurf.IsUPeriodic() && FSurf.IsVPeriodic() );
1139 if( areBothPeriodic )
1140 {
c6541a0c
D
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 );
7fd59977 1143 SolidIsSphereOrTorus = ( yesU && yesV );
1144 }
1145 }
1146
1147 if( SolidIsSphereOrTorus )
1148 return result;
1149
1150 Standard_Boolean SecondShellOk = Standard_True;
1151 TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1152 aMapEF.Clear();
1153 Standard_Integer NbEdges = 0, NbFaces = 0, iE = 0;
1154
1155 if( NbFacesSol1 == 1 )
1156 TopExp::MapShapesAndAncestors(S2, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1157 else
1158 TopExp::MapShapesAndAncestors(S1, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1159
1160 NbEdges = aMapEF.Extent();
1161 for( iE = 1; iE <= NbEdges; iE++)
1162 {
1163 const TopTools_ListOfShape& listFaces = aMapEF.FindFromIndex( iE );
1164 NbFaces = listFaces.Extent();
1165 if( NbFaces != 2 )
1166 {
1167 SecondShellOk = Standard_False;
1168 break;
1169 }
1170 }
1171 aMapEF.Clear();
1172
1173 if( SecondShellOk )
1174 result = (NbFacesSol1 == 1) ? 1 : 2;
1175 }
1176 else
1177 {
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.
1183 //
1184 // so this suggestion must be developed carefully. while we don't classify it!
1185 // *****************************************************************************
1186 }
63c629aa 1187#ifdef TOPOPEBREP_DEB
7fd59977 1188 if( result != 0 )
1189 cout << "# one of the SOLIDs probably is a HALF SPACE" << endl;
1190#endif
1191 }
1192
1193 return result;
1194}
1195
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//=======================================================================
1202static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F)
1203{
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
1207 // previous one.
1208
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
1212 // and location.
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.
1218
1219 TopExp_Explorer ShapeExplorer;
1220
1221 TopoDS_Face hsFace;
1222
1223 for( ShapeExplorer.Init(S, TopAbs_FACE); ShapeExplorer.More(); ShapeExplorer.Next() )
1224 hsFace = TopoDS::Face( ShapeExplorer.Current() );
1225
1226 BRepAdaptor_Surface ASurf( hsFace );
1227
1228 Standard_Real MinU = ASurf.FirstUParameter();
1229 Standard_Real MaxU = ASurf.LastUParameter();
1230 Standard_Real MinV = ASurf.FirstVParameter();
1231 Standard_Real MaxV = ASurf.LastUParameter();
1232
1233 Standard_Real MidU = (MaxU + MinU) * 0.5;
1234 Standard_Real MidV = (MaxV + MinV) * 0.5;
1235
1236 gp_Pnt MidP;
1237 gp_Vec SurfDU, SurfDV;
1238 ASurf.D1( MidU, MidV, MidP, SurfDU, SurfDV );
1239
1240 gp_Vec Normal = SurfDU.Crossed( SurfDV );
1241
1242 if( hsFace.Orientation() == TopAbs_FORWARD )
1243 Normal *= -1.e+10;
1244 else
1245 Normal *= 1.e+10;
1246
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. );
1251
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 );
1257
1258 P1.Translate( Normal );
1259 P2.Translate( Normal );
1260 P3.Translate( Normal );
1261 P4.Translate( Normal );
1262
1263 BRepLib_MakeEdge mke1( P1, P2 );
1264 BRepLib_MakeEdge mke2( P2, P4 );
1265 BRepLib_MakeEdge mke3( P4, P3 );
1266 BRepLib_MakeEdge mke4( P3, P1 );
1267
1268 TopoDS_Edge e1 = mke1.Edge();
1269 TopoDS_Edge e2 = mke2.Edge();
1270 TopoDS_Edge e3 = mke3.Edge();
1271 TopoDS_Edge e4 = mke4.Edge();
1272
1273 BRepLib_MakeWire mkw( e1, e2, e3, e4 );
1274 TopoDS_Wire w = mkw.Wire();
1275
1276 BRepLib_MakeFace mkf( w );
1277 TopoDS_Face infFace = mkf.Face();
1278
1279 TopoDS_Shell newShell;
1280 TopoDS_Solid newSolid;
1281
1282 BRep_Builder newShellBuilder;
1283 newShellBuilder.MakeShell( newShell );
1284 newShellBuilder.Add( newShell, hsFace );
1285 newShellBuilder.Add( newShell, infFace );
ab860031 1286 newShell.Closed (BRep_Tool::IsClosed (newShell));
7fd59977 1287
1288 BRep_Builder newSolidBuilder;
1289 newSolidBuilder.MakeSolid( newSolid );
1290 newSolidBuilder.Add( newSolid, newShell );
1291
1292 F = infFace;
1293 return newSolid;
1294}