0024157: Parallelization of assembly part of BO
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <TopOpeBRep_ShapeIntersector.ixx>
23
24#include <TopAbs.hxx>
25#include <Bnd_Box.hxx>
26#include <TopOpeBRepTool_box.hxx>
27#include <TopOpeBRep_define.hxx>
28
29#ifdef DEB
1d0a9d4d 30extern Standard_Boolean TopOpeBRep_GettraceSI();
31extern Standard_Boolean TopOpeBRep_GetcontextFFOR();
32extern Standard_Integer SAVFFi1; // FacesIntersector
33extern Standard_Integer SAVFFi2; // FacesIntersector
34extern void TopOpeBRep_SettraceEEFF(const Standard_Boolean b);
35extern Standard_Boolean TopOpeBRep_GettraceEEFF(const Standard_Integer e1,const Standard_Integer e2,const Standard_Integer f1,const Standard_Integer f2);
7fd59977 36void seteeff(const Standard_Boolean b,const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2)
37{cout<<"b,e1,e2,f1,f2 : "<<b<<" "<<e1<<","<<e2<<","<<f1<<","<<f2<<endl;TopOpeBRep_SettraceEEFF(b);}
38void seteefft(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_True,e1,e2,f1,f2);}
39void seteefff(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_False,e1,e2,f1,f2);}
40#endif
41
42// modified by NIZHNY-OFV Thu Apr 18 17:15:38 2002 (S)
43#include <TopoDS.hxx>
44#include <TopoDS_Shape.hxx>
45#include <TopoDS_Solid.hxx>
46#include <TopoDS_Shell.hxx>
47#include <TopoDS_Face.hxx>
48#include <TopoDS_Wire.hxx>
49#include <TopoDS_Edge.hxx>
50#include <TopExp_Explorer.hxx>
51#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
52#include <TopTools_ListOfShape.hxx>
53#include <TopExp.hxx>
54#include <gp_Pnt.hxx>
55#include <gp_Vec.hxx>
56#include <BRepLib_MakeEdge.hxx>
57#include <BRepLib_MakeWire.hxx>
58#include <BRepLib_MakeFace.hxx>
59#include <BRep_Builder.hxx>
60#include <BRepAdaptor_Surface.hxx>
61static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2);
62static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F);
63// modified by NIZHNY-OFV Thu Apr 18 17:16:45 2002 (F)
64
65//=======================================================================
66//function : TopOpeBRep_ShapeIntersector
67//purpose :
68//=======================================================================
69
70TopOpeBRep_ShapeIntersector::TopOpeBRep_ShapeIntersector()
71{
72 Reset();
73 myFFIntersector.GetTolerances(myTol1,myTol2);
74 myHBoxTool = FBOX_GetHBoxTool();
75 myFaceScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
76 myEdgeScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
77}
78
79//=======================================================================
80//function : Reset
81//purpose :
82//=======================================================================
83
84void TopOpeBRep_ShapeIntersector::Reset()
85{
86 myIntersectionDone = Standard_False;
87
88 myFFDone = Standard_False;
89 myFFSameDomain = Standard_False;
90 myEEFFDone = Standard_False;
91 myEFDone = Standard_False;
92 myFEDone = Standard_False;
93 myEEDone = Standard_False;
94
95 myFFInit = Standard_False;
96 myEEFFInit = Standard_False;
97 myEFInit = Standard_False;
98 myFEInit = Standard_False;
99 myEEInit = Standard_False;
100}
101
102//=======================================================================
103//function : Init
104//purpose :
105//=======================================================================
106
107void TopOpeBRep_ShapeIntersector::Init
108(const TopoDS_Shape& S1, const TopoDS_Shape& S2)
109{
110 Reset();
111 myShape1 = S1;
112 myShape2 = S2;
113}
114
115//=======================================================================
116//function : SetIntersectionDone
117//purpose :
118//=======================================================================
119
120void TopOpeBRep_ShapeIntersector::SetIntersectionDone()
121{
122 myIntersectionDone = (myFFDone ||
123 myEEFFDone ||
124 myFEDone ||
125 myEFDone ||
126 myEEDone);
127}
128
129
130//=======================================================================
131//function : CurrentGeomShape
132//purpose :
133//=======================================================================
134
135const TopoDS_Shape& TopOpeBRep_ShapeIntersector::CurrentGeomShape
136 (const Standard_Integer Index) const
137{
138 if ( myIntersectionDone ) {
139 if (myFFDone) {
140 if ( Index == 1 ) return myFaceScanner.Current();
141 else if ( Index == 2 ) return myFaceExplorer.Current();
142 }
143 else if (myEEFFDone) {
144 if ( Index == 1 ) return myEdgeScanner.Current();
145 else if ( Index == 2 ) return myEdgeExplorer.Current();
146 }
147 else if (myFEDone) {
148 if ( Index == 1 ) return myFaceScanner.Current();
149 else if ( Index == 2 ) return myEdgeExplorer.Current();
150 }
151 else if (myEFDone) {
152 if ( Index == 1 ) return myEdgeScanner.Current();
153 else if ( Index == 2 ) return myFaceExplorer.Current();
154 }
155 else if (myEEDone) {
156 if ( Index == 1 ) return myEdgeScanner.Current();
157 else if ( Index == 2 ) return myEdgeExplorer.Current();
158 }
159 }
160
161 Standard_Failure::Raise("CurrentGeomShape : no intersection");
162 TopoDS_Shape* bid = new TopoDS_Shape();
163 return *bid;
164}
165//modified by NIZNHY-PKV Fri Sep 24 11:02:59 1999 from
166//=======================================================================
167//function : RejectedFaces
168//purpose :
169//=======================================================================
170void TopOpeBRep_ShapeIntersector::RejectedFaces (const TopoDS_Shape& anObj,
171 const TopoDS_Shape& aReference,
172 TopTools_ListOfShape& aListOfShape)
173{
174
175 Standard_Integer isHalfSpace = OneShapeIsHalfSpace( anObj, aReference );
176 if( isHalfSpace != 0 )
177 {
178 TopoDS_Face newRejectFace;
179 TopoDS_Solid newSolid;
180 aListOfShape.Clear();
181
182 if( isHalfSpace == 1 )
183 {
184 newSolid = GetNewSolid( anObj, newRejectFace );
185 Init( newSolid, aReference );
186
187 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
188 TopAbs_ShapeEnum texplo = TopAbs_FACE;
189 myFaceScanner.Clear();
190 myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
191 myFaceExplorer.Init( newSolid, texplo );
192
193 for(; myFaceExplorer.More(); myFaceExplorer.Next())
194 {
195 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
196 if(!aBS.Compare(myFaceExplorer.Current()).More())
197 {
198 const TopoDS_Shape& aS=myFaceExplorer.Current();
199 aListOfShape.Append (aS);
200 }
201 }
202
203 texplo = TopAbs_EDGE;
204 myFaceScanner.Clear();
205 myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
206 myFaceExplorer.Init( newSolid, texplo );
207
208 for(; myFaceExplorer.More(); myFaceExplorer.Next())
209 {
210 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
211 if(!aBS.Compare(myFaceExplorer.Current()).More())
212 {
213 const TopoDS_Shape& aS=myFaceExplorer.Current();
214 aListOfShape.Append (aS);
215 }
216 }
217 }
218 else
219 {
220 newSolid = GetNewSolid( aReference, newRejectFace );
221 Init( anObj, newSolid );
222
223 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
224 TopAbs_ShapeEnum texplo = TopAbs_FACE;
225 myFaceScanner.Clear();
226 myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
227 myFaceExplorer.Init( anObj, texplo);
228
229 for(; myFaceExplorer.More(); myFaceExplorer.Next())
230 {
231 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
232 if(!aBS.Compare(myFaceExplorer.Current()).More())
233 {
234 const TopoDS_Shape& aS=myFaceExplorer.Current();
235 aListOfShape.Append (aS);
236 }
237 }
238
239 texplo = TopAbs_EDGE;
240 myFaceScanner.Clear();
241 myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
242 myFaceExplorer.Init( anObj, texplo );
243
244 for(; myFaceExplorer.More(); myFaceExplorer.Next())
245 {
246 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
247 if(!aBS.Compare(myFaceExplorer.Current()).More())
248 {
249 const TopoDS_Shape& aS=myFaceExplorer.Current();
250 aListOfShape.Append (aS);
251 }
252 }
253 }
254 // remove all shapes of < newRejectFace > from list
255 TopExp_Explorer ExpRF(newRejectFace, TopAbs_EDGE);
256 for(; ExpRF.More(); ExpRF.Next() )
257 {
258 const TopoDS_Edge& edgef = TopoDS::Edge( ExpRF.Current() );
259 TopTools_ListIteratorOfListOfShape it( aListOfShape );
260 for(; it.More(); it.Next() )
261 {
262 const TopoDS_Shape& shape = it.Value();
263
264 if( shape.ShapeType() != TopAbs_EDGE )
265 continue;
266
267 const TopoDS_Edge& edgel = TopoDS::Edge( shape );
268 if( edgef.IsSame( edgel ) )
269 {
270 aListOfShape.Remove(it);
271 break;
272 }
273 }
274 }
275 TopTools_ListIteratorOfListOfShape it( aListOfShape );
276 for(; it.More(); it.Next() )
277 {
278 const TopoDS_Shape& shape = it.Value();
279
280 if( shape.ShapeType() != TopAbs_FACE )
281 continue;
282
283 const TopoDS_Face& facel = TopoDS::Face( shape );
284 if( facel.IsSame( newRejectFace ) )
285 {
286 aListOfShape.Remove(it);
287 break;
288 }
289 }
290
291 Init(anObj, aReference);
292 return;
293 }
294
295 Init(anObj, aReference);
296
297 aListOfShape.Clear();
298 //find faces to reject
299
300 TopAbs_ShapeEnum tscann = TopAbs_SOLID;
301 TopAbs_ShapeEnum texplo = TopAbs_FACE;
302 myFaceScanner.Clear();
303 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
304 myFaceExplorer.Init(anObj,texplo);
305
306 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
307 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
308 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
309 const TopoDS_Shape& aS=myFaceExplorer.Current();
310 aListOfShape.Append (aS);
311 }
312 }
313
314 //modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000
315 texplo = TopAbs_EDGE;
316 myFaceScanner.Clear();
317 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
318 myFaceExplorer.Init(anObj,texplo);
319
320 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
321 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
322 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
323 const TopoDS_Shape& aS=myFaceExplorer.Current();
324 aListOfShape.Append (aS);
325 }
326 }
327
328 //modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000
329/* texplo = TopAbs_VERTEX;
330 myFaceScanner.Clear();
331 myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
332 myFaceExplorer.Init(anObj,texplo);
333
334 for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
335 TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
336 if(!aBS.Compare(myFaceExplorer.Current()).More()) {
337 const TopoDS_Shape& aS=myFaceExplorer.Current();
338 aListOfShape.Append (aS);
339 }
340 }
341*/
342}
343//modified by NIZNHY-PKV Fri Sep 24 11:03:02 1999 to
344
345
346
347
348//=======================================================================
349//function : InitIntersection
350//purpose :
351//=======================================================================
352
353 void TopOpeBRep_ShapeIntersector::InitIntersection (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
354{
355 Init(S1,S2);
356
357 InitFFIntersection();
358 if ( MoreFFCouple() ) return;
359
360 InitFEIntersection();
361 if ( MoreFECouple() ) return;
362
363 InitEFIntersection();
364 if ( MoreEFCouple() ) return;
365}
366
367
368//=======================================================================
369//function : InitIntersection
370//purpose :
371//=======================================================================
372
373void TopOpeBRep_ShapeIntersector::InitIntersection
374 (const TopoDS_Shape& S1, const TopoDS_Shape& S2,
375 const TopoDS_Face& F1, const TopoDS_Face& F2)
376{
377 Init(S1,S2);
378
379 myEEFace1 = F1;
380 myEEFace2 = F2;
381
382 InitEEIntersection();
383}
384
385
386//=======================================================================
387//function : MoreIntersection
388//purpose :
389//=======================================================================
390
391Standard_Boolean TopOpeBRep_ShapeIntersector::MoreIntersection() const
392{
393 Standard_Boolean res = myIntersectionDone;
394
395#ifdef DEB
7fd59977 396 if (TopOpeBRep_GettraceSI() && res) {
397 if ( myFFDone ) cout<<"FF : ";
398 else if ( myEEFFDone ) cout<<" EE : ";
399 DumpCurrent(1);
400 DumpCurrent(2);
401 if ( myFFDone && myFFSameDomain ) cout<<"(FF SameDomain)";
402 else if ( myEEFFDone ) cout<<"(EE of FF SameDomain)";
403 else if ( myEEDone ) cout<<"EE : ";
404 cout<<endl;
405 if (myEEFFDone) {
406 Standard_Integer ie1 = myEdgeScanner.Index();
407 Standard_Integer ie2 = myEdgeExplorer.Index();
408 Standard_Integer if1 = myFaceScanner.Index();
409 Standard_Integer if2 = myFaceExplorer.Index();
410 cout<<" trc teeff 1 "<<ie1<<" "<<ie2<<" "<<if1<<" "<<if2<<"; # ie1 ie2 if1 if2"<<endl;
411 Standard_Boolean b = TopOpeBRep_GettraceEEFF(ie1,ie2,if1,if2);
412 if (b) seteefft(ie1,ie2,if1,if2);
413 else seteefff(ie1,ie2,if1,if2);
414 }
415 }
416#endif
417
418 return res;
419}
420
421
422//=======================================================================
423//function : DumpCurrent
424//purpose :
425//=======================================================================
426
498ce76b 427#ifdef DEB
7fd59977 428void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer K) const
429{
7fd59977 430 if ( myFFDone ) {
431 if ( K == 1 ) myFaceScanner.DumpCurrent(cout);
432 else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout);
433 }
434 else if ( myEEFFDone ) {
435 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
436 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
437 }
438 else if ( myFEDone ) {
439 if ( K == 1 ) myFaceScanner.DumpCurrent(cout);
440 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
441 }
442 else if ( myEFDone ) {
443 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
444 else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout);
445 }
446 else if ( myEEDone ) {
447 if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
448 else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
449 }
7fd59977 450}
498ce76b 451#else
452void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer) const {}
453#endif
7fd59977 454
455//=======================================================================
456//function : Index
457//purpose :
458//=======================================================================
459
498ce76b 460#ifdef DEB
7fd59977 461Standard_Integer TopOpeBRep_ShapeIntersector::Index
462(const Standard_Integer K)const
463{
464 Standard_Integer i = 0;
498ce76b 465
7fd59977 466 if ( myFFDone ) {
467 if ( K == 1 ) i = myFaceScanner.Index();
468 else if ( K == 2 ) i = myFaceExplorer.Index();
469 }
470 else if ( myEEFFDone ) {
471 if ( K == 1 ) i = myEdgeScanner.Index();
472 else if ( K == 2 ) i = myEdgeExplorer.Index();
473 }
474 else if ( myFEDone ) {
475 if ( K == 1 ) i = myFaceScanner.Index();
476 else if ( K == 2 ) i = myEdgeExplorer.Index();
477 }
478 else if ( myEFDone ) {
479 if ( K == 1 ) i = myEdgeScanner.Index();
480 else if ( K == 2 ) i = myFaceExplorer.Index();
481 }
482 else if ( myEEDone ) {
483 if ( K == 1 ) i = myEdgeScanner.Index();
484 else if ( K == 2 ) i = myEdgeExplorer.Index();
485 }
7fd59977 486 return i;
487}
498ce76b 488#else
489Standard_Integer TopOpeBRep_ShapeIntersector::Index (const Standard_Integer)const
490{
491 return 0;
492}
493#endif
7fd59977 494
495
496//=======================================================================
497//function : NextIntersection
498//purpose :
499//=======================================================================
500
501void TopOpeBRep_ShapeIntersector::NextIntersection()
502{
503 myIntersectionDone = Standard_False;
504
505 if (myFFSameDomain) {
506 // precedant etat du More() : 2 faces samedomain
507 myFFDone = Standard_False;
508 myFFSameDomain = Standard_False;
509 InitEEFFIntersection();
510 FindEEFFIntersection();
511 if ( !myIntersectionDone ) {
512 NextFFCouple();
513 FindFFIntersection();
514 }
515 }
516 else if (myFFDone) {
517 NextFFCouple();
518 FindFFIntersection();
519 }
520 else if ( myEEFFDone ) {
521 NextEEFFCouple();
522 FindEEFFIntersection();
523 if ( !myIntersectionDone ) {
524 NextFFCouple();
525 FindFFIntersection();
526 }
527 }
528 else if ( myFEDone ) {
529 NextFECouple();
530 FindFEIntersection();
531 }
532 else if ( myEFDone ) {
533 NextEFCouple();
534 FindEFIntersection();
535 }
536 else if ( myEEDone ) {
537 NextEECouple();
538 FindEEIntersection();
539 }
540
541 if ( !myIntersectionDone ) {
542 InitFFIntersection();
543 }
544
545 if ( !myIntersectionDone ) {
546 InitFEIntersection();
547 }
548
549 if ( !myIntersectionDone ) {
550 InitEFIntersection();
551 }
552
553 if ( !myIntersectionDone ) {
554 if ( !myEEFace1.IsNull() && !myEEFace2.IsNull() ) {
555 InitEEIntersection();
556 }
557 }
558
559}
560
561
562// ========
563// FFFFFFFF
564// ========
565
566
567//=======================================================================
568//function : InitFFIntersection
569//purpose :
570//=======================================================================
571
572void TopOpeBRep_ShapeIntersector::InitFFIntersection()
573{
574 if ( !myFFInit) {
575 TopAbs_ShapeEnum tscann = TopAbs_FACE;
576 TopAbs_ShapeEnum texplo = TopAbs_FACE;
577 myFaceScanner.Clear();
578 myFaceScanner.AddBoxesMakeCOB(myShape1,tscann);
579 myFaceExplorer.Init(myShape2,texplo);
580 myFaceScanner.Init(myFaceExplorer);
581 FindFFIntersection();
582 }
583 myFFInit = Standard_True;
584}
585
586
587//=======================================================================
588//function : FindFFIntersection
589//purpose :
590//=======================================================================
591
592void TopOpeBRep_ShapeIntersector::FindFFIntersection()
593{
594 myFFDone = Standard_False;
595 myFFSameDomain = Standard_False ;
596
597 while ( MoreFFCouple() ) {
598
599 // The two candidate intersecting GeomShapes GS1,GS2 and their types t1,t2
600 const TopoDS_Shape& GS1 = myFaceScanner.Current();
601 const TopoDS_Shape& GS2 = myFaceExplorer.Current();
602
603#ifdef DEB
604 SAVFFi1 = myFaceScanner.Index(); SAVFFi2 = myFaceExplorer.Index();
605 if (TopOpeBRep_GettraceSI()) {
7fd59977 606 cout<<"?? FF : ";
607 myFaceScanner.DumpCurrent(cout); myFaceExplorer.DumpCurrent(cout);
608 cout<<endl;
609 }
610#endif
611
612 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
613 const Bnd_Box& B1 = BS.Box(GS1);
614 const Bnd_Box& B2 = BS.Box(GS2);
615 myFFIntersector.Perform(GS1,GS2,B1,B2);
616 Standard_Boolean ok = myFFIntersector.IsDone(); //xpu210998
617 if (!ok) {
618 NextFFCouple();
619 continue;
620 }
621
622 myFFSameDomain = myFFIntersector.SameDomain();
623
624 if (myFFSameDomain) {
625 myFFDone = Standard_True;
626 break;
627 }
628 else {
629 myFFDone = ! (myFFIntersector.IsEmpty());
630
631 // update face/face intersection tolerances
632 if (myFFDone) {
633 Standard_Real tol1,tol2;
634 myFFIntersector.GetTolerances(tol1,tol2);
635 myTol1 = Max(myTol1,tol1); myTol2 = Max(myTol2,tol2);
636 }
637
638 if ( myFFDone ) {
639 break;
640 }
641 }
642
643 NextFFCouple();
644 }
645
646 SetIntersectionDone();
647}
648
649
650//=======================================================================
651//function : MoreFFCouple
652//purpose :
653//=======================================================================
654
655Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFFCouple() const
656{
657 Standard_Boolean more1 = myFaceScanner.More();
658 Standard_Boolean more2 = myFaceExplorer.More();
659 return (more1 && more2);
660}
661
662
663//=======================================================================
664//function : NextFFCouple
665//purpose :
666//=======================================================================
667
668void TopOpeBRep_ShapeIntersector::NextFFCouple()
669{
670 myFaceScanner.Next();
671 Standard_Boolean b1,b2;
672
673 b1 = (!myFaceScanner.More());
674 b2 = (myFaceExplorer.More());
675 while ( b1 && b2 ) {
676 myFaceExplorer.Next();
677 myFaceScanner.Init(myFaceExplorer);
678 b1 = (!myFaceScanner.More());
679 b2 = (myFaceExplorer.More());
680 }
681
682}
683
684
685// ========
686// EEFFEEFF
687// ========
688
689
690//=======================================================================
691//function : InitEEFFIntersection
692//purpose :
693//=======================================================================
694
695void TopOpeBRep_ShapeIntersector::InitEEFFIntersection()
696{
697 // prepare exploration of the edges of the two current SameDomain faces
698 TopoDS_Shape face1 = myFaceScanner.Current(); // -26-08-96
699 TopoDS_Shape face2 = myFaceExplorer.Current(); // -26-08-96
700
701#ifdef DEB
702 if (TopOpeBRep_GetcontextFFOR()) {
703 face1.Orientation(TopAbs_FORWARD); //-05/07
704 face2.Orientation(TopAbs_FORWARD); //-05/07
705 cout<<"ctx : InitEEFFIntersection : faces FORWARD"<<endl;
706 }
707#endif
708
709 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
710 const Bnd_Box& B1 = BS.Box(face1);
711 const Bnd_Box& B2 = BS.Box(face2);
712 myEEIntersector.SetFaces(face1,face2,B1,B2);
713
714 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
715 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
716 myEdgeScanner.Clear();
717 myEdgeScanner.AddBoxesMakeCOB(face1,tscann);
718 myEdgeExplorer.Init(face2,texplo);
719 myEdgeScanner.Init(myEdgeExplorer);
720
721 myEEFFInit = Standard_True;
722}
723
724
725//=======================================================================
726//function : FindEEFFIntersection
727//purpose :
728//=======================================================================
729
730void TopOpeBRep_ShapeIntersector::FindEEFFIntersection()
731{
732 myEEFFDone = Standard_False;
733 while ( MoreEEFFCouple() ) {
734 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
735 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
736 myEEIntersector.Perform(GS1,GS2);
737
738#ifdef DEB
7fd59977 739 if (TopOpeBRep_GettraceSI() && myEEIntersector.IsEmpty()) {
740 cout<<" EE : ";
741 myEdgeScanner.DumpCurrent(cout);
742 myEdgeExplorer.DumpCurrent(cout);
743 cout<<"(EE of FF SameDomain)";
744 cout<<" : EMPTY INTERSECTION";
745 cout<<endl;
746 }
747#endif
748
749 myEEFFDone = ! (myEEIntersector.IsEmpty());
750 if (myEEFFDone) break;
751 else NextEEFFCouple();
752 }
753 SetIntersectionDone();
754}
755
756
757//=======================================================================
758//function : MoreEEFFCouple
759//purpose :
760//=======================================================================
761
762Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEEFFCouple() const
763{
764 Standard_Boolean more1 = myEdgeScanner.More();
765 Standard_Boolean more2 = myEdgeExplorer.More();
766 return (more1 && more2);
767}
768
769
770//=======================================================================
771//function : NextEEFFCouple
772//purpose :
773//=======================================================================
774
775void TopOpeBRep_ShapeIntersector::NextEEFFCouple()
776{
777 myEdgeScanner.Next();
778 while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
779 myEdgeExplorer.Next();
780 myEdgeScanner.Init(myEdgeExplorer);
781 }
782}
783
784
785// ========
786// FEFEFEFE
787// ========
788
789
790//=======================================================================
791//function : InitFEIntersection
792//purpose :
793//=======================================================================
794
795void TopOpeBRep_ShapeIntersector::InitFEIntersection()
796{
797 if ( !myFEInit) {
798 TopAbs_ShapeEnum tscann = TopAbs_FACE;
799 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
800 myFaceScanner.Clear();
801 myFaceScanner.AddBoxesMakeCOB(myShape1,tscann);
802 myEdgeExplorer.Init(myShape2,texplo,TopAbs_FACE); // NYI defaut de spec
803 myFaceScanner.Init(myEdgeExplorer);
804 FindFEIntersection();
805 }
806 myFEInit = Standard_True;
807}
808
809
810//=======================================================================
811//function : FindFEIntersection
812//purpose :
813//=======================================================================
814
815void TopOpeBRep_ShapeIntersector::FindFEIntersection()
816{
817 myFEDone = Standard_False;
818 while ( MoreFECouple() ) {
819 const TopoDS_Shape& GS1 = myFaceScanner.Current();
820 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
821 myFEIntersector.Perform(GS1,GS2);
822 myFEDone = ! (myFEIntersector.IsEmpty());
823 if (myFEDone) break;
824 else NextFECouple();
825 }
826 SetIntersectionDone();
827}
828
829
830//=======================================================================
831//function : MoreFECouple
832//purpose :
833//=======================================================================
834
835Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFECouple() const
836{
837 Standard_Boolean more1 = myFaceScanner.More();
838 Standard_Boolean more2 = myEdgeExplorer.More();
839 return (more1 && more2);
840}
841
842
843//=======================================================================
844//function : NextFECouple
845//purpose :
846//=======================================================================
847
848void TopOpeBRep_ShapeIntersector::NextFECouple()
849{
850 myFaceScanner.Next();
851 while ( ! myFaceScanner.More() && myEdgeExplorer.More() ) {
852 myEdgeExplorer.Next();
853 myFaceScanner.Init(myEdgeExplorer);
854 }
855}
856
857
858// ========
859// EFEFEFEF
860// ========
861
862
863//=======================================================================
864//function : InitEFIntersection
865//purpose :
866//=======================================================================
867
868void TopOpeBRep_ShapeIntersector::InitEFIntersection()
869{
870 if ( !myEFInit) {
871 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
872 TopAbs_ShapeEnum texplo = TopAbs_FACE;
873 myEdgeScanner.Clear();
874 myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann, TopAbs_FACE); // NYI defaut de spec
875 myFaceExplorer.Init(myShape2,texplo);
876 myEdgeScanner.Init(myFaceExplorer);
877 FindEFIntersection();
878 }
879 myEFInit = Standard_True;
880}
881
882//=======================================================================
883//function : FindEFIntersection
884//purpose :
885//=======================================================================
886
887void TopOpeBRep_ShapeIntersector::FindEFIntersection()
888{
889 myEFDone = Standard_False;
890 while ( MoreEFCouple() ) {
891 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
892 const TopoDS_Shape& GS2 = myFaceExplorer.Current();
893 myFEIntersector.Perform(GS2,GS1);
894 myEFDone = ! (myFEIntersector.IsEmpty());
895 if (myEFDone) break;
896 else NextEFCouple();
897 }
898 SetIntersectionDone();
899}
900
901
902//=======================================================================
903//function : MoreEFCouple
904//purpose :
905//=======================================================================
906
907Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEFCouple() const
908{
909 Standard_Boolean more1 = myEdgeScanner.More();
910 Standard_Boolean more2 = myFaceExplorer.More();
911 return (more1 && more2);
912}
913
914
915//=======================================================================
916//function : NextEFCouple
917//purpose :
918//=======================================================================
919
920void TopOpeBRep_ShapeIntersector::NextEFCouple()
921{
922 myEdgeScanner.Next();
923 while ( ! myEdgeScanner.More() && myFaceExplorer.More() ) {
924 myFaceExplorer.Next();
925 myEdgeScanner.Init(myFaceExplorer);
926 }
927}
928
929// ========
930// EEEEEEEE
931// ========
932
933//=======================================================================
934//function : InitEEIntersection
935//purpose :
936//=======================================================================
937
938void TopOpeBRep_ShapeIntersector::InitEEIntersection()
939{
940 if ( ! myEEInit ) {
941 TopoDS_Shape face1 = myEEFace1.Oriented(TopAbs_FORWARD);
942 TopoDS_Shape face2 = myEEFace2.Oriented(TopAbs_FORWARD);
943 const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
944 const Bnd_Box& B1 = BS.Box(face1);
945 const Bnd_Box& B2 = BS.Box(face2);
946 myEEIntersector.SetFaces(face1,face2,B1,B2);
947
948 TopAbs_ShapeEnum tscann = TopAbs_EDGE;
949 TopAbs_ShapeEnum texplo = TopAbs_EDGE;
950 myEdgeScanner.Clear();
951 myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann);
952 myEdgeExplorer.Init(myShape2,texplo);
953 myEdgeScanner.Init(myEdgeExplorer);
954 FindEEIntersection();
955 }
956 myEEInit = Standard_True;
957}
958
959
960//=======================================================================
961//function : FindEEIntersection
962//purpose :
963//=======================================================================
964
965void TopOpeBRep_ShapeIntersector::FindEEIntersection()
966{
967 myEEDone = Standard_False;
968 while ( MoreEECouple() ) {
969 const TopoDS_Shape& GS1 = myEdgeScanner.Current();
970 const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
971 myEEIntersector.Perform(GS1,GS2);
972 myEEDone = ! (myEEIntersector.IsEmpty());
973 if (myEEDone) break;
974 else NextEECouple();
975 }
976 SetIntersectionDone();
977}
978
979
980//=======================================================================
981//function : MoreEECouple
982//purpose :
983//=======================================================================
984
985Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEECouple() const
986{
987 Standard_Boolean more1 = myEdgeScanner.More();
988 Standard_Boolean more2 = myEdgeExplorer.More();
989 return (more1 && more2);
990}
991
992
993//=======================================================================
994//function : NextEECouple
995//purpose :
996//=======================================================================
997
998void TopOpeBRep_ShapeIntersector::NextEECouple()
999{
1000 myEdgeScanner.Next();
1001 while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
1002 myEdgeExplorer.Next();
1003 myEdgeScanner.Init(myEdgeExplorer);
1004 }
1005}
1006
1007
1008//=======================================================================
1009//function : Shape
1010//purpose :
1011//=======================================================================
1012
1013const TopoDS_Shape& TopOpeBRep_ShapeIntersector::Shape
1014 ( const Standard_Integer Index )const
1015{
1016 if ( Index == 1 ) return myShape1;
1017 else if ( Index == 2 ) return myShape2;
1018
1019 Standard_Failure::Raise("ShapeIntersector : no shape");
1020 TopoDS_Shape* bid = new TopoDS_Shape();
1021 return *bid;
1022}
1023
1024
1025//=======================================================================
1026//function : ChangeFacesIntersector
1027//purpose :
1028//=======================================================================
1029
1030TopOpeBRep_FacesIntersector&
1031TopOpeBRep_ShapeIntersector::ChangeFacesIntersector()
1032{ return myFFIntersector; }
1033
1034
1035//=======================================================================
1036//function : ChangeEdgesIntersector
1037//purpose :
1038//=======================================================================
1039
1040TopOpeBRep_EdgesIntersector&
1041TopOpeBRep_ShapeIntersector::ChangeEdgesIntersector()
1042{ return myEEIntersector; }
1043
1044
1045//=======================================================================
1046//function : ChangeFaceEdgeIntersector
1047//purpose :
1048//=======================================================================
1049
1050TopOpeBRep_FaceEdgeIntersector&
1051TopOpeBRep_ShapeIntersector::ChangeFaceEdgeIntersector()
1052{ return myFEIntersector; }
1053
1054
1055//=======================================================================
1056//function : GetTolerances
1057//purpose :
1058//=======================================================================
1059
1060void TopOpeBRep_ShapeIntersector::GetTolerances(Standard_Real& tol1,
1061 Standard_Real& tol2)const
1062{ tol1 = myTol1; tol2 = myTol2; }
1063
1064
1065
1066
1067//=======================================================================
1068//function : IsHalfSpaceShape
1069//purpose : tries to define if one of solids is a half space object
1070// returns:
1071// 0 - no half spaces ( default )
1072// 1 - half space is S1
1073// 2 - half space is S2
1074//=======================================================================
1075static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
1076{
1077 Standard_Integer result = 0;
1078
1079 if( S1.ShapeType() == TopAbs_SOLID && S2.ShapeType() == TopAbs_SOLID )
1080 {
1081 TopExp_Explorer ExpSol1(S1, TopAbs_FACE);
1082 TopExp_Explorer ExpSol2(S2, TopAbs_FACE);
1083 Standard_Integer NbFacesSol1 = 0;
1084 Standard_Integer NbFacesSol2 = 0;
1085
1086 for(; ExpSol1.More(); ExpSol1.Next() )
1087 NbFacesSol1++;
1088
1089 for(; ExpSol2.More(); ExpSol2.Next() )
1090 NbFacesSol2++;
1091
1092 if( NbFacesSol1 == 0 || NbFacesSol2 == 0 ) // strange solids!!!
1093 return result;
1094 if( NbFacesSol1 == 1 && NbFacesSol2 == 1 ) // both shapes are half spaces ???
1095 return result;
1096
1097 if( (NbFacesSol1 == 1 && NbFacesSol2 >= 2) || (NbFacesSol2 == 1 && NbFacesSol1 >= 2) )
1098 {
1099 // if one solid has shell consisted of only a face but other one has valid closed
1100 // shell we can detect current boolean operation as operation with half space object.
1101 // if shell of second solid is not valid too we cann't detect what kind of objects
1102 // we try to perform. in this case we do nothing and just return.
1103
1104 // but before we must avoid shperes, toruses and solids with a face biult on spherical surfaces
1105 // of revolution (SSRFS) - solids with shell of one face:
1106 // sphere (U: 0, 2PI) (V: -PI/2, PI/2),
1107 // torus (U: 0, 2PI) (V: 0, 2PI).
1108 // SSRFS (U period = (PI), 2PI) (V period = (PI), 2PI)
1109 // these solids are not halfspaces.
1110
1111 TopExp_Explorer SolidExplorer;
1112 TopoDS_Face testFace;
1113
1114 if( NbFacesSol1 == 1 )
1115 {
1116 for( SolidExplorer.Init(S1, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
1117 testFace = TopoDS::Face( SolidExplorer.Current() );
1118 }
1119 else
1120 {
1121 for( SolidExplorer.Init(S2, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
1122 testFace = TopoDS::Face( SolidExplorer.Current() );
1123 }
1124
1125 BRepAdaptor_Surface FSurf( testFace );
1126 Standard_Boolean SolidIsSphereOrTorus = Standard_False;
1127
1128 if( FSurf.GetType() == GeomAbs_Sphere || FSurf.GetType() == GeomAbs_Torus )
1129 {
1130 Standard_Real minU = FSurf.FirstUParameter();
1131 Standard_Real maxU = FSurf.LastUParameter();
1132 Standard_Real minV = FSurf.FirstVParameter();
1133 Standard_Real maxV = FSurf.LastVParameter();
c6541a0c 1134 Standard_Boolean yesU = ( Abs(minU - 0.) < 1.e-9 && Abs(maxU - 2*M_PI) < 1.e-9 );
7fd59977 1135 Standard_Boolean yesV = ( FSurf.GetType() == GeomAbs_Sphere ) ?
c6541a0c
D
1136 ( Abs(minV - (-M_PI/2.)) < 1.e-9 && Abs(maxV - M_PI/2.) < 1.e-9 ) :
1137 ( Abs(minV - 0.) < 1.e-9 && Abs(maxV - 2*M_PI) < 1.e-9 );
7fd59977 1138 SolidIsSphereOrTorus = ( yesU && yesV );
1139 }
1140
1141 if( FSurf.GetType() == GeomAbs_SurfaceOfRevolution )
1142 {
1143 Standard_Boolean areBothPeriodic = ( FSurf.IsUPeriodic() && FSurf.IsVPeriodic() );
1144 if( areBothPeriodic )
1145 {
c6541a0c
D
1146 Standard_Boolean yesU = ( Abs(FSurf.UPeriod() - M_PI) < 1.e-9 || Abs(FSurf.UPeriod() - 2*M_PI) < 1.e-9 );
1147 Standard_Boolean yesV = ( Abs(FSurf.VPeriod() - M_PI) < 1.e-9 || Abs(FSurf.VPeriod() - 2*M_PI) < 1.e-9 );
7fd59977 1148 SolidIsSphereOrTorus = ( yesU && yesV );
1149 }
1150 }
1151
1152 if( SolidIsSphereOrTorus )
1153 return result;
1154
1155 Standard_Boolean SecondShellOk = Standard_True;
1156 TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1157 aMapEF.Clear();
1158 Standard_Integer NbEdges = 0, NbFaces = 0, iE = 0;
1159
1160 if( NbFacesSol1 == 1 )
1161 TopExp::MapShapesAndAncestors(S2, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1162 else
1163 TopExp::MapShapesAndAncestors(S1, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1164
1165 NbEdges = aMapEF.Extent();
1166 for( iE = 1; iE <= NbEdges; iE++)
1167 {
1168 const TopTools_ListOfShape& listFaces = aMapEF.FindFromIndex( iE );
1169 NbFaces = listFaces.Extent();
1170 if( NbFaces != 2 )
1171 {
1172 SecondShellOk = Standard_False;
1173 break;
1174 }
1175 }
1176 aMapEF.Clear();
1177
1178 if( SecondShellOk )
1179 result = (NbFacesSol1 == 1) ? 1 : 2;
1180 }
1181 else
1182 {
1183 // ************************** IMPORTANT !!! ************************************
1184 // both shells are of more than 2 faces. if both solids have invalid shells
1185 // we do nothing and just return. on the other hand if only one shell is valid
1186 // currently we should suppose that solid with invalid shell is a half space too,
1187 // but this is not always true.
1188 //
1189 // so this suggestion must be developed carefully. while we don't classify it!
1190 // *****************************************************************************
1191 }
1192#ifdef DEB
1193 if( result != 0 )
1194 cout << "# one of the SOLIDs probably is a HALF SPACE" << endl;
1195#endif
1196 }
1197
1198 return result;
1199}
1200
1201//=======================================================================
1202//function : GetNewSolid
1203//purpose : rebuild halfspace solid adding new "face on infinity"
1204// to build correct bounding box to classify carefully
1205// "rejected shapes".
1206//=======================================================================
1207static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F)
1208{
1209 // "new solid" is a new halfspace solid consists of two faces now: the first face is a face
1210 // used to build halfspace solid and the second face is a new "face on infinity" specially
1211 // created to constuct correct bounding box around halfspace solid with bounds more wide than
1212 // previous one.
1213
1214 // the following algorithm is used:
1215 // 1. get face used to build halfspace solid and calculate its normal, Min/Max (U,V) parameters,
1216 // four points lying on the surface of the face inside its restrictions, surface, tolerance
1217 // and location.
1218 // 2. define the direction into the halfspace solid and project four points along this direction
1219 // on infinite distance. then use those points to create "face on infinity".
1220 // 3. build new shell with two new faces and new "halfspace solid".
1221 // 4. return this solid and "face on infinity" to remove it and all its subshapes from the list
1222 // of rejected shapes.
1223
1224 TopExp_Explorer ShapeExplorer;
1225
1226 TopoDS_Face hsFace;
1227
1228 for( ShapeExplorer.Init(S, TopAbs_FACE); ShapeExplorer.More(); ShapeExplorer.Next() )
1229 hsFace = TopoDS::Face( ShapeExplorer.Current() );
1230
1231 BRepAdaptor_Surface ASurf( hsFace );
1232
1233 Standard_Real MinU = ASurf.FirstUParameter();
1234 Standard_Real MaxU = ASurf.LastUParameter();
1235 Standard_Real MinV = ASurf.FirstVParameter();
1236 Standard_Real MaxV = ASurf.LastUParameter();
1237
1238 Standard_Real MidU = (MaxU + MinU) * 0.5;
1239 Standard_Real MidV = (MaxV + MinV) * 0.5;
1240
1241 gp_Pnt MidP;
1242 gp_Vec SurfDU, SurfDV;
1243 ASurf.D1( MidU, MidV, MidP, SurfDU, SurfDV );
1244
1245 gp_Vec Normal = SurfDU.Crossed( SurfDV );
1246
1247 if( hsFace.Orientation() == TopAbs_FORWARD )
1248 Normal *= -1.e+10;
1249 else
1250 Normal *= 1.e+10;
1251
1252 Standard_Real Pu1 = MinU + Abs( (MaxU - MinU) / 4. );
1253 Standard_Real Pu2 = MinU + Abs( (MaxU - MinU) / 4. * 3. );
1254 Standard_Real Pv1 = MinV + Abs( (MaxV - MinV) / 4. );
1255 Standard_Real Pv2 = MinV + Abs( (MaxV - MinV) / 4. * 3. );
1256
1257 gp_Pnt P1, P2, P3, P4;
1258 ASurf.D0( Pu1, Pv1, P1 );
1259 ASurf.D0( Pu1, Pv2, P2 );
1260 ASurf.D0( Pu2, Pv1, P3 );
1261 ASurf.D0( Pu2, Pv2, P4 );
1262
1263 P1.Translate( Normal );
1264 P2.Translate( Normal );
1265 P3.Translate( Normal );
1266 P4.Translate( Normal );
1267
1268 BRepLib_MakeEdge mke1( P1, P2 );
1269 BRepLib_MakeEdge mke2( P2, P4 );
1270 BRepLib_MakeEdge mke3( P4, P3 );
1271 BRepLib_MakeEdge mke4( P3, P1 );
1272
1273 TopoDS_Edge e1 = mke1.Edge();
1274 TopoDS_Edge e2 = mke2.Edge();
1275 TopoDS_Edge e3 = mke3.Edge();
1276 TopoDS_Edge e4 = mke4.Edge();
1277
1278 BRepLib_MakeWire mkw( e1, e2, e3, e4 );
1279 TopoDS_Wire w = mkw.Wire();
1280
1281 BRepLib_MakeFace mkf( w );
1282 TopoDS_Face infFace = mkf.Face();
1283
1284 TopoDS_Shell newShell;
1285 TopoDS_Solid newSolid;
1286
1287 BRep_Builder newShellBuilder;
1288 newShellBuilder.MakeShell( newShell );
1289 newShellBuilder.Add( newShell, hsFace );
1290 newShellBuilder.Add( newShell, infFace );
1291
1292 BRep_Builder newSolidBuilder;
1293 newSolidBuilder.MakeSolid( newSolid );
1294 newSolidBuilder.Add( newSolid, newShell );
1295
1296 F = infFace;
1297 return newSolid;
1298}