0027067: Avoid use of virtual methods for implementation of destructors in legacy...
[occt.git] / src / BRepAlgo / BRepAlgo_BooleanOperation.cxx
CommitLineData
b311480e 1// Created on: 1993-10-15
2// Created by: Remi LEQUETTE
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#define TRC 0
18#define MODIF 1
19
42cf5bc1 20
7fd59977 21#include <BRep_Builder.hxx>
7fd59977 22#include <BRep_Tool.hxx>
42cf5bc1 23#include <BRepAlgo_BooleanOperation.hxx>
7fd59977 24#include <BRepBuilderAPI_Sewing.hxx>
25#include <BRepCheck.hxx>
26#include <BRepCheck_Edge.hxx>
27#include <BRepCheck_Shell.hxx>
42cf5bc1 28#include <BRepClass3d_SolidClassifier.hxx>
29#include <BRepLib.hxx>
30#include <BRepTools_Substitution.hxx>
7fd59977 31#include <TopExp.hxx>
42cf5bc1 32#include <TopExp_Explorer.hxx>
33#include <TopoDS.hxx>
34#include <TopoDS_Shape.hxx>
35#include <TopOpeBRep_DSFiller.hxx>
36#include <TopOpeBRepBuild_HBuilder.hxx>
37#include <TopOpeBRepBuild_Tools.hxx>
38#include <TopOpeBRepDS_BuildTool.hxx>
39#include <TopOpeBRepDS_DSX.hxx>
40#include <TopOpeBRepDS_HDataStructure.hxx>
41#include <TopOpeBRepTool_GeomTool.hxx>
42#include <TopOpeBRepTool_OutCurveType.hxx>
7fd59977 43#include <TopTools_IndexedMapOfShape.hxx>
42cf5bc1 44#include <TopTools_ListIteratorOfListOfShape.hxx>
45#include <TopTools_ListOfShape.hxx>
46#include <TopTools_MapOfShape.hxx>
7fd59977 47
42cf5bc1 48// sewing
0797d9d3 49#ifdef OCCT_DEBUG
1d0a9d4d 50extern Standard_Boolean TopOpeBRepTool_GetcontextNOSEW();
7fd59977 51#endif
52
53#define Opecom(st1,st2) (((st1)==TopAbs_IN) && ((st2)==TopAbs_IN))
54#define Opefus(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_OUT))
55#define Opecut(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_IN))
56
57// -------------------------------------------------------------------
58static void Sub_Classify(TopExp_Explorer& Ex,
59 const TopAbs_State St1,
60 TopTools_ListOfShape& Solids2,
61 BRep_Builder& BB,
62 TopTools_ListIteratorOfListOfShape& LIter,
63 TopoDS_Shape& myShape);
64
65
0797d9d3 66#ifdef OCCT_DEBUG
7fd59977 67Standard_IMPORT Standard_Integer TopOpeBRepTool_BOOOPE_CHECK_DEB;
68#endif
69
70//modified by NIZHNY-MZV Wed Apr 19 17:19:11 2000
71//see comments at the top of file TopOpeBRepBuild_Builder1.cxx
72//about using of this global variable
1d0a9d4d 73extern Standard_Boolean GLOBAL_USE_NEW_BUILDER;
7fd59977 74//
75//modified by NIZNHY-PKV Sun Dec 15 17:17:56 2002 f
1d0a9d4d 76extern void FDSCNX_Close();// see TopOpeBRepDS_connex.cxx
77extern void FDSSDM_Close();// see TopOpeBRepDS_samdom.cxx
7fd59977 78
79//=======================================================================
e6f550da 80//function : ~BRepAlgo_BooleanOperation
81//purpose :
7fd59977 82//=======================================================================
e6f550da 83BRepAlgo_BooleanOperation::~BRepAlgo_BooleanOperation()
7fd59977 84{
85 FDSSDM_Close();
86 FDSCNX_Close();
87}
88//modified by NIZNHY-PKV Sun Dec 15 17:17:58 2002 t
89
90//=======================================================================
91//function : BRepAlgoAPI_BooleanOperation
92//purpose :
93//=======================================================================
94 BRepAlgo_BooleanOperation::BRepAlgo_BooleanOperation(const TopoDS_Shape& S1,
95 const TopoDS_Shape& S2)
96: myS1(S1),myS2(S2),myBuilderCanWork(Standard_False)
97{
98 TopOpeBRepDS_BuildTool BT;
99 myHBuilder = new TopOpeBRepBuild_HBuilder(BT);
100}
101
102//=======================================================================
103//function : PerformDS
104//purpose :
105//=======================================================================
106 void BRepAlgo_BooleanOperation::PerformDS()
107{
108// const Standard_Boolean CheckShapes = Standard_True;
109
110 // create a data structure
111 Handle(TopOpeBRepDS_HDataStructure) HDS;
112 if (myHBuilder->DataStructure().IsNull())
113 HDS = new TopOpeBRepDS_HDataStructure();
114 else {
115 HDS = myHBuilder->DataStructure();
116 HDS->ChangeDS().Init();
117 }
118
0797d9d3 119#ifdef OCCT_DEBUG
7fd59977 120 TopOpeBRepDS_SettraceSPSX_HDS(HDS);
121#endif
122
123 // fill the data Structure
124 TopOpeBRep_DSFiller DSFiller;
125
126 // define face/face intersection tolerances
127 Standard_Boolean forcetoli = Standard_False;
128 if (forcetoli) {
7fd59977 129 Standard_Real tolarc=0,toltang=0;
7fd59977 130 TopOpeBRep_ShapeIntersector& tobsi = DSFiller.ChangeShapeIntersector();
131 TopOpeBRep_FacesIntersector& tobfi = tobsi.ChangeFacesIntersector();
132 tobfi.ForceTolerances(tolarc,toltang);
133 }
134 DSFiller.Insert(myS1,myS2,HDS);
135
0d969553
Y
136 // 020499 : JYL : reject if there is an edge of the SD
137 // not coded sameparameter and not degenerated
7fd59977 138 Standard_Boolean esp = HDS->EdgesSameParameter();
139 Standard_Boolean tede = Standard_True;
140 if (!esp) {
141 Standard_Integer i,n = HDS->NbShapes();
142 for (i = 1 ; i <= n; i++) {
143 const TopoDS_Shape& s = HDS->Shape(i);
144 if ( s.ShapeType() == TopAbs_EDGE ) {
145 const TopoDS_Edge& e = TopoDS::Edge(s);
146 Standard_Boolean sp = BRep_Tool::SameParameter(e);
147 Standard_Boolean de = BRep_Tool::Degenerated(e);
148 if ( !sp && !de ) {
149 tede = Standard_False;
150 break;
151 }
152 }
153 }
154 }
155 myBuilderCanWork = (esp || tede) ;
0797d9d3 156#ifdef OCCT_DEBUG
7fd59977 157 if (!esp) cout<<"BRepAlgo_BooleanOperation(DEB) some edges not SameParameter"<<endl;
158#endif
159 if (!myBuilderCanWork) return;
160
161 Standard_Real tol3dAPPROX = 1e-7;
162 Standard_Real tol2dAPPROX = 1e-7;
163 // set tolerance values used by the APPROX process
164
165 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
166 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
167 GTofBTofBuilder.SetTolerances(tol3dAPPROX,tol2dAPPROX);
168
169 //modified by NIZHNY-MZV Thu Apr 20 09:35:44 2000
170 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
171 //about using of this global variable
172 GLOBAL_USE_NEW_BUILDER = Standard_True;
173 myHBuilder->Perform(HDS,myS1,myS2);
174 GLOBAL_USE_NEW_BUILDER = Standard_False;
175}
176
177//=======================================================================
178//function : Perform
179//purpose :
180//=======================================================================
181 void BRepAlgo_BooleanOperation::Perform(const TopAbs_State St1,
182 const TopAbs_State St2)
183{
184 if ( ! BuilderCanWork() ) {
185 return;
186 }
187
188 // modif JYL suite aux modifs LBR #if MODIF ...
189 // on privilegie le traitement KPart (si c'en est un)
190 // a tous les autres
191 Standard_Integer kp = myHBuilder->IsKPart();
192 BRep_Builder BB;
193 Standard_Boolean sewing = Standard_True;
194 if ( kp ) {
195 //modified by NIZHNY-MZV Thu Apr 20 09:34:33 2000
196 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
197 //about using of this global variable
198 GLOBAL_USE_NEW_BUILDER = Standard_True;
199 myHBuilder->MergeKPart(St1,St2);
200 GLOBAL_USE_NEW_BUILDER = Standard_False;
201
202 BB.MakeCompound(TopoDS::Compound(myShape));
203 Done();
204
205 TopTools_ListIteratorOfListOfShape its(myHBuilder->Merged(myS1,St1));
206 for(; its.More(); its.Next()) BB.Add(myShape,its.Value());
207
208 }
209 else {
210#if MODIF
211
212 //======================================================================
0d969553
Y
213 //== Exploration of input shapes
214 //== Creation of the list of solids
215 //== Creation of the list of faces OUT OF solid
216 //== Creation of the list of edges OUT OF face
7fd59977 217 Standard_Integer nbs1,nbs2,nbf1,nbf2,nbe1,nbe2,nbv1,nbv2;
218
219 TopTools_ListOfShape Solids1,Solids2,Faces1,Faces2,Edges1,Edges2,Vertex1,Vertex2;
220 TopExp_Explorer Ex;
221 for(Ex.Init(myS1,TopAbs_SOLID),nbs1=0; Ex.More(); Ex.Next()) {
222 Solids1.Append(Ex.Current()); nbs1++;
223 }
224 for(Ex.Init(myS2,TopAbs_SOLID),nbs2=0; Ex.More(); Ex.Next()) {
225 Solids2.Append(Ex.Current()); nbs2++;
226 }
0d969553 227 //== Faces not in a solid
7fd59977 228 for(Ex.Init(myS1,TopAbs_FACE,TopAbs_SOLID),nbf1=0; Ex.More(); Ex.Next()) {
229 Faces1.Append(Ex.Current()); nbf1++;
230 }
231 for(Ex.Init(myS2,TopAbs_FACE,TopAbs_SOLID),nbf2=0; Ex.More(); Ex.Next()) {
232 Faces2.Append(Ex.Current()); nbf2++;
233 }
0d969553 234 //== Edges not in a solid
7fd59977 235 for(Ex.Init(myS1,TopAbs_EDGE,TopAbs_FACE),nbe1=0; Ex.More(); Ex.Next()) {
236 Edges1.Append(Ex.Current()); nbe1++;
237 }
238 for(Ex.Init(myS2,TopAbs_EDGE,TopAbs_FACE),nbe2=0; Ex.More(); Ex.Next()) {
239 Edges2.Append(Ex.Current()); nbe2++;
240 }
0d969553 241 //== Vertices not in an edge
7fd59977 242 for(Ex.Init(myS1,TopAbs_VERTEX,TopAbs_EDGE),nbv1=0; Ex.More(); Ex.Next()) {
243 Vertex1.Append(Ex.Current()); nbv1++;
244 }
245 for(Ex.Init(myS2,TopAbs_VERTEX,TopAbs_EDGE),nbv2=0; Ex.More(); Ex.Next()) {
246 Vertex2.Append(Ex.Current()); nbv2++;
247 }
248
249 //-- cout<<"Solids1: "<<nbs1<<" Faces1: "<<nbf1<<" Edges1:"<<nbe1<<" Vtx1:"<<nbv1<<endl;
250 //-- cout<<"Solids2: "<<nbs2<<" Faces2: "<<nbf2<<" Edges2:"<<nbe2<<" Vtx2:"<<nbv2<<endl;
251
252 //==
253
0d969553 254 //== Reject operations without direction
7fd59977 255
256
0d969553 257 //-- Cut Solid by Edge
7fd59977 258// Standard_Boolean Correct = Standard_True;
259 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_IN)
260 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_IN)) {
261 //-- cout<<"***** Invalid Operation : Cut of a Solid by a Non Solid "<<endl;
262 Done();
263 return;
264 }
265
266 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_OUT)
267 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_OUT)) {
268 //-- cout<<"***** Invalid Operation : Fusion of a Solid and a Non Solid "<<endl;
269 Done();
270 return;
271 }
272
273
274 if( (nbs1>0 && nbs2>0)
275 && (nbe1 || nbe2 || nbf1 || nbf2 || nbv1 || nbv2)) {
276 //-- cout<<"***** Not Yet Implemented : Compound of solid and non Solid"<<endl;
277 Done();
278 return;
279 }
280 //======================================================================
281 // make a compound with the new solids
282 BB.MakeCompound(TopoDS::Compound(myShape));
283
284 TopTools_ListIteratorOfListOfShape LIter;
285 //----------------------------------------------------------------------
286 TopoDS_Shape SNULL;
287
288 if (nbf1 && nbf2) {
289 SNULL.Nullify();
290 if ( Opecom(St1,St2) ) {
291 TopTools_ListIteratorOfListOfShape itloe = myHBuilder->Section();
292 for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
293 }
294 else {
295 if(nbf1) {
296 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
297
298 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
299 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
300 TopTools_ListIteratorOfListOfShape its;
301 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
302 its.More();its.Next()) BB.Add(myShape,its.Value());
303 }
304 else {
305 const TopoDS_Shape& LV = LIter.Value();
306 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
307 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
308 BB.Add(myShape,LV);
309 }
310 else {
0d969553 311 //-- Classify :
7fd59977 312 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
313 }
0d969553 314 //-- End Classification
7fd59977 315 }
316 }
317 } // nbf1
318 SNULL.Nullify();
319 if ( Opefus(St1,St2) ) {
320 if(nbf2) {
321 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
322 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
323 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
324 TopTools_ListIteratorOfListOfShape its;
325 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
326 its.More();its.Next()) BB.Add(myShape,its.Value());
327 }
328 else {
329 const TopoDS_Shape& LV = LIter.Value();
330 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
331 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
332 BB.Add(myShape,LV);
333 }
334 else {
0d969553 335 //-- Classify :
7fd59977 336 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
337 }
0d969553 338 //-- End Classification
7fd59977 339 }
340 }
341 } // nbf2
342 } // Fus
343 }
344 } // nbf1 && nbf2
345 else if (nbf1 || nbf2) {
346 SNULL.Nullify();
347 if(nbf1) {
348 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
349 // modified by IFV for treating operation between shell and solid
350 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS1,St1);
351 TopTools_IndexedMapOfShape aMapOfFaces;
352
353 sewing = Standard_False;
354
355 if(MergedShapes.Extent() != 0) {
356 TopTools_ListIteratorOfListOfShape its(MergedShapes);
357 for(; its.More(); its.Next()) {
358 BB.Add(myShape,its.Value());
359 }
360 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
361 }
362
363 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
364
365 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
366 TopTools_ListIteratorOfListOfShape its;
367 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
368 its.More();its.Next()) {
369 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
370 }
371 }
372 else {
373 const TopoDS_Shape& LV = LIter.Value();
374 if(!aMapOfFaces.Contains(LV)) {
375 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
376 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
377 BB.Add(myShape,LV);
378 }
379 else {
0d969553 380 //-- Classify :
7fd59977 381 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
382 }
0d969553 383 //-- End Classification
7fd59977 384 }
385 }
386 }
387 } // nbf1
388 SNULL.Nullify();
389 if(nbf2) {
390 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
391 // modified by IFV for treating operation between shell and solid
392 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS2,St2);
393 TopTools_IndexedMapOfShape aMapOfFaces;
394 sewing = Standard_False;
395
396 if(MergedShapes.Extent() != 0) {
397 TopTools_ListIteratorOfListOfShape its(MergedShapes);
398 for(; its.More(); its.Next()) {
399 BB.Add(myShape,its.Value());
400 }
401 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
402 }
403
404 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
405 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
406 TopTools_ListIteratorOfListOfShape its;
407 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
408 its.More();its.Next()) {
409 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
410 }
411 }
412 else {
413 const TopoDS_Shape& LV = LIter.Value();
414 if(!aMapOfFaces.Contains(LV)) {
415 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
416 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
417 BB.Add(myShape,LV);
418 }
419 else {
0d969553 420 //-- Classify :
7fd59977 421 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
422 }
0d969553 423 //-- End Classification
7fd59977 424 }
425 }
426 }
427 } // nbf2
428 } // (nbf1 || nbf2)
429
430 //----------------------------------------------------------------------
431 if(nbe1) {
432 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
433
434 for(LIter.Initialize(Edges1);LIter.More();LIter.Next()) {
435 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
436 TopTools_ListIteratorOfListOfShape its;
437 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
438 its.More();its.Next()) {
439 BB.Add(myShape,its.Value());
440 }
441 }
442 else {
443 const TopoDS_Shape& LV = LIter.Value();
444 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
445 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
446 BB.Add(myShape,LV);
447 }
448 else {
0d969553 449 //-- Classify :
7fd59977 450 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
451 }
0d969553 452 //-- End Classification
7fd59977 453 }
454 }
455 }
456 if(nbe2) {
457 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
458
459 for(LIter.Initialize(Edges2);LIter.More();LIter.Next()) {
460 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
461 TopTools_ListIteratorOfListOfShape its;
462 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
463 its.More();its.Next()) {
464 BB.Add(myShape,its.Value());
465 }
466 }
467 else {
468 const TopoDS_Shape& LV = LIter.Value();
469 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
470 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
471 BB.Add(myShape,LV);
472 }
473 else {
0d969553 474 //-- Classify :
7fd59977 475 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
476 }
0d969553 477 //-- End Classification
7fd59977 478 }
479 }
480 }
481 //----------------------------------------------------------------------
0d969553
Y
482 //-- V1:Vertex1 state1 = OUT -> Preserve V1 if V1 is Out all S2
483 //-- V1:Vertex1 state1 = IN -> Preserve V1 if V1 is In one of S2
7fd59977 484 if(nbv1 && nbs2) {
485 if(St1 == TopAbs_IN) {
486 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
487 Standard_Boolean keep = Standard_False;
488 Standard_Boolean ok = Standard_True;
489 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
490 gp_Pnt P=BRep_Tool::Pnt(V);
491 Standard_Real Tol = BRep_Tool::Tolerance(V);
492 TopTools_ListIteratorOfListOfShape SIter;
493 for(SIter.Initialize(Solids2);
494 SIter.More() && ok==Standard_True;
495 SIter.Next()) {
496 BRepClass3d_SolidClassifier SolClass(SIter.Value());
497 SolClass.Perform(P,Tol);
498 if(SolClass.State() == TopAbs_IN) {
499 ok=Standard_False;
500 keep = Standard_True;
501 }
502 }
503 if(keep) {
504 BB.Add(myShape,LIter.Value());
505 }
506 }
507 }
508 else {
509 if(St1 == TopAbs_OUT) {
510 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
511 Standard_Boolean keep = Standard_True;
512 Standard_Boolean ok = Standard_True;
513 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
514 gp_Pnt P=BRep_Tool::Pnt(V);
515 Standard_Real Tol = BRep_Tool::Tolerance(V);
516 TopTools_ListIteratorOfListOfShape SIter;
517 for(SIter.Initialize(Solids2);
518 SIter.More() && ok==Standard_True;
519 SIter.Next()) {
520 BRepClass3d_SolidClassifier SolClass(SIter.Value());
521 SolClass.Perform(P,Tol);
522 if(SolClass.State() != TopAbs_OUT) {
523 keep = Standard_False;
524 ok = Standard_False;
525 }
526 }
527 if(keep) {
528 BB.Add(myShape,LIter.Value());
529 }
530 }
531 }
532 }
533 }
534
535 if(nbv2 && nbs1) {
536 if(St2 == TopAbs_IN) {
537 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
538 Standard_Boolean keep = Standard_False;
539 Standard_Boolean ok = Standard_True;
540 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
541 gp_Pnt P=BRep_Tool::Pnt(V);
542 Standard_Real Tol = BRep_Tool::Tolerance(V);
543 TopTools_ListIteratorOfListOfShape SIter;
544 for(SIter.Initialize(Solids1);
545 SIter.More() && ok==Standard_True;
546 SIter.Next()) {
547 BRepClass3d_SolidClassifier SolClass(SIter.Value());
548 SolClass.Perform(P,Tol);
549 if(SolClass.State() == TopAbs_IN) {
550 ok=Standard_False;
551 keep = Standard_True;
552 }
553 }
554 if(keep) {
555 BB.Add(myShape,LIter.Value());
556 }
557 }
558 }
559 else {
560 if(St2 == TopAbs_OUT) {
561 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
562 Standard_Boolean keep = Standard_True;
563 Standard_Boolean ok = Standard_True;
564 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
565 gp_Pnt P=BRep_Tool::Pnt(V);
566 Standard_Real Tol = BRep_Tool::Tolerance(V);
567 TopTools_ListIteratorOfListOfShape SIter;
568 for(SIter.Initialize(Solids1);
569 SIter.More() && ok==Standard_True;
570 SIter.Next()) {
571 BRepClass3d_SolidClassifier SolClass(SIter.Value());
572 SolClass.Perform(P,Tol);
573 if(SolClass.State() != TopAbs_OUT) {
574 keep = Standard_False;
575 ok = Standard_False;
576 }
577 }
578 if(keep) {
579 BB.Add(myShape,LIter.Value());
580 }
581 }
582 }
583 }
584 }
585
586 if(nbs1 && nbs2 ) {
587 myHBuilder->MergeShapes(myS1,St1,myS2,St2);
588 if(myHBuilder->IsMerged(myS1,St1)) {
589 TopTools_ListIteratorOfListOfShape its;
590 its = myHBuilder->Merged(myS1,St1);
591 Standard_Integer nbSolids = 0;
592 for(; its.More(); its.Next(), nbSolids++) {
593 BB.Add(myShape,its.Value());
594 }
595 }
596 }
597
598#else
599
600 myHBuilder->MergeSolids(myS1,St1,myS2,St2);
601 TopTools_ListIteratorOfListOfShape its;
602
603 BB.MakeCompound(TopoDS::Compound(myShape));
604 its = myHBuilder->Merged(myS1,St1);
605 while (its.More()) {
606 BB.Add(myShape,its.Value());
607 its.Next();
608 }
609
610#endif
611// #if MODIF
612
613 }
614
615 // Creation of the Map used in IsDeleted.
616 TopExp_Explorer ex;
617 ex.Init(myShape,TopAbs_FACE);
618 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
0d969553 619 ex.Init(myShape,TopAbs_EDGE); // for FRIKO
7fd59977 620 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
621
0d969553 622 // Checking same parameter of new edges of section
7fd59977 623 Standard_Real eTol,cTol;
624 for (myHBuilder->InitSection(1);
625 myHBuilder->MoreSection();
626 myHBuilder->NextSection()) {
627 const TopoDS_Shape& cur = myHBuilder->CurrentSection();
628 if (cur.ShapeType()==TopAbs_EDGE) {
629 BRepCheck_Edge bce(TopoDS::Edge(cur));
630 cTol=bce.Tolerance();
631 eTol = BRep_Tool::Tolerance(TopoDS::Edge(cur));
632 if (eTol<cTol) {
633 BB.UpdateEdge(TopoDS::Edge(cur), cTol);
634 for (ex.Init(cur, TopAbs_VERTEX); ex.More(); ex.Next()) {
635 eTol = BRep_Tool::Tolerance(TopoDS::Vertex(ex.Current()));
636 if (eTol<cTol) {
0d969553
Y
637 // Update can only increase tolerance, so if the vertex
638 // has a greater tolerance thanits edges it is not touched
7fd59977 639 BB.UpdateVertex(TopoDS::Vertex(ex.Current()), cTol);
640 }
641 }
642 }
643 }
644 }
645
646 Standard_Real maxTol = RealLast(); // MSV: unlimit tolerance
647 TopOpeBRepBuild_Tools::CorrectTolerances(myShape,maxTol);
648
649 TopExp_Explorer ex1, ex2, ex3;
650 TopTools_ListOfShape theOldShell, theNewShell;
651 Standard_Boolean modif =Standard_False;
652
0797d9d3 653#ifdef OCCT_DEBUG
7fd59977 654 Standard_Boolean nosew = TopOpeBRepTool_GetcontextNOSEW();
655 if (nosew) sewing = Standard_False;
656#endif
657
658 if (sewing) {
659 topToSew.Clear();
660 for (ex1.Init(myShape, TopAbs_SHELL); ex1.More(); ex1.Next()) {
661 BRepCheck_Shell bcs(TopoDS::Shell(ex1.Current()));
662 if (bcs.Closed()==BRepCheck_NotClosed) {
0d969553 663 // it is required to add them face by face to avoid IsModified on faces
7fd59977 664 BRepBuilderAPI_Sewing brts;
665 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
666 brts.Add(ex3.Current());
667 }
668 brts.Perform();
669 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
670 if (ex2.More()) {
671 ex2.Next();
672 if (!ex2.More()) {
673 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
674 theOldShell.Append(ex1.Current());
675 theNewShell.Append(ex2.Current());
676 modif =Standard_True;
677 for (ex3.Init(ex1.Current(), TopAbs_EDGE); ex3.More(); ex3.Next()) {
678 const TopoDS_Edge& ledg = TopoDS::Edge(ex3.Current());
679 if (brts.IsSectionBound(ledg)) {
680 topToSew.Bind(ledg, brts.SectionToBoundary(ledg));
681 if (!BRep_Tool::SameParameter(brts.SectionToBoundary(ledg))) {
682 BRepLib::SameParameter(ledg, BRep_Tool::Tolerance(brts.SectionToBoundary(ledg)));
683 }
684 }
685 }
686 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
687 if (brts.IsModified(ex3.Current())) {
688 topToSew.Bind(ex3.Current(), brts.Modified(ex3.Current()));
689 }
690 }
691 }
692 }
693 }
694 }
695 } // sewing
696
697 if (modif) {
698 BRepTools_Substitution bsub;
699 TopTools_ListIteratorOfListOfShape itl(theOldShell);
700 TopTools_ListOfShape forSub;
701 for (; itl.More();itl.Next()) {
702 forSub.Append(theNewShell.First());
703 bsub.Substitute(itl.Value(), forSub);
704 theNewShell.RemoveFirst();
705 forSub.Clear();
706 }
707 bsub.Build(myShape);
708 if (bsub.IsCopied(myShape)) {
709 myShape=(bsub.Copy(myShape)).First();
710 }
711 }
712
713 Done();
714}
715
716
717
718//=======================================================================
719//function : Builder
720//purpose :
721//=======================================================================
722 Handle(TopOpeBRepBuild_HBuilder) BRepAlgo_BooleanOperation::Builder()const
723{
724 return myHBuilder;
725}
726
727
728//=======================================================================
729//function : TopoDS_Shape&
730//purpose :
731//=======================================================================
732 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape1() const
733{
734 return myS1;
735}
736
737
738//=======================================================================
739//function : TopoDS_Shape&
740//purpose :
741//=======================================================================
742 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape2() const
743{
744 return myS2;
745}
746
747//=======================================================================
748//function : BuilderCanWork
749//purpose :
750//=======================================================================
751 void BRepAlgo_BooleanOperation::BuilderCanWork(const Standard_Boolean Val)
752{
753 myBuilderCanWork = Val;
754}
755
756//=======================================================================
757//function : BuilderCanWork
758//purpose :
759//=======================================================================
760 Standard_Boolean BRepAlgo_BooleanOperation::BuilderCanWork() const
761{
762 return myBuilderCanWork;
763}
764
765
766void Sub_Classify(TopExp_Explorer& Ex,
767 const TopAbs_State St1,
768 TopTools_ListOfShape& Solids2,
769 BRep_Builder& BB,
770 TopTools_ListIteratorOfListOfShape& LIter,
771 TopoDS_Shape& myShape) {
772 Ex.Init(LIter.Value(),TopAbs_VERTEX);
773 if(Ex.More()) {
774 if(St1 == TopAbs_IN) {
775 Standard_Boolean keep = Standard_False;
776 Standard_Boolean ok = Standard_True;
777 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
778 gp_Pnt P=BRep_Tool::Pnt(V);
779 Standard_Real Tol = BRep_Tool::Tolerance(V);
780 TopTools_ListIteratorOfListOfShape SIter;
781 for(SIter.Initialize(Solids2);
782 SIter.More() && ok==Standard_True;
783 SIter.Next()) {
784 BRepClass3d_SolidClassifier SolClass(SIter.Value());
785 SolClass.Perform(P,Tol);
786 if(SolClass.State() == TopAbs_IN) {
787 ok=Standard_False;
788 keep = Standard_True;
789 }
790 }
791 if(keep) {
792 BB.Add(myShape,LIter.Value());
793 }
794 }
795 else {
796 if(St1 == TopAbs_OUT) {
797 Standard_Boolean keep = Standard_True;
798 Standard_Boolean ok = Standard_True;
799 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
800 gp_Pnt P=BRep_Tool::Pnt(V);
801 Standard_Real Tol = BRep_Tool::Tolerance(V);
802 TopTools_ListIteratorOfListOfShape SIter;
803 for(SIter.Initialize(Solids2);
804 SIter.More() && ok==Standard_True;
805 SIter.Next()) {
806 BRepClass3d_SolidClassifier SolClass(SIter.Value());
807 SolClass.Perform(P,Tol);
808 if(SolClass.State() != TopAbs_OUT) {
809 keep = Standard_False;
810 ok = Standard_False;
811 }
812 }
813 if(keep) {
814 BB.Add(myShape,LIter.Value());
815 }
816 }
817 }
818 }
819}
820
821
822//=======================================================================
823//function : InitParameters
0d969553 824//purpose : Info on geometry : PCurve, Approx, ...
7fd59977 825//=======================================================================
826void BRepAlgo_BooleanOperation::InitParameters()
827{
828 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
829 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
830
831 GTofBTofBuilder.Define(TopOpeBRepTool_APPROX);
832 GTofBTofBuilder.DefineCurves(Standard_True);
833 GTofBTofBuilder.DefinePCurves1(Standard_True);
834 GTofBTofBuilder.DefinePCurves2(Standard_True);
835}
836
837//=======================================================================
838//function : Modified
839//purpose :
840//=======================================================================
841const TopTools_ListOfShape& BRepAlgo_BooleanOperation::Modified(const TopoDS_Shape& S)
842{
843 myGenerated.Clear();
844 TopTools_MapOfShape aMap; // to check if shape can be added in list more then one time
845 aMap.Clear();
846 if (myHBuilder->IsSplit(S, TopAbs_OUT)) {
847 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_OUT));
848 for(;It.More();It.Next()) {
849 if (topToSew.IsBound(It.Value()))
850 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
851 else
852 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
853 }
854 }
855 if (myHBuilder->IsSplit(S, TopAbs_IN)) {
856 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_IN));
857 for(;It.More();It.Next()) {
858 if (topToSew.IsBound(It.Value()))
859 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
860 else
861 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
862 }
863 }
864 if (myHBuilder->IsSplit(S, TopAbs_ON)) {
865 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_ON));
866 for(;It.More();It.Next()) {
867 if (topToSew.IsBound(It.Value()))
868 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
869 else
870 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
871 }
872 }
873
874 if (myHBuilder->IsMerged(S, TopAbs_OUT)) {
875 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_OUT));
876 for(;It.More();It.Next()) {
877 if (topToSew.IsBound(It.Value()))
878 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
879 else
880 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
881 }
882 }
883 if (myHBuilder->IsMerged(S, TopAbs_IN)) {
884 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_IN));
885 for(;It.More();It.Next()) {
886 if (topToSew.IsBound(It.Value()))
887 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
888 else
889 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
890 }
891 }
892 if (myHBuilder->IsMerged(S, TopAbs_ON)) {
893 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_ON));
894 for(;It.More();It.Next()) {
895 if (topToSew.IsBound(It.Value()))
896 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
897 else
898 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
899 }
900 }
901 return myGenerated;
902}
903
904
905//=======================================================================
906//function : IsDeleted
907//purpose :
908//=======================================================================
909Standard_Boolean BRepAlgo_BooleanOperation::IsDeleted(const TopoDS_Shape& S)
910{
911 Standard_Boolean Deleted = Standard_True;
912 if (myMap.Contains(S) ||
913 myHBuilder->IsMerged(S, TopAbs_OUT) ||
914 myHBuilder->IsMerged(S, TopAbs_IN) ||
915 myHBuilder->IsMerged(S, TopAbs_ON) ||
916 myHBuilder->IsSplit (S, TopAbs_OUT) ||
917 myHBuilder->IsSplit (S, TopAbs_IN) ||
918 myHBuilder->IsSplit (S, TopAbs_ON))
919 return Standard_False;
920
921 return Deleted;
922}