1 // Created on: 1993-10-15
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
21 #include <BRep_Builder.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepAlgo_BooleanOperation.hxx>
24 #include <BRepBuilderAPI_Sewing.hxx>
25 #include <BRepCheck.hxx>
26 #include <BRepCheck_Edge.hxx>
27 #include <BRepCheck_Shell.hxx>
28 #include <BRepClass3d_SolidClassifier.hxx>
29 #include <BRepLib.hxx>
30 #include <BRepTools_Substitution.hxx>
32 #include <TopExp_Explorer.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_HDataStructure.hxx>
40 #include <TopOpeBRepTool_GeomTool.hxx>
41 #include <TopOpeBRepTool_OutCurveType.hxx>
42 #include <TopTools_IndexedMapOfShape.hxx>
43 #include <TopTools_ListIteratorOfListOfShape.hxx>
44 #include <TopTools_ListOfShape.hxx>
45 #include <TopTools_MapOfShape.hxx>
49 extern Standard_Boolean TopOpeBRepTool_GetcontextNOSEW();
52 #define Opecom(st1,st2) (((st1)==TopAbs_IN) && ((st2)==TopAbs_IN))
53 #define Opefus(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_OUT))
54 #define Opecut(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_IN))
56 // -------------------------------------------------------------------
57 static void Sub_Classify(TopExp_Explorer& Ex,
58 const TopAbs_State St1,
59 TopTools_ListOfShape& Solids2,
61 TopTools_ListIteratorOfListOfShape& LIter,
62 TopoDS_Shape& myShape);
66 Standard_IMPORT Standard_Integer TopOpeBRepTool_BOOOPE_CHECK_DEB;
69 //modified by NIZHNY-MZV Wed Apr 19 17:19:11 2000
70 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
71 //about using of this global variable
72 extern Standard_Boolean GLOBAL_USE_NEW_BUILDER;
74 //modified by NIZNHY-PKV Sun Dec 15 17:17:56 2002 f
75 extern void FDSCNX_Close();// see TopOpeBRepDS_connex.cxx
76 extern void FDSSDM_Close();// see TopOpeBRepDS_samdom.cxx
78 //=======================================================================
79 //function : ~BRepAlgo_BooleanOperation
81 //=======================================================================
82 BRepAlgo_BooleanOperation::~BRepAlgo_BooleanOperation()
87 //modified by NIZNHY-PKV Sun Dec 15 17:17:58 2002 t
89 //=======================================================================
90 //function : BRepAlgoAPI_BooleanOperation
92 //=======================================================================
93 BRepAlgo_BooleanOperation::BRepAlgo_BooleanOperation(const TopoDS_Shape& S1,
94 const TopoDS_Shape& S2)
95 : myS1(S1),myS2(S2),myBuilderCanWork(Standard_False)
97 TopOpeBRepDS_BuildTool BT;
98 myHBuilder = new TopOpeBRepBuild_HBuilder(BT);
101 //=======================================================================
102 //function : PerformDS
104 //=======================================================================
105 void BRepAlgo_BooleanOperation::PerformDS()
107 // const Standard_Boolean CheckShapes = Standard_True;
109 // create a data structure
110 Handle(TopOpeBRepDS_HDataStructure) HDS;
111 if (myHBuilder->DataStructure().IsNull())
112 HDS = new TopOpeBRepDS_HDataStructure();
114 HDS = myHBuilder->DataStructure();
115 HDS->ChangeDS().Init();
118 // fill the data Structure
119 TopOpeBRep_DSFiller DSFiller;
121 // define face/face intersection tolerances
122 Standard_Boolean forcetoli = Standard_False;
124 Standard_Real tolarc=0,toltang=0;
125 TopOpeBRep_ShapeIntersector& tobsi = DSFiller.ChangeShapeIntersector();
126 TopOpeBRep_FacesIntersector& tobfi = tobsi.ChangeFacesIntersector();
127 tobfi.ForceTolerances(tolarc,toltang);
129 DSFiller.Insert(myS1,myS2,HDS);
131 // 020499 : JYL : reject if there is an edge of the SD
132 // not coded sameparameter and not degenerated
133 Standard_Boolean esp = HDS->EdgesSameParameter();
134 Standard_Boolean tede = Standard_True;
136 Standard_Integer i,n = HDS->NbShapes();
137 for (i = 1 ; i <= n; i++) {
138 const TopoDS_Shape& s = HDS->Shape(i);
139 if ( s.ShapeType() == TopAbs_EDGE ) {
140 const TopoDS_Edge& e = TopoDS::Edge(s);
141 Standard_Boolean sp = BRep_Tool::SameParameter(e);
142 Standard_Boolean de = BRep_Tool::Degenerated(e);
144 tede = Standard_False;
150 myBuilderCanWork = (esp || tede) ;
152 if (!esp) std::cout<<"BRepAlgo_BooleanOperation(DEB) some edges not SameParameter"<<std::endl;
154 if (!myBuilderCanWork) return;
156 Standard_Real tol3dAPPROX = 1e-7;
157 Standard_Real tol2dAPPROX = 1e-7;
158 // set tolerance values used by the APPROX process
160 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
161 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
162 GTofBTofBuilder.SetTolerances(tol3dAPPROX,tol2dAPPROX);
164 //modified by NIZHNY-MZV Thu Apr 20 09:35:44 2000
165 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
166 //about using of this global variable
167 GLOBAL_USE_NEW_BUILDER = Standard_True;
168 myHBuilder->Perform(HDS,myS1,myS2);
169 GLOBAL_USE_NEW_BUILDER = Standard_False;
172 //=======================================================================
175 //=======================================================================
176 void BRepAlgo_BooleanOperation::Perform(const TopAbs_State St1,
177 const TopAbs_State St2)
179 if ( ! BuilderCanWork() ) {
183 // modif JYL suite aux modifs LBR #if MODIF ...
184 // on privilegie le traitement KPart (si c'en est un)
186 Standard_Integer kp = myHBuilder->IsKPart();
188 Standard_Boolean sewing = Standard_True;
190 //modified by NIZHNY-MZV Thu Apr 20 09:34:33 2000
191 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
192 //about using of this global variable
193 GLOBAL_USE_NEW_BUILDER = Standard_True;
194 myHBuilder->MergeKPart(St1,St2);
195 GLOBAL_USE_NEW_BUILDER = Standard_False;
197 BB.MakeCompound(TopoDS::Compound(myShape));
200 TopTools_ListIteratorOfListOfShape its(myHBuilder->Merged(myS1,St1));
201 for(; its.More(); its.Next()) BB.Add(myShape,its.Value());
207 //======================================================================
208 //== Exploration of input shapes
209 //== Creation of the list of solids
210 //== Creation of the list of faces OUT OF solid
211 //== Creation of the list of edges OUT OF face
212 Standard_Integer nbs1,nbs2,nbf1,nbf2,nbe1,nbe2,nbv1,nbv2;
214 TopTools_ListOfShape Solids1,Solids2,Faces1,Faces2,Edges1,Edges2,Vertex1,Vertex2;
216 for(Ex.Init(myS1,TopAbs_SOLID),nbs1=0; Ex.More(); Ex.Next()) {
217 Solids1.Append(Ex.Current()); nbs1++;
219 for(Ex.Init(myS2,TopAbs_SOLID),nbs2=0; Ex.More(); Ex.Next()) {
220 Solids2.Append(Ex.Current()); nbs2++;
222 //== Faces not in a solid
223 for(Ex.Init(myS1,TopAbs_FACE,TopAbs_SOLID),nbf1=0; Ex.More(); Ex.Next()) {
224 Faces1.Append(Ex.Current()); nbf1++;
226 for(Ex.Init(myS2,TopAbs_FACE,TopAbs_SOLID),nbf2=0; Ex.More(); Ex.Next()) {
227 Faces2.Append(Ex.Current()); nbf2++;
229 //== Edges not in a solid
230 for(Ex.Init(myS1,TopAbs_EDGE,TopAbs_FACE),nbe1=0; Ex.More(); Ex.Next()) {
231 Edges1.Append(Ex.Current()); nbe1++;
233 for(Ex.Init(myS2,TopAbs_EDGE,TopAbs_FACE),nbe2=0; Ex.More(); Ex.Next()) {
234 Edges2.Append(Ex.Current()); nbe2++;
236 //== Vertices not in an edge
237 for(Ex.Init(myS1,TopAbs_VERTEX,TopAbs_EDGE),nbv1=0; Ex.More(); Ex.Next()) {
238 Vertex1.Append(Ex.Current()); nbv1++;
240 for(Ex.Init(myS2,TopAbs_VERTEX,TopAbs_EDGE),nbv2=0; Ex.More(); Ex.Next()) {
241 Vertex2.Append(Ex.Current()); nbv2++;
244 //-- std::cout<<"Solids1: "<<nbs1<<" Faces1: "<<nbf1<<" Edges1:"<<nbe1<<" Vtx1:"<<nbv1<<std::endl;
245 //-- std::cout<<"Solids2: "<<nbs2<<" Faces2: "<<nbf2<<" Edges2:"<<nbe2<<" Vtx2:"<<nbv2<<std::endl;
249 //== Reject operations without direction
252 //-- Cut Solid by Edge
253 // Standard_Boolean Correct = Standard_True;
254 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_IN)
255 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_IN)) {
256 //-- std::cout<<"***** Invalid Operation : Cut of a Solid by a Non Solid "<<std::endl;
261 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_OUT)
262 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_OUT)) {
263 //-- std::cout<<"***** Invalid Operation : Fusion of a Solid and a Non Solid "<<std::endl;
269 if( (nbs1>0 && nbs2>0)
270 && (nbe1 || nbe2 || nbf1 || nbf2 || nbv1 || nbv2)) {
271 //-- std::cout<<"***** Not Yet Implemented : Compound of solid and non Solid"<<std::endl;
275 //======================================================================
276 // make a compound with the new solids
277 BB.MakeCompound(TopoDS::Compound(myShape));
279 TopTools_ListIteratorOfListOfShape LIter;
280 //----------------------------------------------------------------------
285 if ( Opecom(St1,St2) ) {
286 TopTools_ListIteratorOfListOfShape itloe = myHBuilder->Section();
287 for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
291 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
293 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
294 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
295 TopTools_ListIteratorOfListOfShape its;
296 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
297 its.More();its.Next()) BB.Add(myShape,its.Value());
300 const TopoDS_Shape& LV = LIter.Value();
301 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
302 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
307 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
309 //-- End Classification
314 if ( Opefus(St1,St2) ) {
316 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
317 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
318 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
319 TopTools_ListIteratorOfListOfShape its;
320 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
321 its.More();its.Next()) BB.Add(myShape,its.Value());
324 const TopoDS_Shape& LV = LIter.Value();
325 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
326 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
331 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
333 //-- End Classification
340 else if (nbf1 || nbf2) {
343 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
344 // modified by IFV for treating operation between shell and solid
345 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS1,St1);
346 TopTools_IndexedMapOfShape aMapOfFaces;
348 sewing = Standard_False;
350 if(MergedShapes.Extent() != 0) {
351 TopTools_ListIteratorOfListOfShape its(MergedShapes);
352 for(; its.More(); its.Next()) {
353 BB.Add(myShape,its.Value());
355 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
358 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
360 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
361 TopTools_ListIteratorOfListOfShape its;
362 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
363 its.More();its.Next()) {
364 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
368 const TopoDS_Shape& LV = LIter.Value();
369 if(!aMapOfFaces.Contains(LV)) {
370 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
371 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
376 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
378 //-- End Classification
385 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
386 // modified by IFV for treating operation between shell and solid
387 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS2,St2);
388 TopTools_IndexedMapOfShape aMapOfFaces;
389 sewing = Standard_False;
391 if(MergedShapes.Extent() != 0) {
392 TopTools_ListIteratorOfListOfShape its(MergedShapes);
393 for(; its.More(); its.Next()) {
394 BB.Add(myShape,its.Value());
396 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
399 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
400 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
401 TopTools_ListIteratorOfListOfShape its;
402 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
403 its.More();its.Next()) {
404 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
408 const TopoDS_Shape& LV = LIter.Value();
409 if(!aMapOfFaces.Contains(LV)) {
410 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
411 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
416 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
418 //-- End Classification
425 //----------------------------------------------------------------------
427 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
429 for(LIter.Initialize(Edges1);LIter.More();LIter.Next()) {
430 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
431 TopTools_ListIteratorOfListOfShape its;
432 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
433 its.More();its.Next()) {
434 BB.Add(myShape,its.Value());
438 const TopoDS_Shape& LV = LIter.Value();
439 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
440 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
445 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
447 //-- End Classification
452 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
454 for(LIter.Initialize(Edges2);LIter.More();LIter.Next()) {
455 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
456 TopTools_ListIteratorOfListOfShape its;
457 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
458 its.More();its.Next()) {
459 BB.Add(myShape,its.Value());
463 const TopoDS_Shape& LV = LIter.Value();
464 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
465 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
470 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
472 //-- End Classification
476 //----------------------------------------------------------------------
477 //-- V1:Vertex1 state1 = OUT -> Preserve V1 if V1 is Out all S2
478 //-- V1:Vertex1 state1 = IN -> Preserve V1 if V1 is In one of S2
480 if(St1 == TopAbs_IN) {
481 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
482 Standard_Boolean keep = Standard_False;
483 Standard_Boolean ok = Standard_True;
484 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
485 gp_Pnt P=BRep_Tool::Pnt(V);
486 Standard_Real Tol = BRep_Tool::Tolerance(V);
487 TopTools_ListIteratorOfListOfShape SIter;
488 for(SIter.Initialize(Solids2);
489 SIter.More() && ok==Standard_True;
491 BRepClass3d_SolidClassifier SolClass(SIter.Value());
492 SolClass.Perform(P,Tol);
493 if(SolClass.State() == TopAbs_IN) {
495 keep = Standard_True;
499 BB.Add(myShape,LIter.Value());
504 if(St1 == TopAbs_OUT) {
505 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
506 Standard_Boolean keep = Standard_True;
507 Standard_Boolean ok = Standard_True;
508 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
509 gp_Pnt P=BRep_Tool::Pnt(V);
510 Standard_Real Tol = BRep_Tool::Tolerance(V);
511 TopTools_ListIteratorOfListOfShape SIter;
512 for(SIter.Initialize(Solids2);
513 SIter.More() && ok==Standard_True;
515 BRepClass3d_SolidClassifier SolClass(SIter.Value());
516 SolClass.Perform(P,Tol);
517 if(SolClass.State() != TopAbs_OUT) {
518 keep = Standard_False;
523 BB.Add(myShape,LIter.Value());
531 if(St2 == TopAbs_IN) {
532 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
533 Standard_Boolean keep = Standard_False;
534 Standard_Boolean ok = Standard_True;
535 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
536 gp_Pnt P=BRep_Tool::Pnt(V);
537 Standard_Real Tol = BRep_Tool::Tolerance(V);
538 TopTools_ListIteratorOfListOfShape SIter;
539 for(SIter.Initialize(Solids1);
540 SIter.More() && ok==Standard_True;
542 BRepClass3d_SolidClassifier SolClass(SIter.Value());
543 SolClass.Perform(P,Tol);
544 if(SolClass.State() == TopAbs_IN) {
546 keep = Standard_True;
550 BB.Add(myShape,LIter.Value());
555 if(St2 == TopAbs_OUT) {
556 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
557 Standard_Boolean keep = Standard_True;
558 Standard_Boolean ok = Standard_True;
559 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
560 gp_Pnt P=BRep_Tool::Pnt(V);
561 Standard_Real Tol = BRep_Tool::Tolerance(V);
562 TopTools_ListIteratorOfListOfShape SIter;
563 for(SIter.Initialize(Solids1);
564 SIter.More() && ok==Standard_True;
566 BRepClass3d_SolidClassifier SolClass(SIter.Value());
567 SolClass.Perform(P,Tol);
568 if(SolClass.State() != TopAbs_OUT) {
569 keep = Standard_False;
574 BB.Add(myShape,LIter.Value());
582 myHBuilder->MergeShapes(myS1,St1,myS2,St2);
583 if(myHBuilder->IsMerged(myS1,St1)) {
584 TopTools_ListIteratorOfListOfShape its;
585 its = myHBuilder->Merged(myS1,St1);
586 Standard_Integer nbSolids = 0;
587 for(; its.More(); its.Next(), nbSolids++) {
588 BB.Add(myShape,its.Value());
595 myHBuilder->MergeSolids(myS1,St1,myS2,St2);
596 TopTools_ListIteratorOfListOfShape its;
598 BB.MakeCompound(TopoDS::Compound(myShape));
599 its = myHBuilder->Merged(myS1,St1);
601 BB.Add(myShape,its.Value());
610 // Creation of the Map used in IsDeleted.
612 ex.Init(myShape,TopAbs_FACE);
613 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
614 ex.Init(myShape,TopAbs_EDGE); // for FRIKO
615 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
617 // Checking same parameter of new edges of section
618 Standard_Real eTol,cTol;
619 for (myHBuilder->InitSection(1);
620 myHBuilder->MoreSection();
621 myHBuilder->NextSection()) {
622 const TopoDS_Shape& cur = myHBuilder->CurrentSection();
623 if (cur.ShapeType()==TopAbs_EDGE) {
624 BRepCheck_Edge bce(TopoDS::Edge(cur));
625 cTol=bce.Tolerance();
626 eTol = BRep_Tool::Tolerance(TopoDS::Edge(cur));
628 BB.UpdateEdge(TopoDS::Edge(cur), cTol);
629 for (ex.Init(cur, TopAbs_VERTEX); ex.More(); ex.Next()) {
630 eTol = BRep_Tool::Tolerance(TopoDS::Vertex(ex.Current()));
632 // Update can only increase tolerance, so if the vertex
633 // has a greater tolerance thanits edges it is not touched
634 BB.UpdateVertex(TopoDS::Vertex(ex.Current()), cTol);
641 Standard_Real maxTol = RealLast(); // MSV: unlimit tolerance
642 TopOpeBRepBuild_Tools::CorrectTolerances(myShape,maxTol);
644 TopExp_Explorer ex1, ex2, ex3;
645 TopTools_ListOfShape theOldShell, theNewShell;
646 Standard_Boolean modif =Standard_False;
649 Standard_Boolean nosew = TopOpeBRepTool_GetcontextNOSEW();
650 if (nosew) sewing = Standard_False;
655 for (ex1.Init(myShape, TopAbs_SHELL); ex1.More(); ex1.Next()) {
656 BRepCheck_Shell bcs(TopoDS::Shell(ex1.Current()));
657 if (bcs.Closed()==BRepCheck_NotClosed) {
658 // it is required to add them face by face to avoid IsModified on faces
659 BRepBuilderAPI_Sewing brts;
660 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
661 brts.Add(ex3.Current());
664 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
668 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
669 theOldShell.Append(ex1.Current());
670 theNewShell.Append(ex2.Current());
671 modif =Standard_True;
672 for (ex3.Init(ex1.Current(), TopAbs_EDGE); ex3.More(); ex3.Next()) {
673 const TopoDS_Edge& ledg = TopoDS::Edge(ex3.Current());
674 if (brts.IsSectionBound(ledg)) {
675 topToSew.Bind(ledg, brts.SectionToBoundary(ledg));
676 if (!BRep_Tool::SameParameter(brts.SectionToBoundary(ledg))) {
677 BRepLib::SameParameter(ledg, BRep_Tool::Tolerance(brts.SectionToBoundary(ledg)));
681 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
682 if (brts.IsModified(ex3.Current())) {
683 topToSew.Bind(ex3.Current(), brts.Modified(ex3.Current()));
693 BRepTools_Substitution bsub;
694 TopTools_ListIteratorOfListOfShape itl(theOldShell);
695 TopTools_ListOfShape forSub;
696 for (; itl.More();itl.Next()) {
697 forSub.Append(theNewShell.First());
698 bsub.Substitute(itl.Value(), forSub);
699 theNewShell.RemoveFirst();
703 if (bsub.IsCopied(myShape)) {
704 myShape=(bsub.Copy(myShape)).First();
713 //=======================================================================
716 //=======================================================================
717 Handle(TopOpeBRepBuild_HBuilder) BRepAlgo_BooleanOperation::Builder()const
723 //=======================================================================
724 //function : TopoDS_Shape&
726 //=======================================================================
727 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape1() const
733 //=======================================================================
734 //function : TopoDS_Shape&
736 //=======================================================================
737 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape2() const
742 //=======================================================================
743 //function : BuilderCanWork
745 //=======================================================================
746 void BRepAlgo_BooleanOperation::BuilderCanWork(const Standard_Boolean Val)
748 myBuilderCanWork = Val;
751 //=======================================================================
752 //function : BuilderCanWork
754 //=======================================================================
755 Standard_Boolean BRepAlgo_BooleanOperation::BuilderCanWork() const
757 return myBuilderCanWork;
761 void Sub_Classify(TopExp_Explorer& Ex,
762 const TopAbs_State St1,
763 TopTools_ListOfShape& Solids2,
765 TopTools_ListIteratorOfListOfShape& LIter,
766 TopoDS_Shape& myShape) {
767 Ex.Init(LIter.Value(),TopAbs_VERTEX);
769 if(St1 == TopAbs_IN) {
770 Standard_Boolean keep = Standard_False;
771 Standard_Boolean ok = Standard_True;
772 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
773 gp_Pnt P=BRep_Tool::Pnt(V);
774 Standard_Real Tol = BRep_Tool::Tolerance(V);
775 TopTools_ListIteratorOfListOfShape SIter;
776 for(SIter.Initialize(Solids2);
777 SIter.More() && ok==Standard_True;
779 BRepClass3d_SolidClassifier SolClass(SIter.Value());
780 SolClass.Perform(P,Tol);
781 if(SolClass.State() == TopAbs_IN) {
783 keep = Standard_True;
787 BB.Add(myShape,LIter.Value());
791 if(St1 == TopAbs_OUT) {
792 Standard_Boolean keep = Standard_True;
793 Standard_Boolean ok = Standard_True;
794 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
795 gp_Pnt P=BRep_Tool::Pnt(V);
796 Standard_Real Tol = BRep_Tool::Tolerance(V);
797 TopTools_ListIteratorOfListOfShape SIter;
798 for(SIter.Initialize(Solids2);
799 SIter.More() && ok==Standard_True;
801 BRepClass3d_SolidClassifier SolClass(SIter.Value());
802 SolClass.Perform(P,Tol);
803 if(SolClass.State() != TopAbs_OUT) {
804 keep = Standard_False;
809 BB.Add(myShape,LIter.Value());
817 //=======================================================================
818 //function : InitParameters
819 //purpose : Info on geometry : PCurve, Approx, ...
820 //=======================================================================
821 void BRepAlgo_BooleanOperation::InitParameters()
823 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
824 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
826 GTofBTofBuilder.Define(TopOpeBRepTool_APPROX);
827 GTofBTofBuilder.DefineCurves(Standard_True);
828 GTofBTofBuilder.DefinePCurves1(Standard_True);
829 GTofBTofBuilder.DefinePCurves2(Standard_True);
832 //=======================================================================
833 //function : Modified
835 //=======================================================================
836 const TopTools_ListOfShape& BRepAlgo_BooleanOperation::Modified(const TopoDS_Shape& S)
839 TopTools_MapOfShape aMap; // to check if shape can be added in list more then one time
841 if (myHBuilder->IsSplit(S, TopAbs_OUT)) {
842 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_OUT));
843 for(;It.More();It.Next()) {
844 if (topToSew.IsBound(It.Value()))
845 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
847 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
850 if (myHBuilder->IsSplit(S, TopAbs_IN)) {
851 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_IN));
852 for(;It.More();It.Next()) {
853 if (topToSew.IsBound(It.Value()))
854 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
856 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
859 if (myHBuilder->IsSplit(S, TopAbs_ON)) {
860 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_ON));
861 for(;It.More();It.Next()) {
862 if (topToSew.IsBound(It.Value()))
863 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
865 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
869 if (myHBuilder->IsMerged(S, TopAbs_OUT)) {
870 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_OUT));
871 for(;It.More();It.Next()) {
872 if (topToSew.IsBound(It.Value()))
873 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
875 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
878 if (myHBuilder->IsMerged(S, TopAbs_IN)) {
879 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_IN));
880 for(;It.More();It.Next()) {
881 if (topToSew.IsBound(It.Value()))
882 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
884 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
887 if (myHBuilder->IsMerged(S, TopAbs_ON)) {
888 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_ON));
889 for(;It.More();It.Next()) {
890 if (topToSew.IsBound(It.Value()))
891 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
893 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
900 //=======================================================================
901 //function : IsDeleted
903 //=======================================================================
904 Standard_Boolean BRepAlgo_BooleanOperation::IsDeleted(const TopoDS_Shape& S)
906 Standard_Boolean Deleted = Standard_True;
907 if (myMap.Contains(S) ||
908 myHBuilder->IsMerged(S, TopAbs_OUT) ||
909 myHBuilder->IsMerged(S, TopAbs_IN) ||
910 myHBuilder->IsMerged(S, TopAbs_ON) ||
911 myHBuilder->IsSplit (S, TopAbs_OUT) ||
912 myHBuilder->IsSplit (S, TopAbs_IN) ||
913 myHBuilder->IsSplit (S, TopAbs_ON))
914 return Standard_False;